@tangle-network/agent-eval 0.131.1 → 0.133.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.
- package/CHANGELOG.md +14 -0
- package/dist/analyst/index.d.ts +5 -5
- package/dist/analyst/index.js +3 -3
- package/dist/{analyze-runs-CBnCgfse.d.ts → analyze-runs-DZr7JW-m.d.ts} +5 -5
- package/dist/{analyze-runs-CBnCgfse.d.ts.map → analyze-runs-DZr7JW-m.d.ts.map} +1 -1
- package/dist/benchmarks/index.d.ts +1 -1
- package/dist/benchmarks/index.js +1 -1
- package/dist/{benchmarks-BDtRiOvE.js → benchmarks-DncrVrSr.js} +3 -3
- package/dist/{benchmarks-BDtRiOvE.js.map → benchmarks-DncrVrSr.js.map} +1 -1
- package/dist/campaign/index.d.ts +4 -4
- package/dist/campaign/index.js +2 -2
- package/dist/{campaign-CLG6y9jF.js → campaign-CyQMCCEU.js} +4 -4
- package/dist/{campaign-CLG6y9jF.js.map → campaign-CyQMCCEU.js.map} +1 -1
- package/dist/cli.js +1 -1
- package/dist/{client-w90OcvvR.d.ts → client-D4F9hdzR.d.ts} +4 -4
- package/dist/{client-w90OcvvR.d.ts.map → client-D4F9hdzR.d.ts.map} +1 -1
- package/dist/contract/index.d.ts +188 -22
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +1663 -65
- package/dist/contract/index.js.map +1 -1
- package/dist/control.d.ts +1 -1
- package/dist/{cost-ledger-DIgQUFZZ.js → cost-ledger-BrJxbrMy.js} +278 -9
- package/dist/cost-ledger-BrJxbrMy.js.map +1 -0
- package/dist/{cost-ledger-Dye6jCgg.d.ts → cost-ledger-fGS_u_O1.d.ts} +18 -2
- package/dist/cost-ledger-fGS_u_O1.d.ts.map +1 -0
- package/dist/{default-registry-Cj1oUpLN.d.ts → default-registry-Cl3pHo4n.d.ts} +4 -4
- package/dist/{default-registry-Cj1oUpLN.d.ts.map → default-registry-Cl3pHo4n.d.ts.map} +1 -1
- package/dist/{default-registry-C-vFCSEc.js → default-registry-D3T9XbuY.js} +4 -13
- package/dist/default-registry-D3T9XbuY.js.map +1 -0
- package/dist/{eval-campaign-C2k-m4aY.js → eval-campaign-CYkUME2T.js} +2 -2
- package/dist/{eval-campaign-C2k-m4aY.js.map → eval-campaign-CYkUME2T.js.map} +1 -1
- package/dist/{task-failure-attributes-CQZlB3et.js → extract-usage-2j25whHw.js} +154 -2
- package/dist/extract-usage-2j25whHw.js.map +1 -0
- package/dist/fuzz.d.ts +1 -1
- package/dist/fuzz.js +1 -1
- package/dist/hosted/index.d.ts +2 -2
- package/dist/{index-B11XCkdf2.d.ts → index-3cdlURSk.d.ts} +2 -2
- package/dist/index-3cdlURSk.d.ts.map +1 -0
- package/dist/{index-VTypFU3t.d.ts → index-B_eUhU9K.d.ts} +7 -7
- package/dist/{index-VTypFU3t.d.ts.map → index-B_eUhU9K.d.ts.map} +1 -1
- package/dist/{index-DNXoNaFF.d.ts → index-C2fkZhv_.d.ts} +2 -2
- package/dist/{index-DNXoNaFF.d.ts.map → index-C2fkZhv_.d.ts.map} +1 -1
- package/dist/{index-NPeSWD98.d.ts → index-CiP2DRCj.d.ts} +5 -5
- package/dist/{index-NPeSWD98.d.ts.map → index-CiP2DRCj.d.ts.map} +1 -1
- package/dist/index.d.ts +69 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +100 -12
- package/dist/index.js.map +1 -1
- package/dist/{llm-client-B_nIBlYo.d.ts → llm-client-BiK4HW0u.d.ts} +2 -2
- package/dist/{llm-client-B_nIBlYo.d.ts.map → llm-client-BiK4HW0u.d.ts.map} +1 -1
- package/dist/{llm-client--GR4JbZE.js → llm-client-ClPW-dWB.js} +2 -2
- package/dist/{llm-client--GR4JbZE.js.map → llm-client-ClPW-dWB.js.map} +1 -1
- package/dist/meta-eval/index.d.ts +216 -3
- package/dist/{index-D_F6VAKe.d.ts.map → meta-eval/index.d.ts.map} +1 -1
- package/dist/meta-eval/index.js +91 -1
- package/dist/meta-eval/index.js.map +1 -1
- package/dist/multishot/index.d.ts +1 -1
- package/dist/openapi.json +1 -1
- package/dist/{release-report-Crg9oFJ0.d.ts → release-report-DfmKSIEE.d.ts} +3 -3
- package/dist/{release-report-Crg9oFJ0.d.ts.map → release-report-DfmKSIEE.d.ts.map} +1 -1
- package/dist/{replay-RE97Ckjl.d.ts → replay-BI6CVKkp.d.ts} +2 -2
- package/dist/{replay-RE97Ckjl.d.ts.map → replay-BI6CVKkp.d.ts.map} +1 -1
- package/dist/{replay-D18-pBAA.js → replay-BMR4TEYY.js} +2 -3
- package/dist/{replay-D18-pBAA.js.map → replay-BMR4TEYY.js.map} +1 -1
- package/dist/reporting.d.ts +4 -4
- package/dist/{researcher-Q5rpPqZY.d.ts → researcher-DMimgHtN.d.ts} +4 -4
- package/dist/{researcher-Q5rpPqZY.d.ts.map → researcher-DMimgHtN.d.ts.map} +1 -1
- package/dist/{reward-hacking-CW-3HN0n.d.ts → reward-hacking-D-QqXvg-.d.ts} +2 -2
- package/dist/{reward-hacking-CW-3HN0n.d.ts.map → reward-hacking-D-QqXvg-.d.ts.map} +1 -1
- package/dist/rl.d.ts +156 -6
- package/dist/rl.d.ts.map +1 -1
- package/dist/rl.js +217 -2
- package/dist/rl.js.map +1 -1
- package/dist/rollout/index.d.ts +1 -1
- package/dist/{rubric-predictive-validity-lXLmashy.d.ts → rubric-predictive-validity-C1dCLcvb.d.ts} +2 -2
- package/dist/{rubric-predictive-validity-lXLmashy.d.ts.map → rubric-predictive-validity-C1dCLcvb.d.ts.map} +1 -1
- package/dist/{run-evidence-oByzm-dE.d.ts → run-evidence-DokQtX0-.d.ts} +2 -2
- package/dist/{run-evidence-oByzm-dE.d.ts.map → run-evidence-DokQtX0-.d.ts.map} +1 -1
- package/dist/run-record-CN8Zd21B.js.map +1 -1
- package/dist/{run-record-BJnYdTxO.d.ts → run-record-DcObtIGh.d.ts} +4 -14
- package/dist/run-record-DcObtIGh.d.ts.map +1 -0
- package/dist/{semantic-concept-judge-b5m3irbR.js → semantic-concept-judge-BypLt6Fw.js} +4 -4
- package/dist/{semantic-concept-judge-b5m3irbR.js.map → semantic-concept-judge-BypLt6Fw.js.map} +1 -1
- package/dist/{server-m5D9cvnG.js → server-BPqlDBWK.js} +3 -3
- package/dist/{server-m5D9cvnG.js.map → server-BPqlDBWK.js.map} +1 -1
- package/dist/{skill-usage-D5mlWdAJ.d.ts → skill-usage-BaaxFSJR.d.ts} +5 -5
- package/dist/{skill-usage-D5mlWdAJ.d.ts.map → skill-usage-BaaxFSJR.d.ts.map} +1 -1
- package/dist/{skillopt-optimization-method-D0MVjJdP.d.ts → skillopt-optimization-method-CAASpcS3.d.ts} +9 -9
- package/dist/{skillopt-optimization-method-D0MVjJdP.d.ts.map → skillopt-optimization-method-CAASpcS3.d.ts.map} +1 -1
- package/dist/{skillopt-optimization-method-eOJL2570.js → skillopt-optimization-method-DgN7U9iR.js} +3 -3
- package/dist/{skillopt-optimization-method-eOJL2570.js.map → skillopt-optimization-method-DgN7U9iR.js.map} +1 -1
- package/dist/{statistics-Cmj6nynr.d.ts → statistics-DbvkkDPa.d.ts} +2 -2
- package/dist/{statistics-Cmj6nynr.d.ts.map → statistics-DbvkkDPa.d.ts.map} +1 -1
- package/dist/{summary-report-CWwB_LiV.d.ts → summary-report-DnUcjVpV.d.ts} +2 -2
- package/dist/{summary-report-CWwB_LiV.d.ts.map → summary-report-DnUcjVpV.d.ts.map} +1 -1
- package/dist/traces.d.ts +2 -2
- package/dist/traces.js +2 -2
- package/dist/{types-CsD5nTfV.d.ts → types-BokuXvOG.d.ts} +4 -4
- package/dist/{types-CsD5nTfV.d.ts.map → types-BokuXvOG.d.ts.map} +1 -1
- package/dist/{types-DGsxbAEd.d.ts → types-Cc3qbqzj.d.ts} +3 -3
- package/dist/{types-DGsxbAEd.d.ts.map → types-Cc3qbqzj.d.ts.map} +1 -1
- package/dist/wire/index.d.ts +2 -2
- package/dist/wire/index.js +1 -1
- package/package.json +3 -8
- package/dist/belief-state/index.d.ts +0 -622
- package/dist/belief-state/index.d.ts.map +0 -1
- package/dist/belief-state/index.js +0 -1819
- package/dist/belief-state/index.js.map +0 -1
- package/dist/calibration-CNWWA6K8.js +0 -94
- package/dist/calibration-CNWWA6K8.js.map +0 -1
- package/dist/code-agent-session-BjkMTQ7H.js +0 -1390
- package/dist/code-agent-session-BjkMTQ7H.js.map +0 -1
- package/dist/code-agent-session-aYa3SGKz.d.ts +0 -143
- package/dist/code-agent-session-aYa3SGKz.d.ts.map +0 -1
- package/dist/cost-ledger-DIgQUFZZ.js.map +0 -1
- package/dist/cost-ledger-Dye6jCgg.d.ts.map +0 -1
- package/dist/default-registry-C-vFCSEc.js.map +0 -1
- package/dist/extract-usage-BrQ8mCLX.js +0 -155
- package/dist/extract-usage-BrQ8mCLX.js.map +0 -1
- package/dist/index-B11XCkdf2.d.ts.map +0 -1
- package/dist/index-D_F6VAKe.d.ts +0 -217
- package/dist/metrics-C9YY1OcL.js +0 -239
- package/dist/metrics-C9YY1OcL.js.map +0 -1
- package/dist/off-policy-DvgzvtIx.js +0 -220
- package/dist/off-policy-DvgzvtIx.js.map +0 -1
- package/dist/off-policy-mskQw8Mb.d.ts +0 -153
- package/dist/off-policy-mskQw8Mb.d.ts.map +0 -1
- package/dist/run-record-BJnYdTxO.d.ts.map +0 -1
- package/dist/runtime-trajectory-1gyaTOoC.js +0 -93
- package/dist/runtime-trajectory-1gyaTOoC.js.map +0 -1
- package/dist/runtime-trajectory-BXxG4lyi.d.ts +0 -50
- package/dist/runtime-trajectory-BXxG4lyi.d.ts.map +0 -1
- package/dist/task-failure-attributes-CQZlB3et.js.map +0 -1
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, firstTokenCount, tokenUsageSource } from "@tangle-network/agent-core/telemetry";
|
|
2
|
-
import { SSEChunkParser } from "@tangle-network/agent-core/sse";
|
|
3
|
-
//#region src/trace/extract-usage.ts
|
|
4
|
-
/**
|
|
5
|
-
* Provider response and SSE usage extraction.
|
|
6
|
-
*
|
|
7
|
-
* Missing usage returns `null`; reported zeroes and cache-only activity remain
|
|
8
|
-
* distinguishable from absent telemetry.
|
|
9
|
-
*/
|
|
10
|
-
const INPUT_OTHER_KEYS = ["input_other"];
|
|
11
|
-
const EXCLUSIVE_REASONING_KEYS = [
|
|
12
|
-
"reasoning",
|
|
13
|
-
"reasoning_tokens",
|
|
14
|
-
"reasoningTokens"
|
|
15
|
-
];
|
|
16
|
-
const INCLUSIVE_REASONING_KEYS = ["reasoning_output_tokens", "reasoningOutputTokens"];
|
|
17
|
-
const INPUT_DETAIL_KEYS = ["prompt_tokens_details", "input_tokens_details"];
|
|
18
|
-
const OUTPUT_DETAIL_KEYS = ["completion_tokens_details", "output_tokens_details"];
|
|
19
|
-
const CACHED_KEYS = [
|
|
20
|
-
"cache",
|
|
21
|
-
"cached_tokens",
|
|
22
|
-
"cached_input_tokens",
|
|
23
|
-
"cache_read_tokens",
|
|
24
|
-
"cache_read_input_tokens",
|
|
25
|
-
"cachedTokens",
|
|
26
|
-
"cachedInputTokens",
|
|
27
|
-
"cacheReadTokens",
|
|
28
|
-
"cacheReadInputTokens",
|
|
29
|
-
"input_cache_read"
|
|
30
|
-
];
|
|
31
|
-
const CACHE_WRITE_KEYS = [
|
|
32
|
-
"cache_creation_tokens",
|
|
33
|
-
"cache_creation_input_tokens",
|
|
34
|
-
"cacheCreationTokens",
|
|
35
|
-
"cacheCreationInputTokens",
|
|
36
|
-
"input_cache_creation"
|
|
37
|
-
];
|
|
38
|
-
function nestedRecord(source, key) {
|
|
39
|
-
const value = source[key];
|
|
40
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
41
|
-
}
|
|
42
|
-
function nestedNumber(source, recordKeys, valueKeys) {
|
|
43
|
-
for (const recordKey of recordKeys) {
|
|
44
|
-
const value = firstTokenCount(nestedRecord(source, recordKey), valueKeys);
|
|
45
|
-
if (value !== void 0) return value;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Pull `{ input, output, cached?, cacheWrite? }` from a parsed response
|
|
50
|
-
* body. Accepts a top-level `usage` object (the common case) or a body that IS
|
|
51
|
-
* the usage object. Returns null only when none of those categories is present.
|
|
52
|
-
*/
|
|
53
|
-
function extractUsage(body) {
|
|
54
|
-
if (!body || typeof body !== "object") return null;
|
|
55
|
-
const usage = tokenUsageSource(body);
|
|
56
|
-
const input = firstTokenCount(usage, TOKEN_USAGE_INPUT_KEYS);
|
|
57
|
-
const inputOther = firstTokenCount(usage, INPUT_OTHER_KEYS);
|
|
58
|
-
const output = firstTokenCount(usage, TOKEN_USAGE_OUTPUT_KEYS);
|
|
59
|
-
const exclusiveReasoning = firstTokenCount(usage, EXCLUSIVE_REASONING_KEYS);
|
|
60
|
-
const inclusiveReasoning = firstTokenCount(usage, INCLUSIVE_REASONING_KEYS) ?? nestedNumber(usage, OUTPUT_DETAIL_KEYS, ["reasoning_tokens", "reasoningTokens"]);
|
|
61
|
-
const reasoning = exclusiveReasoning ?? inclusiveReasoning;
|
|
62
|
-
const nestedCache = nestedRecord(usage, "cache");
|
|
63
|
-
const cached = firstTokenCount(usage, CACHED_KEYS) ?? firstTokenCount(nestedCache, ["read"]) ?? nestedNumber(usage, INPUT_DETAIL_KEYS, ["cached_tokens", "cachedTokens"]);
|
|
64
|
-
const cacheWrite = firstTokenCount(usage, CACHE_WRITE_KEYS) ?? firstTokenCount(nestedCache, ["write"]);
|
|
65
|
-
if (input === void 0 && inputOther === void 0 && output === void 0 && reasoning === void 0 && cached === void 0 && cacheWrite === void 0) return null;
|
|
66
|
-
const result = {
|
|
67
|
-
input: (input ?? 0) + (inputOther ?? 0),
|
|
68
|
-
output: (output ?? (inclusiveReasoning !== void 0 ? inclusiveReasoning : 0)) + (exclusiveReasoning ?? 0)
|
|
69
|
-
};
|
|
70
|
-
if (reasoning !== void 0) result.reasoning = reasoning;
|
|
71
|
-
if (cached !== void 0) result.cached = cached;
|
|
72
|
-
if (cacheWrite !== void 0) result.cacheWrite = cacheWrite;
|
|
73
|
-
return result;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Extract token usage from a complete SSE response body using the shared SSE
|
|
77
|
-
* frame parser. Cumulative snapshots are the fail-safe default because summing
|
|
78
|
-
* them inflates billing; callers with explicit delta events opt into `mode: 'delta'`.
|
|
79
|
-
*/
|
|
80
|
-
function extractUsageFromSse(text, options = {}) {
|
|
81
|
-
const mode = options.mode ?? "cumulative";
|
|
82
|
-
let input = 0;
|
|
83
|
-
let output = 0;
|
|
84
|
-
let reasoning = 0;
|
|
85
|
-
let sawReasoning = false;
|
|
86
|
-
let cached = 0;
|
|
87
|
-
let sawCached = false;
|
|
88
|
-
let cacheWrite = 0;
|
|
89
|
-
let sawCacheWrite = false;
|
|
90
|
-
let found = false;
|
|
91
|
-
const parser = new SSEChunkParser({ transform: parseSseJson });
|
|
92
|
-
const events = [...parser.push(text), ...parser.flush()];
|
|
93
|
-
const merge = mode === "delta" ? (current, next) => current + next : Math.max;
|
|
94
|
-
for (const event of events) {
|
|
95
|
-
const usage = extractUsage(event.data);
|
|
96
|
-
if (!usage) continue;
|
|
97
|
-
input = merge(input, usage.input);
|
|
98
|
-
output = merge(output, usage.output);
|
|
99
|
-
if (usage.reasoning !== void 0) {
|
|
100
|
-
reasoning = merge(reasoning, usage.reasoning);
|
|
101
|
-
sawReasoning = true;
|
|
102
|
-
}
|
|
103
|
-
if (usage.cached !== void 0) {
|
|
104
|
-
cached = merge(cached, usage.cached);
|
|
105
|
-
sawCached = true;
|
|
106
|
-
}
|
|
107
|
-
if (usage.cacheWrite !== void 0) {
|
|
108
|
-
cacheWrite = merge(cacheWrite, usage.cacheWrite);
|
|
109
|
-
sawCacheWrite = true;
|
|
110
|
-
}
|
|
111
|
-
found = true;
|
|
112
|
-
}
|
|
113
|
-
if (!found) return null;
|
|
114
|
-
return {
|
|
115
|
-
input,
|
|
116
|
-
output,
|
|
117
|
-
...sawReasoning ? { reasoning } : {},
|
|
118
|
-
...sawCached ? { cached } : {},
|
|
119
|
-
...sawCacheWrite ? { cacheWrite } : {}
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
function parseSseJson(raw) {
|
|
123
|
-
const payload = raw.trim();
|
|
124
|
-
if (!payload || payload === "[DONE]") return null;
|
|
125
|
-
try {
|
|
126
|
-
return JSON.parse(payload);
|
|
127
|
-
} catch {
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Extract usage from an HTTP `Response` without consuming the caller's body:
|
|
133
|
-
* clones, reads the text, and tries the JSON parser first, then the SSE
|
|
134
|
-
* accumulator. Best-effort — returns null on any read/parse miss so a usage tee
|
|
135
|
-
* never takes down the underlying call.
|
|
136
|
-
*/
|
|
137
|
-
async function extractUsageFromResponse(response, sseOptions) {
|
|
138
|
-
let text;
|
|
139
|
-
try {
|
|
140
|
-
text = await response.clone().text();
|
|
141
|
-
} catch {
|
|
142
|
-
return null;
|
|
143
|
-
}
|
|
144
|
-
let json;
|
|
145
|
-
try {
|
|
146
|
-
json = JSON.parse(text);
|
|
147
|
-
} catch {
|
|
148
|
-
json = void 0;
|
|
149
|
-
}
|
|
150
|
-
return extractUsage(json) ?? extractUsageFromSse(text, sseOptions);
|
|
151
|
-
}
|
|
152
|
-
//#endregion
|
|
153
|
-
export { extractUsageFromResponse as n, extractUsageFromSse as r, extractUsage as t };
|
|
154
|
-
|
|
155
|
-
//# sourceMappingURL=extract-usage-BrQ8mCLX.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extract-usage-BrQ8mCLX.js","names":["obj"],"sources":["../src/trace/extract-usage.ts"],"sourcesContent":["/**\n * Provider response and SSE usage extraction.\n *\n * Missing usage returns `null`; reported zeroes and cache-only activity remain\n * distinguishable from absent telemetry.\n */\n\nimport { SSEChunkParser } from '@tangle-network/agent-core/sse'\nimport {\n firstTokenCount,\n TOKEN_USAGE_INPUT_KEYS,\n TOKEN_USAGE_OUTPUT_KEYS,\n tokenUsageSource,\n} from '@tangle-network/agent-core/telemetry'\nimport type { RunTokenUsage } from '../run-record'\n\nexport type ExtractedUsage = RunTokenUsage\nexport type SseUsageMode = 'cumulative' | 'delta'\n\nexport interface ExtractUsageFromSseOptions {\n /** Provider usage events are cumulative snapshots unless explicitly marked as deltas. */\n mode?: SseUsageMode\n}\n\nconst INPUT_OTHER_KEYS = ['input_other'] as const\nconst EXCLUSIVE_REASONING_KEYS = ['reasoning', 'reasoning_tokens', 'reasoningTokens'] as const\nconst INCLUSIVE_REASONING_KEYS = ['reasoning_output_tokens', 'reasoningOutputTokens'] as const\nconst INPUT_DETAIL_KEYS = ['prompt_tokens_details', 'input_tokens_details'] as const\nconst OUTPUT_DETAIL_KEYS = ['completion_tokens_details', 'output_tokens_details'] as const\nconst CACHED_KEYS = [\n 'cache',\n 'cached_tokens',\n 'cached_input_tokens',\n 'cache_read_tokens',\n 'cache_read_input_tokens',\n 'cachedTokens',\n 'cachedInputTokens',\n 'cacheReadTokens',\n 'cacheReadInputTokens',\n 'input_cache_read',\n] as const\nconst CACHE_WRITE_KEYS = [\n 'cache_creation_tokens',\n 'cache_creation_input_tokens',\n 'cacheCreationTokens',\n 'cacheCreationInputTokens',\n 'input_cache_creation',\n] as const\n\nfunction nestedRecord(\n source: Record<string, unknown>,\n key: string,\n): Record<string, unknown> | undefined {\n const value = source[key]\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined\n}\n\nfunction nestedNumber(\n source: Record<string, unknown>,\n recordKeys: readonly string[],\n valueKeys: readonly string[],\n): number | undefined {\n for (const recordKey of recordKeys) {\n const value = firstTokenCount(nestedRecord(source, recordKey), valueKeys)\n if (value !== undefined) return value\n }\n return undefined\n}\n\n/**\n * Pull `{ input, output, cached?, cacheWrite? }` from a parsed response\n * body. Accepts a top-level `usage` object (the common case) or a body that IS\n * the usage object. Returns null only when none of those categories is present.\n */\nexport function extractUsage(body: unknown): ExtractedUsage | null {\n if (!body || typeof body !== 'object') return null\n const obj = body as Record<string, unknown>\n const usage = tokenUsageSource(obj)\n const input = firstTokenCount(usage, TOKEN_USAGE_INPUT_KEYS)\n const inputOther = firstTokenCount(usage, INPUT_OTHER_KEYS)\n const output = firstTokenCount(usage, TOKEN_USAGE_OUTPUT_KEYS)\n const exclusiveReasoning = firstTokenCount(usage, EXCLUSIVE_REASONING_KEYS)\n const inclusiveReasoning =\n firstTokenCount(usage, INCLUSIVE_REASONING_KEYS) ??\n nestedNumber(usage, OUTPUT_DETAIL_KEYS, ['reasoning_tokens', 'reasoningTokens'])\n const reasoning = exclusiveReasoning ?? inclusiveReasoning\n const nestedCache = nestedRecord(usage, 'cache')\n const cached =\n firstTokenCount(usage, CACHED_KEYS) ??\n firstTokenCount(nestedCache, ['read']) ??\n nestedNumber(usage, INPUT_DETAIL_KEYS, ['cached_tokens', 'cachedTokens'])\n const cacheWrite =\n firstTokenCount(usage, CACHE_WRITE_KEYS) ?? firstTokenCount(nestedCache, ['write'])\n if (\n input === undefined &&\n inputOther === undefined &&\n output === undefined &&\n reasoning === undefined &&\n cached === undefined &&\n cacheWrite === undefined\n )\n return null\n const result: ExtractedUsage = {\n input: (input ?? 0) + (inputOther ?? 0),\n output:\n (output ?? (inclusiveReasoning !== undefined ? inclusiveReasoning : 0)) +\n (exclusiveReasoning ?? 0),\n }\n if (reasoning !== undefined) result.reasoning = reasoning\n if (cached !== undefined) result.cached = cached\n if (cacheWrite !== undefined) result.cacheWrite = cacheWrite\n return result\n}\n\n/**\n * Extract token usage from a complete SSE response body using the shared SSE\n * frame parser. Cumulative snapshots are the fail-safe default because summing\n * them inflates billing; callers with explicit delta events opt into `mode: 'delta'`.\n */\nexport function extractUsageFromSse(\n text: string,\n options: ExtractUsageFromSseOptions = {},\n): ExtractedUsage | null {\n const mode = options.mode ?? 'cumulative'\n let input = 0\n let output = 0\n let reasoning = 0\n let sawReasoning = false\n let cached = 0\n let sawCached = false\n let cacheWrite = 0\n let sawCacheWrite = false\n let found = false\n const parser = new SSEChunkParser<unknown>({ transform: parseSseJson })\n const events = [...parser.push(text), ...parser.flush()]\n const merge = mode === 'delta' ? (current: number, next: number) => current + next : Math.max\n\n for (const event of events) {\n const usage = extractUsage(event.data)\n if (!usage) continue\n input = merge(input, usage.input)\n output = merge(output, usage.output)\n if (usage.reasoning !== undefined) {\n reasoning = merge(reasoning, usage.reasoning)\n sawReasoning = true\n }\n if (usage.cached !== undefined) {\n cached = merge(cached, usage.cached)\n sawCached = true\n }\n if (usage.cacheWrite !== undefined) {\n cacheWrite = merge(cacheWrite, usage.cacheWrite)\n sawCacheWrite = true\n }\n found = true\n }\n if (!found) return null\n return {\n input,\n output,\n ...(sawReasoning ? { reasoning } : {}),\n ...(sawCached ? { cached } : {}),\n ...(sawCacheWrite ? { cacheWrite } : {}),\n }\n}\n\nfunction parseSseJson(raw: string): unknown | null {\n const payload = raw.trim()\n if (!payload || payload === '[DONE]') return null\n try {\n return JSON.parse(payload)\n } catch {\n return null\n }\n}\n\n/**\n * Extract usage from an HTTP `Response` without consuming the caller's body:\n * clones, reads the text, and tries the JSON parser first, then the SSE\n * accumulator. Best-effort — returns null on any read/parse miss so a usage tee\n * never takes down the underlying call.\n */\nexport async function extractUsageFromResponse(\n response: Response,\n sseOptions?: ExtractUsageFromSseOptions,\n): Promise<ExtractedUsage | null> {\n let text: string\n try {\n text = await response.clone().text()\n } catch {\n return null\n }\n let json: unknown\n try {\n json = JSON.parse(text)\n } catch {\n json = undefined\n }\n return extractUsage(json) ?? extractUsageFromSse(text, sseOptions)\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-B11XCkdf2.d.ts","names":[],"sources":["../src/rollout/exporters.ts","../src/rollout/gate-checks.ts","../src/rollout/interchange/harbor.ts","../src/rollout/ledger.ts","../src/rollout/reward.ts","../src/rollout/mint.ts","../src/rollout/readers/claude-jsonl.ts","../src/rollout/readers/opencode-sqlite.ts","../src/rollout/release/gate-report.ts","../src/rollout/release/scrub.ts","../src/rollout/release/card.ts","../src/rollout/release/hf-dataset.ts"],"mappings":"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"}
|
package/dist/index-D_F6VAKe.d.ts
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
import { f as Run } from "./schema-BtVldJ3T.js";
|
|
2
|
-
import { s as TraceStore } from "./store-CT9YIIve.js";
|
|
3
|
-
import { a as OutcomeFilter, o as OutcomeStore } from "./outcome-store-BYHIuO0e.js";
|
|
4
|
-
import "./rubric-predictive-validity-lXLmashy.js";
|
|
5
|
-
import { a as ContinuousCalibrationResult, n as CandidateScore, o as GoldenItem, r as ContinuousAgreement, t as CalibrationResult } from "./judge-calibration-DFtEMlde.js";
|
|
6
|
-
import { n as SeriesConvergenceResult, t as SeriesConvergenceOptions } from "./series-convergence-ofsqPWhs.js";
|
|
7
|
-
import { i as CorpusAgreementReport } from "./statistics-Cmj6nynr.js";
|
|
8
|
-
//#region src/meta-eval/correlation-study.d.ts
|
|
9
|
-
interface EvalMetricSpec {
|
|
10
|
-
id: string;
|
|
11
|
-
/** Extract a scalar from a run (defaults cover score/pass/durationMs/costUsd/tokens). */
|
|
12
|
-
extract?: (run: Run, store: TraceStore) => Promise<number | null>;
|
|
13
|
-
}
|
|
14
|
-
interface OutcomePair {
|
|
15
|
-
evalMetric: string;
|
|
16
|
-
outcomeMetric: string;
|
|
17
|
-
}
|
|
18
|
-
interface CorrelationResult {
|
|
19
|
-
evalMetric: string;
|
|
20
|
-
outcomeMetric: string;
|
|
21
|
-
n: number;
|
|
22
|
-
pearson: number;
|
|
23
|
-
spearman: number;
|
|
24
|
-
/** 95% bootstrap CI for Pearson. */
|
|
25
|
-
pearsonCi95: {
|
|
26
|
-
lower: number;
|
|
27
|
-
upper: number;
|
|
28
|
-
};
|
|
29
|
-
/** Rough verdict: 'strong' ≥ 0.7, 'moderate' ≥ 0.4, else 'weak'. */
|
|
30
|
-
verdict: 'strong' | 'moderate' | 'weak';
|
|
31
|
-
}
|
|
32
|
-
interface CorrelationStudyResult {
|
|
33
|
-
pairs: CorrelationResult[];
|
|
34
|
-
joinedSamples: number;
|
|
35
|
-
skippedRuns: number;
|
|
36
|
-
}
|
|
37
|
-
interface CorrelationStudyOptions {
|
|
38
|
-
/** Only join outcomes captured within this window after run.startedAt. */
|
|
39
|
-
maxCaptureLagMs?: number;
|
|
40
|
-
/** Restrict to a subset of outcomes (cohort, region, source). */
|
|
41
|
-
outcomeFilter?: OutcomeFilter;
|
|
42
|
-
/** Which outcome per run to use when multiple exist. Default 'latest'. */
|
|
43
|
-
reduction?: 'latest' | 'mean' | 'max';
|
|
44
|
-
/** Bootstrap iterations for the CI. Default 500. */
|
|
45
|
-
bootstrapIterations?: number;
|
|
46
|
-
}
|
|
47
|
-
declare function correlationStudy(traceStore: TraceStore, outcomeStore: OutcomeStore, evalMetrics: EvalMetricSpec[], outcomeMetricNames: string[], options?: CorrelationStudyOptions): Promise<CorrelationStudyResult>;
|
|
48
|
-
//#endregion
|
|
49
|
-
//#region src/meta-eval/calibration.d.ts
|
|
50
|
-
interface CalibrationBin {
|
|
51
|
-
lower: number;
|
|
52
|
-
upper: number;
|
|
53
|
-
n: number;
|
|
54
|
-
evalMean: number;
|
|
55
|
-
outcomeMean: number;
|
|
56
|
-
/** |outcomeMean − evalMean|; contributes to ECE weighted by n/total. */
|
|
57
|
-
gap: number;
|
|
58
|
-
}
|
|
59
|
-
interface CalibrationReport {
|
|
60
|
-
evalMetric: string;
|
|
61
|
-
outcomeMetric: string;
|
|
62
|
-
n: number;
|
|
63
|
-
bins: CalibrationBin[];
|
|
64
|
-
/** Expected Calibration Error — Σ (n_i/N) × |outcomeMean_i − evalMean_i|. */
|
|
65
|
-
ece: number;
|
|
66
|
-
/** Max bin gap — upper bound on miscalibration. */
|
|
67
|
-
maxGap: number;
|
|
68
|
-
}
|
|
69
|
-
interface CalibrationOptions {
|
|
70
|
-
bins?: number;
|
|
71
|
-
/** Equal-width (fixed bin edges) or equal-frequency (quantile bins). */
|
|
72
|
-
binning?: 'equal-width' | 'equal-frequency';
|
|
73
|
-
/** Clip eval values to [lo, hi] before binning. */
|
|
74
|
-
range?: {
|
|
75
|
-
lo: number;
|
|
76
|
-
hi: number;
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
interface CalibrationPair {
|
|
80
|
-
evalScore: number;
|
|
81
|
-
outcome: number;
|
|
82
|
-
}
|
|
83
|
-
declare function calibrationCurve(traceStore: TraceStore, outcomeStore: OutcomeStore, evalMetric: EvalMetricSpec, outcomeMetric: string, options?: CalibrationOptions): Promise<CalibrationReport | null>;
|
|
84
|
-
declare function calibrationFromPairs(inputPairs: CalibrationPair[], evalMetric: string, outcomeMetric: string, options?: CalibrationOptions): CalibrationReport | null;
|
|
85
|
-
//#endregion
|
|
86
|
-
//#region src/meta-eval/sentinel.d.ts
|
|
87
|
-
declare const SENTINEL_METRIC_NAMES: readonly ['irr', 'calibrationKappa', 'sentinelPassRate'];
|
|
88
|
-
type SentinelMetricName = (typeof SENTINEL_METRIC_NAMES)[number];
|
|
89
|
-
interface SentinelMetrics {
|
|
90
|
-
/** Inter-rater reliability — ICC(2,1) from agreement instruments. */
|
|
91
|
-
irr?: number;
|
|
92
|
-
/** Weighted κ vs the human golden set (`calibrateJudge*`). */
|
|
93
|
-
calibrationKappa?: number;
|
|
94
|
-
/** Fraction of a fixed sentinel golden set the judge still scores within tolerance. */
|
|
95
|
-
sentinelPassRate?: number;
|
|
96
|
-
}
|
|
97
|
-
interface SentinelSnapshot {
|
|
98
|
-
/** Caller-supplied ISO-8601 timestamp — the module never reads a clock. */
|
|
99
|
-
at: string;
|
|
100
|
-
judgeId: string;
|
|
101
|
-
/** Exact model identity behind the judge (pin the full version string). */
|
|
102
|
-
judgeModel: string;
|
|
103
|
-
/**
|
|
104
|
-
* Metrics measured at `at`. May be empty: an empty-metrics snapshot is a
|
|
105
|
-
* model-change marker — it records the new `judgeModel` immediately and
|
|
106
|
-
* the silent-upgrade alarm stays raised until a golden-grounded snapshot
|
|
107
|
-
* (calibrationKappa or sentinelPassRate) follows.
|
|
108
|
-
*/
|
|
109
|
-
metrics: SentinelMetrics;
|
|
110
|
-
}
|
|
111
|
-
/** Identity + timestamp the caller supplies alongside an instrument output. */
|
|
112
|
-
interface SnapshotMeta {
|
|
113
|
-
at: string;
|
|
114
|
-
judgeId: string;
|
|
115
|
-
judgeModel: string;
|
|
116
|
-
}
|
|
117
|
-
/** Shape guard for snapshots crossing a boundary (store append, JSONL load, report input). */
|
|
118
|
-
declare function validateSentinelSnapshot(snapshot: SentinelSnapshot, source?: string): void;
|
|
119
|
-
/**
|
|
120
|
-
* From `calibrateJudge` / `calibrateJudgeContinuous` output. Prefers the
|
|
121
|
-
* un-rounded continuous κ_w when the report carries one (integer κ
|
|
122
|
-
* discards information for [0,1] judges).
|
|
123
|
-
*/
|
|
124
|
-
declare function snapshotFromCalibration(report: CalibrationResult | ContinuousCalibrationResult, meta: SnapshotMeta): SentinelSnapshot;
|
|
125
|
-
/**
|
|
126
|
-
* From `corpusInterRaterAgreement` (statistics.ts) or `continuousAgreement`
|
|
127
|
-
* (judge-calibration.ts) output. IRR = ICC(2,1) — the reliability
|
|
128
|
-
* coefficient both instruments compute. For ensemble-level agreement,
|
|
129
|
-
* `meta.judgeId` names the ensemble and `meta.judgeModel` pins its
|
|
130
|
-
* composition (e.g. a joined list of member model strings).
|
|
131
|
-
*/
|
|
132
|
-
declare function snapshotFromAgreement(report: CorpusAgreementReport | ContinuousAgreement, meta: SnapshotMeta): SentinelSnapshot;
|
|
133
|
-
interface SentinelSetOptions {
|
|
134
|
-
/** Max |judge − human| for an item to count as passed. Default 0.1 (tuned for [0,1] scores). */
|
|
135
|
-
tolerance?: number;
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* From a rerun of a fixed sentinel golden set: the same `GoldenItem`s the
|
|
139
|
-
* judge was originally calibrated on, re-scored periodically. Pass rate =
|
|
140
|
-
* fraction of joined items where the judge stays within `tolerance` of the
|
|
141
|
-
* human score. Items the judge didn't score are excluded from the
|
|
142
|
-
* denominator; zero joined items is an error, not a 0% pass rate.
|
|
143
|
-
*/
|
|
144
|
-
declare function snapshotFromSentinelSet(scores: CandidateScore[], golden: GoldenItem[], meta: SnapshotMeta, options?: SentinelSetOptions): SentinelSnapshot;
|
|
145
|
-
interface SentinelStore {
|
|
146
|
-
append(snapshot: SentinelSnapshot): Promise<void>;
|
|
147
|
-
/** All snapshots (optionally for one judge), in append order. */
|
|
148
|
-
history(judgeId?: string): Promise<SentinelSnapshot[]>;
|
|
149
|
-
}
|
|
150
|
-
declare function inMemorySentinelStore(initial?: SentinelSnapshot[]): SentinelStore;
|
|
151
|
-
/**
|
|
152
|
-
* JSONL store — one snapshot per line, appended atomically per call.
|
|
153
|
-
* A corrupt or shape-invalid line is a loud error naming the file and
|
|
154
|
-
* line number: a sentinel history that silently drops records would
|
|
155
|
-
* defeat the drift detection it exists to provide.
|
|
156
|
-
*/
|
|
157
|
-
declare function fileSentinelStore(path: string): SentinelStore;
|
|
158
|
-
interface SentinelThresholds {
|
|
159
|
-
/** Floor for irr — below it the judge ensemble is unreliable regardless of trend. Default 0.6. */
|
|
160
|
-
minIrr?: number;
|
|
161
|
-
/** Max tolerated calibrationKappa drop vs the series baseline. Default 0.15. */
|
|
162
|
-
maxKappaDrop?: number;
|
|
163
|
-
/** Max tolerated sentinelPassRate drop vs the series baseline. Default 0.1. */
|
|
164
|
-
maxSentinelDrop?: number;
|
|
165
|
-
/** Newest snapshot older than this (days, vs asOf) = the sentinel itself went blind. Default 30. */
|
|
166
|
-
staleAfterDays?: number;
|
|
167
|
-
}
|
|
168
|
-
interface JudgeSentinelOptions {
|
|
169
|
-
/** Caller-supplied ISO timestamp staleness is measured against. */
|
|
170
|
-
asOf: string;
|
|
171
|
-
thresholds?: SentinelThresholds;
|
|
172
|
-
/** Forwarded to `analyzeSeries` (window, stableCv, driftRun). */
|
|
173
|
-
convergence?: SeriesConvergenceOptions;
|
|
174
|
-
}
|
|
175
|
-
interface SentinelTrend {
|
|
176
|
-
judgeId: string;
|
|
177
|
-
metric: SentinelMetricName;
|
|
178
|
-
/** Verbatim `analyzeSeries` state for this judge×metric history. */
|
|
179
|
-
state: SeriesConvergenceResult['state'];
|
|
180
|
-
/** Newest value in the series. */
|
|
181
|
-
current: number;
|
|
182
|
-
/** Oldest value in the series — the reference the drop thresholds compare against. */
|
|
183
|
-
baseline: number;
|
|
184
|
-
/** current − baseline (signed; negative = decayed). */
|
|
185
|
-
drift: number;
|
|
186
|
-
alarmed: boolean;
|
|
187
|
-
reason?: string;
|
|
188
|
-
}
|
|
189
|
-
interface SentinelReport {
|
|
190
|
-
perJudge: SentinelTrend[];
|
|
191
|
-
alarms: string[];
|
|
192
|
-
healthy: boolean;
|
|
193
|
-
/**
|
|
194
|
-
* `judgeId:metric` pairs with too few snapshots for the convergence
|
|
195
|
-
* machine. Named, not counted — a blind spot you can't see is a blind
|
|
196
|
-
* spot you won't fix. Floor/drop checks still apply to thin series, so
|
|
197
|
-
* insufficient history alone never masks an alarm.
|
|
198
|
-
*/
|
|
199
|
-
insufficientHistory: string[];
|
|
200
|
-
}
|
|
201
|
-
declare function judgeSentinelReport(history: SentinelSnapshot[], opts: JudgeSentinelOptions): SentinelReport;
|
|
202
|
-
interface EvalHealthStamp {
|
|
203
|
-
healthy: boolean;
|
|
204
|
-
alarms: string[];
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* The object a campaign attaches to its verdicts. Compute it from the
|
|
208
|
-
* sentinel report in a post-campaign hook (or a nightly job feeding the
|
|
209
|
-
* next day's campaigns) and store it alongside the verdict payload.
|
|
210
|
-
* `healthy: false` means the judges that produced those verdicts have an
|
|
211
|
-
* unresolved drift / decay / silent-upgrade / staleness alarm — treat the
|
|
212
|
-
* verdicts as carrying an integrity warning until recalibration clears it.
|
|
213
|
-
*/
|
|
214
|
-
declare function evalHealthStamp(report: SentinelReport): EvalHealthStamp;
|
|
215
|
-
//#endregion
|
|
216
|
-
export { EvalMetricSpec as A, CalibrationPair as C, CorrelationResult as D, calibrationFromPairs as E, correlationStudy as M, CorrelationStudyOptions as O, CalibrationOptions as S, calibrationCurve as T, snapshotFromAgreement as _, SentinelMetrics as a, validateSentinelSnapshot as b, SentinelSnapshot as c, SentinelTrend as d, SnapshotMeta as f, judgeSentinelReport as g, inMemorySentinelStore as h, SentinelMetricName as i, OutcomePair as j, CorrelationStudyResult as k, SentinelStore as l, fileSentinelStore as m, JudgeSentinelOptions as n, SentinelReport as o, evalHealthStamp as p, SENTINEL_METRIC_NAMES as r, SentinelSetOptions as s, EvalHealthStamp as t, SentinelThresholds as u, snapshotFromCalibration as v, CalibrationReport as w, CalibrationBin as x, snapshotFromSentinelSet as y };
|
|
217
|
-
//# sourceMappingURL=index-D_F6VAKe.d.ts.map
|
package/dist/metrics-C9YY1OcL.js
DELETED
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
//#region src/metrics.ts
|
|
2
|
-
/** Per-1K token pricing for exact model ids. */
|
|
3
|
-
const MODEL_PRICING = {
|
|
4
|
-
"gpt-4o": {
|
|
5
|
-
input: .0025,
|
|
6
|
-
output: .01
|
|
7
|
-
},
|
|
8
|
-
"gpt-4o-mini": {
|
|
9
|
-
input: 15e-5,
|
|
10
|
-
output: 6e-4
|
|
11
|
-
},
|
|
12
|
-
"gpt-4-turbo": {
|
|
13
|
-
input: .01,
|
|
14
|
-
output: .03
|
|
15
|
-
},
|
|
16
|
-
"claude-sonnet-4-20250514": {
|
|
17
|
-
input: .003,
|
|
18
|
-
output: .015
|
|
19
|
-
},
|
|
20
|
-
"claude-opus-4-20250514": {
|
|
21
|
-
input: .015,
|
|
22
|
-
output: .075
|
|
23
|
-
},
|
|
24
|
-
"claude-3-haiku-20240307": {
|
|
25
|
-
input: 25e-5,
|
|
26
|
-
output: .00125
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
/** Family-level pricing fallbacks (per-1K), matched against a normalized id
|
|
30
|
-
* after exact lookup misses. Ordered — first match wins. Covers the model
|
|
31
|
-
* ids actually used through the Tangle router + cli-bridge harnesses
|
|
32
|
-
* (`claude-code/sonnet`, `opencode/zai-coding-plan/glm-5.1`,
|
|
33
|
-
* `kimi-code/kimi-k2.6`, `deepseek-v4-pro`, `anthropic/claude-sonnet-4-6`, …),
|
|
34
|
-
* none of which appear in the exact table above — without this they priced
|
|
35
|
-
* to a silent $0, blanking every cost/Pareto axis downstream. */
|
|
36
|
-
const FAMILY_PRICING = [
|
|
37
|
-
[/claude.*opus/, {
|
|
38
|
-
input: .015,
|
|
39
|
-
output: .075
|
|
40
|
-
}],
|
|
41
|
-
[/claude.*haiku/, {
|
|
42
|
-
input: 8e-4,
|
|
43
|
-
output: .004
|
|
44
|
-
}],
|
|
45
|
-
[/claude.*sonnet|claude-code|claude-sonnet/, {
|
|
46
|
-
input: .003,
|
|
47
|
-
output: .015
|
|
48
|
-
}],
|
|
49
|
-
[/gpt-4o-mini/, {
|
|
50
|
-
input: 15e-5,
|
|
51
|
-
output: 6e-4
|
|
52
|
-
}],
|
|
53
|
-
[/gpt-5|gpt-4\.1|o[134]\b/, {
|
|
54
|
-
input: .00125,
|
|
55
|
-
output: .01
|
|
56
|
-
}],
|
|
57
|
-
[/gpt-4o|gpt-4/, {
|
|
58
|
-
input: .0025,
|
|
59
|
-
output: .01
|
|
60
|
-
}],
|
|
61
|
-
[/deepseek/, {
|
|
62
|
-
input: 3e-4,
|
|
63
|
-
output: .0011
|
|
64
|
-
}],
|
|
65
|
-
[/glm|zhipu|zai/, {
|
|
66
|
-
input: 6e-4,
|
|
67
|
-
output: .0022
|
|
68
|
-
}],
|
|
69
|
-
[/kimi|moonshot/, {
|
|
70
|
-
input: 6e-4,
|
|
71
|
-
output: .0025
|
|
72
|
-
}],
|
|
73
|
-
[/qwen/, {
|
|
74
|
-
input: 4e-4,
|
|
75
|
-
output: .0012
|
|
76
|
-
}],
|
|
77
|
-
[/gemini.*flash/, {
|
|
78
|
-
input: 1e-4,
|
|
79
|
-
output: 4e-4
|
|
80
|
-
}],
|
|
81
|
-
[/gemini/, {
|
|
82
|
-
input: .00125,
|
|
83
|
-
output: .005
|
|
84
|
-
}],
|
|
85
|
-
[/llama/, {
|
|
86
|
-
input: 2e-4,
|
|
87
|
-
output: 6e-4
|
|
88
|
-
}]
|
|
89
|
-
];
|
|
90
|
-
/** Normalize a model id for pricing: drop a `@snapshot` suffix, lowercase,
|
|
91
|
-
* and keep the final harness/provider-prefixed segment so family regexes
|
|
92
|
-
* match (`opencode/zai-coding-plan/glm-5.1` → `glm-5.1`). */
|
|
93
|
-
function normalizeModelId(model) {
|
|
94
|
-
return (model.split("@")[0] ?? model).trim().toLowerCase();
|
|
95
|
-
}
|
|
96
|
-
/** Resolve pricing for a model id: exact table, then family fallback.
|
|
97
|
-
* Returns null when the id matches nothing (caller decides — never a
|
|
98
|
-
* silent-zero masquerading as a real $0 cost). */
|
|
99
|
-
function resolveModelPricing(model) {
|
|
100
|
-
if (MODEL_PRICING[model]) return MODEL_PRICING[model];
|
|
101
|
-
const id = normalizeModelId(model);
|
|
102
|
-
if (MODEL_PRICING[id]) return MODEL_PRICING[id];
|
|
103
|
-
for (const [pattern, price] of FAMILY_PRICING) if (pattern.test(id)) return price;
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
/** True when `model` has known pricing (exact or family). Lets cost-aware
|
|
107
|
-
* callers distinguish a real $0 from an unpriced model. */
|
|
108
|
-
function isModelPriced(model) {
|
|
109
|
-
return resolveModelPricing(model) !== null;
|
|
110
|
-
}
|
|
111
|
-
const warnedUnpricedModels = /* @__PURE__ */ new Set();
|
|
112
|
-
/** Estimate token count from string length (chars / 4 approximation) */
|
|
113
|
-
function estimateTokens(text) {
|
|
114
|
-
return Math.ceil(text.length / 4);
|
|
115
|
-
}
|
|
116
|
-
/** Calculate cost in USD from token counts and model. Unknown models warn
|
|
117
|
-
* once (not a silent zero) and return 0 so callers that ignore pricing keep
|
|
118
|
-
* working; cost-sensitive callers should gate on {@link isModelPriced}. */
|
|
119
|
-
function estimateCost(inputTokens, outputTokens, model) {
|
|
120
|
-
const pricing = resolveModelPricing(model);
|
|
121
|
-
if (!pricing) {
|
|
122
|
-
if (!warnedUnpricedModels.has(model)) {
|
|
123
|
-
warnedUnpricedModels.add(model);
|
|
124
|
-
console.warn(`estimateCost: no pricing for model "${model}" — returning 0; add it to MODEL_PRICING/FAMILY_PRICING (cost/Pareto axes will be blank until then)`);
|
|
125
|
-
}
|
|
126
|
-
return 0;
|
|
127
|
-
}
|
|
128
|
-
return inputTokens / 1e3 * pricing.input + outputTokens / 1e3 * pricing.output;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* TokenCounter — accumulates token usage and cost across turns.
|
|
132
|
-
*/
|
|
133
|
-
var TokenCounter = class {
|
|
134
|
-
totalInput = 0;
|
|
135
|
-
totalOutput = 0;
|
|
136
|
-
totalCost = 0;
|
|
137
|
-
model;
|
|
138
|
-
constructor(model = "gpt-4o") {
|
|
139
|
-
this.model = model;
|
|
140
|
-
}
|
|
141
|
-
/** Record tokens for a turn, returns per-turn cost */
|
|
142
|
-
record(inputTokens, outputTokens) {
|
|
143
|
-
this.totalInput += inputTokens;
|
|
144
|
-
this.totalOutput += outputTokens;
|
|
145
|
-
const cost = estimateCost(inputTokens, outputTokens, this.model);
|
|
146
|
-
this.totalCost += cost;
|
|
147
|
-
return cost;
|
|
148
|
-
}
|
|
149
|
-
/** Estimate and record from raw text */
|
|
150
|
-
recordFromText(inputText, outputText) {
|
|
151
|
-
const inputTokens = estimateTokens(inputText);
|
|
152
|
-
const outputTokens = estimateTokens(outputText);
|
|
153
|
-
return {
|
|
154
|
-
inputTokens,
|
|
155
|
-
outputTokens,
|
|
156
|
-
cost: this.record(inputTokens, outputTokens)
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
getTotalInput() {
|
|
160
|
-
return this.totalInput;
|
|
161
|
-
}
|
|
162
|
-
getTotalOutput() {
|
|
163
|
-
return this.totalOutput;
|
|
164
|
-
}
|
|
165
|
-
getTotalCost() {
|
|
166
|
-
return this.totalCost;
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
/**
|
|
170
|
-
* MetricsCollector — collects per-turn metrics from the product.
|
|
171
|
-
*
|
|
172
|
-
* After each turn, queries the product's APIs to measure state changes.
|
|
173
|
-
*/
|
|
174
|
-
var MetricsCollector = class {
|
|
175
|
-
client;
|
|
176
|
-
workspaceId;
|
|
177
|
-
metrics = [];
|
|
178
|
-
constructor(client, workspaceId) {
|
|
179
|
-
this.client = client;
|
|
180
|
-
this.workspaceId = workspaceId;
|
|
181
|
-
}
|
|
182
|
-
/** Collect metrics after a turn completes */
|
|
183
|
-
async collect(turn, responseLatencyMs, responseChars, codeBlocksProduced, blocksExtracted, completionCriteriaMet, completionCriteriaTotal, qualityScore, inputTokens = 0, outputTokens = 0, estimatedCostUsd = 0) {
|
|
184
|
-
const state = await this.getState();
|
|
185
|
-
const m = {
|
|
186
|
-
turn,
|
|
187
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
188
|
-
tasks: state.tasks,
|
|
189
|
-
events: state.events,
|
|
190
|
-
proposals: state.proposals,
|
|
191
|
-
vaultFiles: state.vaultFiles.length,
|
|
192
|
-
responseLatencyMs,
|
|
193
|
-
responseChars,
|
|
194
|
-
codeBlocksProduced,
|
|
195
|
-
blocksExtracted,
|
|
196
|
-
qualityScore,
|
|
197
|
-
inputTokens,
|
|
198
|
-
outputTokens,
|
|
199
|
-
estimatedCostUsd,
|
|
200
|
-
totalCostUsd: estimatedCostUsd,
|
|
201
|
-
completionPercent: completionCriteriaTotal > 0 ? completionCriteriaMet / completionCriteriaTotal * 100 : 0
|
|
202
|
-
};
|
|
203
|
-
this.metrics.push(m);
|
|
204
|
-
return m;
|
|
205
|
-
}
|
|
206
|
-
/** Get current product state */
|
|
207
|
-
async getState() {
|
|
208
|
-
const [tasks, events, approvals, vaultFiles] = await Promise.all([
|
|
209
|
-
this.client.getTasks(this.workspaceId),
|
|
210
|
-
this.client.getEvents(this.workspaceId),
|
|
211
|
-
this.client.getApprovals(this.workspaceId),
|
|
212
|
-
this.client.getVaultTree(this.workspaceId)
|
|
213
|
-
]);
|
|
214
|
-
return {
|
|
215
|
-
tasks: tasks.length,
|
|
216
|
-
events: events.length,
|
|
217
|
-
proposals: {
|
|
218
|
-
pending: approvals.filter((a) => a.status === "pending").length,
|
|
219
|
-
approved: approvals.filter((a) => a.status === "approved").length,
|
|
220
|
-
rejected: approvals.filter((a) => a.status === "rejected").length
|
|
221
|
-
},
|
|
222
|
-
vaultFiles,
|
|
223
|
-
codeBlocks: 0,
|
|
224
|
-
generations: 0
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
/** Get all collected metrics */
|
|
228
|
-
getMetrics() {
|
|
229
|
-
return [...this.metrics];
|
|
230
|
-
}
|
|
231
|
-
/** Get convergence curve (completion% over turns) */
|
|
232
|
-
getConvergenceCurve() {
|
|
233
|
-
return this.metrics.map((m) => m.completionPercent);
|
|
234
|
-
}
|
|
235
|
-
};
|
|
236
|
-
//#endregion
|
|
237
|
-
export { estimateTokens as a, estimateCost as i, MetricsCollector as n, isModelPriced as o, TokenCounter as r, resolveModelPricing as s, MODEL_PRICING as t };
|
|
238
|
-
|
|
239
|
-
//# sourceMappingURL=metrics-C9YY1OcL.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metrics-C9YY1OcL.js","names":[],"sources":["../src/metrics.ts"],"sourcesContent":["import type { ProductClient } from './client'\nimport type { DriverState, TurnMetrics } from './types'\n\ninterface TokenPrice {\n input: number\n output: number\n}\n\n/** Per-1K token pricing for exact model ids. */\nexport const MODEL_PRICING: Record<string, TokenPrice> = {\n 'gpt-4o': { input: 0.0025, output: 0.01 },\n 'gpt-4o-mini': { input: 0.00015, output: 0.0006 },\n 'gpt-4-turbo': { input: 0.01, output: 0.03 },\n 'claude-sonnet-4-20250514': { input: 0.003, output: 0.015 },\n 'claude-opus-4-20250514': { input: 0.015, output: 0.075 },\n 'claude-3-haiku-20240307': { input: 0.00025, output: 0.00125 },\n}\n\n/** Family-level pricing fallbacks (per-1K), matched against a normalized id\n * after exact lookup misses. Ordered — first match wins. Covers the model\n * ids actually used through the Tangle router + cli-bridge harnesses\n * (`claude-code/sonnet`, `opencode/zai-coding-plan/glm-5.1`,\n * `kimi-code/kimi-k2.6`, `deepseek-v4-pro`, `anthropic/claude-sonnet-4-6`, …),\n * none of which appear in the exact table above — without this they priced\n * to a silent $0, blanking every cost/Pareto axis downstream. */\nconst FAMILY_PRICING: Array<[RegExp, TokenPrice]> = [\n [/claude.*opus/, { input: 0.015, output: 0.075 }],\n [/claude.*haiku/, { input: 0.0008, output: 0.004 }],\n [/claude.*sonnet|claude-code|claude-sonnet/, { input: 0.003, output: 0.015 }],\n [/gpt-4o-mini/, { input: 0.00015, output: 0.0006 }],\n [/gpt-5|gpt-4\\.1|o[134]\\b/, { input: 0.00125, output: 0.01 }],\n [/gpt-4o|gpt-4/, { input: 0.0025, output: 0.01 }],\n [/deepseek/, { input: 0.0003, output: 0.0011 }],\n [/glm|zhipu|zai/, { input: 0.0006, output: 0.0022 }],\n [/kimi|moonshot/, { input: 0.0006, output: 0.0025 }],\n [/qwen/, { input: 0.0004, output: 0.0012 }],\n [/gemini.*flash/, { input: 0.0001, output: 0.0004 }],\n [/gemini/, { input: 0.00125, output: 0.005 }],\n [/llama/, { input: 0.0002, output: 0.0006 }],\n]\n\n/** Normalize a model id for pricing: drop a `@snapshot` suffix, lowercase,\n * and keep the final harness/provider-prefixed segment so family regexes\n * match (`opencode/zai-coding-plan/glm-5.1` → `glm-5.1`). */\nfunction normalizeModelId(model: string): string {\n return (model.split('@')[0] ?? model).trim().toLowerCase()\n}\n\n/** Resolve pricing for a model id: exact table, then family fallback.\n * Returns null when the id matches nothing (caller decides — never a\n * silent-zero masquerading as a real $0 cost). */\nexport function resolveModelPricing(model: string): TokenPrice | null {\n if (MODEL_PRICING[model]) return MODEL_PRICING[model]\n const id = normalizeModelId(model)\n if (MODEL_PRICING[id]) return MODEL_PRICING[id]\n for (const [pattern, price] of FAMILY_PRICING) {\n if (pattern.test(id)) return price\n }\n return null\n}\n\n/** True when `model` has known pricing (exact or family). Lets cost-aware\n * callers distinguish a real $0 from an unpriced model. */\nexport function isModelPriced(model: string): boolean {\n return resolveModelPricing(model) !== null\n}\n\nconst warnedUnpricedModels = new Set<string>()\n\n/** Estimate token count from string length (chars / 4 approximation) */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n}\n\n/** Calculate cost in USD from token counts and model. Unknown models warn\n * once (not a silent zero) and return 0 so callers that ignore pricing keep\n * working; cost-sensitive callers should gate on {@link isModelPriced}. */\nexport function estimateCost(inputTokens: number, outputTokens: number, model: string): number {\n const pricing = resolveModelPricing(model)\n if (!pricing) {\n if (!warnedUnpricedModels.has(model)) {\n warnedUnpricedModels.add(model)\n console.warn(\n `estimateCost: no pricing for model \"${model}\" — returning 0; add it to ` +\n 'MODEL_PRICING/FAMILY_PRICING (cost/Pareto axes will be blank until then)',\n )\n }\n return 0\n }\n return (inputTokens / 1000) * pricing.input + (outputTokens / 1000) * pricing.output\n}\n\n/**\n * TokenCounter — accumulates token usage and cost across turns.\n */\nexport class TokenCounter {\n private totalInput = 0\n private totalOutput = 0\n private totalCost = 0\n private model: string\n\n constructor(model = 'gpt-4o') {\n this.model = model\n }\n\n /** Record tokens for a turn, returns per-turn cost */\n record(inputTokens: number, outputTokens: number): number {\n this.totalInput += inputTokens\n this.totalOutput += outputTokens\n const cost = estimateCost(inputTokens, outputTokens, this.model)\n this.totalCost += cost\n return cost\n }\n\n /** Estimate and record from raw text */\n recordFromText(\n inputText: string,\n outputText: string,\n ): { inputTokens: number; outputTokens: number; cost: number } {\n const inputTokens = estimateTokens(inputText)\n const outputTokens = estimateTokens(outputText)\n const cost = this.record(inputTokens, outputTokens)\n return { inputTokens, outputTokens, cost }\n }\n\n getTotalInput(): number {\n return this.totalInput\n }\n getTotalOutput(): number {\n return this.totalOutput\n }\n getTotalCost(): number {\n return this.totalCost\n }\n}\n\n/**\n * MetricsCollector — collects per-turn metrics from the product.\n *\n * After each turn, queries the product's APIs to measure state changes.\n */\nexport class MetricsCollector {\n private client: ProductClient\n private workspaceId: string\n private metrics: TurnMetrics[] = []\n constructor(client: ProductClient, workspaceId: string) {\n this.client = client\n this.workspaceId = workspaceId\n }\n\n /** Collect metrics after a turn completes */\n async collect(\n turn: number,\n responseLatencyMs: number,\n responseChars: number,\n codeBlocksProduced: number,\n blocksExtracted: number,\n completionCriteriaMet: number,\n completionCriteriaTotal: number,\n qualityScore?: number,\n inputTokens = 0,\n outputTokens = 0,\n estimatedCostUsd = 0,\n ): Promise<TurnMetrics> {\n const state = await this.getState()\n\n const m: TurnMetrics = {\n turn,\n timestamp: new Date().toISOString(),\n tasks: state.tasks,\n events: state.events,\n proposals: state.proposals,\n vaultFiles: state.vaultFiles.length,\n responseLatencyMs,\n responseChars,\n codeBlocksProduced,\n blocksExtracted,\n qualityScore,\n inputTokens,\n outputTokens,\n estimatedCostUsd,\n totalCostUsd: estimatedCostUsd,\n completionPercent:\n completionCriteriaTotal > 0 ? (completionCriteriaMet / completionCriteriaTotal) * 100 : 0,\n }\n\n this.metrics.push(m)\n return m\n }\n\n /** Get current product state */\n async getState(): Promise<DriverState> {\n const [tasks, events, approvals, vaultFiles] = await Promise.all([\n this.client.getTasks(this.workspaceId),\n this.client.getEvents(this.workspaceId),\n this.client.getApprovals(this.workspaceId),\n this.client.getVaultTree(this.workspaceId),\n ])\n\n return {\n tasks: tasks.length,\n events: events.length,\n proposals: {\n pending: approvals.filter((a) => a.status === 'pending').length,\n approved: approvals.filter((a) => a.status === 'approved').length,\n rejected: approvals.filter((a) => a.status === 'rejected').length,\n },\n vaultFiles,\n codeBlocks: 0,\n generations: 0,\n }\n }\n\n /** Get all collected metrics */\n getMetrics(): TurnMetrics[] {\n return [...this.metrics]\n }\n\n /** Get convergence curve (completion% over turns) */\n getConvergenceCurve(): number[] {\n return this.metrics.map((m) => m.completionPercent)\n }\n}\n"],"mappings":"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"}
|