@ramarivera/coding-agent-langfuse 0.1.40 → 0.1.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/backfill.d.ts +5 -1
- package/dist/backfill.js +43 -4
- package/package.json +1 -1
package/dist/backfill.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ type BackfillOptions = {
|
|
|
39
39
|
limit?: number;
|
|
40
40
|
sinceMs?: number;
|
|
41
41
|
untilMs?: number;
|
|
42
|
+
sessionIds: Set<string>;
|
|
42
43
|
batchSize: number;
|
|
43
44
|
maxRequestBytes: number;
|
|
44
45
|
maxFieldBytes: number;
|
|
@@ -63,7 +64,10 @@ type FollowSummary = RunSummary & {
|
|
|
63
64
|
declare const allAgents: AgentName[];
|
|
64
65
|
declare const defaultEndpoint = "https://langfuse.ai.roxasroot.net/otel/v1/traces";
|
|
65
66
|
declare function parseArgs(argv: string[]): BackfillOptions;
|
|
66
|
-
declare function codexEvents(homeDir: string
|
|
67
|
+
declare function codexEvents(homeDir: string, options?: {
|
|
68
|
+
sessionIds?: Set<string>;
|
|
69
|
+
sinceMs?: number;
|
|
70
|
+
}): BackfillEvent[];
|
|
67
71
|
declare function claudeEvents(homeDir: string): BackfillEvent[];
|
|
68
72
|
declare function piEvents(homeDir: string): BackfillEvent[];
|
|
69
73
|
declare function grokEvents(homeDir: string): BackfillEvent[];
|
package/dist/backfill.js
CHANGED
|
@@ -40,6 +40,7 @@ Options:
|
|
|
40
40
|
--home PATH Home directory to scan (default: current user home)
|
|
41
41
|
--since ISO_OR_MS Only import events at or after this timestamp
|
|
42
42
|
--until ISO_OR_MS Only import events before or at this timestamp
|
|
43
|
+
--session-id ID Only import one session id; repeat or comma-separate
|
|
43
44
|
--limit N Stop after N unsent events
|
|
44
45
|
--batch-size N OTLP spans per POST (default: 50)
|
|
45
46
|
--max-request-bytes N Split OTLP POSTs below this JSON byte size (default: ${defaultMaxRequestBytes})
|
|
@@ -74,6 +75,7 @@ function parseArgs(argv) {
|
|
|
74
75
|
let pollIntervalMs = 5_000;
|
|
75
76
|
let idleExitAfterMs;
|
|
76
77
|
const agents = new Set(allAgents);
|
|
78
|
+
const sessionIds = new Set();
|
|
77
79
|
for (let i = 0; i < argv.length; i++) {
|
|
78
80
|
const arg = argv[i];
|
|
79
81
|
const next = () => {
|
|
@@ -138,6 +140,13 @@ function parseArgs(argv) {
|
|
|
138
140
|
else if (arg === "--until") {
|
|
139
141
|
untilMs = parseTime(next());
|
|
140
142
|
}
|
|
143
|
+
else if (arg === "--session-id") {
|
|
144
|
+
for (const item of next().split(",")) {
|
|
145
|
+
const sessionId = item.trim();
|
|
146
|
+
if (sessionId.length > 0)
|
|
147
|
+
sessionIds.add(sessionId);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
141
150
|
else {
|
|
142
151
|
throw new Error(`Unknown argument '${arg}'`);
|
|
143
152
|
}
|
|
@@ -176,6 +185,7 @@ function parseArgs(argv) {
|
|
|
176
185
|
limit,
|
|
177
186
|
sinceMs,
|
|
178
187
|
untilMs,
|
|
188
|
+
sessionIds,
|
|
179
189
|
batchSize,
|
|
180
190
|
maxRequestBytes,
|
|
181
191
|
maxFieldBytes,
|
|
@@ -235,7 +245,7 @@ function listFiles(root, predicate) {
|
|
|
235
245
|
}
|
|
236
246
|
if (stat.isDirectory())
|
|
237
247
|
stack.push(path);
|
|
238
|
-
else if (stat.isFile() && predicate(path))
|
|
248
|
+
else if (stat.isFile() && predicate(path, stat))
|
|
239
249
|
out.push(path);
|
|
240
250
|
}
|
|
241
251
|
}
|
|
@@ -378,8 +388,33 @@ function isGenerationEvent(event) {
|
|
|
378
388
|
return event.usage !== undefined && event.role !== "user" &&
|
|
379
389
|
event.role !== "developer" && event.role !== "system";
|
|
380
390
|
}
|
|
381
|
-
function
|
|
382
|
-
const
|
|
391
|
+
function codexSessionPathTimeMs(path) {
|
|
392
|
+
const rolloutMatch = path.match(/rollout-(\d{4})-(\d{2})-(\d{2})T(\d{2})-(\d{2})-(\d{2})/);
|
|
393
|
+
if (rolloutMatch) {
|
|
394
|
+
const [, year, month, day, hour, minute, second] = rolloutMatch;
|
|
395
|
+
return Date.UTC(Number(year), Number(month) - 1, Number(day), Number(hour), Number(minute), Number(second));
|
|
396
|
+
}
|
|
397
|
+
const folderMatch = path.match(/[\\/]sessions[\\/](\d{4})[\\/](\d{2})[\\/](\d{2})[\\/]/);
|
|
398
|
+
if (!folderMatch)
|
|
399
|
+
return undefined;
|
|
400
|
+
const [, year, month, day] = folderMatch;
|
|
401
|
+
return Date.UTC(Number(year), Number(month) - 1, Number(day));
|
|
402
|
+
}
|
|
403
|
+
function fileMayContainCodexWindow(path, stat, options) {
|
|
404
|
+
if (options.sessionIds !== undefined &&
|
|
405
|
+
options.sessionIds.size > 0 &&
|
|
406
|
+
![...options.sessionIds].some((sessionId) => path.includes(sessionId))) {
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
if (options.sinceMs === undefined)
|
|
410
|
+
return true;
|
|
411
|
+
if (stat.mtimeMs >= options.sinceMs)
|
|
412
|
+
return true;
|
|
413
|
+
const pathTimeMs = codexSessionPathTimeMs(path);
|
|
414
|
+
return pathTimeMs === undefined || pathTimeMs >= options.sinceMs;
|
|
415
|
+
}
|
|
416
|
+
function codexEvents(homeDir, options = {}) {
|
|
417
|
+
const files = listFiles(join(homeDir, ".codex/sessions"), (path, stat) => path.endsWith(".jsonl") && fileMayContainCodexWindow(path, stat, options));
|
|
383
418
|
const seenTokenCounts = new Set();
|
|
384
419
|
return files.flatMap((path) => {
|
|
385
420
|
const rows = parseJsonl(path).map(asRecord);
|
|
@@ -1388,7 +1423,10 @@ function describeError(error) {
|
|
|
1388
1423
|
function discoverEvents(options) {
|
|
1389
1424
|
const providers = {
|
|
1390
1425
|
claude: (inner) => claudeEvents(inner.homeDir),
|
|
1391
|
-
codex: (inner) => codexEvents(inner.homeDir
|
|
1426
|
+
codex: (inner) => codexEvents(inner.homeDir, {
|
|
1427
|
+
sessionIds: inner.sessionIds,
|
|
1428
|
+
sinceMs: inner.sinceMs,
|
|
1429
|
+
}),
|
|
1392
1430
|
grok: (inner) => grokEvents(inner.homeDir),
|
|
1393
1431
|
opencode: (inner) => opencodeEvents(inner.homeDir, {
|
|
1394
1432
|
rowLimit: inner.limit,
|
|
@@ -1402,6 +1440,7 @@ function discoverEvents(options) {
|
|
|
1402
1440
|
.flatMap((agent) => providers[agent](options))
|
|
1403
1441
|
.filter((event) => options.sinceMs === undefined || event.startMs >= options.sinceMs)
|
|
1404
1442
|
.filter((event) => options.untilMs === undefined || event.startMs <= options.untilMs)
|
|
1443
|
+
.filter((event) => options.sessionIds.size === 0 || options.sessionIds.has(event.sessionId))
|
|
1405
1444
|
.sort((a, b) => a.startMs - b.startMs);
|
|
1406
1445
|
}
|
|
1407
1446
|
async function run(options) {
|