chore: drop unreachable external knowledge states and helpers

Remove code with no production path: the probeStatus value 'healthy' that no
probe can produce, the external.transportConfirm string and the
remote-missing and config-invalid state strings that nothing renders,
KnowledgeService.searchHybridMany which lost its last caller when chat search
moved to retrieveMany, and the sourceUrl field that no provider parser
populates.

Keep sourceUrl in externalKnowledgeLocatorSchema because that schema parses
already-persisted citations. Point the affected fixtures at catalog-ready,
the status testInstance actually writes.

Document why ProjectActivity adjusts state during render: the guarded call is
the recommended pattern for resetting state on prop changes here, and the
repository lint rule rejects the useEffect alternative.
This commit is contained in:
mesalogo
2026-09-13 16:02:01 +08:00
parent 4222351f3c
commit f7f0332143
7 changed files with 12 additions and 10 deletions
+3 -3
View File
@@ -8459,7 +8459,7 @@ describe('registerIpcHandlers agent terminal state', () => {
})
it('returns no results for an explicitly empty knowledge search scope', async () => {
const searchHybridMany = vi.fn(() => {
const retrieveMany = vi.fn(() => {
throw new Error('must not search')
})
const harness = createHarness(
@@ -8474,7 +8474,7 @@ describe('registerIpcHandlers agent terminal state', () => {
undefined,
{
database: { listKnowledgeBases: vi.fn(() => []) },
searchHybridMany
retrieveMany
}
)
await expect(
@@ -8483,7 +8483,7 @@ describe('registerIpcHandlers agent terminal state', () => {
{ libraryIds: [], query: 'anything' }
)
).resolves.toEqual([])
expect(searchHybridMany).not.toHaveBeenCalled()
expect(retrieveMany).not.toHaveBeenCalled()
await harness.dispose()
})
+1 -1
View File
@@ -6337,7 +6337,7 @@ describe("App", () => {
it("adds a new external binding to the current selection without re-enabling an excluded library", async () => {
const existing = { id: '11111111-1111-4111-8111-111111111111', name: 'Existing', description: '', storageMode: 'managed' as const, graphEnabled: false, graphStrategy: 'rules' as const, sourceCount: 0, documentCount: 0, indexedDocumentCount: 0 };
const excluded = { ...existing, id: '22222222-2222-4222-8222-222222222222', name: 'Excluded' };
const instance = { id: 'instance-1', name: 'Company Dify', provider: 'dify' as const, baseUrl: 'https://knowledge.example', enabled: true, credentialStatus: 'configured' as const, probeStatus: 'healthy' as const, bindingCount: 0 };
const instance = { id: 'instance-1', name: 'Company Dify', provider: 'dify' as const, baseUrl: 'https://knowledge.example', enabled: true, credentialStatus: 'configured' as const, probeStatus: 'catalog-ready' as const, bindingCount: 0 };
const created = { ...existing, id: '33333333-3333-4333-8333-333333333333', name: 'Remote handbook', external: { knowledgeBaseId: '33333333-3333-4333-8333-333333333333', instanceId: instance.id, provider: 'dify' as const, remoteKnowledgeBaseId: 'remote-1', remoteName: 'Remote handbook', commonConfig: { resultLimit: 6, requestTimeoutMs: 15000, maxSnippetCharacters: 4000 }, providerConfig: { provider: 'dify' as const, useDatasetDefaults: true as const }, lastVerifiedAt: '2026-09-12' } };
const initial = { libraries: [existing, excluded], selectedLibraryId: existing.id, sources: [], documents: [], graphNodes: [], graphRelations: [], evidence: [] };
const updated = { ...initial, libraries: [...initial.libraries, created], selectedLibraryId: created.id };
+1 -1
View File
@@ -6,7 +6,7 @@ import type { ExternalKnowledgeInstanceSummary, ExternalKnowledgeCatalogPage } f
import { ExternalBindingForm, ExternalInstanceManager, ExternalLibraryDetail, externalProviderDefaults } from './ExternalKnowledge'
import i18n from './i18n'
const instance: ExternalKnowledgeInstanceSummary = { id: 'instance-1', name: 'Company knowledge', provider: 'dify', baseUrl: 'https://knowledge.example', enabled: true, credentialStatus: 'configured', probeStatus: 'healthy', bindingCount: 0 }
const instance: ExternalKnowledgeInstanceSummary = { id: 'instance-1', name: 'Company knowledge', provider: 'dify', baseUrl: 'https://knowledge.example', enabled: true, credentialStatus: 'configured', probeStatus: 'catalog-ready', bindingCount: 0 }
const library: KnowledgeLibrary = { id: 'external-1', name: 'Handbook', description: '', storageMode: 'managed', graphEnabled: false, graphStrategy: 'model', sourceCount: 0, documentCount: 0, indexedDocumentCount: 0, external: { knowledgeBaseId: 'external-1', instanceId: instance.id, provider: 'dify', remoteKnowledgeBaseId: 'remote-1', remoteName: 'Handbook', commonConfig: { resultLimit: 6, requestTimeoutMs: 15000, maxSnippetCharacters: 4000 }, providerConfig: externalProviderDefaults('dify'), lastVerifiedAt: '2026-09-12' } }
const snapshot: KnowledgeSnapshot = { libraries: [library], sources: [], documents: [], graphNodes: [], graphRelations: [], evidence: [] }
const bridge = {
+1 -1
View File
@@ -265,7 +265,7 @@ describe('KnowledgeWorkspace', () => {
it('searches external names and instances and filters the unified library list', async () => {
await i18n.changeLanguage('en-US')
const external = { ...library, id: 'external-1', name: 'Company handbook', external: { knowledgeBaseId: 'external-1', instanceId: 'instance-1', provider: 'dify' as const, remoteKnowledgeBaseId: 'remote-1', remoteName: 'Remote policies', commonConfig: { resultLimit: 6, requestTimeoutMs: 15000, maxSnippetCharacters: 4000 }, providerConfig: { provider: 'dify' as const, useDatasetDefaults: true as const }, lastVerifiedAt: '2026-09-12' } }
const props = createProps({ libraries: [library, external], externalInstances: [{ id: 'instance-1', name: 'Enterprise service', provider: 'dify', baseUrl: 'https://knowledge.example', enabled: true, credentialStatus: 'configured', probeStatus: 'healthy', bindingCount: 1 }] })
const props = createProps({ libraries: [library, external], externalInstances: [{ id: 'instance-1', name: 'Enterprise service', provider: 'dify', baseUrl: 'https://knowledge.example', enabled: true, credentialStatus: 'configured', probeStatus: 'catalog-ready', bindingCount: 1 }] })
render(<KnowledgeWorkspace {...props} />)
const nav = screen.getByRole('navigation', { name: 'Library list' })
for (const query of ['Remote policies', 'Enterprise service', 'dify']) {
+2
View File
@@ -143,6 +143,8 @@ export function ProjectActivity({
const { t } = useTranslation('workspace')
const [open, setOpen] = useState(false)
if (!activities.length) {
// Adjusting state during render, guarded so it cannot loop: the dialog must
// not stay queued to reopen once the activity it listed has drained.
if (open) setOpen(false)
return null
}
@@ -19,7 +19,7 @@ export const knowledge = {
credentialNote: 'Credentials are encrypted locally and are never returned after saving.', showKey: 'Show credential', hideKey: 'Hide credential',
clearConfirm: 'Clearing the credential makes libraries using this instance unavailable for retrieval.',
transportNote: 'This HTTP address sends credentials and queries without transport encryption.',
transportConfirm: 'I understand and allow credentials to be sent to this address', enabled: 'Enable instance',
enabled: 'Enable instance',
testConnection: 'Test connection', saveInstance: 'Save instance', saved: 'Saved', removed: 'Removed from GoodBuddy',
noInstances: 'No external instances configured', noInstancesHelp: 'Add your existing Dify, FastGPT, or RAGFlow service.',
selectInstance: 'Select an external instance', remote: 'Remote library', remoteId: 'Remote library ID', remoteName: 'Remote name',
@@ -48,7 +48,7 @@ export const knowledge = {
snapshot: 'Historical citation snapshot', documentId: 'Remote document ID', chunkId: 'Remote snippet ID', providerScore: 'Provider score',
elapsed: 'Total {{ms}} ms', returned: '{{returned}} returned · {{kept}} retained', truncated: 'Results truncated',
allSources: 'All sources', searchLibraries: 'Search libraries', selectTarget: 'Select a remote library',
states: { ready: 'Remote retrieval ready', untested: 'Not tested', 'instance-disabled': 'Instance disabled', 'credential-error': 'Credential unavailable', 'remote-missing': 'Remote target missing', 'config-invalid': 'Settings need confirmation', 'temporarily-unavailable': 'Temporarily unavailable' }
states: { ready: 'Remote retrieval ready', untested: 'Not tested', 'instance-disabled': 'Instance disabled', 'credential-error': 'Credential unavailable', 'temporarily-unavailable': 'Temporarily unavailable' }
},
page: {
title: 'Knowledge Base',
@@ -16,7 +16,7 @@ export const knowledge = {
credentialNote: '凭据由本机加密保存,保存后不会回显。', showKey: '显示凭据', hideKey: '隐藏凭据',
clearConfirm: '清除凭据后,使用此实例的知识库将无法检索。',
transportNote: '此 HTTP 地址通过未加密连接传输凭据和查询。',
transportConfirm: '我了解并允许向此地址发送凭据', enabled: '启用实例',
enabled: '启用实例',
testConnection: '测试连接', saveInstance: '保存实例', saved: '已保存', removed: '已从 GoodBuddy 移除',
noInstances: '尚未配置外部实例', noInstancesHelp: '添加企业现有的 Dify、FastGPT 或 RAGFlow 服务。',
selectInstance: '选择外部实例', remote: '远端知识库', remoteId: '远端知识库 ID', remoteName: '远端名称',
@@ -45,7 +45,7 @@ export const knowledge = {
snapshot: '历史引用快照', documentId: '远端文档 ID', chunkId: '远端片段 ID', providerScore: 'Provider 分数',
elapsed: '总耗时 {{ms}} ms', returned: '返回 {{returned}} 条 · 保留 {{kept}} 条', truncated: '结果已截断',
allSources: '全部来源', searchLibraries: '搜索知识库', selectTarget: '选择远端知识库',
states: { ready: '远端可检索', untested: '未测试', 'instance-disabled': '实例已停用', 'credential-error': '凭据不可用', 'remote-missing': '远端目标不存在', 'config-invalid': '配置需要确认', 'temporarily-unavailable': '暂时无法连接' }
states: { ready: '远端可检索', untested: '未测试', 'instance-disabled': '实例已停用', 'credential-error': '凭据不可用', 'temporarily-unavailable': '暂时无法连接' }
},
page: {
title: '知识库',