-
Notifications
You must be signed in to change notification settings - Fork 3.3k
v0.2.6: fix + feat + improvement #612
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e4141e9
24cb3ac
048c31d
c2faf04
acb4e57
901d20d
9aff331
7a5c407
6779ec7
2d5ddf6
bf98c50
ce0a71d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,7 +49,7 @@ In Sim Studio, the Knowledge Base block enables your agents to perform intellige | |
|
|
||
| ## Usage Instructions | ||
|
|
||
| Perform semantic vector search across one or more knowledge bases or upload new chunks to documents. Uses advanced AI embeddings to understand meaning and context for search operations. | ||
| Perform semantic vector search across knowledge bases, upload individual chunks to existing documents, or create new documents from text content. Uses advanced AI embeddings to understand meaning and context for search operations. | ||
|
|
||
|
|
||
|
|
||
|
|
@@ -100,6 +100,25 @@ Upload a new chunk to a document in a knowledge base | |
| | `createdAt` | string | | ||
| | `updatedAt` | string | | ||
|
|
||
| ### `knowledge_create_document` | ||
|
|
||
| Create a new document in a knowledge base | ||
|
|
||
| #### Input | ||
|
|
||
| | Parameter | Type | Required | Description | | ||
| | --------- | ---- | -------- | ----------- | | ||
| | `knowledgeBaseId` | string | Yes | ID of the knowledge base containing the document | | ||
| | `name` | string | Yes | Name of the document | | ||
| | `content` | string | Yes | Content of the document | | ||
|
|
||
| #### Output | ||
|
|
||
| | Parameter | Type | | ||
| | --------- | ---- | | ||
| | `data` | string | | ||
| | `name` | string | | ||
|
Comment on lines
+119
to
+120
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. logic: Output parameters 'data' and 'name' need more detailed type specifications and descriptions |
||
|
|
||
|
|
||
|
|
||
| ## Block Configuration | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,8 +39,9 @@ describe('/api/files/presigned', () => { | |
| const response = await POST(request) | ||
| const data = await response.json() | ||
|
|
||
| expect(response.status).toBe(400) | ||
| expect(response.status).toBe(500) // Changed from 400 to 500 (StorageConfigError) | ||
| expect(data.error).toBe('Direct uploads are only available when cloud storage is enabled') | ||
| expect(data.code).toBe('STORAGE_CONFIG_ERROR') | ||
| expect(data.directUploadSupported).toBe(false) | ||
| }) | ||
|
|
||
|
|
@@ -64,7 +65,8 @@ describe('/api/files/presigned', () => { | |
| const data = await response.json() | ||
|
|
||
| expect(response.status).toBe(400) | ||
| expect(data.error).toBe('Missing fileName or contentType') | ||
| expect(data.error).toBe('fileName is required and cannot be empty') | ||
| expect(data.code).toBe('VALIDATION_ERROR') | ||
| }) | ||
|
|
||
| it('should return error when contentType is missing', async () => { | ||
|
|
@@ -87,7 +89,59 @@ describe('/api/files/presigned', () => { | |
| const data = await response.json() | ||
|
|
||
| expect(response.status).toBe(400) | ||
| expect(data.error).toBe('Missing fileName or contentType') | ||
| expect(data.error).toBe('contentType is required and cannot be empty') | ||
| expect(data.code).toBe('VALIDATION_ERROR') | ||
| }) | ||
|
|
||
| it('should return error when fileSize is invalid', async () => { | ||
| setupFileApiMocks({ | ||
| cloudEnabled: true, | ||
| storageProvider: 's3', | ||
| }) | ||
|
|
||
| const { POST } = await import('./route') | ||
|
|
||
| const request = new NextRequest('http://localhost:3000/api/files/presigned', { | ||
| method: 'POST', | ||
| body: JSON.stringify({ | ||
| fileName: 'test.txt', | ||
| contentType: 'text/plain', | ||
| fileSize: 0, | ||
| }), | ||
| }) | ||
|
|
||
| const response = await POST(request) | ||
| const data = await response.json() | ||
|
|
||
| expect(response.status).toBe(400) | ||
| expect(data.error).toBe('fileSize must be a positive number') | ||
| expect(data.code).toBe('VALIDATION_ERROR') | ||
| }) | ||
|
|
||
| it('should return error when file size exceeds limit', async () => { | ||
| setupFileApiMocks({ | ||
| cloudEnabled: true, | ||
| storageProvider: 's3', | ||
| }) | ||
|
|
||
| const { POST } = await import('./route') | ||
|
|
||
| const largeFileSize = 150 * 1024 * 1024 // 150MB (exceeds 100MB limit) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style: Magic number 150MB should be defined as a constant at the top of the file |
||
| const request = new NextRequest('http://localhost:3000/api/files/presigned', { | ||
| method: 'POST', | ||
| body: JSON.stringify({ | ||
| fileName: 'large-file.txt', | ||
| contentType: 'text/plain', | ||
| fileSize: largeFileSize, | ||
| }), | ||
| }) | ||
|
|
||
| const response = await POST(request) | ||
| const data = await response.json() | ||
|
|
||
| expect(response.status).toBe(400) | ||
| expect(data.error).toContain('exceeds maximum allowed size') | ||
| expect(data.code).toBe('VALIDATION_ERROR') | ||
| }) | ||
|
|
||
| it('should generate S3 presigned URL successfully', async () => { | ||
|
|
@@ -122,6 +176,34 @@ describe('/api/files/presigned', () => { | |
| expect(data.directUploadSupported).toBe(true) | ||
| }) | ||
|
|
||
| it('should generate knowledge-base S3 presigned URL with kb prefix', async () => { | ||
| setupFileApiMocks({ | ||
| cloudEnabled: true, | ||
| storageProvider: 's3', | ||
| }) | ||
|
|
||
| const { POST } = await import('./route') | ||
|
|
||
| const request = new NextRequest( | ||
| 'http://localhost:3000/api/files/presigned?type=knowledge-base', | ||
| { | ||
| method: 'POST', | ||
| body: JSON.stringify({ | ||
| fileName: 'knowledge-doc.pdf', | ||
| contentType: 'application/pdf', | ||
| fileSize: 2048, | ||
| }), | ||
| } | ||
| ) | ||
|
|
||
| const response = await POST(request) | ||
| const data = await response.json() | ||
|
|
||
| expect(response.status).toBe(200) | ||
| expect(data.fileInfo.key).toMatch(/^kb\/.*knowledge-doc\.pdf$/) | ||
| expect(data.directUploadSupported).toBe(true) | ||
| }) | ||
|
|
||
| it('should generate Azure Blob presigned URL successfully', async () => { | ||
| setupFileApiMocks({ | ||
| cloudEnabled: true, | ||
|
|
@@ -182,8 +264,9 @@ describe('/api/files/presigned', () => { | |
| const response = await POST(request) | ||
| const data = await response.json() | ||
|
|
||
| expect(response.status).toBe(400) | ||
| expect(data.error).toBe('Unknown storage provider') | ||
| expect(response.status).toBe(500) // Changed from 400 to 500 (StorageConfigError) | ||
| expect(data.error).toBe('Unknown storage provider: unknown') // Updated error message | ||
| expect(data.code).toBe('STORAGE_CONFIG_ERROR') | ||
| expect(data.directUploadSupported).toBe(false) | ||
| }) | ||
|
|
||
|
|
@@ -225,8 +308,10 @@ describe('/api/files/presigned', () => { | |
| const data = await response.json() | ||
|
|
||
| expect(response.status).toBe(500) | ||
| expect(data.error).toBe('Error') | ||
| expect(data.message).toBe('S3 service unavailable') | ||
| expect(data.error).toBe( | ||
| 'Failed to generate S3 presigned URL - check AWS credentials and permissions' | ||
| ) // Updated error message | ||
| expect(data.code).toBe('STORAGE_CONFIG_ERROR') | ||
| }) | ||
|
|
||
| it('should handle Azure Blob errors gracefully', async () => { | ||
|
|
@@ -269,8 +354,8 @@ describe('/api/files/presigned', () => { | |
| const data = await response.json() | ||
|
|
||
| expect(response.status).toBe(500) | ||
| expect(data.error).toBe('Error') | ||
| expect(data.message).toBe('Azure service unavailable') | ||
| expect(data.error).toBe('Failed to generate Azure Blob presigned URL') // Updated error message | ||
| expect(data.code).toBe('STORAGE_CONFIG_ERROR') | ||
| }) | ||
|
|
||
| it('should handle malformed JSON gracefully', async () => { | ||
|
|
@@ -289,9 +374,9 @@ describe('/api/files/presigned', () => { | |
| const response = await POST(request) | ||
| const data = await response.json() | ||
|
|
||
| expect(response.status).toBe(500) | ||
| expect(data.error).toBe('SyntaxError') | ||
| expect(data.message).toContain('Unexpected token') | ||
| expect(response.status).toBe(400) // Changed from 500 to 400 (ValidationError) | ||
| expect(data.error).toBe('Invalid JSON in request body') // Updated error message | ||
| expect(data.code).toBe('VALIDATION_ERROR') | ||
| }) | ||
| }) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: knowledgeBaseId parameter description should clarify whether this is for new or existing knowledge bases