Skip to content

Commit f36a140

Browse files
Adam GoughAdam Gough
authored andcommitted
improvement: added knowledge upload
1 parent e93a5ce commit f36a140

6 files changed

Lines changed: 213 additions & 4 deletions

File tree

apps/docs/content/docs/tools/knowledge.mdx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,25 @@ Upload a new chunk to a document in a knowledge base
100100
| `createdAt` | string |
101101
| `updatedAt` | string |
102102

103+
### `knowledge_upload_document`
104+
105+
Upload documents to a knowledge base
106+
107+
#### Input
108+
109+
| Parameter | Type | Required | Description |
110+
| --------- | ---- | -------- | ----------- |
111+
| `knowledgeBaseId` | string | Yes | ID of the knowledge base containing the document |
112+
| `knowledgeBaseName` | string | Yes | Name of the knowledge base to upload the document to |
113+
| `file` | file | Yes | Document\(s\) to upload |
114+
115+
#### Output
116+
117+
| Parameter | Type |
118+
| --------- | ---- |
119+
| `data` | string |
120+
| `name` | string |
121+
103122

104123

105124
## Block Configuration

apps/sim/blocks/blocks/knowledge.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@ export const KnowledgeBlock: BlockConfig = {
1212
category: 'blocks',
1313
docsLink: 'https://docs.simstudio.ai/blocks/knowledge',
1414
tools: {
15-
access: ['knowledge_search', 'knowledge_upload_chunk'],
15+
access: ['knowledge_search', 'knowledge_upload_chunk', 'knowledge_upload_document'],
1616
config: {
1717
tool: (params) => {
1818
switch (params.operation) {
1919
case 'search':
2020
return 'knowledge_search'
2121
case 'upload_chunk':
2222
return 'knowledge_upload_chunk'
23+
case 'upload_document':
24+
return 'knowledge_upload_document'
2325
default:
2426
return 'knowledge_search'
2527
}
@@ -53,6 +55,7 @@ export const KnowledgeBlock: BlockConfig = {
5355
options: [
5456
{ label: 'Search', id: 'search' },
5557
{ label: 'Upload Chunk', id: 'upload_chunk' },
58+
{ label: 'Upload Document', id: 'upload_document' },
5659
],
5760
value: () => 'search',
5861
},
@@ -72,7 +75,7 @@ export const KnowledgeBlock: BlockConfig = {
7275
layout: 'full',
7376
placeholder: 'Select knowledge base',
7477
multiSelect: false,
75-
condition: { field: 'operation', value: 'upload_chunk' },
78+
condition: { field: 'operation', value: ['upload_chunk', 'upload_document'] },
7679
},
7780
{
7881
id: 'query',
@@ -98,6 +101,17 @@ export const KnowledgeBlock: BlockConfig = {
98101
placeholder: 'Select document',
99102
condition: { field: 'operation', value: 'upload_chunk' },
100103
},
104+
{
105+
id: 'file',
106+
title: 'File',
107+
type: 'file-upload',
108+
layout: 'full',
109+
placeholder: 'Select file to upload',
110+
condition: { field: 'operation', value: 'upload_document' },
111+
acceptedTypes: '.pdf,.doc,.docx,.txt,.csv,.xls,.xlsx',
112+
multiple: true, // Allow multiple document uploads
113+
maxSize: 100, // 100MB max for knowledge document uploads
114+
},
101115
{
102116
id: 'content',
103117
title: 'Chunk Content',

apps/sim/tools/knowledge/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { knowledgeSearchTool } from './search'
22
import { knowledgeUploadChunkTool } from './upload_chunk'
3+
import { knowledgeUploadDocumentTool } from './upload_document'
34

4-
export { knowledgeSearchTool, knowledgeUploadChunkTool }
5+
export { knowledgeSearchTool, knowledgeUploadChunkTool, knowledgeUploadDocumentTool }

apps/sim/tools/knowledge/types.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,24 @@ export interface KnowledgeUploadChunkParams {
4949
content: string
5050
enabled?: boolean
5151
}
52+
53+
export interface KnowledgeUploadDocumentResult {
54+
id: string
55+
name: string
56+
size: number
57+
type: string
58+
url: string
59+
enabled: boolean
60+
createdAt: string
61+
updatedAt: string
62+
}
63+
64+
export interface KnowledgeUploadDocumentResponse {
65+
success: boolean
66+
output: {
67+
data: KnowledgeUploadDocumentResult
68+
message: string
69+
documentId: string
70+
}
71+
error?: string
72+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import type { ToolConfig } from '../types'
2+
import type { KnowledgeUploadDocumentResponse } from './types'
3+
4+
export const knowledgeUploadDocumentTool: ToolConfig<any, KnowledgeUploadDocumentResponse> = {
5+
id: 'knowledge_upload_document',
6+
name: 'Knowledge Upload Document',
7+
description: 'Upload documents to a knowledge base',
8+
version: '1.0.0',
9+
params: {
10+
knowledgeBaseId: {
11+
type: 'string',
12+
required: true,
13+
description: 'ID of the knowledge base containing the document',
14+
},
15+
knowledgeBaseName: {
16+
type: 'string',
17+
required: true,
18+
description: 'Name of the knowledge base to upload the document to',
19+
},
20+
file: {
21+
type: 'file',
22+
required: true,
23+
description: 'Document(s) to upload',
24+
},
25+
},
26+
request: {
27+
url: (params) => `/api/knowledge/${params.knowledgeBaseId}/documents`,
28+
method: 'POST',
29+
headers: () => ({
30+
'Content-Type': 'application/json',
31+
}),
32+
body: (params) => {
33+
// Handle both single file and array of files from FileUpload component
34+
const files = Array.isArray(params.file) ? params.file : [params.file]
35+
36+
// Map files to the expected document format
37+
const documents = files.map(
38+
(fileData: { name: string; path: string; size: number; type: string }) => {
39+
// Create file URL (handle both relative and absolute paths)
40+
const fileUrl = fileData.path?.startsWith('http')
41+
? fileData.path
42+
: `${typeof window !== 'undefined' ? window.location.origin : ''}${fileData.path}`
43+
44+
return {
45+
filename: fileData.name,
46+
fileUrl: fileUrl,
47+
fileSize: fileData.size,
48+
mimeType: fileData.type,
49+
}
50+
}
51+
)
52+
53+
// Use bulk upload format (required for processing)
54+
const requestBody = {
55+
documents: documents,
56+
processingOptions: {
57+
chunkSize: 1024,
58+
minCharactersPerChunk: 100,
59+
chunkOverlap: 200,
60+
recipe: 'default',
61+
lang: 'en',
62+
},
63+
bulk: true,
64+
}
65+
66+
return requestBody
67+
},
68+
isInternalRoute: true,
69+
},
70+
transformResponse: async (response): Promise<KnowledgeUploadDocumentResponse> => {
71+
try {
72+
const result = await response.json()
73+
74+
if (!response.ok) {
75+
const errorMessage = result.error?.message || result.message || 'Failed to upload documents'
76+
throw new Error(errorMessage)
77+
}
78+
79+
const data = result.data || result
80+
const documentsCreated = data.documentsCreated || []
81+
82+
// Handle multiple documents response
83+
const uploadCount = documentsCreated.length
84+
const firstDocument = documentsCreated[0]
85+
86+
return {
87+
success: true,
88+
output: {
89+
data: {
90+
id: firstDocument?.documentId || firstDocument?.id || '',
91+
name:
92+
uploadCount > 1 ? `${uploadCount} documents` : firstDocument?.filename || 'Unknown',
93+
size: 0, // Size not returned in bulk response
94+
type: 'document',
95+
url: '',
96+
createdAt: new Date().toISOString(),
97+
updatedAt: new Date().toISOString(),
98+
enabled: true,
99+
},
100+
message:
101+
uploadCount > 1
102+
? `Successfully uploaded ${uploadCount} documents to knowledge base`
103+
: `Successfully uploaded document to knowledge base`,
104+
documentId: firstDocument?.documentId || firstDocument?.id || '',
105+
},
106+
}
107+
} catch (error: any) {
108+
return {
109+
success: false,
110+
output: {
111+
data: {
112+
id: '',
113+
name: '',
114+
size: 0,
115+
type: '',
116+
url: '',
117+
enabled: true,
118+
createdAt: '',
119+
updatedAt: '',
120+
},
121+
message: `Failed to upload documents: ${error.message || 'Unknown error'}`,
122+
documentId: '',
123+
},
124+
error: `Failed to upload documents: ${error.message || 'Unknown error'}`,
125+
}
126+
}
127+
},
128+
transformError: async (error): Promise<KnowledgeUploadDocumentResponse> => {
129+
const errorMessage = `Failed to upload documents: ${error.message || 'Unknown error'}`
130+
return {
131+
success: false,
132+
output: {
133+
data: {
134+
id: '',
135+
name: '',
136+
size: 0,
137+
type: '',
138+
url: '',
139+
enabled: true,
140+
createdAt: '',
141+
updatedAt: '',
142+
},
143+
message: errorMessage,
144+
documentId: '',
145+
},
146+
error: errorMessage,
147+
}
148+
},
149+
}

apps/sim/tools/registry.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ import { contactsTool as hubspotContacts } from './hubspot/contacts'
5353
import { huggingfaceChatTool } from './huggingface'
5454
import { readUrlTool } from './jina'
5555
import { jiraBulkRetrieveTool, jiraRetrieveTool, jiraUpdateTool, jiraWriteTool } from './jira'
56-
import { knowledgeSearchTool, knowledgeUploadChunkTool } from './knowledge'
56+
import {
57+
knowledgeSearchTool,
58+
knowledgeUploadChunkTool,
59+
knowledgeUploadDocumentTool,
60+
} from './knowledge'
5761
import { linearCreateIssueTool, linearReadIssuesTool } from './linear'
5862
import { linkupSearchTool } from './linkup'
5963
import { mem0AddMemoriesTool, mem0GetMemoriesTool, mem0SearchMemoriesTool } from './mem0'
@@ -191,6 +195,7 @@ export const tools: Record<string, ToolConfig> = {
191195
memory_delete: memoryDeleteTool,
192196
knowledge_search: knowledgeSearchTool,
193197
knowledge_upload_chunk: knowledgeUploadChunkTool,
198+
knowledge_upload_document: knowledgeUploadDocumentTool,
194199
elevenlabs_tts: elevenLabsTtsTool,
195200
s3_get_object: s3GetObjectTool,
196201
telegram_message: telegramMessageTool,

0 commit comments

Comments
 (0)