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.
Files changed (309) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/README.md +41 -11
  3. package/data/PROVENANCE.md +19 -0
  4. package/data/pricing-manual.json +22 -0
  5. package/data/pricing-map.json +46362 -0
  6. package/data/pricing-overlay.json +419 -0
  7. package/dist/adapters/anthropic.d.ts +50 -6
  8. package/dist/adapters/anthropic.d.ts.map +1 -1
  9. package/dist/adapters/anthropic.js +123 -29
  10. package/dist/adapters/build-adapters.d.ts +11 -0
  11. package/dist/adapters/build-adapters.d.ts.map +1 -0
  12. package/dist/adapters/build-adapters.js +45 -0
  13. package/dist/adapters/deepseek.d.ts +6 -0
  14. package/dist/adapters/deepseek.d.ts.map +1 -1
  15. package/dist/adapters/deepseek.js +54 -1
  16. package/dist/adapters/gemini.d.ts.map +1 -1
  17. package/dist/adapters/gemini.js +46 -6
  18. package/dist/adapters/grok.d.ts +9 -0
  19. package/dist/adapters/grok.d.ts.map +1 -1
  20. package/dist/adapters/grok.js +67 -3
  21. package/dist/adapters/openai-compat.d.ts +6 -0
  22. package/dist/adapters/openai-compat.d.ts.map +1 -1
  23. package/dist/adapters/openai-compat.js +58 -1
  24. package/dist/adapters/openai-stream.d.ts +58 -0
  25. package/dist/adapters/openai-stream.d.ts.map +1 -0
  26. package/dist/adapters/openai-stream.js +120 -0
  27. package/dist/adapters/openai.d.ts +6 -0
  28. package/dist/adapters/openai.d.ts.map +1 -1
  29. package/dist/adapters/openai.js +60 -1
  30. package/dist/adapters/sampling.d.ts +28 -0
  31. package/dist/adapters/sampling.d.ts.map +1 -0
  32. package/dist/adapters/sampling.js +34 -0
  33. package/dist/adapters/tool-mapping.d.ts +92 -0
  34. package/dist/adapters/tool-mapping.d.ts.map +1 -0
  35. package/dist/adapters/tool-mapping.js +143 -0
  36. package/dist/artifacts/artifact.d.ts +137 -0
  37. package/dist/artifacts/artifact.d.ts.map +1 -0
  38. package/dist/artifacts/artifact.js +377 -0
  39. package/dist/artifacts/content-uploader.d.ts +87 -0
  40. package/dist/artifacts/content-uploader.d.ts.map +1 -0
  41. package/dist/artifacts/content-uploader.js +124 -0
  42. package/dist/artifacts/index.d.ts +63 -0
  43. package/dist/artifacts/index.d.ts.map +1 -0
  44. package/dist/artifacts/index.js +80 -0
  45. package/dist/artifacts/run-context.d.ts +129 -0
  46. package/dist/artifacts/run-context.d.ts.map +1 -0
  47. package/dist/artifacts/run-context.js +208 -0
  48. package/dist/artifacts/scrub.d.ts +60 -0
  49. package/dist/artifacts/scrub.d.ts.map +1 -0
  50. package/dist/artifacts/scrub.js +139 -0
  51. package/dist/artifacts/step.d.ts +26 -0
  52. package/dist/artifacts/step.d.ts.map +1 -0
  53. package/dist/artifacts/step.js +37 -0
  54. package/dist/artifacts/taint.d.ts +63 -0
  55. package/dist/artifacts/taint.d.ts.map +1 -0
  56. package/dist/artifacts/taint.js +76 -0
  57. package/dist/bakeoff/cache-sim.d.ts +99 -0
  58. package/dist/bakeoff/cache-sim.d.ts.map +1 -0
  59. package/dist/bakeoff/cache-sim.js +126 -0
  60. package/dist/bakeoff/eval-cases.d.ts +96 -0
  61. package/dist/bakeoff/eval-cases.d.ts.map +1 -0
  62. package/dist/bakeoff/eval-cases.js +105 -0
  63. package/dist/bakeoff/report.d.ts +41 -0
  64. package/dist/bakeoff/report.d.ts.map +1 -0
  65. package/dist/bakeoff/report.js +142 -0
  66. package/dist/bakeoff/samples.d.ts +15 -0
  67. package/dist/bakeoff/samples.d.ts.map +1 -1
  68. package/dist/bakeoff/samples.js +20 -0
  69. package/dist/cli.d.ts +1 -3
  70. package/dist/cli.d.ts.map +1 -1
  71. package/dist/cli.js +134 -116
  72. package/dist/config.d.ts +100 -0
  73. package/dist/config.d.ts.map +1 -1
  74. package/dist/config.js +104 -0
  75. package/dist/deprecations.d.ts +32 -0
  76. package/dist/deprecations.d.ts.map +1 -0
  77. package/dist/deprecations.js +59 -0
  78. package/dist/gateway/http-protocol.d.ts +175 -0
  79. package/dist/gateway/http-protocol.d.ts.map +1 -0
  80. package/dist/gateway/http-protocol.js +105 -0
  81. package/dist/index.d.ts +105 -18
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +266 -138
  84. package/dist/init/finder.d.ts +15 -0
  85. package/dist/init/finder.d.ts.map +1 -1
  86. package/dist/init/finder.js +46 -0
  87. package/dist/init/init-cli.d.ts +10 -0
  88. package/dist/init/init-cli.d.ts.map +1 -0
  89. package/dist/init/init-cli.js +86 -0
  90. package/dist/init/observe-cli.d.ts +19 -0
  91. package/dist/init/observe-cli.d.ts.map +1 -0
  92. package/dist/init/observe-cli.js +73 -0
  93. package/dist/init/observe.d.ts +81 -0
  94. package/dist/init/observe.d.ts.map +1 -0
  95. package/dist/init/observe.js +245 -0
  96. package/dist/registry/build.d.ts +94 -1
  97. package/dist/registry/build.d.ts.map +1 -1
  98. package/dist/registry/build.js +125 -4
  99. package/dist/registry/cache-policy.d.ts +94 -0
  100. package/dist/registry/cache-policy.d.ts.map +1 -0
  101. package/dist/registry/cache-policy.js +238 -0
  102. package/dist/registry/call-notes.d.ts.map +1 -1
  103. package/dist/registry/call-notes.js +40 -2
  104. package/dist/registry/effective-rate.d.ts +151 -0
  105. package/dist/registry/effective-rate.d.ts.map +1 -0
  106. package/dist/registry/effective-rate.js +156 -0
  107. package/dist/registry/facts.d.ts.map +1 -1
  108. package/dist/registry/facts.js +16 -0
  109. package/dist/registry/parity.d.ts +26 -0
  110. package/dist/registry/parity.d.ts.map +1 -1
  111. package/dist/registry/parity.js +43 -2
  112. package/dist/registry/pricing-shape.d.ts +113 -0
  113. package/dist/registry/pricing-shape.d.ts.map +1 -0
  114. package/dist/registry/pricing-shape.js +123 -0
  115. package/dist/registry/pricing.d.ts +25 -1
  116. package/dist/registry/pricing.d.ts.map +1 -1
  117. package/dist/registry/pricing.js +64 -6
  118. package/dist/rigindex/bootstrap.d.ts +36 -0
  119. package/dist/rigindex/bootstrap.d.ts.map +1 -0
  120. package/dist/rigindex/bootstrap.js +97 -0
  121. package/dist/rigindex/fit.d.ts +24 -0
  122. package/dist/rigindex/fit.d.ts.map +1 -0
  123. package/dist/rigindex/fit.js +76 -0
  124. package/dist/rigindex/gates.d.ts +52 -0
  125. package/dist/rigindex/gates.d.ts.map +1 -0
  126. package/dist/rigindex/gates.js +109 -0
  127. package/dist/rigindex/graph.d.ts +31 -0
  128. package/dist/rigindex/graph.d.ts.map +1 -0
  129. package/dist/rigindex/graph.js +120 -0
  130. package/dist/rigindex/index.d.ts +23 -0
  131. package/dist/rigindex/index.d.ts.map +1 -0
  132. package/dist/rigindex/index.js +112 -0
  133. package/dist/rigindex/types.d.ts +76 -0
  134. package/dist/rigindex/types.d.ts.map +1 -0
  135. package/dist/rigindex/types.js +8 -0
  136. package/dist/routes/cache-lint.d.ts +41 -0
  137. package/dist/routes/cache-lint.d.ts.map +1 -0
  138. package/dist/routes/cache-lint.js +81 -0
  139. package/dist/routes/loader.d.ts +37 -0
  140. package/dist/routes/loader.d.ts.map +1 -1
  141. package/dist/routes/loader.js +138 -0
  142. package/dist/routes/resolved-bundle.d.ts +79 -0
  143. package/dist/routes/resolved-bundle.d.ts.map +1 -0
  144. package/dist/routes/resolved-bundle.js +148 -0
  145. package/dist/routes/sampling-config.d.ts +32 -0
  146. package/dist/routes/sampling-config.d.ts.map +1 -0
  147. package/dist/routes/sampling-config.js +91 -0
  148. package/dist/run/ajv.d.ts +22 -0
  149. package/dist/run/ajv.d.ts.map +1 -0
  150. package/dist/run/ajv.js +32 -0
  151. package/dist/run/cache-handle.d.ts +58 -0
  152. package/dist/run/cache-handle.d.ts.map +1 -0
  153. package/dist/run/cache-handle.js +54 -0
  154. package/dist/run/cache-stamp.d.ts +65 -0
  155. package/dist/run/cache-stamp.d.ts.map +1 -0
  156. package/dist/run/cache-stamp.js +0 -0
  157. package/dist/run/capture-write.d.ts +33 -0
  158. package/dist/run/capture-write.d.ts.map +1 -0
  159. package/dist/run/capture-write.js +55 -0
  160. package/dist/run/cost.d.ts.map +1 -1
  161. package/dist/run/cost.js +1 -1
  162. package/dist/run/dispatch.d.ts +99 -0
  163. package/dist/run/dispatch.d.ts.map +1 -0
  164. package/dist/run/dispatch.js +191 -0
  165. package/dist/run/raw.d.ts +88 -0
  166. package/dist/run/raw.d.ts.map +1 -0
  167. package/dist/run/raw.js +286 -0
  168. package/dist/run/record-attempt.d.ts +40 -0
  169. package/dist/run/record-attempt.d.ts.map +1 -0
  170. package/dist/run/record-attempt.js +99 -0
  171. package/dist/run/resolve.d.ts +75 -2
  172. package/dist/run/resolve.d.ts.map +1 -1
  173. package/dist/run/resolve.js +126 -4
  174. package/dist/run/run.d.ts +14 -0
  175. package/dist/run/run.d.ts.map +1 -1
  176. package/dist/run/run.js +0 -0
  177. package/dist/run/stream.d.ts +49 -0
  178. package/dist/run/stream.d.ts.map +1 -0
  179. package/dist/run/stream.js +87 -0
  180. package/dist/run/validate.d.ts.map +1 -1
  181. package/dist/run/validate.js +6 -7
  182. package/dist/savings/cache-ledger.d.ts +108 -0
  183. package/dist/savings/cache-ledger.d.ts.map +1 -0
  184. package/dist/savings/cache-ledger.js +174 -0
  185. package/dist/savings/cache-reconcile.d.ts +64 -0
  186. package/dist/savings/cache-reconcile.d.ts.map +1 -0
  187. package/dist/savings/cache-reconcile.js +59 -0
  188. package/dist/savings/cache-stats.d.ts +63 -0
  189. package/dist/savings/cache-stats.d.ts.map +1 -0
  190. package/dist/savings/cache-stats.js +108 -0
  191. package/dist/savings/emit.d.ts +13 -0
  192. package/dist/savings/emit.d.ts.map +1 -1
  193. package/dist/savings/emit.js +25 -0
  194. package/dist/savings/swap-execute.d.ts +14 -0
  195. package/dist/savings/swap-execute.d.ts.map +1 -1
  196. package/dist/savings/swap-execute.js +44 -1
  197. package/dist/savings/swaps-client.d.ts +14 -0
  198. package/dist/savings/swaps-client.d.ts.map +1 -1
  199. package/dist/savings/swaps-client.js +16 -2
  200. package/dist/settings/api-fetcher.d.ts +39 -0
  201. package/dist/settings/api-fetcher.d.ts.map +1 -0
  202. package/dist/settings/api-fetcher.js +92 -0
  203. package/dist/settings/index.d.ts +10 -0
  204. package/dist/settings/index.d.ts.map +1 -0
  205. package/dist/settings/index.js +15 -0
  206. package/dist/settings/task-settings.d.ts +91 -0
  207. package/dist/settings/task-settings.d.ts.map +1 -0
  208. package/dist/settings/task-settings.js +116 -0
  209. package/dist/status.d.ts +77 -0
  210. package/dist/status.d.ts.map +1 -0
  211. package/dist/status.js +113 -0
  212. package/dist/telemetry/artifact-store.d.ts +48 -0
  213. package/dist/telemetry/artifact-store.d.ts.map +1 -0
  214. package/dist/telemetry/artifact-store.js +189 -0
  215. package/dist/telemetry/cache-miss-streak.d.ts +79 -0
  216. package/dist/telemetry/cache-miss-streak.d.ts.map +1 -0
  217. package/dist/telemetry/cache-miss-streak.js +99 -0
  218. package/dist/telemetry/capture.d.ts +3 -0
  219. package/dist/telemetry/capture.d.ts.map +1 -1
  220. package/dist/telemetry/capture.js +15 -8
  221. package/dist/telemetry/exporter-setup.d.ts +28 -0
  222. package/dist/telemetry/exporter-setup.d.ts.map +1 -0
  223. package/dist/telemetry/exporter-setup.js +34 -0
  224. package/dist/telemetry/exporter.d.ts +75 -0
  225. package/dist/telemetry/exporter.d.ts.map +1 -1
  226. package/dist/telemetry/exporter.js +324 -47
  227. package/dist/telemetry/health.d.ts +76 -0
  228. package/dist/telemetry/health.d.ts.map +1 -0
  229. package/dist/telemetry/health.js +92 -0
  230. package/dist/telemetry/ingest-protocol.d.ts +152 -3
  231. package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
  232. package/dist/telemetry/ingest-protocol.js +204 -4
  233. package/dist/telemetry/load-error-report.d.ts +24 -0
  234. package/dist/telemetry/load-error-report.d.ts.map +1 -0
  235. package/dist/telemetry/load-error-report.js +50 -0
  236. package/dist/telemetry/otel-map.d.ts +121 -0
  237. package/dist/telemetry/otel-map.d.ts.map +1 -0
  238. package/dist/telemetry/otel-map.js +224 -0
  239. package/dist/telemetry/otel-normalize.d.ts +104 -0
  240. package/dist/telemetry/otel-normalize.d.ts.map +1 -0
  241. package/dist/telemetry/otel-normalize.js +530 -0
  242. package/dist/telemetry/otlp-emitter.d.ts +52 -0
  243. package/dist/telemetry/otlp-emitter.d.ts.map +1 -0
  244. package/dist/telemetry/otlp-emitter.js +144 -0
  245. package/dist/telemetry/otlp-proto.d.ts +29 -0
  246. package/dist/telemetry/otlp-proto.d.ts.map +1 -0
  247. package/dist/telemetry/otlp-proto.js +266 -0
  248. package/dist/telemetry/sinks.d.ts +37 -1
  249. package/dist/telemetry/sinks.d.ts.map +1 -1
  250. package/dist/telemetry/sinks.js +121 -30
  251. package/dist/telemetry/store.d.ts +28 -1
  252. package/dist/telemetry/store.d.ts.map +1 -1
  253. package/dist/telemetry/store.js +218 -3
  254. package/dist/tenancy/api-key-format.d.ts +15 -5
  255. package/dist/tenancy/api-key-format.d.ts.map +1 -1
  256. package/dist/tenancy/api-key-format.js +24 -5
  257. package/dist/types/config-teaching.d.ts +62 -0
  258. package/dist/types/config-teaching.d.ts.map +1 -0
  259. package/dist/types/config-teaching.js +183 -0
  260. package/dist/types/provider.d.ts +122 -1
  261. package/dist/types/provider.d.ts.map +1 -1
  262. package/dist/types/provider.js +21 -1
  263. package/dist/types/route.d.ts +79 -1
  264. package/dist/types/route.d.ts.map +1 -1
  265. package/dist/types/telemetry.d.ts +117 -0
  266. package/dist/types/telemetry.d.ts.map +1 -1
  267. package/dist/validate-cli.d.ts +12 -0
  268. package/dist/validate-cli.d.ts.map +1 -0
  269. package/dist/validate-cli.js +57 -0
  270. package/dist/verify/capture.d.ts +66 -0
  271. package/dist/verify/capture.d.ts.map +1 -0
  272. package/dist/verify/capture.js +180 -0
  273. package/dist/verify/cli-run.d.ts +23 -0
  274. package/dist/verify/cli-run.d.ts.map +1 -0
  275. package/dist/verify/cli-run.js +57 -0
  276. package/dist/verify/diff.d.ts +48 -0
  277. package/dist/verify/diff.d.ts.map +1 -0
  278. package/dist/verify/diff.js +157 -0
  279. package/dist/verify/index.d.ts +17 -0
  280. package/dist/verify/index.d.ts.map +1 -0
  281. package/dist/verify/index.js +24 -0
  282. package/dist/verify/report.d.ts +14 -0
  283. package/dist/verify/report.d.ts.map +1 -0
  284. package/dist/verify/report.js +88 -0
  285. package/dist/verify/types.d.ts +101 -0
  286. package/dist/verify/types.d.ts.map +1 -0
  287. package/dist/verify/types.js +17 -0
  288. package/dist/verify/verify.d.ts +29 -0
  289. package/dist/verify/verify.d.ts.map +1 -0
  290. package/dist/verify/verify.js +148 -0
  291. package/dist/watch/evaluate.d.ts +162 -3
  292. package/dist/watch/evaluate.d.ts.map +1 -1
  293. package/dist/watch/evaluate.js +61 -0
  294. package/dist/watch/monitor.d.ts +116 -0
  295. package/dist/watch/monitor.d.ts.map +1 -0
  296. package/dist/watch/monitor.js +199 -0
  297. package/dist/watch/proposals.d.ts +20 -4
  298. package/dist/watch/proposals.d.ts.map +1 -1
  299. package/dist/watch/proposals.js +31 -3
  300. package/dist/watch/run.d.ts +33 -0
  301. package/dist/watch/run.d.ts.map +1 -1
  302. package/dist/watch/run.js +39 -0
  303. package/package.json +7 -1
  304. package/registry/LICENSE +20 -0
  305. package/registry/leaderboard.json +3639 -0
  306. package/registry/registry.json +7263 -0
  307. package/dist/telemetry/supabase-exporter.d.ts +0 -64
  308. package/dist/telemetry/supabase-exporter.d.ts.map +0 -1
  309. package/dist/telemetry/supabase-exporter.js +0 -211
@@ -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.maxOutputTokens ?? DEFAULT_MAX_TOKENS,
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;AAIhE;;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,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;CACP;AAOD;;2DAE2D;AAC3D,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,YAAY,EACjB,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,GACxC,wBAAwB,CA4B1B;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,CAqH5F"}
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.maxOutputTokens ?? DEFAULT_MAX_TOKENS,
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;AAEhE,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,CAc9E;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,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;CACH;AAID,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,kBAAkB,CAoCtF;AAcD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,eAAe,CAiJhF"}
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"}