From dd64109ce55d79152977a7a2492c225be0ffbc22 Mon Sep 17 00:00:00 2001 From: Bill Leoutsakos Date: Sat, 29 Aug 2026 11:20:07 -0700 Subject: [PATCH 1/2] fix(knowledge): expose create document ID output --- apps/sim/tools/knowledge/create_document.ts | 4 +- apps/sim/tools/knowledge/knowledge.test.ts | 66 +++++++++++++++++++++ apps/sim/tools/knowledge/types.ts | 1 + apps/sim/tools/schema-enrichers.test.ts | 3 +- 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/apps/sim/tools/knowledge/create_document.ts b/apps/sim/tools/knowledge/create_document.ts index 3f1f801babf..bd80bcc2418 100644 --- a/apps/sim/tools/knowledge/create_document.ts +++ b/apps/sim/tools/knowledge/create_document.ts @@ -124,6 +124,7 @@ export const knowledgeCreateDocumentTool: InternalToolConfig 1 ? `Successfully created ${uploadCount} documents in knowledge base` : `Successfully created document in knowledge base`, + documentId, data: { - documentId: firstDocument?.documentId || firstDocument?.id || '', + documentId, documentName: uploadCount > 1 ? `${uploadCount} documents` : firstDocument?.filename || 'Unknown', type: 'document', diff --git a/apps/sim/tools/knowledge/knowledge.test.ts b/apps/sim/tools/knowledge/knowledge.test.ts index 0890360ab77..6fd43ad7f9b 100644 --- a/apps/sim/tools/knowledge/knowledge.test.ts +++ b/apps/sim/tools/knowledge/knowledge.test.ts @@ -157,6 +157,72 @@ describe('Knowledge Tools', () => { }) }) + describe('knowledgeCreateDocumentTool', () => { + describe('transformResponse', () => { + it('exposes the created document ID at both the top level and nested data path', async () => { + const result = await knowledgeCreateDocumentTool.transformResponse!( + createMockResponse({ + data: { + documentsCreated: [{ documentId: 'doc-123', filename: 'document.txt' }], + }, + }) + ) + + expect(result.success).toBe(true) + expect(result.output.documentId).toBe('doc-123') + expect(result.output.data.documentId).toBe('doc-123') + }) + + it('uses the legacy document ID fallback for both output paths', async () => { + const result = await knowledgeCreateDocumentTool.transformResponse!( + createMockResponse({ + documentsCreated: [{ id: 'legacy-doc-123', filename: 'document.txt' }], + }) + ) + + expect(result.output.documentId).toBe('legacy-doc-123') + expect(result.output.data.documentId).toBe('legacy-doc-123') + }) + + it.each([ + ['missing documentsCreated', { data: {} }], + ['null documentsCreated', { data: { documentsCreated: null } }], + ['empty documentsCreated', { data: { documentsCreated: [] } }], + ['created document without an ID', { data: { documentsCreated: [{}] } }], + ])('preserves empty IDs for %s', async (_label, responseBody) => { + const result = await knowledgeCreateDocumentTool.transformResponse!( + createMockResponse(responseBody) + ) + + expect(result.success).toBe(true) + expect(result.output.documentId).toBe('') + expect(result.output.data.documentId).toBe('') + }) + }) + + it.each([ + ['omitted tags', {}], + ['an empty tag array', { documentTags: [] }], + ['a serialized empty tag array', { documentTags: '[]' }], + ])('omits tag data and tag provenance for %s', (_label, tagParams) => { + const params = { + knowledgeBaseId: 'kb-1', + name: 'document.txt', + content: 'document content', + ...tagParams, + } + const body = knowledgeCreateDocumentTool.operation.input(params) as { + documents: Array<{ documentTagsData?: string }> + } + + expect(body.documents[0]).not.toHaveProperty('documentTagsData') + expect(knowledgeCreateDocumentTool.operation.secretProvenance?.request?.(params)).toEqual([ + { key: 'document-filename:0', inputPaths: [['name']] }, + { key: 'document-content:0', inputPaths: [['content']] }, + ]) + }) + }) + describe('knowledgeSearchTool', () => { describe('transformResponse', () => { it('should restructure cost information for logging', async () => { diff --git a/apps/sim/tools/knowledge/types.ts b/apps/sim/tools/knowledge/types.ts index 2dfd64a2f5d..0bf1498e0a3 100644 --- a/apps/sim/tools/knowledge/types.ts +++ b/apps/sim/tools/knowledge/types.ts @@ -132,6 +132,7 @@ export interface KnowledgeCreateDocumentResponse { output: { data: KnowledgeCreateDocumentResult message: string + documentId: string } error?: string } diff --git a/apps/sim/tools/schema-enrichers.test.ts b/apps/sim/tools/schema-enrichers.test.ts index 2cdbb82423e..531760dd164 100644 --- a/apps/sim/tools/schema-enrichers.test.ts +++ b/apps/sim/tools/schema-enrichers.test.ts @@ -131,7 +131,7 @@ describe('enrichKBTagsSchema', () => { it('omits the executionId outside an active run', async () => { mockListKnowledgeTagsAsExecutor.mockResolvedValue([]) - await enrichKBTagsSchema('kb-1', { + const result = await enrichKBTagsSchema('kb-1', { userId: 'user-1', workspaceId: 'workspace-1', workflowId: 'workflow-1', @@ -148,6 +148,7 @@ describe('enrichKBTagsSchema', () => { executorDelegationOrigin: EXECUTOR_ORIGIN, }, }) + expect(result).toBeNull() }) it.each([ From c8cd67d7b3b30ffeae3f7605afd0d5f4ead9157a Mon Sep 17 00:00:00 2001 From: Bill Leoutsakos Date: Sat, 29 Aug 2026 11:44:43 -0700 Subject: [PATCH 2/2] test(knowledge): focus create document coverage --- apps/sim/tools/knowledge/knowledge.test.ts | 31 ++-------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/apps/sim/tools/knowledge/knowledge.test.ts b/apps/sim/tools/knowledge/knowledge.test.ts index 6fd43ad7f9b..0ec7a8f2706 100644 --- a/apps/sim/tools/knowledge/knowledge.test.ts +++ b/apps/sim/tools/knowledge/knowledge.test.ts @@ -184,14 +184,9 @@ describe('Knowledge Tools', () => { expect(result.output.data.documentId).toBe('legacy-doc-123') }) - it.each([ - ['missing documentsCreated', { data: {} }], - ['null documentsCreated', { data: { documentsCreated: null } }], - ['empty documentsCreated', { data: { documentsCreated: [] } }], - ['created document without an ID', { data: { documentsCreated: [{}] } }], - ])('preserves empty IDs for %s', async (_label, responseBody) => { + it('preserves empty IDs when no documents are created', async () => { const result = await knowledgeCreateDocumentTool.transformResponse!( - createMockResponse(responseBody) + createMockResponse({ data: { documentsCreated: [] } }) ) expect(result.success).toBe(true) @@ -199,28 +194,6 @@ describe('Knowledge Tools', () => { expect(result.output.data.documentId).toBe('') }) }) - - it.each([ - ['omitted tags', {}], - ['an empty tag array', { documentTags: [] }], - ['a serialized empty tag array', { documentTags: '[]' }], - ])('omits tag data and tag provenance for %s', (_label, tagParams) => { - const params = { - knowledgeBaseId: 'kb-1', - name: 'document.txt', - content: 'document content', - ...tagParams, - } - const body = knowledgeCreateDocumentTool.operation.input(params) as { - documents: Array<{ documentTagsData?: string }> - } - - expect(body.documents[0]).not.toHaveProperty('documentTagsData') - expect(knowledgeCreateDocumentTool.operation.secretProvenance?.request?.(params)).toEqual([ - { key: 'document-filename:0', inputPaths: [['name']] }, - { key: 'document-content:0', inputPaths: [['content']] }, - ]) - }) }) describe('knowledgeSearchTool', () => {