@ramarivera/coding-agent-langfuse 0.1.37 → 0.1.39
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.js +28 -0
- package/dist/service.d.ts +2 -1
- package/dist/service.js +27 -2
- package/package.json +1 -1
package/dist/backfill.js
CHANGED
|
@@ -19,6 +19,17 @@ const defaultMaxRequestBytes = 12 * 1024 * 1024;
|
|
|
19
19
|
const defaultMaxFieldBytes = 512 * 1024;
|
|
20
20
|
const defaultStatePath = join(homedir(), ".local/state/coding-agent-langfuse/backfill-v6.json");
|
|
21
21
|
const currentHost = hostname();
|
|
22
|
+
function projectMetadata(cwd) {
|
|
23
|
+
if (!cwd)
|
|
24
|
+
return {};
|
|
25
|
+
const normalized = cwd.replace(/[\\/]+$/, "");
|
|
26
|
+
const projectName = normalized.split(/[\\/]+/).filter(Boolean).at(-1);
|
|
27
|
+
return {
|
|
28
|
+
projectPath: cwd,
|
|
29
|
+
projectName,
|
|
30
|
+
projectFolder: projectName,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
22
33
|
function usage() {
|
|
23
34
|
return `Usage: coding-agent-langfuse-backfill [options]
|
|
24
35
|
|
|
@@ -1204,6 +1215,7 @@ function toOtlp(events, options = {}) {
|
|
|
1204
1215
|
const traceStartMs = sortedEvents[0]?.startMs ?? Date.now();
|
|
1205
1216
|
const traceEndMs = Math.max(...sortedEvents.map((event) => event.endMs ?? event.startMs + 1), traceStartMs + 1);
|
|
1206
1217
|
const shouldEmitRootSpan = sortedEvents.some((event) => event.recordId === "session");
|
|
1218
|
+
const firstProject = projectMetadata(first.cwd);
|
|
1207
1219
|
const rootAttributes = [
|
|
1208
1220
|
attr("service.name", `agent.${first.agent}`),
|
|
1209
1221
|
attr("deployment.environment", "local"),
|
|
@@ -1223,6 +1235,9 @@ function toOtlp(events, options = {}) {
|
|
|
1223
1235
|
attr("langfuse.trace.metadata.machine", currentHost),
|
|
1224
1236
|
attr("langfuse.trace.metadata.source_path", first.sourcePath),
|
|
1225
1237
|
attr("langfuse.trace.metadata.cwd", first.cwd),
|
|
1238
|
+
attr("langfuse.trace.metadata.project_path", firstProject.projectPath),
|
|
1239
|
+
attr("langfuse.trace.metadata.project_name", firstProject.projectName),
|
|
1240
|
+
attr("langfuse.trace.metadata.project_folder", firstProject.projectFolder),
|
|
1226
1241
|
attr("langfuse.observation.metadata.agent", first.agent),
|
|
1227
1242
|
attr("langfuse.observation.metadata.host", currentHost),
|
|
1228
1243
|
attr("langfuse.observation.metadata.machine", currentHost),
|
|
@@ -1230,8 +1245,14 @@ function toOtlp(events, options = {}) {
|
|
|
1230
1245
|
attr("langfuse.observation.metadata.record_id", "session-root"),
|
|
1231
1246
|
attr("langfuse.observation.metadata.source_path", first.sourcePath),
|
|
1232
1247
|
attr("langfuse.observation.metadata.cwd", first.cwd),
|
|
1248
|
+
attr("langfuse.observation.metadata.project_path", firstProject.projectPath),
|
|
1249
|
+
attr("langfuse.observation.metadata.project_name", firstProject.projectName),
|
|
1250
|
+
attr("langfuse.observation.metadata.project_folder", firstProject.projectFolder),
|
|
1233
1251
|
attr("source.path", first.sourcePath),
|
|
1234
1252
|
attr("cwd", first.cwd),
|
|
1253
|
+
attr("project.path", firstProject.projectPath),
|
|
1254
|
+
attr("project.name", firstProject.projectName),
|
|
1255
|
+
attr("project.folder", firstProject.projectFolder),
|
|
1235
1256
|
].filter((item) => Boolean(item));
|
|
1236
1257
|
const rootSpan = {
|
|
1237
1258
|
traceId: traceId(first),
|
|
@@ -1251,6 +1272,7 @@ function toOtlp(events, options = {}) {
|
|
|
1251
1272
|
const generation = isGenerationEvent(event);
|
|
1252
1273
|
const usage = usageDetails(event.usage);
|
|
1253
1274
|
const cost = costDetails(event.usage, modelName);
|
|
1275
|
+
const eventProject = projectMetadata(event.cwd);
|
|
1254
1276
|
const costForLangfuse = cost === undefined
|
|
1255
1277
|
? undefined
|
|
1256
1278
|
: {
|
|
@@ -1288,6 +1310,9 @@ function toOtlp(events, options = {}) {
|
|
|
1288
1310
|
attr("langfuse.observation.metadata.record_id", event.recordId),
|
|
1289
1311
|
attr("langfuse.observation.metadata.source_path", event.sourcePath),
|
|
1290
1312
|
attr("langfuse.observation.metadata.cwd", event.cwd),
|
|
1313
|
+
attr("langfuse.observation.metadata.project_path", eventProject.projectPath),
|
|
1314
|
+
attr("langfuse.observation.metadata.project_name", eventProject.projectName),
|
|
1315
|
+
attr("langfuse.observation.metadata.project_folder", eventProject.projectFolder),
|
|
1291
1316
|
attr("langfuse.observation.metadata.model", modelName ?? event.model),
|
|
1292
1317
|
attr("langfuse.observation.metadata.provider", event.provider),
|
|
1293
1318
|
attr("langfuse.observation.metadata.cost_source", cost?.source),
|
|
@@ -1295,6 +1320,9 @@ function toOtlp(events, options = {}) {
|
|
|
1295
1320
|
attr("langfuse.observation.output", event.output),
|
|
1296
1321
|
attr("source.path", event.sourcePath),
|
|
1297
1322
|
attr("cwd", event.cwd),
|
|
1323
|
+
attr("project.path", eventProject.projectPath),
|
|
1324
|
+
attr("project.name", eventProject.projectName),
|
|
1325
|
+
attr("project.folder", eventProject.projectFolder),
|
|
1298
1326
|
attr("role", event.role),
|
|
1299
1327
|
attr("agent.model", event.model),
|
|
1300
1328
|
attr("agent.provider", event.provider),
|
package/dist/service.d.ts
CHANGED
|
@@ -34,5 +34,6 @@ type ServicePlan = {
|
|
|
34
34
|
declare function parseServiceArgs(argv: string[]): ServiceOptions;
|
|
35
35
|
declare function buildServicePlan(options: ServiceOptions): ServicePlan;
|
|
36
36
|
declare function serviceMain(argv?: string[]): Promise<ServicePlan>;
|
|
37
|
+
declare function redactStatusOutput(output: string): string;
|
|
37
38
|
declare function lifecycleEnv(): NodeJS.ProcessEnv;
|
|
38
|
-
export { type ServiceOptions, type ServicePlan, buildServicePlan, parseServiceArgs, serviceMain, lifecycleEnv, };
|
|
39
|
+
export { type ServiceOptions, type ServicePlan, buildServicePlan, redactStatusOutput, parseServiceArgs, serviceMain, lifecycleEnv, };
|
package/dist/service.js
CHANGED
|
@@ -249,7 +249,7 @@ async function serviceMain(argv = process.argv.slice(2)) {
|
|
|
249
249
|
return plan;
|
|
250
250
|
}
|
|
251
251
|
if (options.action === "status") {
|
|
252
|
-
|
|
252
|
+
runStatusCommands(plan.statusCommands);
|
|
253
253
|
console.log(JSON.stringify(plan, null, 2));
|
|
254
254
|
return plan;
|
|
255
255
|
}
|
|
@@ -452,6 +452,31 @@ function runCommands(commands, options = {}) {
|
|
|
452
452
|
}
|
|
453
453
|
}
|
|
454
454
|
}
|
|
455
|
+
function runStatusCommands(commands) {
|
|
456
|
+
const env = lifecycleEnv();
|
|
457
|
+
for (const command of commands) {
|
|
458
|
+
const output = execFileSync(command[0], command.slice(1), {
|
|
459
|
+
encoding: "utf8",
|
|
460
|
+
env,
|
|
461
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
462
|
+
});
|
|
463
|
+
process.stdout.write(redactStatusOutput(output));
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
function redactStatusOutput(output) {
|
|
467
|
+
return output
|
|
468
|
+
.split(/\r?\n/)
|
|
469
|
+
.map((line) => {
|
|
470
|
+
if (/^\s*[A-Za-z_][A-Za-z0-9_()]*\s*=>\s*/.test(line)) {
|
|
471
|
+
return line.replace(/=>\s*.*/, "=> [redacted]");
|
|
472
|
+
}
|
|
473
|
+
if (/^\s*(Path|PATH|.*(?:TOKEN|KEY|SECRET|PASSWORD|AUTH|CREDENTIAL).*)\s*:/i.test(line)) {
|
|
474
|
+
return line.replace(/:\s*.*/, ": [redacted]");
|
|
475
|
+
}
|
|
476
|
+
return line;
|
|
477
|
+
})
|
|
478
|
+
.join("\n");
|
|
479
|
+
}
|
|
455
480
|
function lifecycleEnv() {
|
|
456
481
|
const keys = [
|
|
457
482
|
"PATH",
|
|
@@ -499,4 +524,4 @@ function escapeXml(value) {
|
|
|
499
524
|
.replaceAll('"', """)
|
|
500
525
|
.replaceAll("'", "'");
|
|
501
526
|
}
|
|
502
|
-
export { buildServicePlan, parseServiceArgs, serviceMain, lifecycleEnv, };
|
|
527
|
+
export { buildServicePlan, redactStatusOutput, parseServiceArgs, serviceMain, lifecycleEnv, };
|