fix: make local knowledge bases ready for daily use
Knowledge selection was shared globally, document readiness overstated usable content, and important import and source-management paths exposed technical details or lacked safe recovery actions. Knowledge scope now persists per conversation, readiness reflects real processing channels, and the workspace guides users from creation and import into cited chat with controlled source actions. Release note: 知识库现按对话保存使用范围,准确区分可用、处理中和失败文档,并提供更简洁的创建、检索测试、来源打开、删除确认和失败重试流程。
This commit is contained in:
@@ -298,6 +298,38 @@ describe('conversation branch contracts', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('conversation knowledge scope contracts', () => {
|
||||
it('persists a bounded per-conversation knowledge library selection', () => {
|
||||
const knowledgeLibraryIds = [
|
||||
'00000000-0000-4000-8000-000000000301',
|
||||
'00000000-0000-4000-8000-000000000302'
|
||||
]
|
||||
expect(
|
||||
conversationSnapshotSchema.parse({
|
||||
id: '00000000-0000-4000-8000-000000000303',
|
||||
knowledgeLibraryIds,
|
||||
knowledgeRetrievalMode: 'always',
|
||||
title: '知识问答',
|
||||
updatedAt: 1,
|
||||
messages: []
|
||||
}).knowledgeLibraryIds
|
||||
).toEqual(knowledgeLibraryIds)
|
||||
expect(
|
||||
conversationSnapshotSchema.safeParse({
|
||||
id: '00000000-0000-4000-8000-000000000303',
|
||||
knowledgeLibraryIds: Array.from(
|
||||
{ length: 21 },
|
||||
(_, index) =>
|
||||
`00000000-0000-4000-8000-${String(index).padStart(12, '0')}`
|
||||
),
|
||||
title: '知识问答',
|
||||
updatedAt: 1,
|
||||
messages: []
|
||||
}).success
|
||||
).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('conversation persistence contracts', () => {
|
||||
it('preserves complete tool details without persistence length limits', () => {
|
||||
const input = 'input'.repeat(10_000)
|
||||
|
||||
@@ -485,6 +485,7 @@ export const conversationSnapshotSchema = z
|
||||
id: assistantIdSchema,
|
||||
projectId: assistantIdSchema.optional(),
|
||||
runtimeSelection: agentRuntimeSelectionSchema.optional(),
|
||||
knowledgeLibraryIds: z.array(assistantIdSchema).max(20).optional(),
|
||||
knowledgeRetrievalMode: z.enum(['auto', 'always']).optional(),
|
||||
contextMetrics: conversationContextMetricsSchema.optional(),
|
||||
contextCompressionState:
|
||||
|
||||
@@ -139,6 +139,7 @@ import type {
|
||||
KnowledgeChunkPage,
|
||||
KnowledgeChunkUpdateInput,
|
||||
KnowledgeChunksListInput,
|
||||
KnowledgeDocumentOpenInput,
|
||||
KnowledgeDocumentRebuildInput,
|
||||
KnowledgeLibraryRebuildInput,
|
||||
KnowledgeReferenceContext,
|
||||
@@ -1477,6 +1478,8 @@ export type KnowledgeLibrary = z.infer<typeof knowledgeCreateSchema> & {
|
||||
sourceCount: number
|
||||
documentCount: number
|
||||
indexedDocumentCount: number
|
||||
processingDocumentCount?: number
|
||||
failedDocumentCount?: number
|
||||
retrievalSettings?: KnowledgeRetrievalSettings
|
||||
chunkingSettings?: KnowledgeChunkingSettings
|
||||
chunkingRebuildRequired?: boolean
|
||||
@@ -1505,6 +1508,9 @@ export type KnowledgeDocumentItem = {
|
||||
name: string
|
||||
path?: string
|
||||
status: 'queued' | 'parsing' | 'indexing' | 'ready' | 'failed'
|
||||
textIndexStatus?: 'waiting' | 'ready' | 'failed'
|
||||
vectorIndexStatus?: 'disabled' | 'waiting' | 'ready' | 'failed' | 'missing'
|
||||
graphIndexStatus?: 'disabled' | 'on-demand' | 'waiting' | 'ready' | 'failed'
|
||||
indexProgress?: number
|
||||
chunkCount?: number
|
||||
size?: number
|
||||
@@ -2144,6 +2150,9 @@ export type DesktopApi = {
|
||||
rebuildDocument: (
|
||||
input: KnowledgeDocumentRebuildInput
|
||||
) => Promise<KnowledgeSnapshot>
|
||||
openDocumentSource: (
|
||||
input: KnowledgeDocumentOpenInput
|
||||
) => Promise<void>
|
||||
rebuildLibrary: (
|
||||
input: KnowledgeLibraryRebuildInput
|
||||
) => Promise<{ rebuilt: number; failed: number }>
|
||||
|
||||
@@ -276,6 +276,7 @@ export const ipcChannels = {
|
||||
knowledgeUpdateChunk: 'knowledge:chunk:update',
|
||||
knowledgeDeleteChunk: 'knowledge:chunk:delete',
|
||||
knowledgeRebuildDocument: 'knowledge:document:rebuild',
|
||||
knowledgeOpenDocumentSource: 'knowledge:document:open-source',
|
||||
knowledgeRebuildLibrary: 'knowledge:library:rebuild',
|
||||
knowledgeCancelRebuild: 'knowledge:library:rebuild:cancel',
|
||||
knowledgeEmbeddingIndexGet: 'knowledge:embedding-index:get',
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
defaultKnowledgeRetrievalSettings,
|
||||
knowledgeChunkingSettingsSchema,
|
||||
knowledgeChunkUpdateInputSchema,
|
||||
knowledgeDocumentOpenInputSchema,
|
||||
knowledgeRetrievalSettingsSchema,
|
||||
knowledgeRetrieveInputSchema
|
||||
} from './knowledge-contracts'
|
||||
@@ -85,5 +86,21 @@ describe('knowledge contracts', () => {
|
||||
chunkId: 'chunk'
|
||||
}).success
|
||||
).toBe(false)
|
||||
expect(
|
||||
knowledgeDocumentOpenInputSchema.parse({
|
||||
knowledgeBaseId: 'library',
|
||||
documentId: 'document'
|
||||
})
|
||||
).toEqual({
|
||||
knowledgeBaseId: 'library',
|
||||
documentId: 'document'
|
||||
})
|
||||
expect(
|
||||
knowledgeDocumentOpenInputSchema.safeParse({
|
||||
knowledgeBaseId: 'library',
|
||||
documentId: 'document',
|
||||
path: 'C:\\untrusted.docx'
|
||||
}).success
|
||||
).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -315,6 +315,16 @@ export type KnowledgeDocumentRebuildInput = z.infer<
|
||||
typeof knowledgeDocumentRebuildInputSchema
|
||||
>
|
||||
|
||||
export const knowledgeDocumentOpenInputSchema = z
|
||||
.object({
|
||||
knowledgeBaseId: idSchema,
|
||||
documentId: idSchema
|
||||
})
|
||||
.strict()
|
||||
export type KnowledgeDocumentOpenInput = z.infer<
|
||||
typeof knowledgeDocumentOpenInputSchema
|
||||
>
|
||||
|
||||
export const knowledgeLibraryRebuildInputSchema = z
|
||||
.object({
|
||||
knowledgeBaseId: idSchema
|
||||
|
||||
Reference in New Issue
Block a user