@ramarivera/coding-agent-langfuse 0.1.39 → 0.1.40

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/README.md CHANGED
@@ -3,9 +3,9 @@
3
3
  Universal coding-agent Langfuse backfiller and OTLP exporter helpers.
4
4
 
5
5
  It imports local histories from Codex, Claude Code, Grok, OpenCode, and Pi into
6
- Langfuse as session traces with child observations. LLM usage records are emitted
7
- as Langfuse generations with model names, usage details, and recorded or
8
- estimated cost details. Tool calls remain child spans under the same session.
6
+ Langfuse as session traces with child observations. LLM usage records are kept
7
+ as observation metadata so historical imports do not create Langfuse billing or
8
+ cost rows. Tool calls remain child spans under the same session.
9
9
 
10
10
  ```sh
11
11
  coding-agent-langfuse-backfill --agents codex,claude,grok,pi,opencode
@@ -112,7 +112,7 @@ npm run test:e2e
112
112
  The e2e suite verifies:
113
113
 
114
114
  - Codex full session traces with messages, reasoning, tool calls, tool results,
115
- usage, and costs
115
+ and usage metadata
116
116
  - Follow mode picking up newly written Codex events
117
117
  - One CLI run posting reconstructable traces for Claude Code, Codex, Grok,
118
118
  OpenCode, and Pi
File without changes
package/dist/backfill.js CHANGED
@@ -374,53 +374,6 @@ function usageDetails(usage) {
374
374
  details.total = usage.total;
375
375
  return Object.keys(details).length > 0 ? details : undefined;
376
376
  }
377
- function pricingForModel(model) {
378
- if (!model)
379
- return undefined;
380
- const normalized = normalizeModelName(model) ?? model;
381
- if (normalized === "kimi-for-coding") {
382
- return { input: 0.95, output: 4.0, cacheRead: 0.16, cacheWrite: 0 };
383
- }
384
- if (normalized.includes("accounts/fireworks/routers/kimi-k2p6-turbo")) {
385
- return { input: 2.0, output: 8.0, cacheRead: 0.30, cacheWrite: 0 };
386
- }
387
- if (normalized.includes("accounts/fireworks/models/deepseek-v4-pro")) {
388
- return { input: 1.74, output: 3.48, cacheRead: 0.15, cacheWrite: 0 };
389
- }
390
- if (normalized.includes("DeepSeek-V4-Pro")) {
391
- return { input: 2.1, output: 4.4, cacheRead: 0.2, cacheWrite: 0 };
392
- }
393
- if (normalized.includes("Kimi-K2.6")) {
394
- return { input: 1.2, output: 4.5, cacheRead: 0.2, cacheWrite: 0 };
395
- }
396
- if (normalized.includes("MiniMax-M2.7")) {
397
- return { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 };
398
- }
399
- return undefined;
400
- }
401
- function costDetails(usage, model) {
402
- if (!usage)
403
- return undefined;
404
- const rates = pricingForModel(model);
405
- if (rates) {
406
- const cachedInput = usage.cacheRead ?? 0;
407
- const cacheWriteTokens = usage.cacheWrite ?? 0;
408
- const regularInput = Math.max((usage.input ?? 0) - cachedInput - cacheWriteTokens, 0);
409
- const input = (regularInput * rates.input) / 1_000_000;
410
- const output = (((usage.output ?? 0) + (usage.reasoning ?? 0)) * rates.output) /
411
- 1_000_000;
412
- const cache_read = (cachedInput * rates.cacheRead) / 1_000_000;
413
- const cache_write = (cacheWriteTokens * rates.cacheWrite) / 1_000_000;
414
- const total = input + output + cache_read + cache_write;
415
- if (total > 0) {
416
- return { input, output, cache_read, cache_write, total, source: "estimated" };
417
- }
418
- }
419
- if (usage.cost !== undefined && usage.cost > 0) {
420
- return { total: usage.cost, source: "recorded" };
421
- }
422
- return undefined;
423
- }
424
377
  function isGenerationEvent(event) {
425
378
  return event.usage !== undefined && event.role !== "user" &&
426
379
  event.role !== "developer" && event.role !== "system";
@@ -1271,17 +1224,7 @@ function toOtlp(events, options = {}) {
1271
1224
  const modelName = normalizeModelName(event.model);
1272
1225
  const generation = isGenerationEvent(event);
1273
1226
  const usage = usageDetails(event.usage);
1274
- const cost = costDetails(event.usage, modelName);
1275
1227
  const eventProject = projectMetadata(event.cwd);
1276
- const costForLangfuse = cost === undefined
1277
- ? undefined
1278
- : {
1279
- ...(cost.input !== undefined ? { input: cost.input } : {}),
1280
- ...(cost.output !== undefined ? { output: cost.output } : {}),
1281
- ...(cost.cache_read !== undefined ? { cache_read: cost.cache_read } : {}),
1282
- ...(cost.cache_write !== undefined ? { cache_write: cost.cache_write } : {}),
1283
- total: cost.total,
1284
- };
1285
1228
  const attributes = [
1286
1229
  attr("service.name", `agent.${event.agent}`),
1287
1230
  attr("deployment.environment", "local"),
@@ -1290,13 +1233,6 @@ function toOtlp(events, options = {}) {
1290
1233
  attr("session.id", event.sessionId),
1291
1234
  attr("langfuse.observation.type", generation ? "generation" : "span"),
1292
1235
  attr("langfuse.observation.model.name", generation ? modelName : undefined),
1293
- attr("langfuse.observation.usage_details", usage),
1294
- attr("langfuse.observation.cost_details", costForLangfuse),
1295
- attr("gen_ai.response.model", generation ? modelName : undefined),
1296
- attr("gen_ai.usage.input_tokens", usage?.input),
1297
- attr("gen_ai.usage.output_tokens", usage?.output),
1298
- attr("gen_ai.usage.total_tokens", usage?.total),
1299
- attr("gen_ai.usage.cost", cost?.total),
1300
1236
  attr("agent.name", event.agent),
1301
1237
  attr("host.name", currentHost),
1302
1238
  attr("agent.session_id", event.sessionId),
@@ -1315,7 +1251,8 @@ function toOtlp(events, options = {}) {
1315
1251
  attr("langfuse.observation.metadata.project_folder", eventProject.projectFolder),
1316
1252
  attr("langfuse.observation.metadata.model", modelName ?? event.model),
1317
1253
  attr("langfuse.observation.metadata.provider", event.provider),
1318
- attr("langfuse.observation.metadata.cost_source", cost?.source),
1254
+ attr("langfuse.observation.metadata.usage_details", usage),
1255
+ attr("langfuse.observation.metadata.recorded_cost", event.usage?.cost),
1319
1256
  attr("langfuse.observation.input", event.input),
1320
1257
  attr("langfuse.observation.output", event.output),
1321
1258
  attr("source.path", event.sourcePath),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ramarivera/coding-agent-langfuse",
3
- "version": "0.1.39",
3
+ "version": "0.1.40",
4
4
  "description": "Universal coding-agent Langfuse backfiller and live OTLP helpers",
5
5
  "type": "module",
6
6
  "license": "MIT",