modelrig 0.1.0 → 0.3.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 +158 -0
- package/README.md +53 -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 +10 -0
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +78 -7
- 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 +106 -19
- 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 +48 -0
- package/dist/routes/loader.d.ts.map +1 -1
- package/dist/routes/loader.js +167 -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 +130 -0
- package/dist/run/raw.d.ts.map +1 -0
- package/dist/run/raw.js +363 -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 +147 -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/grok.js
CHANGED
|
@@ -20,6 +20,9 @@ exports.classifyGrokFailure = classifyGrokFailure;
|
|
|
20
20
|
exports.buildGrokParams = buildGrokParams;
|
|
21
21
|
exports.createGrokAdapter = createGrokAdapter;
|
|
22
22
|
const openai_1 = __importDefault(require("openai"));
|
|
23
|
+
const tool_mapping_1 = require("./tool-mapping");
|
|
24
|
+
const openai_stream_1 = require("./openai-stream");
|
|
25
|
+
const sampling_1 = require("./sampling");
|
|
23
26
|
const GROK_BASE_URL = "https://api.x.ai/v1";
|
|
24
27
|
const DEFAULT_MAX_TOKENS = 32000;
|
|
25
28
|
function grokSupports(feature, _model) {
|
|
@@ -27,12 +30,13 @@ function grokSupports(feature, _model) {
|
|
|
27
30
|
case "structured_native":
|
|
28
31
|
case "json_mode":
|
|
29
32
|
case "prefix_cache_implicit":
|
|
33
|
+
case "prompt_cache_key": // prompt_cache_key routing hint (WS-C) — cache-policy registry truth
|
|
30
34
|
return true;
|
|
31
35
|
case "grounded_native": // Live Search exists but is not wired — probes may grant later
|
|
32
36
|
case "context_cache_explicit":
|
|
33
|
-
case "prompt_cache_key":
|
|
34
37
|
case "tier_flex":
|
|
35
38
|
case "trace_visible":
|
|
39
|
+
case "zero_retention": // never a static adapter attestation — set only from the credential-scoped registry facts (claims.ts)
|
|
36
40
|
return false;
|
|
37
41
|
}
|
|
38
42
|
}
|
|
@@ -70,10 +74,16 @@ function buildGrokParams(model, req) {
|
|
|
70
74
|
];
|
|
71
75
|
return {
|
|
72
76
|
model,
|
|
73
|
-
max_tokens: req
|
|
77
|
+
max_tokens: (0, sampling_1.effectiveMaxOutputTokens)(req, DEFAULT_MAX_TOKENS),
|
|
74
78
|
messages,
|
|
75
79
|
stream: true,
|
|
76
80
|
stream_options: { include_usage: true },
|
|
81
|
+
...(0, sampling_1.openAISamplingFields)(req),
|
|
82
|
+
// Prompt caching (WS-C): the run loop stamps `cache.key` (the stable-prefix
|
|
83
|
+
// fingerprint) for prompt_cache_key providers; pass it through as xAI's hint.
|
|
84
|
+
...(req.cache?.key !== undefined && req.cache.key !== ""
|
|
85
|
+
? { prompt_cache_key: req.cache.key }
|
|
86
|
+
: {}),
|
|
77
87
|
...(req.outputSchema !== null
|
|
78
88
|
? {
|
|
79
89
|
response_format: {
|
|
@@ -86,12 +96,21 @@ function buildGrokParams(model, req) {
|
|
|
86
96
|
},
|
|
87
97
|
}
|
|
88
98
|
: {}),
|
|
99
|
+
...(req.tools !== undefined && req.tools.length > 0
|
|
100
|
+
? {
|
|
101
|
+
tools: (0, tool_mapping_1.toOpenAITools)(req.tools),
|
|
102
|
+
...((0, tool_mapping_1.toOpenAIToolChoice)(req.toolChoice) !== undefined
|
|
103
|
+
? { tool_choice: (0, tool_mapping_1.toOpenAIToolChoice)(req.toolChoice) }
|
|
104
|
+
: {}),
|
|
105
|
+
}
|
|
106
|
+
: {}),
|
|
89
107
|
};
|
|
90
108
|
}
|
|
91
109
|
function createGrokAdapter(config) {
|
|
92
110
|
return {
|
|
93
111
|
id: "grok",
|
|
94
112
|
supports: grokSupports,
|
|
113
|
+
supportsTools: () => true,
|
|
95
114
|
async call(req) {
|
|
96
115
|
const model = req.candidate.model;
|
|
97
116
|
// F1: post-stream failures still billed tokens — attach usage.
|
|
@@ -118,28 +137,40 @@ function createGrokAdapter(config) {
|
|
|
118
137
|
let promptTokens = 0;
|
|
119
138
|
let completionTokens = 0;
|
|
120
139
|
let cachedTokens = 0;
|
|
140
|
+
let cacheWriteTokens = 0;
|
|
121
141
|
let finishReason = null;
|
|
142
|
+
const toolCallAcc = (0, tool_mapping_1.createOpenAIToolCallAccumulator)();
|
|
122
143
|
// Only delta.content is accumulated — a reasoning model's trace must
|
|
123
144
|
// never leak into the JSON buffer (deepseek reasoner rule applied).
|
|
124
145
|
for await (const chunk of stream) {
|
|
125
146
|
const choice = chunk.choices[0];
|
|
126
147
|
if (choice?.delta?.content)
|
|
127
148
|
text += choice.delta.content;
|
|
149
|
+
toolCallAcc.push(choice?.delta?.tool_calls);
|
|
128
150
|
if (choice?.finish_reason)
|
|
129
151
|
finishReason = choice.finish_reason;
|
|
130
152
|
if (chunk.usage) {
|
|
131
153
|
promptTokens = chunk.usage.prompt_tokens ?? 0;
|
|
132
154
|
completionTokens = chunk.usage.completion_tokens ?? 0;
|
|
133
155
|
cachedTokens = chunk.usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
156
|
+
cacheWriteTokens = chunk.usage.input_tokens_details?.cache_write_tokens ?? 0;
|
|
134
157
|
}
|
|
135
158
|
}
|
|
136
|
-
// xAI has no service tiers — served is always standard.
|
|
159
|
+
// xAI has no service tiers — served is always standard. prompt_tokens
|
|
160
|
+
// already INCLUDES cached → tokensIn is subset-correct.
|
|
137
161
|
const usage = {
|
|
138
162
|
tokensIn: promptTokens,
|
|
139
163
|
tokensOut: completionTokens,
|
|
140
164
|
tokensCached: cachedTokens,
|
|
165
|
+
tokensCacheWrite: cacheWriteTokens,
|
|
141
166
|
servedTier: "standard",
|
|
142
167
|
};
|
|
168
|
+
// Tool-call turn (spec §4.4): surface normalized calls, skip the
|
|
169
|
+
// empty/truncation content guards below.
|
|
170
|
+
const toolCalls = toolCallAcc.finalize();
|
|
171
|
+
if (toolCalls !== undefined) {
|
|
172
|
+
return { ok: true, text, usage, toolCalls };
|
|
173
|
+
}
|
|
143
174
|
if (text.trim().length === 0) {
|
|
144
175
|
return fail("content_invalid", `empty response from Grok (finish_reason=${finishReason ?? "none"})`, undefined, usage);
|
|
145
176
|
}
|
|
@@ -164,5 +195,38 @@ function createGrokAdapter(config) {
|
|
|
164
195
|
};
|
|
165
196
|
}
|
|
166
197
|
},
|
|
198
|
+
async *stream(req) {
|
|
199
|
+
const model = req.candidate.model;
|
|
200
|
+
try {
|
|
201
|
+
const client = new openai_1.default({ apiKey: config.apiKey, baseURL: GROK_BASE_URL, timeout: req.timeoutMs });
|
|
202
|
+
const params = buildGrokParams(model, req);
|
|
203
|
+
const dispatchedAt = Date.now();
|
|
204
|
+
const stream = await client.chat.completions.create(params);
|
|
205
|
+
// xAI has no service tiers — served is always standard.
|
|
206
|
+
yield* (0, openai_stream_1.streamOpenAIDialect)(stream, req, dispatchedAt, {
|
|
207
|
+
provider: "grok",
|
|
208
|
+
cachedTokenSource: "details",
|
|
209
|
+
mapServedTier: () => "standard",
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
214
|
+
const { cls, fixHint } = classifyGrokFailure(message);
|
|
215
|
+
yield {
|
|
216
|
+
kind: "final",
|
|
217
|
+
result: {
|
|
218
|
+
ok: false,
|
|
219
|
+
failure: {
|
|
220
|
+
class: cls,
|
|
221
|
+
message,
|
|
222
|
+
provider: "grok",
|
|
223
|
+
model,
|
|
224
|
+
cause: error,
|
|
225
|
+
...(fixHint !== undefined ? { fixHint } : {}),
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
},
|
|
167
231
|
};
|
|
168
232
|
}
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import type { CapabilityFlag, ProviderAdapter, ProviderId } from "../types/provider";
|
|
21
21
|
import type { ClassifiedFailure, ShapingInput } from "./gemini";
|
|
22
|
+
import type { OpenAIWireTool, OpenAIWireToolChoice } from "./tool-mapping";
|
|
22
23
|
/** Fireworks serves models at accounts/fireworks/models/<short> — routes
|
|
23
24
|
* declare the short name; the wire gets the full path (LiteLLM
|
|
24
25
|
* fireworks_ai transformation, harvested). */
|
|
@@ -45,6 +46,9 @@ export interface OpenAICompatShapedParams {
|
|
|
45
46
|
readonly stream_options: {
|
|
46
47
|
readonly include_usage: true;
|
|
47
48
|
};
|
|
49
|
+
/** CE-6 declared sampling — present only when the route/raw asks for them. */
|
|
50
|
+
readonly temperature?: number;
|
|
51
|
+
readonly top_p?: number;
|
|
48
52
|
readonly response_format?: {
|
|
49
53
|
readonly type: "json_object";
|
|
50
54
|
} | {
|
|
@@ -55,6 +59,8 @@ export interface OpenAICompatShapedParams {
|
|
|
55
59
|
readonly schema: object;
|
|
56
60
|
};
|
|
57
61
|
};
|
|
62
|
+
readonly tools?: readonly OpenAIWireTool[];
|
|
63
|
+
readonly tool_choice?: OpenAIWireToolChoice;
|
|
58
64
|
}
|
|
59
65
|
/** Pure request shaping. The PROFILE decides the wire shape: strict
|
|
60
66
|
* json_schema only when the registry granted structured_native for this
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-compat.d.ts","sourceRoot":"","sources":["../../src/adapters/openai-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EACf,UAAU,EACX,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"openai-compat.d.ts","sourceRoot":"","sources":["../../src/adapters/openai-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EACf,UAAU,EACX,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAMhE,OAAO,KAAK,EAAuB,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAQhG;;8CAE8C;AAC9C,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACnD;AAED;;;0EAG0E;AAC1E,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,GAAG,WAAW,EAAE,gBAAgB,CAAC,CAG7F,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAiBtF;AAED,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAA;KAAE,CAAC;IAC1D,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,CAAC,EACrB;QAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;KAAE,GAChC;QACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAC7B,QAAQ,CAAC,WAAW,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KACjG,CAAC;IACN,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAOD;;2DAE2D;AAC3D,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,YAAY,EACjB,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,GACxC,wBAAwB,CAqC1B;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD;+DAC2D;IAC3D,QAAQ,CAAC,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,WAAW,CAAC,cAAc,CAAC,CAAC;CAC5E;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,yBAAyB,GAAG,eAAe,CAwK5F"}
|
|
@@ -28,6 +28,9 @@ exports.classifyCompatFailure = classifyCompatFailure;
|
|
|
28
28
|
exports.buildOpenAICompatParams = buildOpenAICompatParams;
|
|
29
29
|
exports.createOpenAICompatAdapter = createOpenAICompatAdapter;
|
|
30
30
|
const openai_1 = __importDefault(require("openai"));
|
|
31
|
+
const tool_mapping_1 = require("./tool-mapping");
|
|
32
|
+
const openai_stream_1 = require("./openai-stream");
|
|
33
|
+
const sampling_1 = require("./sampling");
|
|
31
34
|
const DEFAULT_MAX_TOKENS = 32000;
|
|
32
35
|
/** Fireworks serves models at accounts/fireworks/models/<short> — routes
|
|
33
36
|
* declare the short name; the wire gets the full path (LiteLLM
|
|
@@ -85,10 +88,11 @@ function buildOpenAICompatParams(model, req, profileFlags) {
|
|
|
85
88
|
];
|
|
86
89
|
return {
|
|
87
90
|
model,
|
|
88
|
-
max_tokens: req
|
|
91
|
+
max_tokens: (0, sampling_1.effectiveMaxOutputTokens)(req, DEFAULT_MAX_TOKENS),
|
|
89
92
|
messages,
|
|
90
93
|
stream: true,
|
|
91
94
|
stream_options: { include_usage: true },
|
|
95
|
+
...(0, sampling_1.openAISamplingFields)(req),
|
|
92
96
|
...(wantJson
|
|
93
97
|
? strict
|
|
94
98
|
? {
|
|
@@ -99,6 +103,14 @@ function buildOpenAICompatParams(model, req, profileFlags) {
|
|
|
99
103
|
}
|
|
100
104
|
: { response_format: { type: "json_object" } }
|
|
101
105
|
: {}),
|
|
106
|
+
...(req.tools !== undefined && req.tools.length > 0
|
|
107
|
+
? {
|
|
108
|
+
tools: (0, tool_mapping_1.toOpenAITools)(req.tools),
|
|
109
|
+
...((0, tool_mapping_1.toOpenAIToolChoice)(req.toolChoice) !== undefined
|
|
110
|
+
? { tool_choice: (0, tool_mapping_1.toOpenAIToolChoice)(req.toolChoice) }
|
|
111
|
+
: {}),
|
|
112
|
+
}
|
|
113
|
+
: {}),
|
|
102
114
|
};
|
|
103
115
|
}
|
|
104
116
|
function createOpenAICompatAdapter(config) {
|
|
@@ -108,6 +120,7 @@ function createOpenAICompatAdapter(config) {
|
|
|
108
120
|
supports(feature, model) {
|
|
109
121
|
return config.capabilityProfile(model).has(feature);
|
|
110
122
|
},
|
|
123
|
+
supportsTools: () => true,
|
|
111
124
|
async call(req) {
|
|
112
125
|
const model = req.candidate.model;
|
|
113
126
|
const fail = (cls, message, fixHint, usage) => ({
|
|
@@ -134,31 +147,42 @@ function createOpenAICompatAdapter(config) {
|
|
|
134
147
|
let promptTokens = 0;
|
|
135
148
|
let completionTokens = 0;
|
|
136
149
|
let cachedTokens = 0;
|
|
150
|
+
let cacheWriteTokens = 0;
|
|
137
151
|
let finishReason = null;
|
|
138
152
|
// TTFB (Phase 4 WS3): first streamed chunk = first body byte.
|
|
139
153
|
let ttfbMs;
|
|
154
|
+
const toolCallAcc = (0, tool_mapping_1.createOpenAIToolCallAccumulator)();
|
|
140
155
|
for await (const chunk of stream) {
|
|
141
156
|
if (ttfbMs === undefined)
|
|
142
157
|
ttfbMs = Date.now() - dispatchedAt;
|
|
143
158
|
const choice = chunk.choices[0];
|
|
144
159
|
if (choice?.delta?.content)
|
|
145
160
|
text += choice.delta.content;
|
|
161
|
+
toolCallAcc.push(choice?.delta?.tool_calls);
|
|
146
162
|
if (choice?.finish_reason)
|
|
147
163
|
finishReason = choice.finish_reason;
|
|
148
164
|
if (chunk.usage) {
|
|
149
165
|
promptTokens = chunk.usage.prompt_tokens ?? 0;
|
|
150
166
|
completionTokens = chunk.usage.completion_tokens ?? 0;
|
|
151
167
|
cachedTokens = chunk.usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
168
|
+
cacheWriteTokens = chunk.usage.input_tokens_details?.cache_write_tokens ?? 0;
|
|
152
169
|
}
|
|
153
170
|
}
|
|
154
171
|
// Hosts have no service tiers in this dialect — standard, always.
|
|
172
|
+
// prompt_tokens already INCLUDES cached → tokensIn is subset-correct.
|
|
155
173
|
const usage = {
|
|
156
174
|
tokensIn: promptTokens,
|
|
157
175
|
tokensOut: completionTokens,
|
|
158
176
|
tokensCached: cachedTokens,
|
|
177
|
+
tokensCacheWrite: cacheWriteTokens,
|
|
159
178
|
servedTier: "standard",
|
|
160
179
|
...(ttfbMs !== undefined ? { ttfbMs } : {}),
|
|
161
180
|
};
|
|
181
|
+
// Tool-call turn (spec §4.4): surface normalized calls, skip content guards.
|
|
182
|
+
const toolCalls = toolCallAcc.finalize();
|
|
183
|
+
if (toolCalls !== undefined) {
|
|
184
|
+
return { ok: true, text, usage, toolCalls };
|
|
185
|
+
}
|
|
162
186
|
if (text.trim().length === 0) {
|
|
163
187
|
return fail("content_invalid", `empty response from ${config.providerId} (finish_reason=${finishReason ?? "none"})`, undefined, usage);
|
|
164
188
|
}
|
|
@@ -183,5 +207,38 @@ function createOpenAICompatAdapter(config) {
|
|
|
183
207
|
};
|
|
184
208
|
}
|
|
185
209
|
},
|
|
210
|
+
async *stream(req) {
|
|
211
|
+
const model = req.candidate.model;
|
|
212
|
+
try {
|
|
213
|
+
const client = new openai_1.default({ apiKey: config.apiKey, baseURL: config.baseUrl, timeout: req.timeoutMs });
|
|
214
|
+
const params = buildOpenAICompatParams(shapeModel(model), req, config.capabilityProfile(model));
|
|
215
|
+
const dispatchedAt = Date.now();
|
|
216
|
+
const stream = await client.chat.completions.create(params);
|
|
217
|
+
// Compat hosts have no service tiers in this dialect — standard, always.
|
|
218
|
+
yield* (0, openai_stream_1.streamOpenAIDialect)(stream, req, dispatchedAt, {
|
|
219
|
+
provider: config.providerId,
|
|
220
|
+
cachedTokenSource: "details",
|
|
221
|
+
mapServedTier: () => "standard",
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
226
|
+
const { cls, fixHint } = classifyCompatFailure(message, config.providerId);
|
|
227
|
+
yield {
|
|
228
|
+
kind: "final",
|
|
229
|
+
result: {
|
|
230
|
+
ok: false,
|
|
231
|
+
failure: {
|
|
232
|
+
class: cls,
|
|
233
|
+
message,
|
|
234
|
+
provider: config.providerId,
|
|
235
|
+
model,
|
|
236
|
+
cause: error,
|
|
237
|
+
...(fixHint !== undefined ? { fixHint } : {}),
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
},
|
|
186
243
|
};
|
|
187
244
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared streaming loop for the OpenAI-dialect adapters (G-1/G-5 Phase A,
|
|
3
|
+
* spec §4.3). The openai / grok / deepseek / deepinfra / fireworks adapters all
|
|
4
|
+
* speak `client.chat.completions.create({ stream: true })`; this is the one
|
|
5
|
+
* place that drains such a stream into `AdapterStreamEvent`s — raw text deltas
|
|
6
|
+
* as they arrive, then a single terminal `final` carrying the same
|
|
7
|
+
* `AdapterResult` the adapter's buffered `call()` would return.
|
|
8
|
+
*
|
|
9
|
+
* ADDITIVE: `call()` is untouched. This powers the OPTIONAL `stream()` method
|
|
10
|
+
* the run loop uses only when a delta sink is wired (`rig.runStream`); every
|
|
11
|
+
* other path is byte-for-byte the pre-Phase-A behavior. Providers without a
|
|
12
|
+
* `stream()` (anthropic events / gemini non-streaming) fall back to buffered
|
|
13
|
+
* dispatch, which is the spec's sanctioned `buffered` mode.
|
|
14
|
+
*/
|
|
15
|
+
import type { AdapterRequest, AdapterStreamEvent, ProviderId, ServiceTier } from "../types/provider";
|
|
16
|
+
import type { OpenAIToolCallDelta } from "./tool-mapping";
|
|
17
|
+
/** The permissive chunk shape common to the OpenAI-dialect hosts. */
|
|
18
|
+
export interface OpenAIDialectChunk {
|
|
19
|
+
readonly service_tier?: string;
|
|
20
|
+
readonly choices: Array<{
|
|
21
|
+
readonly delta?: {
|
|
22
|
+
readonly content?: string | null;
|
|
23
|
+
readonly refusal?: string | null;
|
|
24
|
+
readonly tool_calls?: readonly OpenAIToolCallDelta[];
|
|
25
|
+
};
|
|
26
|
+
readonly finish_reason?: string | null;
|
|
27
|
+
}>;
|
|
28
|
+
readonly usage?: {
|
|
29
|
+
readonly prompt_tokens?: number;
|
|
30
|
+
readonly completion_tokens?: number;
|
|
31
|
+
readonly prompt_tokens_details?: {
|
|
32
|
+
readonly cached_tokens?: number;
|
|
33
|
+
};
|
|
34
|
+
readonly prompt_cache_hit_tokens?: number;
|
|
35
|
+
/** Cache-WRITE tokens — GPT-5.6+ bills explicit writes at 1.25× and reports
|
|
36
|
+
* them here (spec §2 table). Absent on ≤5.5 (writes free) and every non-
|
|
37
|
+
* openai dialect host, so cache-write is 0 there. */
|
|
38
|
+
readonly input_tokens_details?: {
|
|
39
|
+
readonly cache_write_tokens?: number;
|
|
40
|
+
};
|
|
41
|
+
} | null;
|
|
42
|
+
}
|
|
43
|
+
export interface OpenAIStreamConfig {
|
|
44
|
+
readonly provider: ProviderId;
|
|
45
|
+
/** Where cached-token counts live in this dialect's usage block. */
|
|
46
|
+
readonly cachedTokenSource: "details" | "cache_hit";
|
|
47
|
+
/** Served-tier resolver (openai maps flex/priority; the rest are standard). */
|
|
48
|
+
readonly mapServedTier: (raw: string | null, requested: ServiceTier) => ServiceTier;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Drain an OpenAI-dialect completion stream into `AdapterStreamEvent`s. Emits a
|
|
52
|
+
* `delta` per content token, then exactly one `final`. The final result mirrors
|
|
53
|
+
* `call()`'s terminal decisions for the shared dialect: refusal → fail;
|
|
54
|
+
* tool-call turn → ok + normalized calls; empty → content_invalid; a
|
|
55
|
+
* schema-route truncation (`finish_reason=length`) → content_invalid.
|
|
56
|
+
*/
|
|
57
|
+
export declare function streamOpenAIDialect(chunks: AsyncIterable<OpenAIDialectChunk>, req: AdapterRequest, dispatchedAt: number, cfg: OpenAIStreamConfig): AsyncGenerator<AdapterStreamEvent>;
|
|
58
|
+
//# sourceMappingURL=openai-stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-stream.d.ts","sourceRoot":"","sources":["../../src/adapters/openai-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAElB,UAAU,EACV,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;QACtB,QAAQ,CAAC,KAAK,CAAC,EAAE;YACf,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YACjC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;SACtD,CAAC;QACF,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACxC,CAAC,CAAC;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE;QACf,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;QACpC,QAAQ,CAAC,qBAAqB,CAAC,EAAE;YAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACrE,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;QAC1C;;6DAEqD;QACrD,QAAQ,CAAC,oBAAoB,CAAC,EAAE;YAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC1E,GAAG,IAAI,CAAC;CACV;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,iBAAiB,EAAE,SAAS,GAAG,WAAW,CAAC;IACpD,+EAA+E;IAC/E,QAAQ,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,WAAW,KAAK,WAAW,CAAC;CACrF;AAED;;;;;;GAMG;AACH,wBAAuB,mBAAmB,CACxC,MAAM,EAAE,aAAa,CAAC,kBAAkB,CAAC,EACzC,GAAG,EAAE,cAAc,EACnB,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,kBAAkB,GACtB,cAAc,CAAC,kBAAkB,CAAC,CAqGpC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared streaming loop for the OpenAI-dialect adapters (G-1/G-5 Phase A,
|
|
4
|
+
* spec §4.3). The openai / grok / deepseek / deepinfra / fireworks adapters all
|
|
5
|
+
* speak `client.chat.completions.create({ stream: true })`; this is the one
|
|
6
|
+
* place that drains such a stream into `AdapterStreamEvent`s — raw text deltas
|
|
7
|
+
* as they arrive, then a single terminal `final` carrying the same
|
|
8
|
+
* `AdapterResult` the adapter's buffered `call()` would return.
|
|
9
|
+
*
|
|
10
|
+
* ADDITIVE: `call()` is untouched. This powers the OPTIONAL `stream()` method
|
|
11
|
+
* the run loop uses only when a delta sink is wired (`rig.runStream`); every
|
|
12
|
+
* other path is byte-for-byte the pre-Phase-A behavior. Providers without a
|
|
13
|
+
* `stream()` (anthropic events / gemini non-streaming) fall back to buffered
|
|
14
|
+
* dispatch, which is the spec's sanctioned `buffered` mode.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.streamOpenAIDialect = streamOpenAIDialect;
|
|
18
|
+
const tool_mapping_1 = require("./tool-mapping");
|
|
19
|
+
/**
|
|
20
|
+
* Drain an OpenAI-dialect completion stream into `AdapterStreamEvent`s. Emits a
|
|
21
|
+
* `delta` per content token, then exactly one `final`. The final result mirrors
|
|
22
|
+
* `call()`'s terminal decisions for the shared dialect: refusal → fail;
|
|
23
|
+
* tool-call turn → ok + normalized calls; empty → content_invalid; a
|
|
24
|
+
* schema-route truncation (`finish_reason=length`) → content_invalid.
|
|
25
|
+
*/
|
|
26
|
+
async function* streamOpenAIDialect(chunks, req, dispatchedAt, cfg) {
|
|
27
|
+
let ttfbMs;
|
|
28
|
+
let text = "";
|
|
29
|
+
let refusalText = "";
|
|
30
|
+
const toolCallAcc = (0, tool_mapping_1.createOpenAIToolCallAccumulator)();
|
|
31
|
+
let promptTokens = 0;
|
|
32
|
+
let completionTokens = 0;
|
|
33
|
+
let cachedTokens = 0;
|
|
34
|
+
let cacheWriteTokens = 0;
|
|
35
|
+
let responseTier = null;
|
|
36
|
+
let finishReason = null;
|
|
37
|
+
for await (const chunk of chunks) {
|
|
38
|
+
if (ttfbMs === undefined)
|
|
39
|
+
ttfbMs = Date.now() - dispatchedAt;
|
|
40
|
+
if (responseTier === null && chunk.service_tier !== undefined)
|
|
41
|
+
responseTier = chunk.service_tier;
|
|
42
|
+
const choice = chunk.choices[0];
|
|
43
|
+
const content = choice?.delta?.content;
|
|
44
|
+
if (content) {
|
|
45
|
+
text += content;
|
|
46
|
+
yield { kind: "delta", text: content };
|
|
47
|
+
}
|
|
48
|
+
if (typeof choice?.delta?.refusal === "string" && choice.delta.refusal.length > 0) {
|
|
49
|
+
refusalText += choice.delta.refusal;
|
|
50
|
+
}
|
|
51
|
+
toolCallAcc.push(choice?.delta?.tool_calls);
|
|
52
|
+
if (choice?.finish_reason)
|
|
53
|
+
finishReason = choice.finish_reason;
|
|
54
|
+
if (chunk.usage) {
|
|
55
|
+
promptTokens = chunk.usage.prompt_tokens ?? 0;
|
|
56
|
+
completionTokens = chunk.usage.completion_tokens ?? 0;
|
|
57
|
+
cachedTokens =
|
|
58
|
+
cfg.cachedTokenSource === "cache_hit"
|
|
59
|
+
? chunk.usage.prompt_cache_hit_tokens ?? 0
|
|
60
|
+
: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
61
|
+
// Cache-write (GPT-5.6+): 0 on every dialect that does not report it.
|
|
62
|
+
cacheWriteTokens = chunk.usage.input_tokens_details?.cache_write_tokens ?? 0;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// prompt_tokens already INCLUDES cached (and any write) on the OpenAI dialect,
|
|
66
|
+
// so tokensIn = promptTokens honors the subset invariant as-is. There is no 1h
|
|
67
|
+
// TTL tier on this dialect (OpenAI 5.6 writes are a single 30m tier) → 1h = 0.
|
|
68
|
+
const usage = {
|
|
69
|
+
tokensIn: promptTokens,
|
|
70
|
+
tokensOut: completionTokens,
|
|
71
|
+
tokensCached: cachedTokens,
|
|
72
|
+
tokensCacheWrite: cacheWriteTokens,
|
|
73
|
+
servedTier: cfg.mapServedTier(responseTier, req.requestedTier),
|
|
74
|
+
...(ttfbMs !== undefined ? { ttfbMs } : {}),
|
|
75
|
+
};
|
|
76
|
+
const fail = (message, fixHint) => ({
|
|
77
|
+
kind: "final",
|
|
78
|
+
result: {
|
|
79
|
+
ok: false,
|
|
80
|
+
failure: {
|
|
81
|
+
class: "content_invalid",
|
|
82
|
+
message,
|
|
83
|
+
provider: cfg.provider,
|
|
84
|
+
model: req.candidate.model,
|
|
85
|
+
...(fixHint !== undefined ? { fixHint } : {}),
|
|
86
|
+
},
|
|
87
|
+
usage,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
if (refusalText.length > 0) {
|
|
91
|
+
yield {
|
|
92
|
+
kind: "final",
|
|
93
|
+
result: {
|
|
94
|
+
ok: false,
|
|
95
|
+
failure: {
|
|
96
|
+
class: "refusal",
|
|
97
|
+
message: `${cfg.provider} refused output: ${refusalText.slice(0, 200)}`,
|
|
98
|
+
provider: cfg.provider,
|
|
99
|
+
model: req.candidate.model,
|
|
100
|
+
},
|
|
101
|
+
usage,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const toolCalls = toolCallAcc.finalize();
|
|
107
|
+
if (toolCalls !== undefined) {
|
|
108
|
+
yield { kind: "final", result: { ok: true, text, usage, toolCalls } };
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (text.trim().length === 0) {
|
|
112
|
+
yield fail(`empty response from ${cfg.provider} (finish_reason=${finishReason ?? "none"})`);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (finishReason === "length" && req.outputSchema !== null) {
|
|
116
|
+
yield fail(`${cfg.provider} output truncated (finish_reason=length)`, "raise maxOutputTokens for this route");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
yield { kind: "final", result: { ok: true, text, usage } };
|
|
120
|
+
}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import type { CapabilityFlag, ProviderAdapter } from "../types/provider";
|
|
15
15
|
import type { ClassifiedFailure, ShapingInput } from "./gemini";
|
|
16
|
+
import type { OpenAIWireTool, OpenAIWireToolChoice } from "./tool-mapping";
|
|
16
17
|
export interface OpenAIAdapterConfig {
|
|
17
18
|
readonly apiKey: string;
|
|
18
19
|
}
|
|
@@ -31,6 +32,9 @@ export interface OpenAIShapedParams {
|
|
|
31
32
|
readonly stream_options: {
|
|
32
33
|
readonly include_usage: true;
|
|
33
34
|
};
|
|
35
|
+
/** CE-6 declared sampling — present only when the route/raw asks for them. */
|
|
36
|
+
readonly temperature?: number;
|
|
37
|
+
readonly top_p?: number;
|
|
34
38
|
readonly service_tier?: "flex" | "priority";
|
|
35
39
|
readonly prompt_cache_key?: string;
|
|
36
40
|
readonly prompt_cache_retention?: "24h";
|
|
@@ -42,6 +46,8 @@ export interface OpenAIShapedParams {
|
|
|
42
46
|
readonly strict: true;
|
|
43
47
|
};
|
|
44
48
|
};
|
|
49
|
+
readonly tools?: readonly OpenAIWireTool[];
|
|
50
|
+
readonly tool_choice?: OpenAIWireToolChoice;
|
|
45
51
|
}
|
|
46
52
|
export declare function buildOpenAIParams(model: string, req: ShapingInput): OpenAIShapedParams;
|
|
47
53
|
export declare function createOpenAIAdapter(config: OpenAIAdapterConfig): ProviderAdapter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAMhE,OAAO,KAAK,EAAuB,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAMhG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAMD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAI9D;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAe9E;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAiBxE;AAED,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAA;KAAE,CAAC;IAC1D,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC5C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,KAAK,CAAC;IACxC,QAAQ,CAAC,eAAe,CAAC,EAAE;QACzB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAC7B,QAAQ,CAAC,WAAW,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;SAAE,CAAC;KACjG,CAAC;IACF,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAID,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,kBAAkB,CA6CtF;AAcD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,eAAe,CAwMhF"}
|