agent-trace 0.2.3 → 0.2.4

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.
Files changed (2) hide show
  1. package/agent-trace.cjs +117 -3
  2. package/package.json +1 -1
package/agent-trace.cjs CHANGED
@@ -25708,6 +25708,12 @@ function toNonNegativeInteger2(value) {
25708
25708
  }
25709
25709
  return Math.floor(value);
25710
25710
  }
25711
+ function toNonNegativeDecimal(value) {
25712
+ if (!Number.isFinite(value) || value <= 0) {
25713
+ return 0;
25714
+ }
25715
+ return Number(value.toFixed(6));
25716
+ }
25711
25717
  function toSessionStatus(trace) {
25712
25718
  return trace.endedAt !== void 0 ? "completed" : "active";
25713
25719
  }
@@ -25731,7 +25737,7 @@ function toPostgresCommitRow(trace, commit) {
25731
25737
  message: toNullableString(commit.message),
25732
25738
  lines_added: toNonNegativeInteger2(commit.linesAdded),
25733
25739
  lines_removed: toNonNegativeInteger2(commit.linesRemoved),
25734
- chain_cost_usd: 0,
25740
+ chain_cost_usd: toNonNegativeDecimal(trace.metrics.totalCostUsd),
25735
25741
  committed_at: toNullableString(commit.committedAt)
25736
25742
  };
25737
25743
  }
@@ -27961,6 +27967,92 @@ var InMemoryRuntimePersistence = class extends WriterBackedRuntimePersistence {
27961
27967
  }
27962
27968
  };
27963
27969
 
27970
+ // packages/schema/src/pricing.ts
27971
+ var MODEL_PRICING = [
27972
+ // Opus 4 / 4.6
27973
+ ["claude-opus-4", {
27974
+ inputPerToken: 15 / 1e6,
27975
+ outputPerToken: 75 / 1e6,
27976
+ cacheReadPerToken: 1.5 / 1e6,
27977
+ cacheWritePerToken: 18.75 / 1e6
27978
+ }],
27979
+ // Sonnet 4 / 4.6
27980
+ ["claude-sonnet-4", {
27981
+ inputPerToken: 3 / 1e6,
27982
+ outputPerToken: 15 / 1e6,
27983
+ cacheReadPerToken: 0.3 / 1e6,
27984
+ cacheWritePerToken: 3.75 / 1e6
27985
+ }],
27986
+ // Haiku 4.5
27987
+ ["claude-haiku-4", {
27988
+ inputPerToken: 0.8 / 1e6,
27989
+ outputPerToken: 4 / 1e6,
27990
+ cacheReadPerToken: 0.08 / 1e6,
27991
+ cacheWritePerToken: 1 / 1e6
27992
+ }],
27993
+ // Claude 3.5 Sonnet
27994
+ ["claude-3-5-sonnet", {
27995
+ inputPerToken: 3 / 1e6,
27996
+ outputPerToken: 15 / 1e6,
27997
+ cacheReadPerToken: 0.3 / 1e6,
27998
+ cacheWritePerToken: 3.75 / 1e6
27999
+ }],
28000
+ // Claude 3.5 Haiku
28001
+ ["claude-3-5-haiku", {
28002
+ inputPerToken: 0.8 / 1e6,
28003
+ outputPerToken: 4 / 1e6,
28004
+ cacheReadPerToken: 0.08 / 1e6,
28005
+ cacheWritePerToken: 1 / 1e6
28006
+ }],
28007
+ // Claude 3 Opus
28008
+ ["claude-3-opus", {
28009
+ inputPerToken: 15 / 1e6,
28010
+ outputPerToken: 75 / 1e6,
28011
+ cacheReadPerToken: 1.5 / 1e6,
28012
+ cacheWritePerToken: 18.75 / 1e6
28013
+ }],
28014
+ // Claude 3 Sonnet
28015
+ ["claude-3-sonnet", {
28016
+ inputPerToken: 3 / 1e6,
28017
+ outputPerToken: 15 / 1e6,
28018
+ cacheReadPerToken: 0.3 / 1e6,
28019
+ cacheWritePerToken: 3.75 / 1e6
28020
+ }],
28021
+ // Claude 3 Haiku
28022
+ ["claude-3-haiku", {
28023
+ inputPerToken: 0.25 / 1e6,
28024
+ outputPerToken: 1.25 / 1e6,
28025
+ cacheReadPerToken: 0.03 / 1e6,
28026
+ cacheWritePerToken: 0.3 / 1e6
28027
+ }]
28028
+ ];
28029
+ var SORTED_PRICING = [...MODEL_PRICING].sort((a, b) => b[0].length - a[0].length);
28030
+ function lookupModelPricing(model) {
28031
+ const normalized = model.toLowerCase();
28032
+ for (const [pattern, pricing] of SORTED_PRICING) {
28033
+ if (normalized.startsWith(pattern)) {
28034
+ return pricing;
28035
+ }
28036
+ }
28037
+ return void 0;
28038
+ }
28039
+ function calculateCostUsd(input) {
28040
+ if (input.model === void 0) {
28041
+ return 0;
28042
+ }
28043
+ const pricing = lookupModelPricing(input.model);
28044
+ if (pricing === void 0) {
28045
+ return 0;
28046
+ }
28047
+ const totalInput = Math.max(0, input.inputTokens);
28048
+ const output = Math.max(0, input.outputTokens);
28049
+ const cacheRead = Math.max(0, input.cacheReadTokens ?? 0);
28050
+ const cacheWrite = Math.max(0, input.cacheWriteTokens ?? 0);
28051
+ const regularInput = Math.max(0, totalInput - cacheRead - cacheWrite);
28052
+ const cost = regularInput * pricing.inputPerToken + cacheRead * pricing.cacheReadPerToken + cacheWrite * pricing.cacheWritePerToken + output * pricing.outputPerToken;
28053
+ return Number(cost.toFixed(6));
28054
+ }
28055
+
27964
28056
  // packages/runtime/src/projector.ts
27965
28057
  function asRecord5(value) {
27966
28058
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
@@ -28045,11 +28137,33 @@ function buildNormalizedDetails(payload) {
28045
28137
  addCamelAlias(normalized, "file_path", "filePath");
28046
28138
  return normalized;
28047
28139
  }
28140
+ function computeEventCost(payload) {
28141
+ const explicit = readNumber3(payload, ["cost_usd", "costUsd"]);
28142
+ if (explicit !== void 0 && explicit > 0) {
28143
+ return explicit;
28144
+ }
28145
+ const model = readString4(payload, ["model"]);
28146
+ const inputTokens = readNumber3(payload, ["input_tokens", "inputTokens"]);
28147
+ const outputTokens = readNumber3(payload, ["output_tokens", "outputTokens"]);
28148
+ if (model === void 0 || inputTokens === void 0 || outputTokens === void 0) {
28149
+ return explicit;
28150
+ }
28151
+ const cacheReadTokens = readNumber3(payload, ["cache_read_tokens", "cacheReadTokens", "cache_read_input_tokens"]);
28152
+ const cacheWriteTokens = readNumber3(payload, ["cache_write_tokens", "cacheWriteTokens", "cache_creation_input_tokens"]);
28153
+ const calculated = calculateCostUsd({
28154
+ model,
28155
+ inputTokens,
28156
+ outputTokens,
28157
+ cacheReadTokens: cacheReadTokens ?? 0,
28158
+ cacheWriteTokens: cacheWriteTokens ?? 0
28159
+ });
28160
+ return calculated > 0 ? calculated : explicit;
28161
+ }
28048
28162
  function toTimelineEvent(envelope) {
28049
28163
  const payload = asRecord5(envelope.payload);
28050
28164
  const inputTokens = readNumber3(payload, ["input_tokens", "inputTokens"]);
28051
28165
  const outputTokens = readNumber3(payload, ["output_tokens", "outputTokens"]);
28052
- const costUsd = readNumber3(payload, ["cost_usd", "costUsd"]);
28166
+ const costUsd = computeEventCost(payload);
28053
28167
  const details = buildNormalizedDetails(envelope.payload);
28054
28168
  return {
28055
28169
  id: envelope.eventId,
@@ -28131,7 +28245,7 @@ function toUpdatedTrace(existing, envelope) {
28131
28245
  const mergedTimeline = [...existing.timeline, timelineEvent];
28132
28246
  const endedAt = shouldMarkEnded(envelope.eventType) ? envelope.eventTimestamp : existing.endedAt;
28133
28247
  const latestTime = endedAt ?? envelope.eventTimestamp;
28134
- const cost = readNumber3(payload, ["cost_usd", "costUsd"]) ?? 0;
28248
+ const cost = computeEventCost(payload) ?? 0;
28135
28249
  const inputTokens = readNumber3(payload, ["input_tokens", "inputTokens"]) ?? 0;
28136
28250
  const outputTokens = readNumber3(payload, ["output_tokens", "outputTokens"]) ?? 0;
28137
28251
  const linesAdded = readNumber3(payload, ["lines_added", "linesAdded"]) ?? 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-trace",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Self-hosted observability for AI coding agents. One command, zero config.",
5
5
  "license": "Apache-2.0",
6
6
  "bin": {