@axlsdk/studio 0.18.1 → 0.19.0

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.
@@ -22,7 +22,7 @@
22
22
  }
23
23
  })();
24
24
  </script>
25
- <script type="module" crossorigin src="./assets/index-CyKf66AB.js"></script>
25
+ <script type="module" crossorigin src="./assets/index-7Nf4lAQm.js"></script>
26
26
  <link rel="stylesheet" crossorigin href="./assets/index-CxBvTZU2.css">
27
27
  </head>
28
28
  <body>
@@ -1,29 +1,42 @@
1
1
  import { AxlRuntime } from '@axlsdk/axl';
2
2
 
3
+ type CostBucket = {
4
+ cost: number;
5
+ calls: number;
6
+ unpricedCalls: number;
7
+ };
8
+ type TokenCostBucket = CostBucket & {
9
+ tokens: {
10
+ input: number;
11
+ output: number;
12
+ };
13
+ };
14
+ type WorkflowCostBucket = {
15
+ cost: number;
16
+ executions: number;
17
+ unpricedCalls: number;
18
+ };
19
+ type EmbedderCostBucket = CostBucket & {
20
+ tokens: number;
21
+ };
3
22
  /** Cost aggregation data */
4
23
  type CostData = {
5
24
  totalCost: number;
25
+ /**
26
+ * Count of cost-bearing leaf calls (`agent_call_end` / `memory_*`) that did
27
+ * measurable work but had no usable cost (unpriced model / pricing-table miss).
28
+ * When > 0, `totalCost` is a LOWER BOUND — the unknown component is not
29
+ * included — so the dashboard can flag it instead of implying an exact figure.
30
+ */
31
+ unpricedCalls: number;
6
32
  totalTokens: {
7
33
  input: number;
8
34
  output: number;
9
35
  reasoning: number;
10
36
  };
11
- byAgent: Record<string, {
12
- cost: number;
13
- calls: number;
14
- }>;
15
- byModel: Record<string, {
16
- cost: number;
17
- calls: number;
18
- tokens: {
19
- input: number;
20
- output: number;
21
- };
22
- }>;
23
- byWorkflow: Record<string, {
24
- cost: number;
25
- executions: number;
26
- }>;
37
+ byAgent: Record<string, CostBucket>;
38
+ byModel: Record<string, TokenCostBucket>;
39
+ byWorkflow: Record<string, WorkflowCostBucket>;
27
40
  /**
28
41
  * Cost decomposition by retry reason. `primary` accumulates cost from
29
42
  * `agent_call` events WITHOUT a `retryReason` (first-attempt calls).
@@ -57,11 +70,7 @@ type CostData = {
57
70
  * and byAgent/byModel/byWorkflow buckets will always sum to ≤
58
71
  * totalCost; the difference is the embedder spend.
59
72
  */
60
- byEmbedder: Record<string, {
61
- cost: number;
62
- calls: number;
63
- tokens: number;
64
- }>;
73
+ byEmbedder: Record<string, EmbedderCostBucket>;
65
74
  };
66
75
  /** Hono app environment bindings */
67
76
  type StudioEnv = {
@@ -1,29 +1,42 @@
1
1
  import { AxlRuntime } from '@axlsdk/axl';
2
2
 
3
+ type CostBucket = {
4
+ cost: number;
5
+ calls: number;
6
+ unpricedCalls: number;
7
+ };
8
+ type TokenCostBucket = CostBucket & {
9
+ tokens: {
10
+ input: number;
11
+ output: number;
12
+ };
13
+ };
14
+ type WorkflowCostBucket = {
15
+ cost: number;
16
+ executions: number;
17
+ unpricedCalls: number;
18
+ };
19
+ type EmbedderCostBucket = CostBucket & {
20
+ tokens: number;
21
+ };
3
22
  /** Cost aggregation data */
4
23
  type CostData = {
5
24
  totalCost: number;
25
+ /**
26
+ * Count of cost-bearing leaf calls (`agent_call_end` / `memory_*`) that did
27
+ * measurable work but had no usable cost (unpriced model / pricing-table miss).
28
+ * When > 0, `totalCost` is a LOWER BOUND — the unknown component is not
29
+ * included — so the dashboard can flag it instead of implying an exact figure.
30
+ */
31
+ unpricedCalls: number;
6
32
  totalTokens: {
7
33
  input: number;
8
34
  output: number;
9
35
  reasoning: number;
10
36
  };
11
- byAgent: Record<string, {
12
- cost: number;
13
- calls: number;
14
- }>;
15
- byModel: Record<string, {
16
- cost: number;
17
- calls: number;
18
- tokens: {
19
- input: number;
20
- output: number;
21
- };
22
- }>;
23
- byWorkflow: Record<string, {
24
- cost: number;
25
- executions: number;
26
- }>;
37
+ byAgent: Record<string, CostBucket>;
38
+ byModel: Record<string, TokenCostBucket>;
39
+ byWorkflow: Record<string, WorkflowCostBucket>;
27
40
  /**
28
41
  * Cost decomposition by retry reason. `primary` accumulates cost from
29
42
  * `agent_call` events WITHOUT a `retryReason` (first-attempt calls).
@@ -57,11 +70,7 @@ type CostData = {
57
70
  * and byAgent/byModel/byWorkflow buckets will always sum to ≤
58
71
  * totalCost; the difference is the embedder spend.
59
72
  */
60
- byEmbedder: Record<string, {
61
- cost: number;
62
- calls: number;
63
- tokens: number;
64
- }>;
73
+ byEmbedder: Record<string, EmbedderCostBucket>;
65
74
  };
66
75
  /** Hono app environment bindings */
67
76
  type StudioEnv = {
@@ -829,6 +829,7 @@ function emptyRetry() {
829
829
  function emptyCostData() {
830
830
  return {
831
831
  totalCost: 0,
832
+ unpricedCalls: 0,
832
833
  totalTokens: { input: 0, output: 0, reasoning: 0 },
833
834
  byAgent: {},
834
835
  byModel: {},
@@ -841,7 +842,7 @@ function reduceCost(acc, event) {
841
842
  const isWorkflowStart = event.type === "workflow_start";
842
843
  if (isWorkflowStart && event.workflow) {
843
844
  const byWorkflow2 = { ...acc.byWorkflow };
844
- const prev = byWorkflow2[event.workflow] ?? { cost: 0, executions: 0 };
845
+ const prev = byWorkflow2[event.workflow] ?? { cost: 0, executions: 0, unpricedCalls: 0 };
845
846
  byWorkflow2[event.workflow] = { ...prev, executions: prev.executions + 1 };
846
847
  return { ...acc, byWorkflow: byWorkflow2 };
847
848
  }
@@ -849,6 +850,7 @@ function reduceCost(acc, event) {
849
850
  const cost = (0, import_axl2.eventCostContribution)(event);
850
851
  if (event.type === "ask_end") return acc;
851
852
  const tokens = event.tokens ?? {};
853
+ const unpricedLeaf = (0, import_axl2.isUnpricedLeaf)(event);
852
854
  const totalTokens = event.type === "agent_call_end" ? {
853
855
  input: acc.totalTokens.input + finite(tokens.input),
854
856
  output: acc.totalTokens.output + finite(tokens.output),
@@ -856,15 +858,25 @@ function reduceCost(acc, event) {
856
858
  } : acc.totalTokens;
857
859
  const byAgent = { ...acc.byAgent };
858
860
  if (event.agent) {
859
- const prev = byAgent[event.agent] ?? { cost: 0, calls: 0 };
860
- byAgent[event.agent] = { cost: prev.cost + cost, calls: prev.calls + 1 };
861
+ const prev = byAgent[event.agent] ?? { cost: 0, calls: 0, unpricedCalls: 0 };
862
+ byAgent[event.agent] = {
863
+ cost: prev.cost + cost,
864
+ calls: prev.calls + 1,
865
+ unpricedCalls: prev.unpricedCalls + (unpricedLeaf ? 1 : 0)
866
+ };
861
867
  }
862
868
  const byModel = { ...acc.byModel };
863
869
  if (event.model) {
864
- const prev = byModel[event.model] ?? { cost: 0, calls: 0, tokens: { input: 0, output: 0 } };
870
+ const prev = byModel[event.model] ?? {
871
+ cost: 0,
872
+ calls: 0,
873
+ unpricedCalls: 0,
874
+ tokens: { input: 0, output: 0 }
875
+ };
865
876
  byModel[event.model] = {
866
877
  cost: prev.cost + cost,
867
878
  calls: prev.calls + 1,
879
+ unpricedCalls: prev.unpricedCalls + (unpricedLeaf ? 1 : 0),
868
880
  tokens: {
869
881
  input: prev.tokens.input + finite(tokens.input),
870
882
  output: prev.tokens.output + finite(tokens.output)
@@ -873,10 +885,11 @@ function reduceCost(acc, event) {
873
885
  }
874
886
  const byWorkflow = { ...acc.byWorkflow };
875
887
  if (event.workflow) {
876
- const prev = byWorkflow[event.workflow] ?? { cost: 0, executions: 0 };
888
+ const prev = byWorkflow[event.workflow] ?? { cost: 0, executions: 0, unpricedCalls: 0 };
877
889
  byWorkflow[event.workflow] = {
878
890
  cost: prev.cost + cost,
879
- executions: prev.executions + (isWorkflowStart ? 1 : 0)
891
+ executions: prev.executions + (isWorkflowStart ? 1 : 0),
892
+ unpricedCalls: prev.unpricedCalls + (unpricedLeaf ? 1 : 0)
880
893
  };
881
894
  }
882
895
  let retry = acc.retry;
@@ -907,15 +920,17 @@ function reduceCost(acc, event) {
907
920
  byEmbedder = { ...acc.byEmbedder };
908
921
  const modelKey = usage?.model ?? "unknown";
909
922
  const embedTokens = typeof usage?.tokens === "number" ? finite(usage.tokens) : 0;
910
- const prev = byEmbedder[modelKey] ?? { cost: 0, calls: 0, tokens: 0 };
923
+ const prev = byEmbedder[modelKey] ?? { cost: 0, calls: 0, unpricedCalls: 0, tokens: 0 };
911
924
  byEmbedder[modelKey] = {
912
925
  cost: prev.cost + cost,
913
926
  calls: prev.calls + 1,
927
+ unpricedCalls: prev.unpricedCalls + (unpricedLeaf ? 1 : 0),
914
928
  tokens: prev.tokens + embedTokens
915
929
  };
916
930
  }
917
931
  return {
918
932
  totalCost: acc.totalCost + cost,
933
+ unpricedCalls: acc.unpricedCalls + (unpricedLeaf ? 1 : 0),
919
934
  totalTokens,
920
935
  byAgent,
921
936
  byModel,