modelrig 0.1.0 → 0.2.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 +94 -0
- package/README.md +41 -11
- package/data/PROVENANCE.md +19 -0
- package/data/pricing-manual.json +22 -0
- package/data/pricing-map.json +46362 -0
- package/data/pricing-overlay.json +419 -0
- package/dist/adapters/anthropic.d.ts +50 -6
- package/dist/adapters/anthropic.d.ts.map +1 -1
- package/dist/adapters/anthropic.js +123 -29
- package/dist/adapters/build-adapters.d.ts +11 -0
- package/dist/adapters/build-adapters.d.ts.map +1 -0
- package/dist/adapters/build-adapters.js +45 -0
- package/dist/adapters/deepseek.d.ts +6 -0
- package/dist/adapters/deepseek.d.ts.map +1 -1
- package/dist/adapters/deepseek.js +54 -1
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +46 -6
- package/dist/adapters/grok.d.ts +9 -0
- package/dist/adapters/grok.d.ts.map +1 -1
- package/dist/adapters/grok.js +67 -3
- package/dist/adapters/openai-compat.d.ts +6 -0
- package/dist/adapters/openai-compat.d.ts.map +1 -1
- package/dist/adapters/openai-compat.js +58 -1
- package/dist/adapters/openai-stream.d.ts +58 -0
- package/dist/adapters/openai-stream.d.ts.map +1 -0
- package/dist/adapters/openai-stream.js +120 -0
- package/dist/adapters/openai.d.ts +6 -0
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +60 -1
- package/dist/adapters/sampling.d.ts +28 -0
- package/dist/adapters/sampling.d.ts.map +1 -0
- package/dist/adapters/sampling.js +34 -0
- package/dist/adapters/tool-mapping.d.ts +92 -0
- package/dist/adapters/tool-mapping.d.ts.map +1 -0
- package/dist/adapters/tool-mapping.js +143 -0
- package/dist/artifacts/artifact.d.ts +137 -0
- package/dist/artifacts/artifact.d.ts.map +1 -0
- package/dist/artifacts/artifact.js +377 -0
- package/dist/artifacts/content-uploader.d.ts +87 -0
- package/dist/artifacts/content-uploader.d.ts.map +1 -0
- package/dist/artifacts/content-uploader.js +124 -0
- package/dist/artifacts/index.d.ts +63 -0
- package/dist/artifacts/index.d.ts.map +1 -0
- package/dist/artifacts/index.js +80 -0
- package/dist/artifacts/run-context.d.ts +129 -0
- package/dist/artifacts/run-context.d.ts.map +1 -0
- package/dist/artifacts/run-context.js +208 -0
- package/dist/artifacts/scrub.d.ts +60 -0
- package/dist/artifacts/scrub.d.ts.map +1 -0
- package/dist/artifacts/scrub.js +139 -0
- package/dist/artifacts/step.d.ts +26 -0
- package/dist/artifacts/step.d.ts.map +1 -0
- package/dist/artifacts/step.js +37 -0
- package/dist/artifacts/taint.d.ts +63 -0
- package/dist/artifacts/taint.d.ts.map +1 -0
- package/dist/artifacts/taint.js +76 -0
- package/dist/bakeoff/cache-sim.d.ts +99 -0
- package/dist/bakeoff/cache-sim.d.ts.map +1 -0
- package/dist/bakeoff/cache-sim.js +126 -0
- package/dist/bakeoff/eval-cases.d.ts +96 -0
- package/dist/bakeoff/eval-cases.d.ts.map +1 -0
- package/dist/bakeoff/eval-cases.js +105 -0
- package/dist/bakeoff/report.d.ts +41 -0
- package/dist/bakeoff/report.d.ts.map +1 -0
- package/dist/bakeoff/report.js +142 -0
- package/dist/bakeoff/samples.d.ts +15 -0
- package/dist/bakeoff/samples.d.ts.map +1 -1
- package/dist/bakeoff/samples.js +20 -0
- package/dist/cli.d.ts +1 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +134 -116
- package/dist/config.d.ts +100 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +104 -0
- package/dist/deprecations.d.ts +32 -0
- package/dist/deprecations.d.ts.map +1 -0
- package/dist/deprecations.js +59 -0
- package/dist/gateway/http-protocol.d.ts +175 -0
- package/dist/gateway/http-protocol.d.ts.map +1 -0
- package/dist/gateway/http-protocol.js +105 -0
- package/dist/index.d.ts +105 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +266 -138
- package/dist/init/finder.d.ts +15 -0
- package/dist/init/finder.d.ts.map +1 -1
- package/dist/init/finder.js +46 -0
- package/dist/init/init-cli.d.ts +10 -0
- package/dist/init/init-cli.d.ts.map +1 -0
- package/dist/init/init-cli.js +86 -0
- package/dist/init/observe-cli.d.ts +19 -0
- package/dist/init/observe-cli.d.ts.map +1 -0
- package/dist/init/observe-cli.js +73 -0
- package/dist/init/observe.d.ts +81 -0
- package/dist/init/observe.d.ts.map +1 -0
- package/dist/init/observe.js +245 -0
- package/dist/registry/build.d.ts +94 -1
- package/dist/registry/build.d.ts.map +1 -1
- package/dist/registry/build.js +125 -4
- package/dist/registry/cache-policy.d.ts +94 -0
- package/dist/registry/cache-policy.d.ts.map +1 -0
- package/dist/registry/cache-policy.js +238 -0
- package/dist/registry/call-notes.d.ts.map +1 -1
- package/dist/registry/call-notes.js +40 -2
- package/dist/registry/effective-rate.d.ts +151 -0
- package/dist/registry/effective-rate.d.ts.map +1 -0
- package/dist/registry/effective-rate.js +156 -0
- package/dist/registry/facts.d.ts.map +1 -1
- package/dist/registry/facts.js +16 -0
- package/dist/registry/parity.d.ts +26 -0
- package/dist/registry/parity.d.ts.map +1 -1
- package/dist/registry/parity.js +43 -2
- package/dist/registry/pricing-shape.d.ts +113 -0
- package/dist/registry/pricing-shape.d.ts.map +1 -0
- package/dist/registry/pricing-shape.js +123 -0
- package/dist/registry/pricing.d.ts +25 -1
- package/dist/registry/pricing.d.ts.map +1 -1
- package/dist/registry/pricing.js +64 -6
- package/dist/rigindex/bootstrap.d.ts +36 -0
- package/dist/rigindex/bootstrap.d.ts.map +1 -0
- package/dist/rigindex/bootstrap.js +97 -0
- package/dist/rigindex/fit.d.ts +24 -0
- package/dist/rigindex/fit.d.ts.map +1 -0
- package/dist/rigindex/fit.js +76 -0
- package/dist/rigindex/gates.d.ts +52 -0
- package/dist/rigindex/gates.d.ts.map +1 -0
- package/dist/rigindex/gates.js +109 -0
- package/dist/rigindex/graph.d.ts +31 -0
- package/dist/rigindex/graph.d.ts.map +1 -0
- package/dist/rigindex/graph.js +120 -0
- package/dist/rigindex/index.d.ts +23 -0
- package/dist/rigindex/index.d.ts.map +1 -0
- package/dist/rigindex/index.js +112 -0
- package/dist/rigindex/types.d.ts +76 -0
- package/dist/rigindex/types.d.ts.map +1 -0
- package/dist/rigindex/types.js +8 -0
- package/dist/routes/cache-lint.d.ts +41 -0
- package/dist/routes/cache-lint.d.ts.map +1 -0
- package/dist/routes/cache-lint.js +81 -0
- package/dist/routes/loader.d.ts +37 -0
- package/dist/routes/loader.d.ts.map +1 -1
- package/dist/routes/loader.js +138 -0
- package/dist/routes/resolved-bundle.d.ts +79 -0
- package/dist/routes/resolved-bundle.d.ts.map +1 -0
- package/dist/routes/resolved-bundle.js +148 -0
- package/dist/routes/sampling-config.d.ts +32 -0
- package/dist/routes/sampling-config.d.ts.map +1 -0
- package/dist/routes/sampling-config.js +91 -0
- package/dist/run/ajv.d.ts +22 -0
- package/dist/run/ajv.d.ts.map +1 -0
- package/dist/run/ajv.js +32 -0
- package/dist/run/cache-handle.d.ts +58 -0
- package/dist/run/cache-handle.d.ts.map +1 -0
- package/dist/run/cache-handle.js +54 -0
- package/dist/run/cache-stamp.d.ts +65 -0
- package/dist/run/cache-stamp.d.ts.map +1 -0
- package/dist/run/cache-stamp.js +0 -0
- package/dist/run/capture-write.d.ts +33 -0
- package/dist/run/capture-write.d.ts.map +1 -0
- package/dist/run/capture-write.js +55 -0
- package/dist/run/cost.d.ts.map +1 -1
- package/dist/run/cost.js +1 -1
- package/dist/run/dispatch.d.ts +99 -0
- package/dist/run/dispatch.d.ts.map +1 -0
- package/dist/run/dispatch.js +191 -0
- package/dist/run/raw.d.ts +88 -0
- package/dist/run/raw.d.ts.map +1 -0
- package/dist/run/raw.js +286 -0
- package/dist/run/record-attempt.d.ts +40 -0
- package/dist/run/record-attempt.d.ts.map +1 -0
- package/dist/run/record-attempt.js +99 -0
- package/dist/run/resolve.d.ts +75 -2
- package/dist/run/resolve.d.ts.map +1 -1
- package/dist/run/resolve.js +126 -4
- package/dist/run/run.d.ts +14 -0
- package/dist/run/run.d.ts.map +1 -1
- package/dist/run/run.js +0 -0
- package/dist/run/stream.d.ts +49 -0
- package/dist/run/stream.d.ts.map +1 -0
- package/dist/run/stream.js +87 -0
- package/dist/run/validate.d.ts.map +1 -1
- package/dist/run/validate.js +6 -7
- package/dist/savings/cache-ledger.d.ts +108 -0
- package/dist/savings/cache-ledger.d.ts.map +1 -0
- package/dist/savings/cache-ledger.js +174 -0
- package/dist/savings/cache-reconcile.d.ts +64 -0
- package/dist/savings/cache-reconcile.d.ts.map +1 -0
- package/dist/savings/cache-reconcile.js +59 -0
- package/dist/savings/cache-stats.d.ts +63 -0
- package/dist/savings/cache-stats.d.ts.map +1 -0
- package/dist/savings/cache-stats.js +108 -0
- package/dist/savings/emit.d.ts +13 -0
- package/dist/savings/emit.d.ts.map +1 -1
- package/dist/savings/emit.js +25 -0
- package/dist/savings/swap-execute.d.ts +14 -0
- package/dist/savings/swap-execute.d.ts.map +1 -1
- package/dist/savings/swap-execute.js +44 -1
- package/dist/savings/swaps-client.d.ts +14 -0
- package/dist/savings/swaps-client.d.ts.map +1 -1
- package/dist/savings/swaps-client.js +16 -2
- package/dist/settings/api-fetcher.d.ts +39 -0
- package/dist/settings/api-fetcher.d.ts.map +1 -0
- package/dist/settings/api-fetcher.js +92 -0
- package/dist/settings/index.d.ts +10 -0
- package/dist/settings/index.d.ts.map +1 -0
- package/dist/settings/index.js +15 -0
- package/dist/settings/task-settings.d.ts +91 -0
- package/dist/settings/task-settings.d.ts.map +1 -0
- package/dist/settings/task-settings.js +116 -0
- package/dist/status.d.ts +77 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +113 -0
- package/dist/telemetry/artifact-store.d.ts +48 -0
- package/dist/telemetry/artifact-store.d.ts.map +1 -0
- package/dist/telemetry/artifact-store.js +189 -0
- package/dist/telemetry/cache-miss-streak.d.ts +79 -0
- package/dist/telemetry/cache-miss-streak.d.ts.map +1 -0
- package/dist/telemetry/cache-miss-streak.js +99 -0
- package/dist/telemetry/capture.d.ts +3 -0
- package/dist/telemetry/capture.d.ts.map +1 -1
- package/dist/telemetry/capture.js +15 -8
- package/dist/telemetry/exporter-setup.d.ts +28 -0
- package/dist/telemetry/exporter-setup.d.ts.map +1 -0
- package/dist/telemetry/exporter-setup.js +34 -0
- package/dist/telemetry/exporter.d.ts +75 -0
- package/dist/telemetry/exporter.d.ts.map +1 -1
- package/dist/telemetry/exporter.js +324 -47
- package/dist/telemetry/health.d.ts +76 -0
- package/dist/telemetry/health.d.ts.map +1 -0
- package/dist/telemetry/health.js +92 -0
- package/dist/telemetry/ingest-protocol.d.ts +152 -3
- package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
- package/dist/telemetry/ingest-protocol.js +204 -4
- package/dist/telemetry/load-error-report.d.ts +24 -0
- package/dist/telemetry/load-error-report.d.ts.map +1 -0
- package/dist/telemetry/load-error-report.js +50 -0
- package/dist/telemetry/otel-map.d.ts +121 -0
- package/dist/telemetry/otel-map.d.ts.map +1 -0
- package/dist/telemetry/otel-map.js +224 -0
- package/dist/telemetry/otel-normalize.d.ts +104 -0
- package/dist/telemetry/otel-normalize.d.ts.map +1 -0
- package/dist/telemetry/otel-normalize.js +530 -0
- package/dist/telemetry/otlp-emitter.d.ts +52 -0
- package/dist/telemetry/otlp-emitter.d.ts.map +1 -0
- package/dist/telemetry/otlp-emitter.js +144 -0
- package/dist/telemetry/otlp-proto.d.ts +29 -0
- package/dist/telemetry/otlp-proto.d.ts.map +1 -0
- package/dist/telemetry/otlp-proto.js +266 -0
- package/dist/telemetry/sinks.d.ts +37 -1
- package/dist/telemetry/sinks.d.ts.map +1 -1
- package/dist/telemetry/sinks.js +121 -30
- package/dist/telemetry/store.d.ts +28 -1
- package/dist/telemetry/store.d.ts.map +1 -1
- package/dist/telemetry/store.js +218 -3
- package/dist/tenancy/api-key-format.d.ts +15 -5
- package/dist/tenancy/api-key-format.d.ts.map +1 -1
- package/dist/tenancy/api-key-format.js +24 -5
- package/dist/types/config-teaching.d.ts +62 -0
- package/dist/types/config-teaching.d.ts.map +1 -0
- package/dist/types/config-teaching.js +183 -0
- package/dist/types/provider.d.ts +122 -1
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/types/provider.js +21 -1
- package/dist/types/route.d.ts +79 -1
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +117 -0
- package/dist/types/telemetry.d.ts.map +1 -1
- package/dist/validate-cli.d.ts +12 -0
- package/dist/validate-cli.d.ts.map +1 -0
- package/dist/validate-cli.js +57 -0
- package/dist/verify/capture.d.ts +66 -0
- package/dist/verify/capture.d.ts.map +1 -0
- package/dist/verify/capture.js +180 -0
- package/dist/verify/cli-run.d.ts +23 -0
- package/dist/verify/cli-run.d.ts.map +1 -0
- package/dist/verify/cli-run.js +57 -0
- package/dist/verify/diff.d.ts +48 -0
- package/dist/verify/diff.d.ts.map +1 -0
- package/dist/verify/diff.js +157 -0
- package/dist/verify/index.d.ts +17 -0
- package/dist/verify/index.d.ts.map +1 -0
- package/dist/verify/index.js +24 -0
- package/dist/verify/report.d.ts +14 -0
- package/dist/verify/report.d.ts.map +1 -0
- package/dist/verify/report.js +88 -0
- package/dist/verify/types.d.ts +101 -0
- package/dist/verify/types.d.ts.map +1 -0
- package/dist/verify/types.js +17 -0
- package/dist/verify/verify.d.ts +29 -0
- package/dist/verify/verify.d.ts.map +1 -0
- package/dist/verify/verify.js +148 -0
- package/dist/watch/evaluate.d.ts +162 -3
- package/dist/watch/evaluate.d.ts.map +1 -1
- package/dist/watch/evaluate.js +61 -0
- package/dist/watch/monitor.d.ts +116 -0
- package/dist/watch/monitor.d.ts.map +1 -0
- package/dist/watch/monitor.js +199 -0
- package/dist/watch/proposals.d.ts +20 -4
- package/dist/watch/proposals.d.ts.map +1 -1
- package/dist/watch/proposals.js +31 -3
- package/dist/watch/run.d.ts +33 -0
- package/dist/watch/run.d.ts.map +1 -1
- package/dist/watch/run.js +39 -0
- package/package.json +7 -1
- package/registry/LICENSE +20 -0
- package/registry/leaderboard.json +3639 -0
- package/registry/registry.json +7263 -0
- package/dist/telemetry/supabase-exporter.d.ts +0 -64
- package/dist/telemetry/supabase-exporter.d.ts.map +0 -1
- package/dist/telemetry/supabase-exporter.js +0 -211
package/dist/adapters/openai.js
CHANGED
|
@@ -22,6 +22,9 @@ exports.classifyOpenAIFailure = classifyOpenAIFailure;
|
|
|
22
22
|
exports.buildOpenAIParams = buildOpenAIParams;
|
|
23
23
|
exports.createOpenAIAdapter = createOpenAIAdapter;
|
|
24
24
|
const openai_1 = __importDefault(require("openai"));
|
|
25
|
+
const tool_mapping_1 = require("./tool-mapping");
|
|
26
|
+
const openai_stream_1 = require("./openai-stream");
|
|
27
|
+
const sampling_1 = require("./sampling");
|
|
25
28
|
/** OpenAI's documented flex-eligible allowlist as of 2026-05 (ported).
|
|
26
29
|
* Mini and nano variants are silently downgraded to default tier. */
|
|
27
30
|
const FLEX_ELIGIBLE_PREFIXES = ["gpt-5.4", "gpt-5.2", "gpt-5.1", "gpt-5", "gpt-4.1"];
|
|
@@ -44,6 +47,7 @@ function openaiSupports(feature, model) {
|
|
|
44
47
|
case "grounded_native":
|
|
45
48
|
case "context_cache_explicit":
|
|
46
49
|
case "trace_visible": // reasoning tokens are billed but never exposed
|
|
50
|
+
case "zero_retention": // never a static adapter attestation — set only from the credential-scoped registry facts (claims.ts)
|
|
47
51
|
return false;
|
|
48
52
|
}
|
|
49
53
|
}
|
|
@@ -77,10 +81,11 @@ function buildOpenAIParams(model, req) {
|
|
|
77
81
|
];
|
|
78
82
|
return {
|
|
79
83
|
model,
|
|
80
|
-
max_completion_tokens: req
|
|
84
|
+
max_completion_tokens: (0, sampling_1.effectiveMaxOutputTokens)(req, DEFAULT_MAX_COMPLETION_TOKENS),
|
|
81
85
|
messages,
|
|
82
86
|
stream: true,
|
|
83
87
|
stream_options: { include_usage: true },
|
|
88
|
+
...(0, sampling_1.openAISamplingFields)(req),
|
|
84
89
|
...(req.requestedTier === "flex"
|
|
85
90
|
? { service_tier: "flex" }
|
|
86
91
|
: req.requestedTier === "priority"
|
|
@@ -105,6 +110,14 @@ function buildOpenAIParams(model, req) {
|
|
|
105
110
|
},
|
|
106
111
|
}
|
|
107
112
|
: {}),
|
|
113
|
+
...(req.tools !== undefined && req.tools.length > 0
|
|
114
|
+
? {
|
|
115
|
+
tools: (0, tool_mapping_1.toOpenAITools)(req.tools),
|
|
116
|
+
...((0, tool_mapping_1.toOpenAIToolChoice)(req.toolChoice) !== undefined
|
|
117
|
+
? { tool_choice: (0, tool_mapping_1.toOpenAIToolChoice)(req.toolChoice) }
|
|
118
|
+
: {}),
|
|
119
|
+
}
|
|
120
|
+
: {}),
|
|
108
121
|
};
|
|
109
122
|
}
|
|
110
123
|
/** Ported suspicious-short heuristic: finish_reason 'stop' + <200 visible
|
|
@@ -124,6 +137,7 @@ function createOpenAIAdapter(config) {
|
|
|
124
137
|
return {
|
|
125
138
|
id: "openai",
|
|
126
139
|
supports: openaiSupports,
|
|
140
|
+
supportsTools: () => true,
|
|
127
141
|
async call(req) {
|
|
128
142
|
const model = req.candidate.model;
|
|
129
143
|
// F1: post-stream failures still billed tokens — attach usage.
|
|
@@ -147,9 +161,11 @@ function createOpenAIAdapter(config) {
|
|
|
147
161
|
let ttfbMs;
|
|
148
162
|
let text = "";
|
|
149
163
|
let refusalText = "";
|
|
164
|
+
const toolCallAcc = (0, tool_mapping_1.createOpenAIToolCallAccumulator)();
|
|
150
165
|
let promptTokens = 0;
|
|
151
166
|
let completionTokens = 0;
|
|
152
167
|
let cachedTokens = 0;
|
|
168
|
+
let cacheWriteTokens = 0;
|
|
153
169
|
let reasoningTokens = 0;
|
|
154
170
|
let responseTier = null;
|
|
155
171
|
let finishReason = null;
|
|
@@ -165,19 +181,23 @@ function createOpenAIAdapter(config) {
|
|
|
165
181
|
if (typeof choice?.delta?.refusal === "string" && choice.delta.refusal.length > 0) {
|
|
166
182
|
refusalText += choice.delta.refusal;
|
|
167
183
|
}
|
|
184
|
+
toolCallAcc.push(choice?.delta?.tool_calls);
|
|
168
185
|
if (choice?.finish_reason)
|
|
169
186
|
finishReason = choice.finish_reason;
|
|
170
187
|
if (chunk.usage) {
|
|
171
188
|
promptTokens = chunk.usage.prompt_tokens ?? 0;
|
|
172
189
|
completionTokens = chunk.usage.completion_tokens ?? 0;
|
|
173
190
|
cachedTokens = chunk.usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
191
|
+
cacheWriteTokens = chunk.usage.input_tokens_details?.cache_write_tokens ?? 0;
|
|
174
192
|
reasoningTokens = chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0;
|
|
175
193
|
}
|
|
176
194
|
}
|
|
195
|
+
// prompt_tokens already INCLUDES cached+write → tokensIn is subset-correct.
|
|
177
196
|
const usage = {
|
|
178
197
|
tokensIn: promptTokens,
|
|
179
198
|
tokensOut: completionTokens,
|
|
180
199
|
tokensCached: cachedTokens,
|
|
200
|
+
tokensCacheWrite: cacheWriteTokens,
|
|
181
201
|
servedTier: mapServedTier(responseTier, req.requestedTier),
|
|
182
202
|
...(ttfbMs !== undefined ? { ttfbMs } : {}),
|
|
183
203
|
};
|
|
@@ -186,6 +206,13 @@ function createOpenAIAdapter(config) {
|
|
|
186
206
|
if (refusalText.length > 0) {
|
|
187
207
|
return fail("refusal", `OpenAI refused structured output: ${refusalText.slice(0, 200)}`, undefined, usage);
|
|
188
208
|
}
|
|
209
|
+
// Tool-call turn (spec §4.4): the model chose to call a tool. Surface
|
|
210
|
+
// the normalized calls; text may legitimately be empty — do NOT run the
|
|
211
|
+
// empty/suspicious-short/validation guards below.
|
|
212
|
+
const toolCalls = toolCallAcc.finalize();
|
|
213
|
+
if (toolCalls !== undefined) {
|
|
214
|
+
return { ok: true, text, usage, toolCalls };
|
|
215
|
+
}
|
|
189
216
|
const visibleCompletionTokens = Math.max(0, completionTokens - reasoningTokens);
|
|
190
217
|
if (finishReason === "stop" &&
|
|
191
218
|
completionTokens > 0 &&
|
|
@@ -218,5 +245,37 @@ function createOpenAIAdapter(config) {
|
|
|
218
245
|
};
|
|
219
246
|
}
|
|
220
247
|
},
|
|
248
|
+
async *stream(req) {
|
|
249
|
+
const model = req.candidate.model;
|
|
250
|
+
try {
|
|
251
|
+
const client = new openai_1.default({ apiKey: config.apiKey, timeout: req.timeoutMs });
|
|
252
|
+
const params = buildOpenAIParams(model, req);
|
|
253
|
+
const dispatchedAt = Date.now();
|
|
254
|
+
const stream = await client.chat.completions.create(params);
|
|
255
|
+
yield* (0, openai_stream_1.streamOpenAIDialect)(stream, req, dispatchedAt, {
|
|
256
|
+
provider: "openai",
|
|
257
|
+
cachedTokenSource: "details",
|
|
258
|
+
mapServedTier,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
263
|
+
const { cls, fixHint } = classifyOpenAIFailure(message);
|
|
264
|
+
yield {
|
|
265
|
+
kind: "final",
|
|
266
|
+
result: {
|
|
267
|
+
ok: false,
|
|
268
|
+
failure: {
|
|
269
|
+
class: cls,
|
|
270
|
+
message,
|
|
271
|
+
provider: "openai",
|
|
272
|
+
model,
|
|
273
|
+
cause: error,
|
|
274
|
+
...(fixHint !== undefined ? { fixHint } : {}),
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
},
|
|
221
280
|
};
|
|
222
281
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared sampling-param mapping for the adapters (CE-6, spec §2/§3). One place
|
|
3
|
+
* resolves `AdapterRequest.sampling` into wire fields so every adapter honours
|
|
4
|
+
* the same precedence and the same absent⇒byte-identical pin.
|
|
5
|
+
*
|
|
6
|
+
* Two rules, everywhere:
|
|
7
|
+
* - max-output-tokens: `sampling.maxOutputTokens` wins, then the existing
|
|
8
|
+
* top-level `maxOutputTokens` (the raw lane's channel), then the adapter's
|
|
9
|
+
* own default. Absent both ⇒ the default ⇒ identical to pre-CE-6.
|
|
10
|
+
* - temperature/top_p: emitted ONLY when the request declares them, so an
|
|
11
|
+
* absent block adds NO keys — the OpenAI-dialect and Anthropic adapters keep
|
|
12
|
+
* sending nothing (provider defaults win), exactly as before CE-6.
|
|
13
|
+
*/
|
|
14
|
+
import type { AdapterRequest } from "../types/provider";
|
|
15
|
+
/** The sampling-relevant slice of a request (also what the pure `build*Params`
|
|
16
|
+
* shaping helpers take, so unit tests never need a branded CandidateRef). */
|
|
17
|
+
export type SamplingShapingInput = Pick<AdapterRequest, "sampling" | "maxOutputTokens">;
|
|
18
|
+
/** Effective max-output-tokens: declared sampling wins, then the top-level
|
|
19
|
+
* (raw-lane) field, then the adapter default. */
|
|
20
|
+
export declare function effectiveMaxOutputTokens(req: SamplingShapingInput, fallback: number): number;
|
|
21
|
+
/** OpenAI-dialect + Anthropic sampling fields — both speak `temperature` and
|
|
22
|
+
* `top_p`. Returns keys ONLY for declared fields, so spreading it onto the
|
|
23
|
+
* params object is a no-op when sampling is absent. */
|
|
24
|
+
export declare function openAISamplingFields(req: SamplingShapingInput): {
|
|
25
|
+
temperature?: number;
|
|
26
|
+
top_p?: number;
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=sampling.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sampling.d.ts","sourceRoot":"","sources":["../../src/adapters/sampling.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;6EAC6E;AAC7E,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,EAAE,UAAU,GAAG,iBAAiB,CAAC,CAAC;AAExF;iDACiD;AACjD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5F;AAED;;uDAEuD;AACvD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,oBAAoB,GACxB;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAO1C"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared sampling-param mapping for the adapters (CE-6, spec §2/§3). One place
|
|
4
|
+
* resolves `AdapterRequest.sampling` into wire fields so every adapter honours
|
|
5
|
+
* the same precedence and the same absent⇒byte-identical pin.
|
|
6
|
+
*
|
|
7
|
+
* Two rules, everywhere:
|
|
8
|
+
* - max-output-tokens: `sampling.maxOutputTokens` wins, then the existing
|
|
9
|
+
* top-level `maxOutputTokens` (the raw lane's channel), then the adapter's
|
|
10
|
+
* own default. Absent both ⇒ the default ⇒ identical to pre-CE-6.
|
|
11
|
+
* - temperature/top_p: emitted ONLY when the request declares them, so an
|
|
12
|
+
* absent block adds NO keys — the OpenAI-dialect and Anthropic adapters keep
|
|
13
|
+
* sending nothing (provider defaults win), exactly as before CE-6.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.effectiveMaxOutputTokens = effectiveMaxOutputTokens;
|
|
17
|
+
exports.openAISamplingFields = openAISamplingFields;
|
|
18
|
+
/** Effective max-output-tokens: declared sampling wins, then the top-level
|
|
19
|
+
* (raw-lane) field, then the adapter default. */
|
|
20
|
+
function effectiveMaxOutputTokens(req, fallback) {
|
|
21
|
+
return req.sampling?.maxOutputTokens ?? req.maxOutputTokens ?? fallback;
|
|
22
|
+
}
|
|
23
|
+
/** OpenAI-dialect + Anthropic sampling fields — both speak `temperature` and
|
|
24
|
+
* `top_p`. Returns keys ONLY for declared fields, so spreading it onto the
|
|
25
|
+
* params object is a no-op when sampling is absent. */
|
|
26
|
+
function openAISamplingFields(req) {
|
|
27
|
+
const s = req.sampling;
|
|
28
|
+
if (s === undefined)
|
|
29
|
+
return {};
|
|
30
|
+
return {
|
|
31
|
+
...(s.temperature !== undefined ? { temperature: s.temperature } : {}),
|
|
32
|
+
...(s.topP !== undefined ? { top_p: s.topP } : {}),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified tool-calling — native ↔ normalized mapping (G-1/G-5 Phase A,
|
|
3
|
+
* http-gateway spec §4.4).
|
|
4
|
+
*
|
|
5
|
+
* ModelRig speaks ONE tool vocabulary to callers: the OpenAI `tools` /
|
|
6
|
+
* `tool_calls` shape (`types/provider.ts`). This module is the single place
|
|
7
|
+
* each provider dialect is translated to and from it. Adapters stay thin: they
|
|
8
|
+
* call a `to<Provider>Tools` on the way out and a `<provider>…ToToolCalls` on
|
|
9
|
+
* the way back. Pure functions, no I/O — every branch is unit-tested here so an
|
|
10
|
+
* adapter integration test never has to reconstruct a provider's tool wire.
|
|
11
|
+
*
|
|
12
|
+
* We normalize the PROTOCOL only. Executing a tool and feeding the result back
|
|
13
|
+
* is the caller's job (spec §4.4).
|
|
14
|
+
*/
|
|
15
|
+
import type { ToolCall, ToolChoice, ToolDefinition } from "../types/provider";
|
|
16
|
+
export interface OpenAIWireTool {
|
|
17
|
+
readonly type: "function";
|
|
18
|
+
readonly function: {
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly description?: string;
|
|
21
|
+
readonly parameters?: object;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export type OpenAIWireToolChoice = "auto" | "none" | "required" | {
|
|
25
|
+
readonly type: "function";
|
|
26
|
+
readonly function: {
|
|
27
|
+
readonly name: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export declare function toOpenAITools(tools: readonly ToolDefinition[]): OpenAIWireTool[];
|
|
31
|
+
export declare function toOpenAIToolChoice(choice: ToolChoice | undefined): OpenAIWireToolChoice | undefined;
|
|
32
|
+
/** One streamed `tool_calls` delta fragment (OpenAI). `arguments` arrives in
|
|
33
|
+
* pieces keyed by `index`; `id`/`name` land on the first fragment. */
|
|
34
|
+
export interface OpenAIToolCallDelta {
|
|
35
|
+
readonly index: number;
|
|
36
|
+
readonly id?: string;
|
|
37
|
+
readonly type?: "function";
|
|
38
|
+
readonly function?: {
|
|
39
|
+
readonly name?: string;
|
|
40
|
+
readonly arguments?: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** Accumulates streamed OpenAI tool-call deltas (and absorbs a non-streamed
|
|
44
|
+
* `tool_calls` array — a single fragment each) into normalized `ToolCall`s. */
|
|
45
|
+
export declare function createOpenAIToolCallAccumulator(): {
|
|
46
|
+
push(deltas: readonly OpenAIToolCallDelta[] | undefined): void;
|
|
47
|
+
finalize(): ToolCall[] | undefined;
|
|
48
|
+
};
|
|
49
|
+
export interface AnthropicWireTool {
|
|
50
|
+
readonly name: string;
|
|
51
|
+
readonly description?: string;
|
|
52
|
+
readonly input_schema: object;
|
|
53
|
+
}
|
|
54
|
+
export type AnthropicWireToolChoice = {
|
|
55
|
+
readonly type: "auto";
|
|
56
|
+
} | {
|
|
57
|
+
readonly type: "any";
|
|
58
|
+
} | {
|
|
59
|
+
readonly type: "tool";
|
|
60
|
+
readonly name: string;
|
|
61
|
+
};
|
|
62
|
+
export declare function toAnthropicTools(tools: readonly ToolDefinition[]): AnthropicWireTool[];
|
|
63
|
+
export declare function toAnthropicToolChoice(choice: ToolChoice | undefined): AnthropicWireToolChoice | undefined;
|
|
64
|
+
/** A completed Anthropic `tool_use` content block. */
|
|
65
|
+
export interface AnthropicToolUseBlock {
|
|
66
|
+
readonly id: string;
|
|
67
|
+
readonly name: string;
|
|
68
|
+
readonly input: unknown;
|
|
69
|
+
}
|
|
70
|
+
export declare function anthropicToolUseToToolCalls(blocks: readonly AnthropicToolUseBlock[]): ToolCall[] | undefined;
|
|
71
|
+
export interface GeminiWireTool {
|
|
72
|
+
readonly functionDeclarations: ReadonlyArray<{
|
|
73
|
+
readonly name: string;
|
|
74
|
+
readonly description?: string;
|
|
75
|
+
readonly parameters?: object;
|
|
76
|
+
}>;
|
|
77
|
+
}
|
|
78
|
+
export type GeminiWireToolConfig = {
|
|
79
|
+
readonly functionCallingConfig: {
|
|
80
|
+
readonly mode: "AUTO" | "ANY" | "NONE";
|
|
81
|
+
readonly allowedFunctionNames?: readonly string[];
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
export declare function toGeminiTools(tools: readonly ToolDefinition[]): GeminiWireTool[];
|
|
85
|
+
export declare function toGeminiToolConfig(choice: ToolChoice | undefined): GeminiWireToolConfig | undefined;
|
|
86
|
+
/** A Gemini response `functionCall` part. */
|
|
87
|
+
export interface GeminiFunctionCall {
|
|
88
|
+
readonly name: string;
|
|
89
|
+
readonly args?: unknown;
|
|
90
|
+
}
|
|
91
|
+
export declare function geminiFunctionCallsToToolCalls(calls: readonly GeminiFunctionCall[]): ToolCall[] | undefined;
|
|
92
|
+
//# sourceMappingURL=tool-mapping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-mapping.d.ts","sourceRoot":"","sources":["../../src/adapters/tool-mapping.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Unified tool-calling — native ↔ normalized mapping (G-1/G-5 Phase A,
|
|
4
|
+
* http-gateway spec §4.4).
|
|
5
|
+
*
|
|
6
|
+
* ModelRig speaks ONE tool vocabulary to callers: the OpenAI `tools` /
|
|
7
|
+
* `tool_calls` shape (`types/provider.ts`). This module is the single place
|
|
8
|
+
* each provider dialect is translated to and from it. Adapters stay thin: they
|
|
9
|
+
* call a `to<Provider>Tools` on the way out and a `<provider>…ToToolCalls` on
|
|
10
|
+
* the way back. Pure functions, no I/O — every branch is unit-tested here so an
|
|
11
|
+
* adapter integration test never has to reconstruct a provider's tool wire.
|
|
12
|
+
*
|
|
13
|
+
* We normalize the PROTOCOL only. Executing a tool and feeding the result back
|
|
14
|
+
* is the caller's job (spec §4.4).
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.toOpenAITools = toOpenAITools;
|
|
18
|
+
exports.toOpenAIToolChoice = toOpenAIToolChoice;
|
|
19
|
+
exports.createOpenAIToolCallAccumulator = createOpenAIToolCallAccumulator;
|
|
20
|
+
exports.toAnthropicTools = toAnthropicTools;
|
|
21
|
+
exports.toAnthropicToolChoice = toAnthropicToolChoice;
|
|
22
|
+
exports.anthropicToolUseToToolCalls = anthropicToolUseToToolCalls;
|
|
23
|
+
exports.toGeminiTools = toGeminiTools;
|
|
24
|
+
exports.toGeminiToolConfig = toGeminiToolConfig;
|
|
25
|
+
exports.geminiFunctionCallsToToolCalls = geminiFunctionCallsToToolCalls;
|
|
26
|
+
function toOpenAITools(tools) {
|
|
27
|
+
return tools.map((t) => ({
|
|
28
|
+
type: "function",
|
|
29
|
+
function: {
|
|
30
|
+
name: t.function.name,
|
|
31
|
+
...(t.function.description !== undefined ? { description: t.function.description } : {}),
|
|
32
|
+
...(t.function.parameters !== undefined ? { parameters: t.function.parameters } : {}),
|
|
33
|
+
},
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
function toOpenAIToolChoice(choice) {
|
|
37
|
+
if (choice === undefined)
|
|
38
|
+
return undefined;
|
|
39
|
+
return choice; // the normalized shape IS the OpenAI shape.
|
|
40
|
+
}
|
|
41
|
+
/** Accumulates streamed OpenAI tool-call deltas (and absorbs a non-streamed
|
|
42
|
+
* `tool_calls` array — a single fragment each) into normalized `ToolCall`s. */
|
|
43
|
+
function createOpenAIToolCallAccumulator() {
|
|
44
|
+
const byIndex = new Map();
|
|
45
|
+
const order = [];
|
|
46
|
+
return {
|
|
47
|
+
push(deltas) {
|
|
48
|
+
if (deltas === undefined)
|
|
49
|
+
return;
|
|
50
|
+
for (const d of deltas) {
|
|
51
|
+
let entry = byIndex.get(d.index);
|
|
52
|
+
if (entry === undefined) {
|
|
53
|
+
entry = { id: "", name: "", args: "" };
|
|
54
|
+
byIndex.set(d.index, entry);
|
|
55
|
+
order.push(d.index);
|
|
56
|
+
}
|
|
57
|
+
if (d.id !== undefined)
|
|
58
|
+
entry.id = d.id;
|
|
59
|
+
if (d.function?.name !== undefined)
|
|
60
|
+
entry.name = d.function.name;
|
|
61
|
+
if (d.function?.arguments !== undefined)
|
|
62
|
+
entry.args += d.function.arguments;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
finalize() {
|
|
66
|
+
if (order.length === 0)
|
|
67
|
+
return undefined;
|
|
68
|
+
return order.map((idx, i) => {
|
|
69
|
+
const e = byIndex.get(idx);
|
|
70
|
+
return {
|
|
71
|
+
// Some hosts omit an id in the stream — synthesize a stable one.
|
|
72
|
+
id: e.id !== "" ? e.id : `call_${i}`,
|
|
73
|
+
type: "function",
|
|
74
|
+
function: { name: e.name, arguments: e.args === "" ? "{}" : e.args },
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const EMPTY_INPUT_SCHEMA = { type: "object", properties: {} };
|
|
81
|
+
function toAnthropicTools(tools) {
|
|
82
|
+
return tools.map((t) => ({
|
|
83
|
+
name: t.function.name,
|
|
84
|
+
...(t.function.description !== undefined ? { description: t.function.description } : {}),
|
|
85
|
+
// Anthropic requires an input_schema; default to an open object when the
|
|
86
|
+
// caller declared a parameterless tool.
|
|
87
|
+
input_schema: (t.function.parameters ?? EMPTY_INPUT_SCHEMA),
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
function toAnthropicToolChoice(choice) {
|
|
91
|
+
if (choice === undefined || choice === "auto")
|
|
92
|
+
return undefined; // auto is Anthropic's default
|
|
93
|
+
if (choice === "none")
|
|
94
|
+
return undefined; // Anthropic omits tools to force no call; caller-handled
|
|
95
|
+
if (choice === "required")
|
|
96
|
+
return { type: "any" };
|
|
97
|
+
return { type: "tool", name: choice.function.name };
|
|
98
|
+
}
|
|
99
|
+
function anthropicToolUseToToolCalls(blocks) {
|
|
100
|
+
if (blocks.length === 0)
|
|
101
|
+
return undefined;
|
|
102
|
+
return blocks.map((b) => ({
|
|
103
|
+
id: b.id,
|
|
104
|
+
type: "function",
|
|
105
|
+
// Anthropic hands back a parsed object; the normalized shape is the raw
|
|
106
|
+
// JSON string (OpenAI parity), so re-stringify.
|
|
107
|
+
function: { name: b.name, arguments: JSON.stringify(b.input ?? {}) },
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
function toGeminiTools(tools) {
|
|
111
|
+
return [
|
|
112
|
+
{
|
|
113
|
+
functionDeclarations: tools.map((t) => ({
|
|
114
|
+
name: t.function.name,
|
|
115
|
+
...(t.function.description !== undefined ? { description: t.function.description } : {}),
|
|
116
|
+
...(t.function.parameters !== undefined ? { parameters: t.function.parameters } : {}),
|
|
117
|
+
})),
|
|
118
|
+
},
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
function toGeminiToolConfig(choice) {
|
|
122
|
+
if (choice === undefined)
|
|
123
|
+
return undefined;
|
|
124
|
+
if (choice === "auto")
|
|
125
|
+
return { functionCallingConfig: { mode: "AUTO" } };
|
|
126
|
+
if (choice === "none")
|
|
127
|
+
return { functionCallingConfig: { mode: "NONE" } };
|
|
128
|
+
if (choice === "required")
|
|
129
|
+
return { functionCallingConfig: { mode: "ANY" } };
|
|
130
|
+
return {
|
|
131
|
+
functionCallingConfig: { mode: "ANY", allowedFunctionNames: [choice.function.name] },
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function geminiFunctionCallsToToolCalls(calls) {
|
|
135
|
+
if (calls.length === 0)
|
|
136
|
+
return undefined;
|
|
137
|
+
return calls.map((c, i) => ({
|
|
138
|
+
// Gemini function calls carry no id — synthesize a stable one.
|
|
139
|
+
id: `call_${i}`,
|
|
140
|
+
type: "function",
|
|
141
|
+
function: { name: c.name, arguments: JSON.stringify(c.args ?? {}) },
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Artifact namespace — Expansion E2 chunk B (spec §2.2, §9).
|
|
3
|
+
*
|
|
4
|
+
* `save/load/link/evaluate` over a durable work product's METADATA. The
|
|
5
|
+
* serialized value is hashed (sha256, node:crypto — no new dep) and the bytes
|
|
6
|
+
* are DISCARDED; nothing but the metadata row is persisted (the 00030
|
|
7
|
+
* counter-annotation). Lineage v0: artifacts saved within a run get
|
|
8
|
+
* `derived_from` edges to artifacts `load`ed since the last save (coverage
|
|
9
|
+
* measured, never promised). Instrumentation never throws into customer code.
|
|
10
|
+
*
|
|
11
|
+
* ── zeroRetention (ratified invariant, named test) ────────────────────────
|
|
12
|
+
* A run with `zeroRetention: true` emits NO artifact rows of any kind: `save`
|
|
13
|
+
* refuses fail-closed at THIS gate (before any row is built) with a counted,
|
|
14
|
+
* logged skip. Structural, not policy-checked at the server.
|
|
15
|
+
*/
|
|
16
|
+
import type { ArtifactStore } from "../telemetry/artifact-store";
|
|
17
|
+
import type { EvalCaseOrigin } from "../types/telemetry";
|
|
18
|
+
import { type ScrubMode } from "./scrub";
|
|
19
|
+
import type { ContentUploadInput, ContentUploadOutcome } from "./content-uploader";
|
|
20
|
+
/** The upload transport `save` fires content through — injected so the SDK's
|
|
21
|
+
* networked implementation and the tests share one seam. */
|
|
22
|
+
export type ArtifactContentUploader = (input: ContentUploadInput) => Promise<ContentUploadOutcome>;
|
|
23
|
+
/** Per-rig content-custody wiring passed to the artifact api (E2-C). Absent =
|
|
24
|
+
* metadata + hash only, today's behaviour. */
|
|
25
|
+
export interface ArtifactContentDeps {
|
|
26
|
+
readonly scrub: ScrubMode;
|
|
27
|
+
readonly upload: ArtifactContentUploader;
|
|
28
|
+
}
|
|
29
|
+
export interface ArtifactHandle {
|
|
30
|
+
readonly id: string;
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly type: string;
|
|
33
|
+
readonly version: number;
|
|
34
|
+
}
|
|
35
|
+
export interface ArtifactSaveOptions {
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly type: string;
|
|
38
|
+
readonly task?: string;
|
|
39
|
+
/** The pipeline step this artifact belongs to — the semantic grouping key the
|
|
40
|
+
* console's chain view orders on (E3 spec §2.1). E2 deferred step attribution
|
|
41
|
+
* ("refined when @step scopes persist, E3"); an EXPLICIT key set by the caller
|
|
42
|
+
* is the E3 refinement — safe under parallel step waves where an ambient
|
|
43
|
+
* mutable current-step would cross-attribute. Null (absent) ⇒ ungrouped. */
|
|
44
|
+
readonly stepKey?: string;
|
|
45
|
+
/** The step attempt this artifact came from (mirrors steps.attempt_no). Only
|
|
46
|
+
* meaningful alongside stepKey; null for artifacts saved outside a step. */
|
|
47
|
+
readonly attemptNo?: number;
|
|
48
|
+
readonly classification?: string;
|
|
49
|
+
/** OPAQUE customer URI (their bucket). We store the string + our hash, never content. */
|
|
50
|
+
readonly contentRef?: string;
|
|
51
|
+
/** Declared JSON Schema (fingerprinted with the same pure fn the loader uses). */
|
|
52
|
+
readonly schema?: object | null;
|
|
53
|
+
/** The artifact this one supersedes (immutable versioning; ruling c column). */
|
|
54
|
+
readonly supersedes?: ArtifactHandle;
|
|
55
|
+
readonly expiresAt?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface ArtifactEvaluateOptions {
|
|
58
|
+
readonly evaluator: string;
|
|
59
|
+
readonly kind: "deterministic" | "model-judge" | "human";
|
|
60
|
+
readonly score?: number;
|
|
61
|
+
readonly passed?: boolean;
|
|
62
|
+
readonly label?: string;
|
|
63
|
+
readonly explanation?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface ArtifactPromoteOptions {
|
|
66
|
+
readonly note?: string;
|
|
67
|
+
/** The route/task this case belongs to. Falls back to the task the source
|
|
68
|
+
* artifact was saved with this session; required (explicitly or via fallback)
|
|
69
|
+
* because an eval case is keyed by task. */
|
|
70
|
+
readonly task?: string;
|
|
71
|
+
/** The corrected/golden artifact — set ⇒ a golden-corrected pair. */
|
|
72
|
+
readonly corrected?: ArtifactHandle | string;
|
|
73
|
+
/** How it entered the suite. Default: `human-corrected` when `corrected` is
|
|
74
|
+
* set, else `promoted-failure`. */
|
|
75
|
+
readonly origin?: EvalCaseOrigin;
|
|
76
|
+
}
|
|
77
|
+
export interface ArtifactApi {
|
|
78
|
+
/** Hash the value's serialization, record metadata + inferred lineage, return
|
|
79
|
+
* a handle. Returns null when the namespace is disabled or a zeroRetention run
|
|
80
|
+
* refuses it (fail-closed). */
|
|
81
|
+
save(value: unknown, opts: ArtifactSaveOptions): ArtifactHandle | null;
|
|
82
|
+
/** Mark an artifact consumed by the current run (feeds derived_from lineage). */
|
|
83
|
+
load(ref: ArtifactHandle | string): void;
|
|
84
|
+
/** Explicit lineage edge the runtime cannot infer. */
|
|
85
|
+
link(from: ArtifactHandle | string, to: ArtifactHandle | string, kind: "consumed" | "derived_from"): void;
|
|
86
|
+
/** Record an evaluation against an artifact. */
|
|
87
|
+
evaluate(ref: ArtifactHandle | string, opts: ArtifactEvaluateOptions): void;
|
|
88
|
+
/** Promote an artifact into the org's durable eval suite (E4 chunk A) — a
|
|
89
|
+
* regression case replayable via `bakeoff --from-eval-cases`. `corrected` set
|
|
90
|
+
* ⇒ a golden-corrected pair; absent ⇒ a failure-case. The `task` binds the
|
|
91
|
+
* case to a route: taken from opts, else the task the artifact was saved with
|
|
92
|
+
* this session; unresolvable ⇒ a warned no-op (returns null, never throws).
|
|
93
|
+
* Returns the new case id on success. */
|
|
94
|
+
promoteToEval(ref: ArtifactHandle | string, opts?: ArtifactPromoteOptions): string | null;
|
|
95
|
+
/** Run `fn` inside a single store transaction and return its value (H8), so a
|
|
96
|
+
* step's several save/link/evaluate writes commit with ONE fsync. On a
|
|
97
|
+
* disabled/inert namespace `fn` runs directly (no store, no transaction). */
|
|
98
|
+
batch<T>(fn: () => T): T;
|
|
99
|
+
/** Await every in-flight content upload (E2-C). Content upload is fire-and-
|
|
100
|
+
* forget off the customer's hot path; a graceful shutdown (and the tests)
|
|
101
|
+
* call this so a process does not exit mid-PUT. No-op when custody is off. */
|
|
102
|
+
flushContent(): Promise<void>;
|
|
103
|
+
/** Re-attempt content uploads that came back `pending` — a 404 from the grant
|
|
104
|
+
* endpoint because the artifact metadata row had not yet been exported when
|
|
105
|
+
* the upload first fired (the 404-until-durable race, E4 chunk 0). The
|
|
106
|
+
* exporter calls this AFTER a confirmed flush of the artifacts stream, so by
|
|
107
|
+
* now the row is durable and the grant succeeds. Each call is exactly ONE
|
|
108
|
+
* retry per queued item (bounded 2 total, then a counted skip). NEVER throws.
|
|
109
|
+
* No-op when custody is off or the queue is empty. */
|
|
110
|
+
retryPendingContent(): Promise<void>;
|
|
111
|
+
/** Inferred-lineage + content-custody coverage counters (measured, never
|
|
112
|
+
* promised). Content counters update asynchronously as uploads settle. */
|
|
113
|
+
coverage(): {
|
|
114
|
+
readonly saves: number;
|
|
115
|
+
readonly inferredEdges: number;
|
|
116
|
+
readonly skippedZeroRetention: number;
|
|
117
|
+
/** Content uploads that reached the store. */
|
|
118
|
+
readonly contentUploaded: number;
|
|
119
|
+
/** Content uploads that degraded to metadata-only (refusal or transient). */
|
|
120
|
+
readonly contentDegraded: number;
|
|
121
|
+
/** Content uploads refused by the scrub `block` mode. */
|
|
122
|
+
readonly contentBlocked: number;
|
|
123
|
+
/** Content uploads awaiting the metadata-durable retry (E4 chunk 0). Drains
|
|
124
|
+
* to 0 as the exporter's post-flush hook re-attempts them; a still-pending
|
|
125
|
+
* item that exhausts its 2 retries moves to `contentDegraded`. */
|
|
126
|
+
readonly contentPending: number;
|
|
127
|
+
/** Total scrub findings (counts across types) seen this session. */
|
|
128
|
+
readonly scrubFindings: number;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
export declare function createArtifactApi(deps: {
|
|
132
|
+
readonly store: ArtifactStore;
|
|
133
|
+
readonly enabled: boolean;
|
|
134
|
+
/** Content custody wiring (E2-C). Absent = metadata + hash only. */
|
|
135
|
+
readonly content?: ArtifactContentDeps;
|
|
136
|
+
}): ArtifactApi;
|
|
137
|
+
//# sourceMappingURL=artifact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact.d.ts","sourceRoot":"","sources":["../../src/artifacts/artifact.ts"],"names":[],"mappings":"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"}
|