Skip to content

Commit 2c5a852

Browse files
waleedlatif1claude
andcommitted
feat(knowledge): add JSONL file support for knowledge base uploads
Parses JSON Lines files by splitting on newlines and converting to a JSON array, which then flows through the existing JsonYamlChunker. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 97a0bd4 commit 2c5a852

6 files changed

Lines changed: 61 additions & 5 deletions

File tree

apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/add-documents-modal/add-documents-modal.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,8 @@ export function AddDocumentsModal({
263263
{isDragging ? 'Drop files here' : 'Drop files here or click to browse'}
264264
</span>
265265
<span className='text-[var(--text-tertiary)] text-xs'>
266-
PDF, DOC, DOCX, TXT, CSV, XLS, XLSX, MD, PPT, PPTX, HTML (max 100MB each)
266+
PDF, DOC, DOCX, TXT, CSV, XLS, XLSX, MD, PPT, PPTX, HTML, JSONL (max 100MB
267+
each)
267268
</span>
268269
</div>
269270
</Button>

apps/sim/app/workspace/[workspaceId]/knowledge/components/create-base-modal/create-base-modal.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,8 @@ export const CreateBaseModal = memo(function CreateBaseModal({
541541
{isDragging ? 'Drop files here' : 'Drop files here or click to browse'}
542542
</span>
543543
<span className='text-[var(--text-tertiary)] text-xs'>
544-
PDF, DOC, DOCX, TXT, CSV, XLS, XLSX, MD, PPT, PPTX, HTML (max 100MB each)
544+
PDF, DOC, DOCX, TXT, CSV, XLS, XLSX, MD, PPT, PPTX, HTML, JSONL (max 100MB
545+
each)
545546
</span>
546547
</div>
547548
</Button>

apps/sim/lib/file-parsers/index.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,21 @@ function getParserInstances(): Record<string, FileParser> {
8686
}
8787

8888
try {
89-
const { parseJSON, parseJSONBuffer } = require('@/lib/file-parsers/json-parser')
89+
const {
90+
parseJSON,
91+
parseJSONBuffer,
92+
parseJSONL,
93+
parseJSONLBuffer,
94+
} = require('@/lib/file-parsers/json-parser')
9095
parserInstances.json = {
9196
parseFile: parseJSON,
9297
parseBuffer: parseJSONBuffer,
9398
}
94-
logger.info('Loaded JSON parser')
99+
parserInstances.jsonl = {
100+
parseFile: parseJSONL,
101+
parseBuffer: parseJSONLBuffer,
102+
}
103+
logger.info('Loaded JSON/JSONL parser')
95104
} catch (error) {
96105
logger.error('Failed to load JSON parser:', error)
97106
}

apps/sim/lib/file-parsers/json-parser.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,49 @@ export async function parseJSONBuffer(buffer: Buffer): Promise<FileParseResult>
5959
}
6060
}
6161

62+
/**
63+
* Parse JSONL (JSON Lines) files — one JSON object per line
64+
*/
65+
export async function parseJSONL(filePath: string): Promise<FileParseResult> {
66+
const fs = await import('fs/promises')
67+
const content = await fs.readFile(filePath, 'utf-8')
68+
return parseJSONLContent(content)
69+
}
70+
71+
/**
72+
* Parse JSONL from buffer
73+
*/
74+
export async function parseJSONLBuffer(buffer: Buffer): Promise<FileParseResult> {
75+
const content = buffer.toString('utf-8')
76+
return parseJSONLContent(content)
77+
}
78+
79+
function parseJSONLContent(content: string): FileParseResult {
80+
const lines = content.split('\n').filter((line) => line.trim())
81+
const items: unknown[] = []
82+
83+
for (const line of lines) {
84+
try {
85+
items.push(JSON.parse(line))
86+
} catch {
87+
throw new Error(`Invalid JSONL: failed to parse line: ${line.slice(0, 100)}`)
88+
}
89+
}
90+
91+
const formattedContent = JSON.stringify(items, null, 2)
92+
93+
return {
94+
content: formattedContent,
95+
metadata: {
96+
type: 'json',
97+
isArray: true,
98+
keys: [],
99+
itemCount: items.length,
100+
depth: items.length > 0 ? 1 + getJsonDepth(items[0]) : 1,
101+
},
102+
}
103+
}
104+
62105
/**
63106
* Calculate the depth of a JSON object
64107
*/

apps/sim/lib/uploads/utils/file-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ export function validateKnowledgeBaseFile(
366366
return null
367367
}
368368

369-
return `File "${file.name}" has an unsupported format. Please use PDF, DOC, DOCX, TXT, CSV, XLS, XLSX, MD, PPT, PPTX, HTML, JSON, YAML, or YML files.`
369+
return `File "${file.name}" has an unsupported format. Please use PDF, DOC, DOCX, TXT, CSV, XLS, XLSX, MD, PPT, PPTX, HTML, JSON, JSONL, YAML, or YML files.`
370370
}
371371

372372
/**

apps/sim/lib/uploads/utils/validation.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export const SUPPORTED_DOCUMENT_EXTENSIONS = [
2828
'html',
2929
'htm',
3030
'json',
31+
'jsonl',
3132
'yaml',
3233
'yml',
3334
] as const
@@ -135,6 +136,7 @@ export const SUPPORTED_MIME_TYPES: Record<SupportedDocumentExtension, string[]>
135136
html: ['text/html', 'application/xhtml+xml'],
136137
htm: ['text/html', 'application/xhtml+xml'],
137138
json: ['application/json', 'text/json', 'application/x-json'],
139+
jsonl: ['application/jsonl', 'application/x-jsonlines', 'text/jsonl', 'application/octet-stream'],
138140
yaml: ['text/yaml', 'text/x-yaml', 'application/yaml', 'application/x-yaml'],
139141
yml: ['text/yaml', 'text/x-yaml', 'application/yaml', 'application/x-yaml'],
140142
}

0 commit comments

Comments
 (0)