@gobing-ai/ts-llm-jsonl-importer 0.4.41 → 0.4.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/mappers.d.ts +10 -2
- package/dist/mappers.d.ts.map +1 -1
- package/dist/mappers.js +43 -5
- package/package.json +4 -4
- package/src/index.ts +1 -0
- package/src/mappers.ts +48 -5
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { HistoryImportError } from './errors';
|
|
|
2
2
|
export { sha256, stableJson } from './hash';
|
|
3
3
|
export { runJsonlImport } from './importer';
|
|
4
4
|
export { applyHistoryImportSchema, normalizeSourceFilePaths } from './jsonl-importer-dao';
|
|
5
|
+
export { sessionIdFromSourcePath } from './mappers';
|
|
5
6
|
export { type OpenCodeImportOptions, runOpenCodeImport } from './opencode-importer';
|
|
6
7
|
export { DEFAULT_REDACTION_RULES, redactRecord, redactValue } from './redaction';
|
|
7
8
|
export { HISTORY_IMPORT_SCHEMA_SQL } from './schema-sql';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAAE,KAAK,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EACH,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,GAC3B,MAAM,WAAW,CAAC;AACnB,YAAY,EACR,cAAc,EACd,WAAW,EACX,UAAU,EACV,aAAa,EACb,YAAY,EACZ,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,gBAAgB,GACnB,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,KAAK,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EACH,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,GAC3B,MAAM,WAAW,CAAC;AACnB,YAAY,EACR,cAAc,EACd,WAAW,EACX,UAAU,EACV,aAAa,EACb,YAAY,EACZ,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,gBAAgB,GACnB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export { HistoryImportError } from './errors.js';
|
|
|
2
2
|
export { sha256, stableJson } from './hash.js';
|
|
3
3
|
export { runJsonlImport } from './importer.js';
|
|
4
4
|
export { applyHistoryImportSchema, normalizeSourceFilePaths } from './jsonl-importer-dao.js';
|
|
5
|
+
export { sessionIdFromSourcePath } from './mappers.js';
|
|
5
6
|
export { runOpenCodeImport } from './opencode-importer.js';
|
|
6
7
|
export { DEFAULT_REDACTION_RULES, redactRecord, redactValue } from './redaction.js';
|
|
7
8
|
export { HISTORY_IMPORT_SCHEMA_SQL } from './schema-sql.js';
|
package/dist/mappers.d.ts
CHANGED
|
@@ -53,11 +53,19 @@ export interface ClaudeToolResultTiming {
|
|
|
53
53
|
*/
|
|
54
54
|
export declare function claudeToolResultTiming(raw: Record<string, unknown>): ClaudeToolResultTiming | null;
|
|
55
55
|
/** Map a Codex JSONL record into one or more ETL split entries. */
|
|
56
|
-
export declare function codexSplit(raw: Record<string, unknown
|
|
56
|
+
export declare function codexSplit(raw: Record<string, unknown>, context?: TransformContext): readonly SplitEntry[];
|
|
57
57
|
/** Map an Antigravity (AGY) JSONL record into one or more ETL split entries. */
|
|
58
|
-
export declare function agySplit(raw: Record<string, unknown
|
|
58
|
+
export declare function agySplit(raw: Record<string, unknown>, context?: TransformContext): readonly SplitEntry[];
|
|
59
59
|
/** Map Gemini CLI message, tool, and session-state events into the forensic contract tables. */
|
|
60
60
|
export declare function geminiSplit(raw: Record<string, unknown>, context?: TransformContext): readonly SplitEntry[];
|
|
61
|
+
/**
|
|
62
|
+
* Pure helper extracting canonical session identity from source transcript paths (task 0638 R4).
|
|
63
|
+
*
|
|
64
|
+
* Normalizes POSIX/Windows separators and returns only valid UUID-shaped identifiers:
|
|
65
|
+
* - agy: segment immediately following `/brain/`
|
|
66
|
+
* - codex: trailing UUID before `.jsonl` in a filename beginning with `rollout-`
|
|
67
|
+
*/
|
|
68
|
+
export declare function sessionIdFromSourcePath(source: string, sourceFile: string): string | undefined;
|
|
61
69
|
/** Map a Grok JSONL record into one or more ETL split entries. */
|
|
62
70
|
export declare function grokSplit(raw: Record<string, unknown>): readonly SplitEntry[];
|
|
63
71
|
/** Compute a stable field-shape key from a JSON object: sorted, lowercased, +-joined top-level keys. */
|
package/dist/mappers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAoExE,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAGhD;AAwCD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAMhG;AAMD,yEAAyE;AACzE,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,UAAU,EAAE,CAkH/E;AAMD,gEAAgE;AAChE,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,UAAU,EAAE,CAmHvG;AAmBD,kEAAkE;AAClE,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,UAAU,EAAE,CA+GxG;AAoBD,mFAAmF;AACnF,MAAM,WAAW,mBAAmB;IAChC,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,yDAAyD;IACzD,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,+FAA+F;AAC/F,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CASrE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB,GAAG,IAAI,CAS5F;AAMD,wEAAwE;AACxE,MAAM,WAAW,sBAAsB;IACnC,uFAAuF;IACvF,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,sBAAsB,GAAG,IAAI,CAkBlG;AAMD,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"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"}
|
package/dist/mappers.js
CHANGED
|
@@ -549,16 +549,25 @@ export function claudeToolResultTiming(raw) {
|
|
|
549
549
|
// Codex mapper
|
|
550
550
|
// ---------------------------------------------------------------------------
|
|
551
551
|
/** Map a Codex JSONL record into one or more ETL split entries. */
|
|
552
|
-
export function codexSplit(raw) {
|
|
552
|
+
export function codexSplit(raw, context) {
|
|
553
553
|
const entries = [];
|
|
554
554
|
const payload = (raw.payload ?? raw);
|
|
555
|
-
const sessionId = s(raw.session_id, o(raw.session_meta).id, raw.id) ?? 'unknown';
|
|
556
555
|
const seq = typeof raw.seq === 'number' ? raw.seq : 0;
|
|
557
556
|
const ts = timestampOf(raw.timestamp, raw.ts, payload.ts);
|
|
558
557
|
const recordType = String(raw.type ?? '');
|
|
559
558
|
const payloadType = String(payload.type ?? '');
|
|
559
|
+
const isShortFormat = recordType === '' && raw.id !== undefined && raw.timestamp !== undefined && raw.instructions !== undefined;
|
|
560
|
+
let explicitSessionId = s(raw.session_id, o(raw.session_meta).id);
|
|
561
|
+
if (explicitSessionId === undefined && recordType === 'session_meta') {
|
|
562
|
+
explicitSessionId = s(payload.id, o(raw.payload).id);
|
|
563
|
+
}
|
|
564
|
+
if (explicitSessionId === undefined && isShortFormat) {
|
|
565
|
+
explicitSessionId = s(raw.id);
|
|
566
|
+
}
|
|
567
|
+
const pathSessionId = context?.sourceFile ? sessionIdFromSourcePath('codex', context.sourceFile) : undefined;
|
|
568
|
+
const sessionId = explicitSessionId ?? pathSessionId ?? 'unknown';
|
|
560
569
|
// Check for older short format
|
|
561
|
-
if (
|
|
570
|
+
if (isShortFormat) {
|
|
562
571
|
return [
|
|
563
572
|
{
|
|
564
573
|
targetTable: 'history_message',
|
|
@@ -711,10 +720,12 @@ export function codexSplit(raw) {
|
|
|
711
720
|
// AGY mapper (Antigravity CLI)
|
|
712
721
|
// ---------------------------------------------------------------------------
|
|
713
722
|
/** Map an Antigravity (AGY) JSONL record into one or more ETL split entries. */
|
|
714
|
-
export function agySplit(raw) {
|
|
723
|
+
export function agySplit(raw, context) {
|
|
715
724
|
const entries = [];
|
|
716
725
|
const recordType = String(raw.type ?? '');
|
|
717
|
-
const
|
|
726
|
+
const explicitSessionId = s(raw.session_id, raw.conversation_id);
|
|
727
|
+
const pathSessionId = context?.sourceFile ? sessionIdFromSourcePath('agy', context.sourceFile) : undefined;
|
|
728
|
+
const sessionId = explicitSessionId ?? pathSessionId ?? 'unknown';
|
|
718
729
|
const seq = typeof raw.seq === 'number' ? raw.seq : typeof raw.step_index === 'number' ? raw.step_index : 0;
|
|
719
730
|
const ts = timestampOf(raw.created_at, raw.timestamp, raw.ts);
|
|
720
731
|
let role;
|
|
@@ -902,6 +913,33 @@ export function geminiSplit(raw, context) {
|
|
|
902
913
|
}
|
|
903
914
|
return entries;
|
|
904
915
|
}
|
|
916
|
+
const UUID_PATTERN = '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';
|
|
917
|
+
const AGY_BRAIN_REGEX = new RegExp(`(?:^|\\/)brain\\/(${UUID_PATTERN})(?:\\/|$)`, 'i');
|
|
918
|
+
const CODEX_ROLLOUT_REGEX = new RegExp(`(?:^|-|_)(${UUID_PATTERN})$`, 'i');
|
|
919
|
+
/**
|
|
920
|
+
* Pure helper extracting canonical session identity from source transcript paths (task 0638 R4).
|
|
921
|
+
*
|
|
922
|
+
* Normalizes POSIX/Windows separators and returns only valid UUID-shaped identifiers:
|
|
923
|
+
* - agy: segment immediately following `/brain/`
|
|
924
|
+
* - codex: trailing UUID before `.jsonl` in a filename beginning with `rollout-`
|
|
925
|
+
*/
|
|
926
|
+
export function sessionIdFromSourcePath(source, sourceFile) {
|
|
927
|
+
const normalized = sourceFile.replace(/\\/g, '/');
|
|
928
|
+
const sLower = source.toLowerCase();
|
|
929
|
+
if (sLower === 'agy' || sLower === 'antigravity') {
|
|
930
|
+
const match = normalized.match(AGY_BRAIN_REGEX);
|
|
931
|
+
return match?.[1];
|
|
932
|
+
}
|
|
933
|
+
if (sLower === 'codex') {
|
|
934
|
+
const basename = normalized.split('/').at(-1) ?? '';
|
|
935
|
+
if (basename.startsWith('rollout-') && basename.endsWith('.jsonl')) {
|
|
936
|
+
const stem = basename.slice(0, -6);
|
|
937
|
+
const match = stem.match(CODEX_ROLLOUT_REGEX);
|
|
938
|
+
return match?.[1];
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
return undefined;
|
|
942
|
+
}
|
|
905
943
|
function sessionIdFromContext(context, raw) {
|
|
906
944
|
if (context !== undefined) {
|
|
907
945
|
const file = context.sourceFile.split('/').at(-1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/ts-llm-jsonl-importer",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.42",
|
|
4
4
|
"description": "@gobing-ai/ts-llm-jsonl-importer — Generic JSONL importer for LLM agent history files.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"release": "echo 'Manual publish is disabled. Releases go through GitHub Actions via Trusted Publishing — push a tag: git tag @gobing-ai/ts-llm-jsonl-importer-v<version> && git push --tags' && exit 1"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@gobing-ai/ts-db": "^0.4.
|
|
51
|
-
"@gobing-ai/ts-runtime": "^0.4.
|
|
52
|
-
"@gobing-ai/ts-utils": "^0.4.
|
|
50
|
+
"@gobing-ai/ts-db": "^0.4.42",
|
|
51
|
+
"@gobing-ai/ts-runtime": "^0.4.42",
|
|
52
|
+
"@gobing-ai/ts-utils": "^0.4.42",
|
|
53
53
|
"zod": "^4.1.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { HistoryImportError } from './errors';
|
|
|
2
2
|
export { sha256, stableJson } from './hash';
|
|
3
3
|
export { runJsonlImport } from './importer';
|
|
4
4
|
export { applyHistoryImportSchema, normalizeSourceFilePaths } from './jsonl-importer-dao';
|
|
5
|
+
export { sessionIdFromSourcePath } from './mappers';
|
|
5
6
|
export { type OpenCodeImportOptions, runOpenCodeImport } from './opencode-importer';
|
|
6
7
|
export { DEFAULT_REDACTION_RULES, redactRecord, redactValue } from './redaction';
|
|
7
8
|
export { HISTORY_IMPORT_SCHEMA_SQL } from './schema-sql';
|
package/src/mappers.ts
CHANGED
|
@@ -605,18 +605,30 @@ export function claudeToolResultTiming(raw: Record<string, unknown>): ClaudeTool
|
|
|
605
605
|
// ---------------------------------------------------------------------------
|
|
606
606
|
|
|
607
607
|
/** Map a Codex JSONL record into one or more ETL split entries. */
|
|
608
|
-
export function codexSplit(raw: Record<string, unknown
|
|
608
|
+
export function codexSplit(raw: Record<string, unknown>, context?: TransformContext): readonly SplitEntry[] {
|
|
609
609
|
const entries: SplitEntry[] = [];
|
|
610
610
|
|
|
611
611
|
const payload = (raw.payload ?? raw) as Record<string, unknown>;
|
|
612
|
-
const sessionId = s(raw.session_id, o(raw.session_meta).id, raw.id) ?? 'unknown';
|
|
613
612
|
const seq = typeof raw.seq === 'number' ? raw.seq : 0;
|
|
614
613
|
const ts = timestampOf(raw.timestamp, raw.ts, payload.ts);
|
|
615
614
|
const recordType = String(raw.type ?? '');
|
|
616
615
|
const payloadType = String(payload.type ?? '');
|
|
617
616
|
|
|
617
|
+
const isShortFormat =
|
|
618
|
+
recordType === '' && raw.id !== undefined && raw.timestamp !== undefined && raw.instructions !== undefined;
|
|
619
|
+
|
|
620
|
+
let explicitSessionId = s(raw.session_id, o(raw.session_meta).id);
|
|
621
|
+
if (explicitSessionId === undefined && recordType === 'session_meta') {
|
|
622
|
+
explicitSessionId = s(payload.id, o(raw.payload).id);
|
|
623
|
+
}
|
|
624
|
+
if (explicitSessionId === undefined && isShortFormat) {
|
|
625
|
+
explicitSessionId = s(raw.id);
|
|
626
|
+
}
|
|
627
|
+
const pathSessionId = context?.sourceFile ? sessionIdFromSourcePath('codex', context.sourceFile) : undefined;
|
|
628
|
+
const sessionId = explicitSessionId ?? pathSessionId ?? 'unknown';
|
|
629
|
+
|
|
618
630
|
// Check for older short format
|
|
619
|
-
if (
|
|
631
|
+
if (isShortFormat) {
|
|
620
632
|
return [
|
|
621
633
|
{
|
|
622
634
|
targetTable: 'history_message',
|
|
@@ -776,10 +788,12 @@ export function codexSplit(raw: Record<string, unknown>): readonly SplitEntry[]
|
|
|
776
788
|
// ---------------------------------------------------------------------------
|
|
777
789
|
|
|
778
790
|
/** Map an Antigravity (AGY) JSONL record into one or more ETL split entries. */
|
|
779
|
-
export function agySplit(raw: Record<string, unknown
|
|
791
|
+
export function agySplit(raw: Record<string, unknown>, context?: TransformContext): readonly SplitEntry[] {
|
|
780
792
|
const entries: SplitEntry[] = [];
|
|
781
793
|
const recordType = String(raw.type ?? '');
|
|
782
|
-
const
|
|
794
|
+
const explicitSessionId = s(raw.session_id, raw.conversation_id);
|
|
795
|
+
const pathSessionId = context?.sourceFile ? sessionIdFromSourcePath('agy', context.sourceFile) : undefined;
|
|
796
|
+
const sessionId = explicitSessionId ?? pathSessionId ?? 'unknown';
|
|
783
797
|
const seq = typeof raw.seq === 'number' ? raw.seq : typeof raw.step_index === 'number' ? raw.step_index : 0;
|
|
784
798
|
const ts = timestampOf(raw.created_at, raw.timestamp, raw.ts);
|
|
785
799
|
|
|
@@ -979,6 +993,35 @@ export function geminiSplit(raw: Record<string, unknown>, context?: TransformCon
|
|
|
979
993
|
return entries;
|
|
980
994
|
}
|
|
981
995
|
|
|
996
|
+
const UUID_PATTERN = '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';
|
|
997
|
+
const AGY_BRAIN_REGEX = new RegExp(`(?:^|\\/)brain\\/(${UUID_PATTERN})(?:\\/|$)`, 'i');
|
|
998
|
+
const CODEX_ROLLOUT_REGEX = new RegExp(`(?:^|-|_)(${UUID_PATTERN})$`, 'i');
|
|
999
|
+
|
|
1000
|
+
/**
|
|
1001
|
+
* Pure helper extracting canonical session identity from source transcript paths (task 0638 R4).
|
|
1002
|
+
*
|
|
1003
|
+
* Normalizes POSIX/Windows separators and returns only valid UUID-shaped identifiers:
|
|
1004
|
+
* - agy: segment immediately following `/brain/`
|
|
1005
|
+
* - codex: trailing UUID before `.jsonl` in a filename beginning with `rollout-`
|
|
1006
|
+
*/
|
|
1007
|
+
export function sessionIdFromSourcePath(source: string, sourceFile: string): string | undefined {
|
|
1008
|
+
const normalized = sourceFile.replace(/\\/g, '/');
|
|
1009
|
+
const sLower = source.toLowerCase();
|
|
1010
|
+
if (sLower === 'agy' || sLower === 'antigravity') {
|
|
1011
|
+
const match = normalized.match(AGY_BRAIN_REGEX);
|
|
1012
|
+
return match?.[1];
|
|
1013
|
+
}
|
|
1014
|
+
if (sLower === 'codex') {
|
|
1015
|
+
const basename = normalized.split('/').at(-1) ?? '';
|
|
1016
|
+
if (basename.startsWith('rollout-') && basename.endsWith('.jsonl')) {
|
|
1017
|
+
const stem = basename.slice(0, -6);
|
|
1018
|
+
const match = stem.match(CODEX_ROLLOUT_REGEX);
|
|
1019
|
+
return match?.[1];
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
return undefined;
|
|
1023
|
+
}
|
|
1024
|
+
|
|
982
1025
|
function sessionIdFromContext(context: TransformContext | undefined, raw: Record<string, unknown>): string {
|
|
983
1026
|
if (context !== undefined) {
|
|
984
1027
|
const file = context.sourceFile.split('/').at(-1);
|