fix(jsonl): align count-only baseline parsing
This commit is contained in:
parent
7518b5af1d
commit
43afc9f907
2 changed files with 70 additions and 4 deletions
|
|
@ -267,17 +267,38 @@ function isCountableJsonlEntryLine(line: string): boolean {
|
||||||
message?: unknown;
|
message?: unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof entry.uuid !== 'string' || !parseMessageType(String(entry.type))) {
|
const type = typeof entry.type === 'string' ? parseMessageType(entry.type) : null;
|
||||||
|
if (typeof entry.uuid !== 'string' || entry.uuid.length === 0 || !type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.type === 'user' || entry.type === 'assistant') {
|
if (type === 'user') {
|
||||||
return entry.message != null && typeof entry.message === 'object';
|
if (entry.message == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const content = (entry.message as { content?: unknown }).content;
|
||||||
|
return content == null || isParserSafeContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'assistant') {
|
||||||
|
if (!isJsonObjectRecord(entry.message)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const content = entry.message.content;
|
||||||
|
return isParserSafeContent(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isJsonObjectRecord(value: unknown): value is Record<string, unknown> {
|
||||||
|
return value != null && typeof value === 'object' && !Array.isArray(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isParserSafeContent(value: unknown): boolean {
|
||||||
|
return typeof value === 'string' || (Array.isArray(value) && value.every((item) => item != null));
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Entry Parsing
|
// Entry Parsing
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
|
||||||
|
|
@ -212,10 +212,49 @@ describe('jsonl', () => {
|
||||||
timestamp: '2026-01-01T00:00:02.000Z',
|
timestamp: '2026-01-01T00:00:02.000Z',
|
||||||
content: 'system line',
|
content: 'system line',
|
||||||
});
|
});
|
||||||
|
const validUserWithoutContent = JSON.stringify({
|
||||||
|
type: 'user',
|
||||||
|
uuid: 'u1',
|
||||||
|
timestamp: '2026-01-01T00:00:03.000Z',
|
||||||
|
message: {
|
||||||
|
role: 'user',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const validUserArrayMessage = JSON.stringify({
|
||||||
|
type: 'user',
|
||||||
|
uuid: 'u2',
|
||||||
|
timestamp: '2026-01-01T00:00:04.000Z',
|
||||||
|
message: [],
|
||||||
|
});
|
||||||
const invalidMissingMessage = JSON.stringify({
|
const invalidMissingMessage = JSON.stringify({
|
||||||
type: 'assistant',
|
type: 'assistant',
|
||||||
uuid: 'bad-assistant',
|
uuid: 'bad-assistant',
|
||||||
});
|
});
|
||||||
|
const invalidEmptyUuid = JSON.stringify({
|
||||||
|
type: 'system',
|
||||||
|
uuid: '',
|
||||||
|
content: 'empty uuid',
|
||||||
|
});
|
||||||
|
const invalidAssistantMissingContent = JSON.stringify({
|
||||||
|
type: 'assistant',
|
||||||
|
uuid: 'bad-assistant-content',
|
||||||
|
message: {
|
||||||
|
role: 'assistant',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const invalidAssistantArrayMessage = JSON.stringify({
|
||||||
|
type: 'assistant',
|
||||||
|
uuid: 'bad-assistant-array',
|
||||||
|
message: [],
|
||||||
|
});
|
||||||
|
const invalidAssistantNullContentBlock = JSON.stringify({
|
||||||
|
type: 'assistant',
|
||||||
|
uuid: 'bad-assistant-null-block',
|
||||||
|
message: {
|
||||||
|
role: 'assistant',
|
||||||
|
content: [null],
|
||||||
|
},
|
||||||
|
});
|
||||||
const unknownType = JSON.stringify({
|
const unknownType = JSON.stringify({
|
||||||
type: 'unknown',
|
type: 'unknown',
|
||||||
uuid: 'unknown-1',
|
uuid: 'unknown-1',
|
||||||
|
|
@ -228,7 +267,13 @@ describe('jsonl', () => {
|
||||||
[
|
[
|
||||||
validAssistant,
|
validAssistant,
|
||||||
validSystem,
|
validSystem,
|
||||||
|
validUserWithoutContent,
|
||||||
|
validUserArrayMessage,
|
||||||
invalidMissingMessage,
|
invalidMissingMessage,
|
||||||
|
invalidEmptyUuid,
|
||||||
|
invalidAssistantMissingContent,
|
||||||
|
invalidAssistantArrayMessage,
|
||||||
|
invalidAssistantNullContentBlock,
|
||||||
unknownType,
|
unknownType,
|
||||||
'not json',
|
'not json',
|
||||||
partialJson,
|
partialJson,
|
||||||
|
|
@ -239,7 +284,7 @@ describe('jsonl', () => {
|
||||||
const parsed = await parseJsonlFileWithStats(filePath);
|
const parsed = await parseJsonlFileWithStats(filePath);
|
||||||
const counted = await countJsonlFileWithStats(filePath);
|
const counted = await countJsonlFileWithStats(filePath);
|
||||||
|
|
||||||
expect(parsed.messages.map((message) => message.uuid)).toEqual(['a1', 's1']);
|
expect(parsed.messages.map((message) => message.uuid)).toEqual(['a1', 's1', 'u1', 'u2']);
|
||||||
expect(counted.parsedLineCount).toBe(parsed.parsedLineCount);
|
expect(counted.parsedLineCount).toBe(parsed.parsedLineCount);
|
||||||
expect(counted.consumedBytes).toBe(parsed.consumedBytes);
|
expect(counted.consumedBytes).toBe(parsed.consumedBytes);
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue