modelrig 0.11.1 → 0.12.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 +34 -0
- package/dist/adapters/anthropic.d.ts +4 -4
- package/dist/adapters/anthropic.d.ts.map +1 -1
- package/dist/adapters/anthropic.js +8 -1
- package/dist/adapters/deepseek.d.ts +2 -4
- package/dist/adapters/deepseek.d.ts.map +1 -1
- package/dist/adapters/deepseek.js +9 -5
- package/dist/adapters/gemini.d.ts +4 -1
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +16 -1
- package/dist/adapters/grok.d.ts +2 -4
- package/dist/adapters/grok.d.ts.map +1 -1
- package/dist/adapters/grok.js +8 -4
- package/dist/adapters/history-mapping.d.ts +126 -0
- package/dist/adapters/history-mapping.d.ts.map +1 -0
- package/dist/adapters/history-mapping.js +230 -0
- package/dist/adapters/openai-compat.d.ts +2 -4
- package/dist/adapters/openai-compat.d.ts.map +1 -1
- package/dist/adapters/openai-compat.js +9 -5
- package/dist/adapters/openai.d.ts +2 -4
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +8 -4
- package/dist/adapters/responses-api.d.ts.map +1 -1
- package/dist/adapters/responses-api.js +9 -4
- package/dist/artifacts/artifact.d.ts.map +1 -1
- package/dist/artifacts/artifact.js +79 -0
- package/dist/artifacts/conversation.d.ts +128 -0
- package/dist/artifacts/conversation.d.ts.map +1 -0
- package/dist/artifacts/conversation.js +172 -0
- package/dist/artifacts/index.d.ts +1 -1
- package/dist/artifacts/index.d.ts.map +1 -1
- package/dist/artifacts/media.d.ts +46 -0
- package/dist/artifacts/media.d.ts.map +1 -0
- package/dist/artifacts/media.js +88 -0
- package/dist/artifacts/run-context.d.ts +61 -2
- package/dist/artifacts/run-context.d.ts.map +1 -1
- package/dist/artifacts/run-context.js +183 -12
- package/dist/artifacts/scrub.d.ts +3 -0
- package/dist/artifacts/scrub.d.ts.map +1 -1
- package/dist/bakeoff/engine.d.ts.map +1 -1
- package/dist/bakeoff/engine.js +34 -7
- package/dist/bakeoff/eval-cases.d.ts +5 -0
- package/dist/bakeoff/eval-cases.d.ts.map +1 -1
- package/dist/bakeoff/eval-cases.js +10 -1
- package/dist/bakeoff/replay.d.ts +15 -0
- package/dist/bakeoff/replay.d.ts.map +1 -1
- package/dist/bakeoff/replay.js +19 -1
- package/dist/bakeoff/report.d.ts.map +1 -1
- package/dist/bakeoff/report.js +9 -2
- package/dist/bakeoff/turn-replay.d.ts +93 -0
- package/dist/bakeoff/turn-replay.d.ts.map +1 -0
- package/dist/bakeoff/turn-replay.js +150 -0
- package/dist/bakeoff/types.d.ts +12 -0
- package/dist/bakeoff/types.d.ts.map +1 -1
- package/dist/feedback/grade.d.ts +7 -2
- package/dist/feedback/grade.d.ts.map +1 -1
- package/dist/feedback/grade.js +14 -0
- package/dist/feedback/outcome.d.ts +103 -0
- package/dist/feedback/outcome.d.ts.map +1 -0
- package/dist/feedback/outcome.js +175 -0
- package/dist/gateway/history-bridge.d.ts +32 -0
- package/dist/gateway/history-bridge.d.ts.map +1 -0
- package/dist/gateway/history-bridge.js +64 -0
- package/dist/gateway/serve-client.d.ts.map +1 -1
- package/dist/gateway/serve-client.js +6 -0
- package/dist/index.d.ts +44 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +106 -6
- package/dist/init/observe.d.ts.map +1 -1
- package/dist/init/observe.js +3 -3
- package/dist/registry/build.d.ts +4 -0
- package/dist/registry/build.d.ts.map +1 -1
- package/dist/registry/generation-models.d.ts +68 -0
- package/dist/registry/generation-models.d.ts.map +1 -0
- package/dist/registry/generation-models.js +168 -0
- package/dist/registry/model-kind.d.ts +34 -0
- package/dist/registry/model-kind.d.ts.map +1 -0
- package/dist/registry/model-kind.js +40 -0
- package/dist/registry/pricing-shape.d.ts +29 -1
- package/dist/registry/pricing-shape.d.ts.map +1 -1
- package/dist/registry/pricing-shape.js +9 -0
- package/dist/registry/pricing.d.ts +26 -0
- package/dist/registry/pricing.d.ts.map +1 -1
- package/dist/registry/pricing.js +29 -0
- package/dist/registry/rows.d.ts.map +1 -1
- package/dist/registry/rows.js +3 -1
- package/dist/registry/unit-pricing.d.ts +32 -0
- package/dist/registry/unit-pricing.d.ts.map +1 -0
- package/dist/registry/unit-pricing.js +62 -0
- package/dist/routes/input-loader.d.ts +38 -0
- package/dist/routes/input-loader.d.ts.map +1 -0
- package/dist/routes/input-loader.js +80 -0
- package/dist/routes/loader.d.ts.map +1 -1
- package/dist/routes/loader.js +3 -0
- package/dist/routes/resolved-bundle.d.ts +2 -0
- package/dist/routes/resolved-bundle.d.ts.map +1 -1
- package/dist/routes/resolved-bundle.js +3 -0
- package/dist/run/cost.d.ts +28 -0
- package/dist/run/cost.d.ts.map +1 -1
- package/dist/run/cost.js +74 -0
- package/dist/run/dispatch.d.ts +4 -1
- package/dist/run/dispatch.d.ts.map +1 -1
- package/dist/run/dispatch.js +3 -0
- package/dist/run/limits.d.ts +88 -0
- package/dist/run/limits.d.ts.map +1 -0
- package/dist/run/limits.js +155 -0
- package/dist/run/messages.d.ts +199 -0
- package/dist/run/messages.d.ts.map +1 -0
- package/dist/run/messages.js +430 -0
- package/dist/run/raw-finalize.d.ts +5 -2
- package/dist/run/raw-finalize.d.ts.map +1 -1
- package/dist/run/raw-finalize.js +8 -5
- package/dist/run/raw-request.d.ts.map +1 -1
- package/dist/run/raw-request.js +2 -1
- package/dist/run/raw.d.ts +10 -4
- package/dist/run/raw.d.ts.map +1 -1
- package/dist/run/raw.js +11 -3
- package/dist/run/record-attempt.d.ts.map +1 -1
- package/dist/run/record-attempt.js +16 -6
- package/dist/run/record-call.d.ts +13 -2
- package/dist/run/record-call.d.ts.map +1 -1
- package/dist/run/record-call.js +50 -7
- package/dist/run/run.d.ts.map +1 -1
- package/dist/run/run.js +12 -8
- package/dist/telemetry/attempt-meta.d.ts +49 -1
- package/dist/telemetry/attempt-meta.d.ts.map +1 -1
- package/dist/telemetry/attempt-meta.js +45 -1
- package/dist/telemetry/exporter.d.ts.map +1 -1
- package/dist/telemetry/exporter.js +2 -1
- package/dist/telemetry/grade-mappers.d.ts +1 -1
- package/dist/telemetry/grade-mappers.d.ts.map +1 -1
- package/dist/telemetry/grade-mappers.js +7 -1
- package/dist/telemetry/grade-task.d.ts +49 -0
- package/dist/telemetry/grade-task.d.ts.map +1 -0
- package/dist/telemetry/grade-task.js +85 -0
- package/dist/telemetry/grades-sql.d.ts +16 -1
- package/dist/telemetry/grades-sql.d.ts.map +1 -1
- package/dist/telemetry/grades-sql.js +64 -4
- package/dist/telemetry/ingest-protocol.d.ts +24 -1
- package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
- package/dist/telemetry/ingest-protocol.js +72 -43
- package/dist/telemetry/otel-content.d.ts +31 -0
- package/dist/telemetry/otel-content.d.ts.map +1 -0
- package/dist/telemetry/otel-content.js +106 -0
- package/dist/telemetry/otel-hierarchy.d.ts +57 -0
- package/dist/telemetry/otel-hierarchy.d.ts.map +1 -0
- package/dist/telemetry/otel-hierarchy.js +155 -0
- package/dist/telemetry/otel-normalize.d.ts +15 -1
- package/dist/telemetry/otel-normalize.d.ts.map +1 -1
- package/dist/telemetry/otel-normalize.js +24 -39
- package/dist/telemetry/sinks.d.ts +4 -1
- package/dist/telemetry/sinks.d.ts.map +1 -1
- package/dist/telemetry/sinks.js +53 -34
- package/dist/telemetry/store-migrations.d.ts.map +1 -1
- package/dist/telemetry/store-migrations.js +8 -0
- package/dist/telemetry/store.d.ts +9 -0
- package/dist/telemetry/store.d.ts.map +1 -1
- package/dist/telemetry/store.js +10 -0
- package/dist/telemetry/uniform-rows.d.ts +43 -0
- package/dist/telemetry/uniform-rows.d.ts.map +1 -0
- package/dist/telemetry/uniform-rows.js +139 -0
- package/dist/types/failures-teaching.d.ts.map +1 -1
- package/dist/types/failures-teaching.js +11 -0
- package/dist/types/failures.d.ts +1 -1
- package/dist/types/failures.d.ts.map +1 -1
- package/dist/types/failures.js +2 -0
- package/dist/types/provider.d.ts +12 -0
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/types/route.d.ts +13 -0
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +14 -1
- package/dist/types/telemetry.d.ts.map +1 -1
- package/docs/agent-skill/SKILL.md +16 -3
- package/docs/how-it-fits.md +3 -3
- package/docs/instrumentation.md +15 -6
- package/docs/llms.txt +55 -7
- package/docs/mcp-oracle.md +15 -4
- package/docs/quickstart.md +6 -5
- package/package.json +4 -2
- package/registry/registry.json +456 -0
- package/templates/creative-approval.json +81 -0
- package/templates/support-conversation.json +82 -0
|
@@ -84,10 +84,28 @@ export type ImageInputPrice = {
|
|
|
84
84
|
readonly source: string;
|
|
85
85
|
readonly as_of: string;
|
|
86
86
|
};
|
|
87
|
-
/**
|
|
87
|
+
/** Where a modality block's UNIT rates came from (ARC-4). REQUIRED for any of
|
|
88
|
+
* `image_per_unit` / `audio_per_second` / `video_per_second` /
|
|
89
|
+
* `characters_per_million` to be priced: a unit rate with no provenance is
|
|
90
|
+
* never used (L5 — absent beats guessed). */
|
|
91
|
+
export interface UnitRateProvenance {
|
|
92
|
+
readonly source: string;
|
|
93
|
+
readonly as_of: string;
|
|
94
|
+
}
|
|
95
|
+
/** Non-token units, USD per unit. For an `llm` entry these are INPUT units (an
|
|
96
|
+
* image or a second of audio sent in); for a declared generation model
|
|
97
|
+
* (registry `kind` image_gen | video_gen | tts | stt — ARC-4) they are what the
|
|
98
|
+
* call is billed in: images generated, seconds produced (video/tts) or
|
|
99
|
+
* transcribed (stt), characters synthesized. */
|
|
88
100
|
export interface ModalityRates {
|
|
89
101
|
readonly image_per_unit?: number | null;
|
|
90
102
|
readonly audio_per_second?: number | null;
|
|
103
|
+
/** ARC-4: USD per second of generated video. */
|
|
104
|
+
readonly video_per_second?: number | null;
|
|
105
|
+
/** ARC-4: USD per MILLION characters (TTS input text). */
|
|
106
|
+
readonly characters_per_million?: number | null;
|
|
107
|
+
/** ARC-4: provenance for the unit rates above (see {@link UnitRateProvenance}). */
|
|
108
|
+
readonly provenance?: UnitRateProvenance | null;
|
|
91
109
|
/** Typed, provenance-bearing image-input price (UC-3 M0). Additive and
|
|
92
110
|
* optional; absent when the vendor's image price could not be sourced —
|
|
93
111
|
* absence is honest, never a zero or a guess. Supersedes the bare
|
|
@@ -169,4 +187,14 @@ export interface PricingV2Display {
|
|
|
169
187
|
* guarantee lives here, in code, so no consumer can bypass it.
|
|
170
188
|
*/
|
|
171
189
|
export declare function describePricingV2(pricing: ModelPricingV2): PricingV2Display;
|
|
190
|
+
/**
|
|
191
|
+
* ARC-4: the price block of a DECLARED-ONLY generation model (registry `kind`
|
|
192
|
+
* other than `llm`). Same shape as {@link ModelPricingV2} except `base` is
|
|
193
|
+
* null: these models publish no per-token rate, and a placeholder `0` would be
|
|
194
|
+
* read as "$0 per token" by anything that reads the registry (L5). The price is
|
|
195
|
+
* the `modality` unit rates, with their provenance.
|
|
196
|
+
*/
|
|
197
|
+
export interface GenerationPricingV2 extends Omit<ModelPricingV2, "base"> {
|
|
198
|
+
readonly base: null;
|
|
199
|
+
}
|
|
172
200
|
//# sourceMappingURL=pricing-shape.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pricing-shape.d.ts","sourceRoot":"","sources":["../../src/registry/pricing-shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+BAA+B;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,uEAAuE;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;kFAC8E;IAC9E,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED;2EAC2E;AAC3E,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,wBAAwB,CAAC;AAE/D,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC3C,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;CACvC;AAED,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GACvB;IACE,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,GACD;IACE;iDAC6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEN,
|
|
1
|
+
{"version":3,"file":"pricing-shape.d.ts","sourceRoot":"","sources":["../../src/registry/pricing-shape.ts"],"names":[],"mappings":"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"}
|
|
@@ -142,6 +142,7 @@ function describePricingV2(pricing) {
|
|
|
142
142
|
if (pricing.modality?.audio_per_second != null) {
|
|
143
143
|
modality.push(`audio: $${pricing.modality.audio_per_second.toFixed(4)} per second`);
|
|
144
144
|
}
|
|
145
|
+
pushGenerationRates(modality, pricing.modality ?? null);
|
|
145
146
|
const urlMatch = URL_RE.exec(pricing.source);
|
|
146
147
|
return {
|
|
147
148
|
basis: pricing.basis,
|
|
@@ -158,3 +159,11 @@ function describePricingV2(pricing) {
|
|
|
158
159
|
vendorUrl: urlMatch ? urlMatch[0] : null,
|
|
159
160
|
};
|
|
160
161
|
}
|
|
162
|
+
/** ARC-4: the generation unit rates (video seconds, TTS characters), rendered
|
|
163
|
+
* only when present — honest absence otherwise. */
|
|
164
|
+
function pushGenerationRates(out, m) {
|
|
165
|
+
if (m?.video_per_second != null)
|
|
166
|
+
out.push(`video: $${m.video_per_second.toFixed(4)} per second`);
|
|
167
|
+
if (m?.characters_per_million != null)
|
|
168
|
+
out.push(`text-to-speech: $${m.characters_per_million.toFixed(2)} per 1M characters`);
|
|
169
|
+
}
|
|
@@ -41,4 +41,30 @@ export declare function estimateCostUsd(pricing: ModelPricing, tokensIn: number,
|
|
|
41
41
|
tokensCacheWrite?: number,
|
|
42
42
|
/** 1h-TTL portion of the write (bills at the higher multiplier when known). */
|
|
43
43
|
tokensCacheWrite1h?: number): number;
|
|
44
|
+
/**
|
|
45
|
+
* ARC-4: the per-unit rates the vendored LiteLLM snapshot publishes for a
|
|
46
|
+
* GENERATION model, read by mode (LiteLLM spells the same unit differently per
|
|
47
|
+
* mode, so the mode decides which key is the billed unit — nothing is summed or
|
|
48
|
+
* inferred across keys):
|
|
49
|
+
* - `image_generation`: USD per generated image = `output_cost_per_image`,
|
|
50
|
+
* else `input_cost_per_image` (LiteLLM files OpenAI's per-image price there).
|
|
51
|
+
* - `video_generation`: USD per second = `output_cost_per_video_per_second`,
|
|
52
|
+
* else `output_cost_per_second`.
|
|
53
|
+
* - `audio_speech` (TTS): USD per character = `input_cost_per_character`;
|
|
54
|
+
* USD per second of produced audio = `output_cost_per_second` (billed only
|
|
55
|
+
* when the entry has no per-character rate — one billed unit per model).
|
|
56
|
+
* - `audio_transcription` (STT): USD per second of input audio =
|
|
57
|
+
* `input_cost_per_second` (the snapshot's `output_cost_per_second` on some STT
|
|
58
|
+
* entries is not a billed unit and is ignored).
|
|
59
|
+
* Any other mode (chat, embedding, …) has NO unit price here. Key resolution:
|
|
60
|
+
* a known provider's own prefixes, then `<provider>/<model>`.
|
|
61
|
+
*/
|
|
62
|
+
export interface MapUnitRates {
|
|
63
|
+
readonly key: string;
|
|
64
|
+
readonly mode: string;
|
|
65
|
+
readonly perImage: number | null;
|
|
66
|
+
readonly perSecond: number | null;
|
|
67
|
+
readonly perCharacter: number | null;
|
|
68
|
+
}
|
|
69
|
+
export declare function getMapUnitRates(provider: string, model: string): MapUnitRates | null;
|
|
44
70
|
//# sourceMappingURL=pricing.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../src/registry/pricing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C;;uEAEmE;IACnE,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C;;sEAEkE;IAClE,QAAQ,CAAC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/C;
|
|
1
|
+
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../src/registry/pricing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C;;uEAEmE;IACnE,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C;;sEAEkE;IAClE,QAAQ,CAAC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/C;AA0ED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CA6BnF;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAYvF;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM;AACpB;;;0CAG0C;AAC1C,gBAAgB,SAAI;AACpB,+EAA+E;AAC/E,kBAAkB,SAAI,GACrB,MAAM,CAsBR;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAMD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAsBpF"}
|
package/dist/registry/pricing.js
CHANGED
|
@@ -13,6 +13,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
13
13
|
exports.getPricing = getPricing;
|
|
14
14
|
exports.getPricingV2 = getPricingV2;
|
|
15
15
|
exports.estimateCostUsd = estimateCostUsd;
|
|
16
|
+
exports.getMapUnitRates = getMapUnitRates;
|
|
16
17
|
const node_fs_1 = require("node:fs");
|
|
17
18
|
const node_path_1 = require("node:path");
|
|
18
19
|
/** LiteLLM key prefixes per provider, most-specific first. Verified against
|
|
@@ -129,3 +130,31 @@ tokensCacheWrite1h = 0) {
|
|
|
129
130
|
write1h * write1hRate +
|
|
130
131
|
Math.max(tokensOut, 0) * pricing.outputUsdPerTok);
|
|
131
132
|
}
|
|
133
|
+
function finiteRate(v) {
|
|
134
|
+
return typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : null;
|
|
135
|
+
}
|
|
136
|
+
function getMapUnitRates(provider, model) {
|
|
137
|
+
if (provider === "" || model === "")
|
|
138
|
+
return null;
|
|
139
|
+
const map = loadMap();
|
|
140
|
+
const prefixes = KEY_PREFIXES[provider] ?? [];
|
|
141
|
+
const candidates = [...prefixes.map((p) => `${p}${model}`), `${provider}/${model}`];
|
|
142
|
+
for (const key of candidates) {
|
|
143
|
+
const e = map[key];
|
|
144
|
+
if (e === undefined || typeof e.mode !== "string")
|
|
145
|
+
continue;
|
|
146
|
+
switch (e.mode) {
|
|
147
|
+
case "image_generation":
|
|
148
|
+
return { key, mode: e.mode, perImage: finiteRate(e.output_cost_per_image) ?? finiteRate(e.input_cost_per_image), perSecond: null, perCharacter: null };
|
|
149
|
+
case "video_generation":
|
|
150
|
+
return { key, mode: e.mode, perImage: null, perSecond: finiteRate(e.output_cost_per_video_per_second) ?? finiteRate(e.output_cost_per_second), perCharacter: null };
|
|
151
|
+
case "audio_speech":
|
|
152
|
+
return { key, mode: e.mode, perImage: null, perSecond: finiteRate(e.output_cost_per_second), perCharacter: finiteRate(e.input_cost_per_character) };
|
|
153
|
+
case "audio_transcription":
|
|
154
|
+
return { key, mode: e.mode, perImage: null, perSecond: finiteRate(e.input_cost_per_second), perCharacter: null };
|
|
155
|
+
default:
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../../src/registry/rows.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../../src/registry/rows.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AA4C/C;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE,CA6BxE"}
|
package/dist/registry/rows.js
CHANGED
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.loadRegistryRows = loadRegistryRows;
|
|
11
11
|
const node_fs_1 = require("node:fs");
|
|
12
12
|
const node_path_1 = require("node:path");
|
|
13
|
+
const model_kind_1 = require("./model-kind");
|
|
13
14
|
function packagedRegistryDir() {
|
|
14
15
|
// dist/ and src/ both sit one level under the package root.
|
|
15
16
|
return (0, node_path_1.join)(__dirname, "..", "..", "registry");
|
|
@@ -38,7 +39,8 @@ function loadRegistryRows(registryPath) {
|
|
|
38
39
|
const dir = registryFile.slice(0, Math.max(registryFile.lastIndexOf("/"), 0));
|
|
39
40
|
const leaderboard = readJson((0, node_path_1.join)(dir, "leaderboard.json")) ?? [];
|
|
40
41
|
const effective = new Map(leaderboard.map((r) => [r.model_key, r.effective_usd_per_1k_conformant ?? null]));
|
|
41
|
-
|
|
42
|
+
// ARC-4 rank wall: declared-only generation models never enter selection.
|
|
43
|
+
return (registry.models ?? []).filter(model_kind_1.isRankable).map((entry) => {
|
|
42
44
|
const [provider] = entry.model_key.split("/");
|
|
43
45
|
return {
|
|
44
46
|
key: entry.model_key,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ARC-4 — the registry half of unit pricing: a DECLARED-ONLY generation entry's
|
|
3
|
+
* `pricing_v2.modality` unit rates, read from the packaged registry.json. Only
|
|
4
|
+
* a non-`llm` entry (model-kind.ts) whose modality carries `provenance` (source
|
|
5
|
+
* + as_of) answers; anything else is "no registry price" and the caller falls
|
|
6
|
+
* through to the vendored pricing map (run/cost.ts `estimateUnitCostUsd`).
|
|
7
|
+
*/
|
|
8
|
+
import { type GenerationKind } from "./model-kind";
|
|
9
|
+
import type { ModalityRates } from "./pricing-shape";
|
|
10
|
+
export interface RegistryUnitRates {
|
|
11
|
+
readonly modelKey: string;
|
|
12
|
+
readonly kind: GenerationKind;
|
|
13
|
+
readonly modality: ModalityRates;
|
|
14
|
+
}
|
|
15
|
+
interface RegistryEntryShape {
|
|
16
|
+
readonly model_key?: unknown;
|
|
17
|
+
readonly kind?: unknown;
|
|
18
|
+
readonly declared?: {
|
|
19
|
+
readonly pricing_v2?: {
|
|
20
|
+
readonly modality?: ModalityRates | null;
|
|
21
|
+
} | null;
|
|
22
|
+
} | null;
|
|
23
|
+
}
|
|
24
|
+
/** Build the lookup from registry entries (exported for tests and the registry
|
|
25
|
+
* drift test). */
|
|
26
|
+
export declare function unitRatesIndex(models: readonly RegistryEntryShape[]): Map<string, RegistryUnitRates>;
|
|
27
|
+
/** The registry's unit rates for `provider/model`, or null. */
|
|
28
|
+
export declare function getRegistryUnitRates(provider: string, model: string): RegistryUnitRates | null;
|
|
29
|
+
/** Test-only: replace (or with null, reset) the loaded registry index. */
|
|
30
|
+
export declare function setRegistryUnitRatesForTest(models: readonly RegistryEntryShape[] | null): void;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=unit-pricing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unit-pricing.d.ts","sourceRoot":"","sources":["../../src/registry/unit-pricing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;CAClC;AAED,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,UAAU,CAAC,EAAE;YAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI,CAAA;SAAE,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;CAC1G;AAcD;kBACkB;AAClB,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CASpG;AAkBD,+DAA+D;AAC/D,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAE9F;AAED,0EAA0E;AAC1E,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,GAAG,IAAI,GAAG,IAAI,CAE9F"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ARC-4 — the registry half of unit pricing: a DECLARED-ONLY generation entry's
|
|
4
|
+
* `pricing_v2.modality` unit rates, read from the packaged registry.json. Only
|
|
5
|
+
* a non-`llm` entry (model-kind.ts) whose modality carries `provenance` (source
|
|
6
|
+
* + as_of) answers; anything else is "no registry price" and the caller falls
|
|
7
|
+
* through to the vendored pricing map (run/cost.ts `estimateUnitCostUsd`).
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.unitRatesIndex = unitRatesIndex;
|
|
11
|
+
exports.getRegistryUnitRates = getRegistryUnitRates;
|
|
12
|
+
exports.setRegistryUnitRatesForTest = setRegistryUnitRatesForTest;
|
|
13
|
+
const node_fs_1 = require("node:fs");
|
|
14
|
+
const node_path_1 = require("node:path");
|
|
15
|
+
const model_kind_1 = require("./model-kind");
|
|
16
|
+
let cached = null;
|
|
17
|
+
function packagedRegistryPath() {
|
|
18
|
+
// dist/ and src/ both sit one level under the package root.
|
|
19
|
+
return (0, node_path_1.join)(__dirname, "..", "..", "registry", "registry.json");
|
|
20
|
+
}
|
|
21
|
+
function hasProvenance(m) {
|
|
22
|
+
const p = m?.provenance;
|
|
23
|
+
return p != null && typeof p.source === "string" && p.source !== "" && typeof p.as_of === "string" && p.as_of !== "";
|
|
24
|
+
}
|
|
25
|
+
/** Build the lookup from registry entries (exported for tests and the registry
|
|
26
|
+
* drift test). */
|
|
27
|
+
function unitRatesIndex(models) {
|
|
28
|
+
const out = new Map();
|
|
29
|
+
for (const e of models) {
|
|
30
|
+
if (typeof e.model_key !== "string" || !(0, model_kind_1.isModelKind)(e.kind) || e.kind === "llm")
|
|
31
|
+
continue;
|
|
32
|
+
const modality = e.declared?.pricing_v2?.modality;
|
|
33
|
+
if (!hasProvenance(modality))
|
|
34
|
+
continue;
|
|
35
|
+
out.set(e.model_key, { modelKey: e.model_key, kind: e.kind, modality });
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
function load() {
|
|
40
|
+
if (cached === null) {
|
|
41
|
+
const path = packagedRegistryPath();
|
|
42
|
+
let models = [];
|
|
43
|
+
if ((0, node_fs_1.existsSync)(path)) {
|
|
44
|
+
try {
|
|
45
|
+
models = (JSON.parse((0, node_fs_1.readFileSync)(path, "utf8")).models ?? []);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
models = []; // an unreadable registry is "no registry price", never a throw
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
cached = unitRatesIndex(models);
|
|
52
|
+
}
|
|
53
|
+
return cached;
|
|
54
|
+
}
|
|
55
|
+
/** The registry's unit rates for `provider/model`, or null. */
|
|
56
|
+
function getRegistryUnitRates(provider, model) {
|
|
57
|
+
return load().get(`${provider}/${model}`) ?? null;
|
|
58
|
+
}
|
|
59
|
+
/** Test-only: replace (or with null, reset) the loaded registry index. */
|
|
60
|
+
function setRegistryUnitRatesForTest(models) {
|
|
61
|
+
cached = models === null ? null : unitRatesIndex(models);
|
|
62
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route INPUT contract at load — ARC-β messages lane (builder-prompt-02 §1.3).
|
|
3
|
+
* Carved out of routes/loader.ts (near the 700-LOC cap), like output-loader.ts.
|
|
4
|
+
*
|
|
5
|
+
* YAML forms accepted for `input:`:
|
|
6
|
+
* (absent) → variables (the default; byte-identical)
|
|
7
|
+
* input: variables → variables (explicit; identical to absent)
|
|
8
|
+
* input: messages → a chat / tool-loop route
|
|
9
|
+
* input: { kind: messages } → same
|
|
10
|
+
* input: { kind: variables } → variables
|
|
11
|
+
*
|
|
12
|
+
* The parsed result OMITS `inputKind` for variables so an existing route's
|
|
13
|
+
* bundle (and its `bundle_sha`) is unchanged; only `messages` is ever carried.
|
|
14
|
+
*
|
|
15
|
+
* Fail-closed pairing: `repair:` re-asks without the conversation (ruling M1);
|
|
16
|
+
* `mask:` and `screen:` operate on the rendered user slot
|
|
17
|
+
* and the declared untrusted variables — they do not yet see caller history.
|
|
18
|
+
* Rather than serve a conversation the guard cannot read, a messages route that
|
|
19
|
+
* declares either is a LOAD error that says so.
|
|
20
|
+
*/
|
|
21
|
+
export declare const INPUT_KINDS: ReadonlySet<string>;
|
|
22
|
+
export interface ParsedInputBlock {
|
|
23
|
+
/** Present ONLY for `messages` (variables ⇒ omitted ⇒ byte-identical bundle). */
|
|
24
|
+
readonly inputKind?: "messages";
|
|
25
|
+
}
|
|
26
|
+
export interface InputBlockContext {
|
|
27
|
+
readonly maskDeclared: boolean;
|
|
28
|
+
readonly screenDeclared: boolean;
|
|
29
|
+
/** A `repair:` rung on the route or any variant (architect ruling M1). */
|
|
30
|
+
readonly repairDeclared: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** The teaching problem for a messages route that also declares mask/screen —
|
|
33
|
+
* shared by the loader and the run-time guard (mirror bundles skip the loader). */
|
|
34
|
+
export declare function messagesGuardConflict(ctx: InputBlockContext): string | null;
|
|
35
|
+
/** Parse the bundle's `input:` key. Pushes teaching problems; returns `{}` for
|
|
36
|
+
* variables (absent / explicit) so the bundle spread adds nothing. */
|
|
37
|
+
export declare function parseInputBlock(raw: unknown, ctx: InputBlockContext, problems: string[]): ParsedInputBlock;
|
|
38
|
+
//# sourceMappingURL=input-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-loader.d.ts","sourceRoot":"","sources":["../../src/routes/input-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,MAAM,CAAsC,CAAC;AAGnF,MAAM,WAAW,gBAAgB;IAC/B,iFAAiF;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAMD;mFACmF;AACnF,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAkB3E;AAED;sEACsE;AACtE,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAyB1G"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Route INPUT contract at load — ARC-β messages lane (builder-prompt-02 §1.3).
|
|
4
|
+
* Carved out of routes/loader.ts (near the 700-LOC cap), like output-loader.ts.
|
|
5
|
+
*
|
|
6
|
+
* YAML forms accepted for `input:`:
|
|
7
|
+
* (absent) → variables (the default; byte-identical)
|
|
8
|
+
* input: variables → variables (explicit; identical to absent)
|
|
9
|
+
* input: messages → a chat / tool-loop route
|
|
10
|
+
* input: { kind: messages } → same
|
|
11
|
+
* input: { kind: variables } → variables
|
|
12
|
+
*
|
|
13
|
+
* The parsed result OMITS `inputKind` for variables so an existing route's
|
|
14
|
+
* bundle (and its `bundle_sha`) is unchanged; only `messages` is ever carried.
|
|
15
|
+
*
|
|
16
|
+
* Fail-closed pairing: `repair:` re-asks without the conversation (ruling M1);
|
|
17
|
+
* `mask:` and `screen:` operate on the rendered user slot
|
|
18
|
+
* and the declared untrusted variables — they do not yet see caller history.
|
|
19
|
+
* Rather than serve a conversation the guard cannot read, a messages route that
|
|
20
|
+
* declares either is a LOAD error that says so.
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.INPUT_KINDS = void 0;
|
|
24
|
+
exports.messagesGuardConflict = messagesGuardConflict;
|
|
25
|
+
exports.parseInputBlock = parseInputBlock;
|
|
26
|
+
exports.INPUT_KINDS = new Set(["variables", "messages"]);
|
|
27
|
+
const INPUT_BLOCK_KEYS = new Set(["kind"]);
|
|
28
|
+
function isRecord(v) {
|
|
29
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
30
|
+
}
|
|
31
|
+
/** The teaching problem for a messages route that also declares mask/screen —
|
|
32
|
+
* shared by the loader and the run-time guard (mirror bundles skip the loader). */
|
|
33
|
+
function messagesGuardConflict(ctx) {
|
|
34
|
+
// Architect ruling M1 (2026-10-24): the repair rung re-asks WITHOUT the
|
|
35
|
+
// conversation, so on a messages route it would answer a turn it cannot see —
|
|
36
|
+
// refused rather than served a context-free "corrected" reply.
|
|
37
|
+
if (ctx.repairDeclared) {
|
|
38
|
+
return ("input: messages cannot be combined with repair: — the repair rung re-asks the model without the " +
|
|
39
|
+
"conversation, so a repaired reply would answer a turn it cannot see. Remove repair: (route and variants) " +
|
|
40
|
+
"from this route; an invalid reply is retried from the content_invalid budget instead (see messages-lane.md)");
|
|
41
|
+
}
|
|
42
|
+
const which = [ctx.maskDeclared ? "mask:" : null, ctx.screenDeclared ? "screen:" : null].filter((x) => x !== null);
|
|
43
|
+
if (which.length === 0)
|
|
44
|
+
return null;
|
|
45
|
+
return (`input: messages cannot be combined with ${which.join(" / ")} yet — masking and screening read the rendered ` +
|
|
46
|
+
"user slot and declared variables, not caller history, so the conversation would pass unguarded. Remove " +
|
|
47
|
+
`${which.join(" / ")} from this route, or serve the content as variables (see messages-lane.md)`);
|
|
48
|
+
}
|
|
49
|
+
/** Parse the bundle's `input:` key. Pushes teaching problems; returns `{}` for
|
|
50
|
+
* variables (absent / explicit) so the bundle spread adds nothing. */
|
|
51
|
+
function parseInputBlock(raw, ctx, problems) {
|
|
52
|
+
if (raw === undefined || raw === null)
|
|
53
|
+
return {};
|
|
54
|
+
let kind;
|
|
55
|
+
if (typeof raw === "string") {
|
|
56
|
+
kind = raw;
|
|
57
|
+
}
|
|
58
|
+
else if (isRecord(raw)) {
|
|
59
|
+
for (const key of Object.keys(raw)) {
|
|
60
|
+
if (!INPUT_BLOCK_KEYS.has(key))
|
|
61
|
+
problems.push(`input.${key} is not a known key — the block is {kind: variables|messages}`);
|
|
62
|
+
}
|
|
63
|
+
kind = raw.kind;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
problems.push(`input must be "variables", "messages", or {kind} — got ${JSON.stringify(raw)}`);
|
|
67
|
+
return {};
|
|
68
|
+
}
|
|
69
|
+
if (typeof kind !== "string" || !exports.INPUT_KINDS.has(kind)) {
|
|
70
|
+
problems.push(`input kind "${String(kind)}" is not one of [variables, messages] — write \`input: { kind: messages }\` for a ` +
|
|
71
|
+
"chat or tool-loop route, or omit it for a variables route (the default)");
|
|
72
|
+
return {};
|
|
73
|
+
}
|
|
74
|
+
if (kind === "variables")
|
|
75
|
+
return {};
|
|
76
|
+
const conflict = messagesGuardConflict(ctx);
|
|
77
|
+
if (conflict !== null)
|
|
78
|
+
problems.push(conflict);
|
|
79
|
+
return { inputKind: "messages" };
|
|
80
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/routes/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAKV,WAAW,EAGZ,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/routes/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAKV,WAAW,EAGZ,MAAM,gBAAgB,CAAC;AAcxB,OAAO,EAAE,sBAAsB,EAAE,kCAAkC,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAE/H;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;gBAEzB,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAO;CAOxF;AA+BD,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC;IAChC,IAAI,IAAI,SAAS,WAAW,EAAE,CAAC;CAChC;AA6aD;;;;;;;GAOG;AACH;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,YAAY,CAItF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,GAAG,YAAY,CAyB1F;AAED;;yBAEyB;AACzB,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,EAAE,CA6CtE;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CA2C1D"}
|
package/dist/routes/loader.js
CHANGED
|
@@ -24,6 +24,7 @@ const screen_loader_1 = require("./screen-loader");
|
|
|
24
24
|
const prompt_loader_1 = require("./prompt-loader"); // issue #5 (R1): `prompt.user` + the prompt block (moved out for the LOC cap)
|
|
25
25
|
const mask_loader_1 = require("./mask-loader");
|
|
26
26
|
const objective_loader_1 = require("./objective-loader");
|
|
27
|
+
const input_loader_1 = require("./input-loader");
|
|
27
28
|
const output_loader_1 = require("./output-loader"); // issue #1: `output: text` (prose) + the schema reader (moved out for the LOC cap)
|
|
28
29
|
// Re-exported so existing importers of "./loader" keep resolving these advisories
|
|
29
30
|
// (they live in ./loader-warnings to hold loader.ts under the 700-LOC cap).
|
|
@@ -392,6 +393,7 @@ function loadBundleFile(filePath) {
|
|
|
392
393
|
// x-trust) — parsed in prompt-loader.ts; both templates are files relative to
|
|
393
394
|
// the bundle and share one declared-variable list.
|
|
394
395
|
const { systemTemplate, userTemplate, variables, variableTrust } = (0, prompt_loader_1.parsePromptBlock)(doc.prompt, bundleDir, problems);
|
|
396
|
+
const input = (0, input_loader_1.parseInputBlock)(doc.input, { maskDeclared: mask !== undefined, screenDeclared: screen !== undefined, repairDeclared: repair !== undefined || variants.some((v) => v.repair !== undefined) }, problems); // ARC-β `input: messages` (input-loader.ts)
|
|
395
397
|
(0, screen_loader_1.pushUndeclaredVariableProblems)(systemTemplate, groundingQuery, variables, problems, userTemplate);
|
|
396
398
|
if (problems.length > 0) {
|
|
397
399
|
throw new RouteConfigError("invalid route bundle", { file: filePath, problems });
|
|
@@ -443,6 +445,7 @@ function loadBundleFile(filePath) {
|
|
|
443
445
|
prefer: Object.freeze(prefer),
|
|
444
446
|
systemTemplate,
|
|
445
447
|
...(userTemplate !== undefined ? { userTemplate } : {}), // issue #5 (R1): present ONLY when declared (absent ⇒ unchanged bundle_sha)
|
|
448
|
+
...input, // ARC-β inputKind — present ONLY for `input: messages` (variables ⇒ nothing added)
|
|
446
449
|
variables: Object.freeze(variables),
|
|
447
450
|
policy,
|
|
448
451
|
...(repair !== undefined ? { repair } : {}),
|
|
@@ -56,6 +56,8 @@ export interface ResolvedRouteBundle {
|
|
|
56
56
|
* `bundle_sha`), so the hosted/mirror lane renders the same user turn and a
|
|
57
57
|
* cache handle composes there too. */
|
|
58
58
|
readonly userTemplate?: string;
|
|
59
|
+
/** ARC-β — `input: messages`, carried ONLY when declared (unchanged `bundle_sha` otherwise). */
|
|
60
|
+
readonly inputKind?: "messages";
|
|
59
61
|
readonly variables: readonly string[];
|
|
60
62
|
readonly policy: RoutePolicy;
|
|
61
63
|
readonly repair?: RepairPolicy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolved-bundle.d.ts","sourceRoot":"","sources":["../../src/routes/resolved-bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,WAAW,EACX,YAAY,EACb,MAAM,gBAAgB,CAAC;AAExB;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iFAAiF;IACjF,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;;;+EAG2E;IAC3E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,4DAA4D;IAC5D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;0CAGsC;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;iFAC6E;IAC7E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IACpD;;;;2BAIuB;IACvB,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAC/D;;;;;;;;;;;mBAWe;IACf,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACrC;;;;;;;mCAO+B;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,kBAAkB,CAAC;IACnC;;;;;oEAKgE;IAChE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAC9B;AAED;sEACsE;AACtE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,mBAAmB,
|
|
1
|
+
{"version":3,"file":"resolved-bundle.d.ts","sourceRoot":"","sources":["../../src/routes/resolved-bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,WAAW,EACX,YAAY,EACb,MAAM,gBAAgB,CAAC;AAExB;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iFAAiF;IACjF,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;;;+EAG2E;IAC3E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,4DAA4D;IAC5D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;0CAGsC;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,gGAAgG;IAChG,QAAQ,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;iFAC6E;IAC7E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IACpD;;;;2BAIuB;IACvB,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAC/D;;;;;;;;;;;mBAWe;IACf,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACrC;;;;;;;mCAO+B;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,kBAAkB,CAAC;IACnC;;;;;oEAKgE;IAChE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAC9B;AAED;sEACsE;AACtE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,mBAAmB,CA+B3E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAe1D;AAiBD,mEAAmE;AACnE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAEvE;AAED;gFACgF;AAChF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAEtE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,CAsE5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,YAAY,CAclE"}
|
|
@@ -51,6 +51,7 @@ function resolveRouteBundle(bundle) {
|
|
|
51
51
|
prefer: bundle.prefer,
|
|
52
52
|
systemTemplate: bundle.systemTemplate,
|
|
53
53
|
...(bundle.userTemplate !== undefined ? { userTemplate: bundle.userTemplate } : {}), // issue #5 (R1)
|
|
54
|
+
...(bundle.inputKind === "messages" ? { inputKind: "messages" } : {}), // ARC-β
|
|
54
55
|
variables: bundle.variables,
|
|
55
56
|
policy: bundle.policy,
|
|
56
57
|
...(bundle.repair !== undefined ? { repair: bundle.repair } : {}),
|
|
@@ -174,6 +175,8 @@ function bundleFromResolved(raw) {
|
|
|
174
175
|
// Issue #5 (R1): a mirrored `prompt.user` rebuilds as the user turn; anything
|
|
175
176
|
// but a non-empty string ⇒ absent ⇒ the fixed trigger (byte-identical).
|
|
176
177
|
...(typeof b.userTemplate === "string" && b.userTemplate !== "" ? { userTemplate: b.userTemplate } : {}),
|
|
178
|
+
// ARC-β: only the literal "messages" rebuilds a messages route (anything else ⇒ variables).
|
|
179
|
+
...(b.inputKind === "messages" ? { inputKind: "messages" } : {}),
|
|
177
180
|
variables: Object.freeze([...(b.variables ?? [])]),
|
|
178
181
|
policy: b.policy,
|
|
179
182
|
...(b.repair !== undefined ? { repair: b.repair } : {}),
|
package/dist/run/cost.d.ts
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* WITHOUT a served tier and so prices at base. That is a money path and is
|
|
21
21
|
* deliberately not changed alongside this; tracked for the next money-path MR.
|
|
22
22
|
*/
|
|
23
|
+
import type { RecordedUnits, UnitKey } from "../telemetry/attempt-meta";
|
|
23
24
|
import type { ModelPricing } from "../registry/pricing";
|
|
24
25
|
import type { AdapterUsage, ProviderId, ServiceTier } from "../types/provider";
|
|
25
26
|
/** The `servedTier` an attempt reports, when the caller has it — optional so
|
|
@@ -64,5 +65,32 @@ export declare function costComponents(provider: ProviderId, model: string, usag
|
|
|
64
65
|
/** Pre-dispatch upper-bound estimate for the envelope precheck: prompt
|
|
65
66
|
* length + the full output bound, at real pricing or the conservative rate. */
|
|
66
67
|
export declare function dispatchEstimateUsd(provider: ProviderId, model: string, promptChars: number, unpricedRatePerTok: number): number;
|
|
68
|
+
/** Where a unit price came from. */
|
|
69
|
+
export type UnitPriceSource = "registry" | "pricing-map";
|
|
70
|
+
export interface UnitCost {
|
|
71
|
+
/** USD for the call's BILLED unit; 0 when unpriced. */
|
|
72
|
+
readonly costUsd: number;
|
|
73
|
+
/** True when the call reported units ModelRig cannot price (never guessed). */
|
|
74
|
+
readonly pricingMissing: boolean;
|
|
75
|
+
/** The unit the price applies to (one per model — the others are recorded,
|
|
76
|
+
* not priced, so a TTS call's seconds never double-bill its characters). */
|
|
77
|
+
readonly billedUnit: UnitKey | null;
|
|
78
|
+
readonly usdPerUnit: number | null;
|
|
79
|
+
readonly source: UnitPriceSource | null;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* ARC-4 — the list-price cost of a call's non-token units. The chain, first
|
|
83
|
+
* hit wins (dev-rule L5 — never guessed, NEVER synthesized from token rates):
|
|
84
|
+
* 1. the registry: a declared generation entry's `pricing_v2.modality` unit
|
|
85
|
+
* rate, which must carry provenance (source + as_of);
|
|
86
|
+
* 2. the vendored LiteLLM pricing map's per-mode unit key;
|
|
87
|
+
* 3. else `pricingMissing: true`, cost 0.
|
|
88
|
+
* Each model bills ONE unit (its kind / mode decides which); other units are
|
|
89
|
+
* recorded on `meta.units` but not priced. A call whose billed unit is absent
|
|
90
|
+
* or zero while it reports other units is `pricingMissing` (we cannot price what
|
|
91
|
+
* it reported). `steps` is never billed. No units (or all zero) ⇒ $0, not
|
|
92
|
+
* missing. Pure apart from the cached registry/map reads.
|
|
93
|
+
*/
|
|
94
|
+
export declare function estimateUnitCostUsd(provider: string, model: string, units: RecordedUnits | undefined): UnitCost;
|
|
67
95
|
export {};
|
|
68
96
|
//# sourceMappingURL=cost.d.ts.map
|
package/dist/run/cost.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../../src/run/cost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;
|
|
1
|
+
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../../src/run/cost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAS/E;uEACuE;AACvE,KAAK,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;AAE3D;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,WAAW,GAAG,SAAS,GAClC,YAAY,GAAG,IAAI,CAiBrB;AAED,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,0BAA0B,QAAS,CAAC;AAEjD;;yEAEyE;AACzE,eAAO,MAAM,kCAAkC,MAAM,CAAC;AAEtD,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAED,wBAAgB,WAAW,CACzB,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,YAAY,EACnB,kBAAkB,EAAE,MAAM,GACzB,WAAW,CAoBb;AAED;;;;;4EAK4E;AAC5E,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,IAAI,CACT,YAAY,EACZ,UAAU,GAAG,WAAW,GAAG,cAAc,GAAG,kBAAkB,GAAG,oBAAoB,CACtF,GACC,SAAS,GACV;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAmB5F;AAED;+EAC+E;AAC/E,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,kBAAkB,EAAE,MAAM,GACzB,MAAM,CAOR;AAID,oCAAoC;AACpC,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,aAAa,CAAC;AAEzD,MAAM,WAAW,QAAQ;IACvB,uDAAuD;IACvD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;gFAC4E;IAC5E,QAAQ,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;CACzC;AAiDD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,QAAQ,CAc/G"}
|
package/dist/run/cost.js
CHANGED
|
@@ -27,7 +27,9 @@ exports.pricingForServedTier = pricingForServedTier;
|
|
|
27
27
|
exports.attemptCost = attemptCost;
|
|
28
28
|
exports.costComponents = costComponents;
|
|
29
29
|
exports.dispatchEstimateUsd = dispatchEstimateUsd;
|
|
30
|
+
exports.estimateUnitCostUsd = estimateUnitCostUsd;
|
|
30
31
|
const pricing_1 = require("../registry/pricing");
|
|
32
|
+
const unit_pricing_1 = require("../registry/unit-pricing");
|
|
31
33
|
const pricing_shape_1 = require("../registry/pricing-shape");
|
|
32
34
|
/** The served tiers that carry their own published rates (issue #2). `standard`
|
|
33
35
|
* is `base` by definition; an unlisted tier bills at base (fail-closed, L5). */
|
|
@@ -121,3 +123,75 @@ function dispatchEstimateUsd(provider, model, promptChars, unpricedRatePerTok) {
|
|
|
121
123
|
}
|
|
122
124
|
return (0, pricing_1.estimateCostUsd)(pricing, promptTokens, exports.ESTIMATE_MAX_OUTPUT_TOKENS, 0);
|
|
123
125
|
}
|
|
126
|
+
/** The registry profile of a declared generation model: its kind names the
|
|
127
|
+
* billed unit; the rate is the matching `pricing_v2.modality` field. */
|
|
128
|
+
function registryProfile(provider, model) {
|
|
129
|
+
const r = (0, unit_pricing_1.getRegistryUnitRates)(provider, model);
|
|
130
|
+
if (r === null)
|
|
131
|
+
return null;
|
|
132
|
+
const m = r.modality;
|
|
133
|
+
switch (r.kind) {
|
|
134
|
+
case "image_gen":
|
|
135
|
+
return { billedUnit: "images", usdPerUnit: m.image_per_unit ?? null };
|
|
136
|
+
case "video_gen":
|
|
137
|
+
return { billedUnit: "seconds", usdPerUnit: m.video_per_second ?? null };
|
|
138
|
+
case "tts":
|
|
139
|
+
return m.characters_per_million != null
|
|
140
|
+
? { billedUnit: "characters", usdPerUnit: m.characters_per_million / 1000000 }
|
|
141
|
+
: { billedUnit: "seconds", usdPerUnit: m.audio_per_second ?? null };
|
|
142
|
+
case "stt":
|
|
143
|
+
return { billedUnit: "seconds", usdPerUnit: m.audio_per_second ?? null };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/** The vendored pricing map's profile, by LiteLLM mode (pricing.ts
|
|
147
|
+
* `getMapUnitRates` documents which key is the billed unit per mode). */
|
|
148
|
+
function mapProfile(provider, model) {
|
|
149
|
+
const r = (0, pricing_1.getMapUnitRates)(provider, model);
|
|
150
|
+
if (r === null)
|
|
151
|
+
return null;
|
|
152
|
+
switch (r.mode) {
|
|
153
|
+
case "image_generation":
|
|
154
|
+
return { billedUnit: "images", usdPerUnit: r.perImage };
|
|
155
|
+
case "video_generation":
|
|
156
|
+
case "audio_transcription":
|
|
157
|
+
return { billedUnit: "seconds", usdPerUnit: r.perSecond };
|
|
158
|
+
case "audio_speech":
|
|
159
|
+
return r.perCharacter !== null
|
|
160
|
+
? { billedUnit: "characters", usdPerUnit: r.perCharacter }
|
|
161
|
+
: { billedUnit: "seconds", usdPerUnit: r.perSecond };
|
|
162
|
+
default:
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const UNPRICED = { costUsd: 0, pricingMissing: true, billedUnit: null, usdPerUnit: null, source: null };
|
|
167
|
+
/**
|
|
168
|
+
* ARC-4 — the list-price cost of a call's non-token units. The chain, first
|
|
169
|
+
* hit wins (dev-rule L5 — never guessed, NEVER synthesized from token rates):
|
|
170
|
+
* 1. the registry: a declared generation entry's `pricing_v2.modality` unit
|
|
171
|
+
* rate, which must carry provenance (source + as_of);
|
|
172
|
+
* 2. the vendored LiteLLM pricing map's per-mode unit key;
|
|
173
|
+
* 3. else `pricingMissing: true`, cost 0.
|
|
174
|
+
* Each model bills ONE unit (its kind / mode decides which); other units are
|
|
175
|
+
* recorded on `meta.units` but not priced. A call whose billed unit is absent
|
|
176
|
+
* or zero while it reports other units is `pricingMissing` (we cannot price what
|
|
177
|
+
* it reported). `steps` is never billed. No units (or all zero) ⇒ $0, not
|
|
178
|
+
* missing. Pure apart from the cached registry/map reads.
|
|
179
|
+
*/
|
|
180
|
+
function estimateUnitCostUsd(provider, model, units) {
|
|
181
|
+
const any = units !== undefined && Object.values(units).some((v) => typeof v === "number" && v > 0);
|
|
182
|
+
if (!any || units === undefined)
|
|
183
|
+
return { costUsd: 0, pricingMissing: false, billedUnit: null, usdPerUnit: null, source: null };
|
|
184
|
+
const candidates = [
|
|
185
|
+
["registry", registryProfile(provider, model)],
|
|
186
|
+
["pricing-map", mapProfile(provider, model)],
|
|
187
|
+
];
|
|
188
|
+
for (const [source, profile] of candidates) {
|
|
189
|
+
if (profile === null || profile.usdPerUnit === null)
|
|
190
|
+
continue;
|
|
191
|
+
const count = units[profile.billedUnit] ?? 0;
|
|
192
|
+
if (count <= 0)
|
|
193
|
+
return { ...UNPRICED, billedUnit: profile.billedUnit, source };
|
|
194
|
+
return { costUsd: count * profile.usdPerUnit, pricingMissing: false, billedUnit: profile.billedUnit, usdPerUnit: profile.usdPerUnit, source };
|
|
195
|
+
}
|
|
196
|
+
return UNPRICED;
|
|
197
|
+
}
|