@oh-my-pi/pi-catalog 16.1.21 → 16.1.23

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 CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [16.1.23] - 2026-06-26
6
+
7
+ ### Added
8
+
9
+ - Added `OpenAICompat.qwenPreserveThinking` — auto-enabled when the resolved `thinkingFormat` is `"qwen"` or `"qwen-chat-template"` AND `replayReasoningContent` is on (i.e. the four built-in local OpenAI-compatible providers, or a custom provider pointed at a loopback / RFC1918 / `*.local` baseUrl). Pairs with the chat-completions encoder change so the request body carries `preserve_thinking: true` (twin top-level + `chat_template_kwargs` emission), keeping Qwen3.6+ from stripping `<think>...</think>` off older assistant turns and breaking the local slot's KV cache between user messages. Non-Qwen chat templates ignore the parameter, so the flag stays a no-op outside the Qwen path; users on a cloud Qwen host (Alibaba Dashscope / Qwen Portal) can opt in with `compat.qwenPreserveThinking: true`. ([#3541](https://github.com/can1357/oh-my-pi/issues/3541))
10
+ - Added CoreWeave Serverless Inference as an OpenAI-compatible provider with models.dev-backed bundled catalog metadata.
11
+
12
+ ## [16.1.22] - 2026-06-26
13
+
14
+ ### Added
15
+
16
+ - Added `OpenAICompat.replayReasoningContent` — auto-enabled for the built-in local OpenAI-compatible providers (`llama.cpp`, `lm-studio`, `vllm`, `ollama` on `openai-completions`) and for any provider pointed at a loopback / RFC1918 / `*.local` baseUrl. NOT gated on `spec.reasoning`: the runtime discovery paths for `llama.cpp` / `lm-studio` / `openai-models-list` hardcode `reasoning: false` because the upstream `/models` endpoints don't advertise the capability, while the stream parser still records incoming `reasoning_content` deltas as thinking blocks — gating on the spec flag would leave every discovered local Qwen / DeepSeek model re-triggering #3528. The encoder only writes `reasoning_content` when a thinking block actually exists on the turn, so the flag is a no-op on pure-text histories. Built-in proxy providers (currently `litellm`) are excluded from both checks because they forward to an unrelated upstream that gains no KV-cache benefit and may 400 on the extra field; users running a custom proxy in front of a llama.cpp-style backend can opt in via the sparse `compat.replayReasoningContent: true` override. Signals to the `openai-completions` encoder that preserved `thinking` blocks must be re-emitted as `reasoning_content` on every assistant turn so chat templates that reconstruct `<think>…</think>` from the field (Qwen3, DeepSeek-R1, GLM-5.x) keep the prior turn's tokens byte-stable and llama.cpp's prefix KV cache survives. ([#3528](https://github.com/can1357/oh-my-pi/issues/3528))
17
+
5
18
  ## [16.1.20] - 2026-06-25
6
19
 
7
20
  ### Fixed
@@ -12,5 +12,6 @@ export * from "./types";
12
12
  export * from "./utils";
13
13
  export * from "./variant-collapse";
14
14
  export * from "./wire/codex";
15
+ export * from "./wire/coreweave";
15
16
  export * from "./wire/gemini-headers";
16
17
  export * from "./wire/github-copilot";
@@ -339,6 +339,14 @@ export declare const CATALOG_PROVIDERS: readonly [{
339
339
  readonly label: "Wafer Serverless";
340
340
  readonly oauthProvider: "wafer-serverless";
341
341
  };
342
+ }, {
343
+ readonly id: "coreweave";
344
+ readonly defaultModel: "openai/gpt-oss-120b";
345
+ readonly envVars: readonly ["COREWEAVE_API_KEY", "WANDB_API_KEY"];
346
+ readonly createModelManagerOptions: (config: ModelManagerConfig) => import("..").ModelManagerOptions<"openai-completions", unknown>;
347
+ readonly catalogDiscovery: {
348
+ readonly label: "CoreWeave Serverless Inference";
349
+ };
342
350
  }, {
343
351
  readonly id: "xai";
344
352
  readonly defaultModel: "grok-4-fast-non-reasoning";
@@ -34,10 +34,12 @@ export interface ModelsDevModel {
34
34
  * by the generator's policy pass (scripts/generated-policies.ts).
35
35
  */
36
36
  export declare const ANTHROPIC_CURATED_FALLBACK_MODELS: readonly ModelSpec<"anthropic-messages">[];
37
+ type SimpleProviderDiscoveryHeaders = Record<string, string> | (() => Record<string, string> | undefined);
37
38
  type SimpleProviderConfig = {
38
39
  apiKey?: string;
39
40
  baseUrl?: string;
40
41
  fetch?: FetchImpl;
42
+ headers?: SimpleProviderDiscoveryHeaders;
41
43
  };
42
44
  export declare function createSimpleOpenAICompletionsOptions(providerId: Parameters<typeof getBundledModels>[0], defaultBaseUrl: string, config?: SimpleProviderConfig): ModelManagerOptions<"openai-completions">;
43
45
  export interface UmansModelManagerConfig {
@@ -307,6 +309,12 @@ export interface TogetherModelManagerConfig {
307
309
  fetch?: FetchImpl;
308
310
  }
309
311
  export declare function togetherModelManagerOptions(config?: TogetherModelManagerConfig): ModelManagerOptions<"openai-completions">;
312
+ export interface CoreWeaveModelManagerConfig {
313
+ apiKey?: string;
314
+ baseUrl?: string;
315
+ fetch?: FetchImpl;
316
+ }
317
+ export declare function coreWeaveModelManagerOptions(config?: CoreWeaveModelManagerConfig): ModelManagerOptions<"openai-completions">;
310
318
  export interface MoonshotModelManagerConfig {
311
319
  apiKey?: string;
312
320
  baseUrl?: string;
@@ -185,6 +185,42 @@ export interface OpenAICompat {
185
185
  requiresReasoningContentForAllAssistantTurns?: boolean;
186
186
  /** Whether the provider accepts a synthetic placeholder (e.g. ".") for missing reasoning_content on tool-call turns. Default: true. Set to false for providers like DeepSeek that validate the exact reasoning_content value. */
187
187
  allowsSyntheticReasoningContentForToolCalls?: boolean;
188
+ /**
189
+ * Replay preserved thinking blocks as `reasoning_content` (or the configured
190
+ * `reasoningContentField`) on EVERY assistant turn that carried reasoning,
191
+ * regardless of whether the upstream provider validates the field. Local
192
+ * llama.cpp-style servers (llama.cpp, LM Studio, vLLM, sglang, Ollama in
193
+ * openai-completions mode) re-tokenize the full chat-template prompt every
194
+ * request; Qwen3 / DeepSeek-R1 / GLM templates reconstruct the `<think>`
195
+ * block from `reasoning_content`. Dropping the field re-renders the
196
+ * assistant turn without `<think>`, diverging from the slot's KV cache state
197
+ * and forcing full prompt re-processing (#3528). Default: auto-detected
198
+ * (loopback/private baseUrl or local provider id with thinking-enabled
199
+ * models).
200
+ */
201
+ replayReasoningContent?: boolean;
202
+ /**
203
+ * Send `preserve_thinking: true` so the Qwen3.6+ chat template renders
204
+ * `<think>...</think>` markup for EVERY assistant turn (not just turns
205
+ * after the last user message). Without it, the template strips the think
206
+ * block from older assistant turns:
207
+ *
208
+ * ```jinja
209
+ * {%- if (preserve_thinking is defined and preserve_thinking is true)
210
+ * or (loop.index0 > ns.last_query_index) %}
211
+ * <|im_start|>assistant\n<think>\n{rc}\n</think>\n\n{content}
212
+ * {%- else %}
213
+ * <|im_start|>assistant\n{content}
214
+ * ```
215
+ *
216
+ * The cache from the original generation has `<think>...</think>` tokens,
217
+ * so once a new user message arrives the prior assistant turns become
218
+ * "older" and the stripped re-render diverges — full prompt re-processing
219
+ * on SWA models (#3541). Default: auto-detected (Qwen thinking format on
220
+ * a local llama.cpp-style backend, paired with `replayReasoningContent`).
221
+ * Non-Qwen templates ignore the flag, so the auto-detection is safe.
222
+ */
223
+ qwenPreserveThinking?: boolean;
188
224
  /** Whether assistant tool-call messages must include non-empty content. Default: false. */
189
225
  requiresAssistantContentForToolCalls?: boolean;
190
226
  /** Whether the provider supports the `tool_choice` parameter. Default: true. */
@@ -391,6 +427,8 @@ export interface ResolvedOpenAISharedCompat {
391
427
  requiresReasoningContentForToolCalls: boolean;
392
428
  requiresReasoningContentForAllAssistantTurns: boolean;
393
429
  allowsSyntheticReasoningContentForToolCalls: boolean;
430
+ replayReasoningContent: boolean;
431
+ qwenPreserveThinking: boolean;
394
432
  requiresThinkingAsText: boolean;
395
433
  requiresMistralToolIds: boolean;
396
434
  requiresToolResultName: boolean;
@@ -418,7 +456,7 @@ export interface ResolvedOpenAISharedCompat {
418
456
  * `buildModel`; request handlers read fields and never detect, resolve, or
419
457
  * allocate.
420
458
  */
421
- export type ResolvedOpenAICompat = ResolvedOpenAISharedCompat & Required<Omit<OpenAICompat, "supportsDeveloperRole" | "supportsReasoningEffort" | "reasoningEffortMap" | "supportsReasoningParams" | "thinkingFormat" | "reasoningDisableMode" | "omitReasoningEffort" | "includeEncryptedReasoning" | "filterReasoningHistory" | "disableReasoningOnForcedToolChoice" | "disableReasoningOnToolChoice" | "supportsToolChoice" | "supportsForcedToolChoice" | "reasoningContentField" | "requiresReasoningContentForToolCalls" | "requiresReasoningContentForAllAssistantTurns" | "allowsSyntheticReasoningContentForToolCalls" | "requiresThinkingAsText" | "requiresMistralToolIds" | "requiresToolResultName" | "requiresAssistantAfterToolResult" | "requiresAssistantContentForToolCalls" | "stripDeepseekSpecialTokens" | "streamMarkupHealingPattern" | "reasoningDeltasMayBeCumulative" | "emptyLengthFinishIsContextError" | "usesOpenAIToolCallIdLimit" | "promptCacheSessionHeader" | "openRouterRouting" | "isOpenRouterHost" | "supportsStrictMode" | "supportsLongPromptCacheRetention" | "alwaysSendMaxTokens" | "wireModelIdMode" | "vercelGatewayRouting" | "extraBody" | "toolStrictMode" | "toolSchemaFlavor" | "streamIdleTimeoutMs" | "cacheControlFormat" | "thinkingKeep" | "strictResponsesPairing" | "supportsImageDetailOriginal" | "requiresJuiceZeroHack" | "enableGeminiThinkingLoopGuard" | "whenThinking">> & {
459
+ export type ResolvedOpenAICompat = ResolvedOpenAISharedCompat & Required<Omit<OpenAICompat, "supportsDeveloperRole" | "supportsReasoningEffort" | "reasoningEffortMap" | "supportsReasoningParams" | "thinkingFormat" | "reasoningDisableMode" | "omitReasoningEffort" | "includeEncryptedReasoning" | "filterReasoningHistory" | "disableReasoningOnForcedToolChoice" | "disableReasoningOnToolChoice" | "supportsToolChoice" | "supportsForcedToolChoice" | "reasoningContentField" | "requiresReasoningContentForToolCalls" | "requiresReasoningContentForAllAssistantTurns" | "allowsSyntheticReasoningContentForToolCalls" | "replayReasoningContent" | "qwenPreserveThinking" | "requiresThinkingAsText" | "requiresMistralToolIds" | "requiresToolResultName" | "requiresAssistantAfterToolResult" | "requiresAssistantContentForToolCalls" | "stripDeepseekSpecialTokens" | "streamMarkupHealingPattern" | "reasoningDeltasMayBeCumulative" | "emptyLengthFinishIsContextError" | "usesOpenAIToolCallIdLimit" | "promptCacheSessionHeader" | "openRouterRouting" | "isOpenRouterHost" | "supportsStrictMode" | "supportsLongPromptCacheRetention" | "alwaysSendMaxTokens" | "wireModelIdMode" | "vercelGatewayRouting" | "extraBody" | "toolStrictMode" | "toolSchemaFlavor" | "streamIdleTimeoutMs" | "cacheControlFormat" | "thinkingKeep" | "strictResponsesPairing" | "supportsImageDetailOriginal" | "requiresJuiceZeroHack" | "enableGeminiThinkingLoopGuard" | "whenThinking">> & {
422
460
  vercelGatewayRouting?: OpenAICompat["vercelGatewayRouting"];
423
461
  extraBody?: OpenAICompat["extraBody"];
424
462
  cacheControlFormat?: OpenAICompat["cacheControlFormat"];
@@ -0,0 +1,11 @@
1
+ export declare const COREWEAVE_PROJECT_HEADER: "OpenAI-Project";
2
+ export interface CoreWeaveProjectEnv {
3
+ [key: string]: string | undefined;
4
+ COREWEAVE_PROJECT?: string;
5
+ WANDB_INFERENCE_PROJECT?: string;
6
+ WANDB_ENTITY?: string;
7
+ WANDB_PROJECT?: string;
8
+ }
9
+ export declare function resolveCoreWeaveProject(env: CoreWeaveProjectEnv): string | undefined;
10
+ export declare function coreWeaveProjectHeaders(env: CoreWeaveProjectEnv): Record<string, string> | undefined;
11
+ export declare function hasCoreWeaveProjectHeader(headers: Record<string, string>): boolean;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-catalog",
4
- "version": "16.1.21",
4
+ "version": "16.1.23",
5
5
  "description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -34,12 +34,12 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "@bufbuild/protobuf": "^2.12.0",
37
- "@oh-my-pi/pi-utils": "16.1.21",
37
+ "@oh-my-pi/pi-utils": "16.1.23",
38
38
  "arktype": "^2.2.0",
39
39
  "zod": "^4"
40
40
  },
41
41
  "devDependencies": {
42
- "@oh-my-pi/pi-ai": "16.1.21",
42
+ "@oh-my-pi/pi-ai": "16.1.23",
43
43
  "@types/bun": "^1.3.14"
44
44
  },
45
45
  "engines": {
@@ -166,6 +166,53 @@ function detectStrictModeSupport(provider: string, baseUrl: string): boolean {
166
166
  );
167
167
  }
168
168
 
169
+ /**
170
+ * Local OpenAI-compatible inference servers whose chat templates re-tokenize
171
+ * the entire prompt every request — llama.cpp prefix-KV-cache reuse only
172
+ * survives when the rendered tokens stay byte-identical across turns. The
173
+ * runtime auto-enables {@link OpenAICompat.replayReasoningContent} for these
174
+ * providers (and for any provider pointed at a loopback / RFC1918 baseUrl) so
175
+ * Qwen3 / DeepSeek-R1 / GLM templates can reconstruct the prior assistant
176
+ * turn's `<think>` block from `reasoning_content` (#3528).
177
+ */
178
+ const LOCAL_OPENAI_COMPAT_PROVIDERS = new Set(["llama.cpp", "lm-studio", "vllm", "ollama"]);
179
+
180
+ /**
181
+ * Local proxy providers that share the loopback-default baseUrl but forward
182
+ * to an unrelated upstream (OpenAI, Anthropic, …) rather than running a
183
+ * chat-template renderer themselves — `replayReasoningContent` would push
184
+ * `reasoning_content` to the upstream, which gains no KV-cache benefit and
185
+ * may 400 on the extra field. Excluded from BOTH the provider check above
186
+ * and the loopback heuristic below; users who want the replay on a custom
187
+ * proxy setup can opt in via the sparse `compat.replayReasoningContent`
188
+ * override.
189
+ */
190
+ const PROXY_OPENAI_COMPAT_PROVIDERS = new Set(["litellm"]);
191
+
192
+ function hasLocalLoopbackBaseUrl(baseUrl: string | undefined): boolean {
193
+ if (!baseUrl) return false;
194
+ let hostname: string;
195
+ try {
196
+ hostname = new URL(baseUrl).hostname.toLowerCase();
197
+ } catch {
198
+ return false;
199
+ }
200
+ if (
201
+ hostname === "localhost" ||
202
+ hostname === "127.0.0.1" ||
203
+ hostname === "0.0.0.0" ||
204
+ hostname === "::1" ||
205
+ hostname === "[::1]"
206
+ ) {
207
+ return true;
208
+ }
209
+ if (/^10\./.test(hostname)) return true;
210
+ if (/^192\.168\./.test(hostname)) return true;
211
+ if (/^172\.(1[6-9]|2[0-9]|3[01])\./.test(hostname)) return true;
212
+ if (hostname.endsWith(".local")) return true;
213
+ return false;
214
+ }
215
+
169
216
  /**
170
217
  * Build the resolved chat-completions compat record for a model spec.
171
218
  * Provider takes precedence over URL-based detection since it's explicitly configured.
@@ -400,6 +447,41 @@ export function buildOpenAICompat(spec: ModelSpec<"openai-completions">): Resolv
400
447
  // DeepSeek V4 and Xiaomi MiMo reject synthetic reasoning_content placeholders (".") on tool-call turns.
401
448
  // Kimi and OpenRouter accept them when actual reasoning is unavailable.
402
449
  allowsSyntheticReasoningContentForToolCalls: (!isDeepseekFamily || !spec.reasoning) && !isXiaomiMimo,
450
+ // Local llama.cpp-style servers re-tokenize the entire chat-template
451
+ // prompt each request; Qwen3 / DeepSeek-R1 / GLM templates reconstruct
452
+ // the prior assistant turn's `<think>` block from `reasoning_content`,
453
+ // so dropping the field re-renders the assistant turn without thinking
454
+ // content and forces full prompt re-processing (#3528). The
455
+ // `requires*ReasoningContent*` flags above stay off for these hosts —
456
+ // they accept but don't validate the field — so the encoder needs a
457
+ // distinct opt-in to replay on every reasoning turn. NOT gated on
458
+ // `spec.reasoning`: the runtime discovery paths for `llama.cpp` /
459
+ // `lm-studio` / `openai-models-list` hardcode `reasoning: false`
460
+ // because the upstream `/models` endpoints don't advertise the
461
+ // capability, but the OpenAI stream parser still records incoming
462
+ // `reasoning_content` deltas as thinking blocks. Gating on the spec
463
+ // flag would leave every discovered local Qwen / DeepSeek model
464
+ // re-triggering #3528. The encoder only writes `reasoning_content`
465
+ // when a thinking block actually exists on the turn
466
+ // (`nonEmptyThinkingBlocks.length > 0`), so the flag is a no-op on
467
+ // pure-text histories.
468
+ replayReasoningContent:
469
+ !PROXY_OPENAI_COMPAT_PROVIDERS.has(provider) &&
470
+ (LOCAL_OPENAI_COMPAT_PROVIDERS.has(provider) || hasLocalLoopbackBaseUrl(baseUrl)),
471
+ // `preserve_thinking: true` makes the Qwen3.6+ chat template render
472
+ // `<think>...</think>` for older assistant turns too, instead of
473
+ // stripping it the moment a new user message moves them past
474
+ // `last_query_index`. Without it, the slot's KV cache (which holds the
475
+ // raw `<think>X</think>` tokens emitted during generation) diverges
476
+ // from the next-turn render and llama.cpp falls back to full prompt
477
+ // re-processing — the exact symptom reported in #3541. Auto-enabled
478
+ // for Qwen thinking dialects on local llama.cpp-style backends (paired
479
+ // with `replayReasoningContent` above). Non-Qwen templates ignore the
480
+ // parameter, so the flag stays a no-op outside the Qwen path.
481
+ qwenPreserveThinking:
482
+ (thinkingFormat === "qwen" || thinkingFormat === "qwen-chat-template") &&
483
+ !PROXY_OPENAI_COMPAT_PROVIDERS.has(provider) &&
484
+ (LOCAL_OPENAI_COMPAT_PROVIDERS.has(provider) || hasLocalLoopbackBaseUrl(baseUrl)),
403
485
  requiresAssistantContentForToolCalls: isKimiModel || isDirectDeepseekReasoning,
404
486
  cacheControlFormat: isOpenRouter && spec.id.startsWith("anthropic/") ? "anthropic" : undefined,
405
487
  openRouterRouting: undefined,
@@ -517,6 +599,13 @@ export function buildOpenAIResponsesCompat(spec: OpenAIResponsesSpecLike): Resol
517
599
  reasoningCapable,
518
600
  requiresReasoningContentForAllAssistantTurns: isDeepseekFamily && reasoningCapable && !isOpenRouter,
519
601
  allowsSyntheticReasoningContentForToolCalls: !isDeepseekFamily || !reasoningCapable,
602
+ // The Responses API replays reasoning through encrypted `summary` items,
603
+ // not via a top-level `reasoning_content` field — this flag is
604
+ // chat-completions-only.
605
+ replayReasoningContent: false,
606
+ // Responses-only; the Qwen `preserve_thinking` template knob lives on
607
+ // the chat-completions wire shape, never on Responses.
608
+ qwenPreserveThinking: false,
520
609
  requiresThinkingAsText: false,
521
610
  requiresMistralToolIds: false,
522
611
  requiresToolResultName: false,
package/src/index.ts CHANGED
@@ -12,5 +12,6 @@ export * from "./types";
12
12
  export * from "./utils";
13
13
  export * from "./variant-collapse";
14
14
  export * from "./wire/codex";
15
+ export * from "./wire/coreweave";
15
16
  export * from "./wire/gemini-headers";
16
17
  export * from "./wire/github-copilot";
package/src/models.json CHANGED
@@ -13487,6 +13487,802 @@
13487
13487
  }
13488
13488
  }
13489
13489
  },
13490
+ "coreweave": {
13491
+ "deepseek-ai/DeepSeek-V3.1": {
13492
+ "id": "deepseek-ai/DeepSeek-V3.1",
13493
+ "name": "DeepSeek V3.1",
13494
+ "api": "openai-completions",
13495
+ "provider": "coreweave",
13496
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13497
+ "reasoning": false,
13498
+ "input": [
13499
+ "text"
13500
+ ],
13501
+ "cost": {
13502
+ "input": 0.55,
13503
+ "output": 1.65,
13504
+ "cacheRead": 0,
13505
+ "cacheWrite": 0
13506
+ },
13507
+ "contextWindow": 161000,
13508
+ "maxTokens": 161000
13509
+ },
13510
+ "deepseek-ai/DeepSeek-V4-Flash": {
13511
+ "id": "deepseek-ai/DeepSeek-V4-Flash",
13512
+ "name": "DeepSeek V4 Flash",
13513
+ "api": "openai-completions",
13514
+ "provider": "coreweave",
13515
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13516
+ "reasoning": true,
13517
+ "input": [
13518
+ "text"
13519
+ ],
13520
+ "cost": {
13521
+ "input": 0,
13522
+ "output": 0,
13523
+ "cacheRead": 0,
13524
+ "cacheWrite": 0
13525
+ },
13526
+ "contextWindow": 1048576,
13527
+ "maxTokens": 384000,
13528
+ "thinking": {
13529
+ "mode": "effort",
13530
+ "efforts": [
13531
+ "minimal",
13532
+ "low",
13533
+ "medium",
13534
+ "high",
13535
+ "xhigh"
13536
+ ],
13537
+ "effortMap": {
13538
+ "minimal": "high",
13539
+ "low": "high",
13540
+ "medium": "high",
13541
+ "high": "high",
13542
+ "xhigh": "max"
13543
+ }
13544
+ }
13545
+ },
13546
+ "deepseek-ai/DeepSeek-V4-Pro": {
13547
+ "id": "deepseek-ai/DeepSeek-V4-Pro",
13548
+ "name": "DeepSeek V4 Pro",
13549
+ "api": "openai-completions",
13550
+ "provider": "coreweave",
13551
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13552
+ "reasoning": true,
13553
+ "input": [
13554
+ "text"
13555
+ ],
13556
+ "cost": {
13557
+ "input": 0,
13558
+ "output": 0,
13559
+ "cacheRead": 0,
13560
+ "cacheWrite": 0
13561
+ },
13562
+ "contextWindow": 1048576,
13563
+ "maxTokens": 393216,
13564
+ "thinking": {
13565
+ "mode": "effort",
13566
+ "efforts": [
13567
+ "minimal",
13568
+ "low",
13569
+ "medium",
13570
+ "high",
13571
+ "xhigh"
13572
+ ],
13573
+ "effortMap": {
13574
+ "minimal": "high",
13575
+ "low": "high",
13576
+ "medium": "high",
13577
+ "high": "high",
13578
+ "xhigh": "max"
13579
+ }
13580
+ }
13581
+ },
13582
+ "google/gemma-4-31B-it": {
13583
+ "id": "google/gemma-4-31B-it",
13584
+ "name": "Gemma 4 31B Instruct",
13585
+ "api": "openai-completions",
13586
+ "provider": "coreweave",
13587
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13588
+ "reasoning": true,
13589
+ "input": [
13590
+ "text",
13591
+ "image"
13592
+ ],
13593
+ "cost": {
13594
+ "input": 0,
13595
+ "output": 0,
13596
+ "cacheRead": 0,
13597
+ "cacheWrite": 0
13598
+ },
13599
+ "contextWindow": 262144,
13600
+ "maxTokens": 131072,
13601
+ "thinking": {
13602
+ "mode": "effort",
13603
+ "efforts": [
13604
+ "minimal",
13605
+ "low",
13606
+ "medium",
13607
+ "high",
13608
+ "xhigh"
13609
+ ]
13610
+ }
13611
+ },
13612
+ "ibm-granite/granite-4.1-8b": {
13613
+ "id": "ibm-granite/granite-4.1-8b",
13614
+ "name": "Granite 4.1 8B",
13615
+ "api": "openai-completions",
13616
+ "provider": "coreweave",
13617
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13618
+ "reasoning": false,
13619
+ "input": [
13620
+ "text"
13621
+ ],
13622
+ "cost": {
13623
+ "input": 0,
13624
+ "output": 0,
13625
+ "cacheRead": 0,
13626
+ "cacheWrite": 0
13627
+ },
13628
+ "contextWindow": 131072,
13629
+ "maxTokens": 131072
13630
+ },
13631
+ "JetBrains/Mellum2-12B-A2.5B-Instruct": {
13632
+ "id": "JetBrains/Mellum2-12B-A2.5B-Instruct",
13633
+ "name": "JetBrains/Mellum2-12B-A2.5B-Instruct",
13634
+ "api": "openai-completions",
13635
+ "provider": "coreweave",
13636
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13637
+ "reasoning": false,
13638
+ "input": [
13639
+ "text"
13640
+ ],
13641
+ "cost": {
13642
+ "input": 0,
13643
+ "output": 0,
13644
+ "cacheRead": 0,
13645
+ "cacheWrite": 0
13646
+ },
13647
+ "contextWindow": null,
13648
+ "maxTokens": null
13649
+ },
13650
+ "meta-llama/Llama-3.1-70B-Instruct": {
13651
+ "id": "meta-llama/Llama-3.1-70B-Instruct",
13652
+ "name": "Llama 3.1 70B",
13653
+ "api": "openai-completions",
13654
+ "provider": "coreweave",
13655
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13656
+ "reasoning": false,
13657
+ "input": [
13658
+ "text"
13659
+ ],
13660
+ "cost": {
13661
+ "input": 0.8,
13662
+ "output": 0.8,
13663
+ "cacheRead": 0,
13664
+ "cacheWrite": 0
13665
+ },
13666
+ "contextWindow": 128000,
13667
+ "maxTokens": 128000
13668
+ },
13669
+ "meta-llama/Llama-3.1-8B-Instruct": {
13670
+ "id": "meta-llama/Llama-3.1-8B-Instruct",
13671
+ "name": "Meta-Llama-3.1-8B-Instruct",
13672
+ "api": "openai-completions",
13673
+ "provider": "coreweave",
13674
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13675
+ "reasoning": true,
13676
+ "input": [
13677
+ "text"
13678
+ ],
13679
+ "cost": {
13680
+ "input": 0.22,
13681
+ "output": 0.22,
13682
+ "cacheRead": 0,
13683
+ "cacheWrite": 0
13684
+ },
13685
+ "contextWindow": 128000,
13686
+ "maxTokens": 128000,
13687
+ "thinking": {
13688
+ "mode": "effort",
13689
+ "efforts": [
13690
+ "minimal",
13691
+ "low",
13692
+ "medium",
13693
+ "high",
13694
+ "xhigh"
13695
+ ]
13696
+ }
13697
+ },
13698
+ "meta-llama/Llama-3.3-70B-Instruct": {
13699
+ "id": "meta-llama/Llama-3.3-70B-Instruct",
13700
+ "name": "Llama-3.3-70B-Instruct",
13701
+ "api": "openai-completions",
13702
+ "provider": "coreweave",
13703
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13704
+ "reasoning": true,
13705
+ "input": [
13706
+ "text"
13707
+ ],
13708
+ "cost": {
13709
+ "input": 0.71,
13710
+ "output": 0.71,
13711
+ "cacheRead": 0,
13712
+ "cacheWrite": 0
13713
+ },
13714
+ "contextWindow": 128000,
13715
+ "maxTokens": 128000,
13716
+ "thinking": {
13717
+ "mode": "effort",
13718
+ "efforts": [
13719
+ "minimal",
13720
+ "low",
13721
+ "medium",
13722
+ "high",
13723
+ "xhigh"
13724
+ ]
13725
+ }
13726
+ },
13727
+ "meta-llama/Llama-4-Scout-17B-16E-Instruct": {
13728
+ "id": "meta-llama/Llama-4-Scout-17B-16E-Instruct",
13729
+ "name": "Llama 4 Scout 17B 16E Instruct",
13730
+ "api": "openai-completions",
13731
+ "provider": "coreweave",
13732
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13733
+ "reasoning": true,
13734
+ "input": [
13735
+ "text",
13736
+ "image"
13737
+ ],
13738
+ "cost": {
13739
+ "input": 0.17,
13740
+ "output": 0.66,
13741
+ "cacheRead": 0,
13742
+ "cacheWrite": 0
13743
+ },
13744
+ "contextWindow": 64000,
13745
+ "maxTokens": 64000,
13746
+ "thinking": {
13747
+ "mode": "effort",
13748
+ "efforts": [
13749
+ "minimal",
13750
+ "low",
13751
+ "medium",
13752
+ "high",
13753
+ "xhigh"
13754
+ ]
13755
+ }
13756
+ },
13757
+ "microsoft/Phi-4-mini-instruct": {
13758
+ "id": "microsoft/Phi-4-mini-instruct",
13759
+ "name": "Phi-4-mini-instruct",
13760
+ "api": "openai-completions",
13761
+ "provider": "coreweave",
13762
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13763
+ "reasoning": true,
13764
+ "input": [
13765
+ "text"
13766
+ ],
13767
+ "cost": {
13768
+ "input": 0.08,
13769
+ "output": 0.35,
13770
+ "cacheRead": 0,
13771
+ "cacheWrite": 0
13772
+ },
13773
+ "contextWindow": 128000,
13774
+ "maxTokens": 128000,
13775
+ "thinking": {
13776
+ "mode": "effort",
13777
+ "efforts": [
13778
+ "minimal",
13779
+ "low",
13780
+ "medium",
13781
+ "high",
13782
+ "xhigh"
13783
+ ]
13784
+ }
13785
+ },
13786
+ "MiniMaxAI/MiniMax-M2.5": {
13787
+ "id": "MiniMaxAI/MiniMax-M2.5",
13788
+ "name": "MiniMax M2.5",
13789
+ "api": "openai-completions",
13790
+ "provider": "coreweave",
13791
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13792
+ "reasoning": false,
13793
+ "input": [
13794
+ "text"
13795
+ ],
13796
+ "cost": {
13797
+ "input": 0.3,
13798
+ "output": 1.2,
13799
+ "cacheRead": 0,
13800
+ "cacheWrite": 0
13801
+ },
13802
+ "contextWindow": 196608,
13803
+ "maxTokens": 196608
13804
+ },
13805
+ "moonshotai/Kimi-K2.5": {
13806
+ "id": "moonshotai/Kimi-K2.5",
13807
+ "name": "Kimi K2.5",
13808
+ "api": "openai-completions",
13809
+ "provider": "coreweave",
13810
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13811
+ "reasoning": true,
13812
+ "input": [
13813
+ "text",
13814
+ "image"
13815
+ ],
13816
+ "cost": {
13817
+ "input": 0.5,
13818
+ "output": 2.85,
13819
+ "cacheRead": 0,
13820
+ "cacheWrite": 0
13821
+ },
13822
+ "contextWindow": 262144,
13823
+ "maxTokens": 262144,
13824
+ "thinking": {
13825
+ "mode": "effort",
13826
+ "efforts": [
13827
+ "minimal",
13828
+ "low",
13829
+ "medium",
13830
+ "high",
13831
+ "xhigh"
13832
+ ]
13833
+ }
13834
+ },
13835
+ "moonshotai/Kimi-K2.6": {
13836
+ "id": "moonshotai/Kimi-K2.6",
13837
+ "name": "Kimi-K2.6",
13838
+ "api": "openai-completions",
13839
+ "provider": "coreweave",
13840
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13841
+ "reasoning": true,
13842
+ "input": [
13843
+ "text",
13844
+ "image"
13845
+ ],
13846
+ "cost": {
13847
+ "input": 0,
13848
+ "output": 0,
13849
+ "cacheRead": 0,
13850
+ "cacheWrite": 0
13851
+ },
13852
+ "contextWindow": 262144,
13853
+ "maxTokens": 262144,
13854
+ "thinking": {
13855
+ "mode": "effort",
13856
+ "efforts": [
13857
+ "minimal",
13858
+ "low",
13859
+ "medium",
13860
+ "high",
13861
+ "xhigh"
13862
+ ]
13863
+ }
13864
+ },
13865
+ "moonshotai/Kimi-K2.7-Code": {
13866
+ "id": "moonshotai/Kimi-K2.7-Code",
13867
+ "name": "Kimi K2.7 Code",
13868
+ "api": "openai-completions",
13869
+ "provider": "coreweave",
13870
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13871
+ "reasoning": true,
13872
+ "input": [
13873
+ "text",
13874
+ "image"
13875
+ ],
13876
+ "cost": {
13877
+ "input": 0,
13878
+ "output": 0,
13879
+ "cacheRead": 0,
13880
+ "cacheWrite": 0
13881
+ },
13882
+ "contextWindow": 262144,
13883
+ "maxTokens": 262144,
13884
+ "thinking": {
13885
+ "mode": "effort",
13886
+ "efforts": [
13887
+ "minimal",
13888
+ "low",
13889
+ "medium",
13890
+ "high",
13891
+ "xhigh"
13892
+ ]
13893
+ }
13894
+ },
13895
+ "nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-FP8": {
13896
+ "id": "nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-FP8",
13897
+ "name": "NVIDIA Nemotron 3 Super 120B",
13898
+ "api": "openai-completions",
13899
+ "provider": "coreweave",
13900
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13901
+ "reasoning": false,
13902
+ "input": [
13903
+ "text"
13904
+ ],
13905
+ "cost": {
13906
+ "input": 0.2,
13907
+ "output": 0.8,
13908
+ "cacheRead": 0,
13909
+ "cacheWrite": 0
13910
+ },
13911
+ "contextWindow": 262144,
13912
+ "maxTokens": 262144
13913
+ },
13914
+ "nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B": {
13915
+ "id": "nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B",
13916
+ "name": "nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B",
13917
+ "api": "openai-completions",
13918
+ "provider": "coreweave",
13919
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13920
+ "reasoning": false,
13921
+ "input": [
13922
+ "text"
13923
+ ],
13924
+ "cost": {
13925
+ "input": 0,
13926
+ "output": 0,
13927
+ "cacheRead": 0,
13928
+ "cacheWrite": 0
13929
+ },
13930
+ "contextWindow": null,
13931
+ "maxTokens": null
13932
+ },
13933
+ "openai/gpt-oss-120b": {
13934
+ "id": "openai/gpt-oss-120b",
13935
+ "name": "gpt-oss-120b",
13936
+ "api": "openai-completions",
13937
+ "provider": "coreweave",
13938
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13939
+ "reasoning": true,
13940
+ "input": [
13941
+ "text"
13942
+ ],
13943
+ "cost": {
13944
+ "input": 0.15,
13945
+ "output": 0.6,
13946
+ "cacheRead": 0,
13947
+ "cacheWrite": 0
13948
+ },
13949
+ "contextWindow": 131072,
13950
+ "maxTokens": 131072,
13951
+ "thinking": {
13952
+ "mode": "effort",
13953
+ "efforts": [
13954
+ "low",
13955
+ "medium",
13956
+ "high"
13957
+ ]
13958
+ }
13959
+ },
13960
+ "openai/gpt-oss-20b": {
13961
+ "id": "openai/gpt-oss-20b",
13962
+ "name": "gpt-oss-20b",
13963
+ "api": "openai-completions",
13964
+ "provider": "coreweave",
13965
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13966
+ "reasoning": true,
13967
+ "input": [
13968
+ "text"
13969
+ ],
13970
+ "cost": {
13971
+ "input": 0.05,
13972
+ "output": 0.2,
13973
+ "cacheRead": 0,
13974
+ "cacheWrite": 0
13975
+ },
13976
+ "contextWindow": 131072,
13977
+ "maxTokens": 131072,
13978
+ "thinking": {
13979
+ "mode": "effort",
13980
+ "efforts": [
13981
+ "low",
13982
+ "medium",
13983
+ "high"
13984
+ ]
13985
+ }
13986
+ },
13987
+ "OpenPipe/Qwen3-14B-Instruct": {
13988
+ "id": "OpenPipe/Qwen3-14B-Instruct",
13989
+ "name": "OpenPipe Qwen3 14B Instruct",
13990
+ "api": "openai-completions",
13991
+ "provider": "coreweave",
13992
+ "baseUrl": "https://api.inference.wandb.ai/v1",
13993
+ "reasoning": false,
13994
+ "input": [
13995
+ "text"
13996
+ ],
13997
+ "cost": {
13998
+ "input": 0.05,
13999
+ "output": 0.22,
14000
+ "cacheRead": 0,
14001
+ "cacheWrite": 0
14002
+ },
14003
+ "contextWindow": 32768,
14004
+ "maxTokens": 32768
14005
+ },
14006
+ "Qwen/Qwen3-235B-A22B-Instruct-2507": {
14007
+ "id": "Qwen/Qwen3-235B-A22B-Instruct-2507",
14008
+ "name": "Qwen3 235B A22B Instruct 2507",
14009
+ "api": "openai-completions",
14010
+ "provider": "coreweave",
14011
+ "baseUrl": "https://api.inference.wandb.ai/v1",
14012
+ "reasoning": false,
14013
+ "input": [
14014
+ "text"
14015
+ ],
14016
+ "cost": {
14017
+ "input": 0.1,
14018
+ "output": 0.1,
14019
+ "cacheRead": 0,
14020
+ "cacheWrite": 0
14021
+ },
14022
+ "contextWindow": 262144,
14023
+ "maxTokens": 262144
14024
+ },
14025
+ "Qwen/Qwen3-235B-A22B-Thinking-2507": {
14026
+ "id": "Qwen/Qwen3-235B-A22B-Thinking-2507",
14027
+ "name": "Qwen3-235B-A22B-Thinking-2507",
14028
+ "api": "openai-completions",
14029
+ "provider": "coreweave",
14030
+ "baseUrl": "https://api.inference.wandb.ai/v1",
14031
+ "reasoning": true,
14032
+ "input": [
14033
+ "text"
14034
+ ],
14035
+ "cost": {
14036
+ "input": 0.1,
14037
+ "output": 0.1,
14038
+ "cacheRead": 0,
14039
+ "cacheWrite": 0
14040
+ },
14041
+ "contextWindow": 262144,
14042
+ "maxTokens": 262144,
14043
+ "thinking": {
14044
+ "mode": "effort",
14045
+ "efforts": [
14046
+ "minimal",
14047
+ "low",
14048
+ "medium",
14049
+ "high"
14050
+ ],
14051
+ "requiresEffort": true
14052
+ }
14053
+ },
14054
+ "Qwen/Qwen3-30B-A3B-Instruct-2507": {
14055
+ "id": "Qwen/Qwen3-30B-A3B-Instruct-2507",
14056
+ "name": "Qwen3 30B A3B Instruct 2507",
14057
+ "api": "openai-completions",
14058
+ "provider": "coreweave",
14059
+ "baseUrl": "https://api.inference.wandb.ai/v1",
14060
+ "reasoning": false,
14061
+ "input": [
14062
+ "text"
14063
+ ],
14064
+ "cost": {
14065
+ "input": 0.1,
14066
+ "output": 0.3,
14067
+ "cacheRead": 0,
14068
+ "cacheWrite": 0
14069
+ },
14070
+ "contextWindow": 262144,
14071
+ "maxTokens": 262144
14072
+ },
14073
+ "Qwen/Qwen3-Coder-480B-A35B-Instruct": {
14074
+ "id": "Qwen/Qwen3-Coder-480B-A35B-Instruct",
14075
+ "name": "Qwen3-Coder-480B-A35B-Instruct",
14076
+ "api": "openai-completions",
14077
+ "provider": "coreweave",
14078
+ "baseUrl": "https://api.inference.wandb.ai/v1",
14079
+ "reasoning": false,
14080
+ "input": [
14081
+ "text"
14082
+ ],
14083
+ "cost": {
14084
+ "input": 1,
14085
+ "output": 1.5,
14086
+ "cacheRead": 0,
14087
+ "cacheWrite": 0
14088
+ },
14089
+ "contextWindow": 262144,
14090
+ "maxTokens": 262144
14091
+ },
14092
+ "Qwen/Qwen3.5-27B": {
14093
+ "id": "Qwen/Qwen3.5-27B",
14094
+ "name": "Qwen3.5 27B",
14095
+ "api": "openai-completions",
14096
+ "provider": "coreweave",
14097
+ "baseUrl": "https://api.inference.wandb.ai/v1",
14098
+ "reasoning": true,
14099
+ "input": [
14100
+ "text",
14101
+ "image"
14102
+ ],
14103
+ "cost": {
14104
+ "input": 0,
14105
+ "output": 0,
14106
+ "cacheRead": 0,
14107
+ "cacheWrite": 0
14108
+ },
14109
+ "contextWindow": 262144,
14110
+ "maxTokens": 65536,
14111
+ "thinking": {
14112
+ "mode": "effort",
14113
+ "efforts": [
14114
+ "minimal",
14115
+ "low",
14116
+ "medium",
14117
+ "high"
14118
+ ]
14119
+ }
14120
+ },
14121
+ "Qwen/Qwen3.5-35B-A3B": {
14122
+ "id": "Qwen/Qwen3.5-35B-A3B",
14123
+ "name": "Qwen3.5 35B-A3B",
14124
+ "api": "openai-completions",
14125
+ "provider": "coreweave",
14126
+ "baseUrl": "https://api.inference.wandb.ai/v1",
14127
+ "reasoning": true,
14128
+ "input": [
14129
+ "text",
14130
+ "image"
14131
+ ],
14132
+ "cost": {
14133
+ "input": 0,
14134
+ "output": 0,
14135
+ "cacheRead": 0,
14136
+ "cacheWrite": 0
14137
+ },
14138
+ "contextWindow": 262144,
14139
+ "maxTokens": 65536,
14140
+ "thinking": {
14141
+ "mode": "effort",
14142
+ "efforts": [
14143
+ "minimal",
14144
+ "low",
14145
+ "medium",
14146
+ "high"
14147
+ ]
14148
+ }
14149
+ },
14150
+ "Qwen/Qwen3.6-27B": {
14151
+ "id": "Qwen/Qwen3.6-27B",
14152
+ "name": "Qwen3.6 27B",
14153
+ "api": "openai-completions",
14154
+ "provider": "coreweave",
14155
+ "baseUrl": "https://api.inference.wandb.ai/v1",
14156
+ "reasoning": true,
14157
+ "input": [
14158
+ "text",
14159
+ "image"
14160
+ ],
14161
+ "cost": {
14162
+ "input": 0,
14163
+ "output": 0,
14164
+ "cacheRead": 0,
14165
+ "cacheWrite": 0
14166
+ },
14167
+ "contextWindow": 262144,
14168
+ "maxTokens": 65536,
14169
+ "thinking": {
14170
+ "mode": "effort",
14171
+ "efforts": [
14172
+ "minimal",
14173
+ "low",
14174
+ "medium",
14175
+ "high"
14176
+ ]
14177
+ }
14178
+ },
14179
+ "Qwen/Qwen3.6-35B-A3B": {
14180
+ "id": "Qwen/Qwen3.6-35B-A3B",
14181
+ "name": "Qwen3.6 35B-A3B",
14182
+ "api": "openai-completions",
14183
+ "provider": "coreweave",
14184
+ "baseUrl": "https://api.inference.wandb.ai/v1",
14185
+ "reasoning": true,
14186
+ "input": [
14187
+ "text",
14188
+ "image"
14189
+ ],
14190
+ "cost": {
14191
+ "input": 0,
14192
+ "output": 0,
14193
+ "cacheRead": 0,
14194
+ "cacheWrite": 0
14195
+ },
14196
+ "contextWindow": 262144,
14197
+ "maxTokens": 65536,
14198
+ "thinking": {
14199
+ "mode": "effort",
14200
+ "efforts": [
14201
+ "minimal",
14202
+ "low",
14203
+ "medium",
14204
+ "high"
14205
+ ]
14206
+ }
14207
+ },
14208
+ "zai-org/GLM-5-FP8": {
14209
+ "id": "zai-org/GLM-5-FP8",
14210
+ "name": "GLM 5",
14211
+ "api": "openai-completions",
14212
+ "provider": "coreweave",
14213
+ "baseUrl": "https://api.inference.wandb.ai/v1",
14214
+ "reasoning": false,
14215
+ "input": [
14216
+ "text"
14217
+ ],
14218
+ "cost": {
14219
+ "input": 1,
14220
+ "output": 3.2,
14221
+ "cacheRead": 0,
14222
+ "cacheWrite": 0
14223
+ },
14224
+ "contextWindow": 200000,
14225
+ "maxTokens": 200000
14226
+ },
14227
+ "zai-org/GLM-5.1": {
14228
+ "id": "zai-org/GLM-5.1",
14229
+ "name": "GLM-5.1",
14230
+ "api": "openai-completions",
14231
+ "provider": "coreweave",
14232
+ "baseUrl": "https://api.inference.wandb.ai/v1",
14233
+ "reasoning": true,
14234
+ "input": [
14235
+ "text"
14236
+ ],
14237
+ "cost": {
14238
+ "input": 1.4,
14239
+ "output": 4.4,
14240
+ "cacheRead": 0.26,
14241
+ "cacheWrite": 0
14242
+ },
14243
+ "contextWindow": 200000,
14244
+ "maxTokens": 131072,
14245
+ "thinking": {
14246
+ "mode": "effort",
14247
+ "efforts": [
14248
+ "minimal",
14249
+ "low",
14250
+ "medium",
14251
+ "high",
14252
+ "xhigh"
14253
+ ]
14254
+ }
14255
+ },
14256
+ "zai-org/GLM-5.2": {
14257
+ "id": "zai-org/GLM-5.2",
14258
+ "name": "GLM-5.2",
14259
+ "api": "openai-completions",
14260
+ "provider": "coreweave",
14261
+ "baseUrl": "https://api.inference.wandb.ai/v1",
14262
+ "reasoning": true,
14263
+ "input": [
14264
+ "text"
14265
+ ],
14266
+ "cost": {
14267
+ "input": 0,
14268
+ "output": 0,
14269
+ "cacheRead": 0,
14270
+ "cacheWrite": 0
14271
+ },
14272
+ "contextWindow": 262144,
14273
+ "maxTokens": 164000,
14274
+ "thinking": {
14275
+ "mode": "effort",
14276
+ "efforts": [
14277
+ "minimal",
14278
+ "low",
14279
+ "medium",
14280
+ "high",
14281
+ "xhigh"
14282
+ ]
14283
+ }
14284
+ }
14285
+ },
13490
14286
  "cursor": {
13491
14287
  "claude-4.5-opus-high": {
13492
14288
  "id": "claude-4.5-opus-high",
@@ -87658,4 +88454,4 @@
87658
88454
  }
87659
88455
  }
87660
88456
  }
87661
- }
88457
+ }
@@ -14,6 +14,7 @@ import {
14
14
  anthropicModelManagerOptions,
15
15
  cerebrasModelManagerOptions,
16
16
  cloudflareAiGatewayModelManagerOptions,
17
+ coreWeaveModelManagerOptions,
17
18
  deepseekModelManagerOptions,
18
19
  firepassModelManagerOptions,
19
20
  fireworksModelManagerOptions,
@@ -375,6 +376,13 @@ export const CATALOG_PROVIDERS = [
375
376
  oauthProvider: "wafer-serverless",
376
377
  },
377
378
  },
379
+ {
380
+ id: "coreweave",
381
+ defaultModel: "openai/gpt-oss-120b",
382
+ envVars: ["COREWEAVE_API_KEY", "WANDB_API_KEY"],
383
+ createModelManagerOptions: (config: ModelManagerConfig) => coreWeaveModelManagerOptions(config),
384
+ catalogDiscovery: { label: "CoreWeave Serverless Inference" },
385
+ },
378
386
  {
379
387
  id: "xai",
380
388
  defaultModel: "grok-4-fast-non-reasoning",
@@ -10,6 +10,7 @@ import type { ModelManagerOptions } from "../model-manager";
10
10
  import { getBundledModels } from "../models";
11
11
  import type { Api, FetchImpl, Model, ModelSpec, Provider, ThinkingConfig } from "../types";
12
12
  import { isAnthropicOAuthToken, isRecord, toBoolean, toNumber, toPositiveNumber } from "../utils";
13
+ import { coreWeaveProjectHeaders } from "../wire/coreweave";
13
14
  import {
14
15
  COPILOT_API_HEADERS,
15
16
  getGitHubCopilotBaseUrl,
@@ -470,7 +471,19 @@ function isLikelyNanoGptTextModelId(id: string): boolean {
470
471
  return !NANO_GPT_NON_TEXT_MODEL_TOKENS.some(token => normalized.includes(token));
471
472
  }
472
473
 
473
- type SimpleProviderConfig = { apiKey?: string; baseUrl?: string; fetch?: FetchImpl };
474
+ type SimpleProviderDiscoveryHeaders = Record<string, string> | (() => Record<string, string> | undefined);
475
+ type SimpleProviderConfig = {
476
+ apiKey?: string;
477
+ baseUrl?: string;
478
+ fetch?: FetchImpl;
479
+ headers?: SimpleProviderDiscoveryHeaders;
480
+ };
481
+
482
+ function resolveSimpleProviderHeaders(
483
+ headers: SimpleProviderDiscoveryHeaders | undefined,
484
+ ): Record<string, string> | undefined {
485
+ return typeof headers === "function" ? headers() : headers;
486
+ }
474
487
 
475
488
  export function createSimpleOpenAICompletionsOptions(
476
489
  providerId: Parameters<typeof getBundledModels>[0],
@@ -489,6 +502,7 @@ export function createSimpleOpenAICompletionsOptions(
489
502
  provider: providerId,
490
503
  baseUrl,
491
504
  apiKey,
505
+ headers: resolveSimpleProviderHeaders(config?.headers),
492
506
  mapModel: (entry, defaults) => {
493
507
  const reference = references.get(defaults.id);
494
508
  return mapWithBundledReference(entry, defaults, reference);
@@ -516,6 +530,7 @@ function createSimpleOpenAIResponsesOptions(
516
530
  provider: providerId,
517
531
  baseUrl,
518
532
  apiKey,
533
+ headers: resolveSimpleProviderHeaders(config?.headers),
519
534
  mapModel: (entry, defaults) => {
520
535
  const reference = references.get(defaults.id);
521
536
  return mapWithBundledReference(entry, defaults, reference);
@@ -2480,6 +2495,25 @@ export function togetherModelManagerOptions(
2480
2495
  return createSimpleOpenAICompletionsOptions("together", "https://api.together.xyz/v1", config);
2481
2496
  }
2482
2497
 
2498
+ // ---------------------------------------------------------------------------
2499
+ // 15.5 CoreWeave Serverless Inference
2500
+ // ---------------------------------------------------------------------------
2501
+
2502
+ export interface CoreWeaveModelManagerConfig {
2503
+ apiKey?: string;
2504
+ baseUrl?: string;
2505
+ fetch?: FetchImpl;
2506
+ }
2507
+
2508
+ export function coreWeaveModelManagerOptions(
2509
+ config?: CoreWeaveModelManagerConfig,
2510
+ ): ModelManagerOptions<"openai-completions"> {
2511
+ return createSimpleOpenAICompletionsOptions("coreweave", "https://api.inference.wandb.ai/v1", {
2512
+ ...config,
2513
+ headers: () => coreWeaveProjectHeaders(Bun.env),
2514
+ });
2515
+ }
2516
+
2483
2517
  // ---------------------------------------------------------------------------
2484
2518
  // 16. Moonshot
2485
2519
  // ---------------------------------------------------------------------------
@@ -3653,6 +3687,19 @@ const MODELS_DEV_PROVIDER_DESCRIPTORS_CORE: readonly ModelsDevProviderDescriptor
3653
3687
  openAiCompletionsDescriptor("cerebras", "cerebras", "https://api.cerebras.ai/v1"),
3654
3688
  // --- Together ---
3655
3689
  openAiCompletionsDescriptor("togetherai", "together", "https://api.together.xyz/v1"),
3690
+ // --- CoreWeave Serverless Inference ---
3691
+ openAiCompletionsDescriptor("wandb", "coreweave", "https://api.inference.wandb.ai/v1", {
3692
+ transformModel: model => {
3693
+ if (!model.id.startsWith("openai/gpt-oss-")) {
3694
+ return model;
3695
+ }
3696
+ return {
3697
+ ...model,
3698
+ reasoning: true,
3699
+ thinking: { mode: "effort", efforts: [Effort.Low, Effort.Medium, Effort.High] },
3700
+ };
3701
+ },
3702
+ }),
3656
3703
  // --- NVIDIA ---
3657
3704
  openAiCompletionsDescriptor("nvidia", "nvidia", "https://integrate.api.nvidia.com/v1", {
3658
3705
  defaultContextWindow: 131072,
package/src/types.ts CHANGED
@@ -222,6 +222,42 @@ export interface OpenAICompat {
222
222
  requiresReasoningContentForAllAssistantTurns?: boolean;
223
223
  /** Whether the provider accepts a synthetic placeholder (e.g. ".") for missing reasoning_content on tool-call turns. Default: true. Set to false for providers like DeepSeek that validate the exact reasoning_content value. */
224
224
  allowsSyntheticReasoningContentForToolCalls?: boolean;
225
+ /**
226
+ * Replay preserved thinking blocks as `reasoning_content` (or the configured
227
+ * `reasoningContentField`) on EVERY assistant turn that carried reasoning,
228
+ * regardless of whether the upstream provider validates the field. Local
229
+ * llama.cpp-style servers (llama.cpp, LM Studio, vLLM, sglang, Ollama in
230
+ * openai-completions mode) re-tokenize the full chat-template prompt every
231
+ * request; Qwen3 / DeepSeek-R1 / GLM templates reconstruct the `<think>`
232
+ * block from `reasoning_content`. Dropping the field re-renders the
233
+ * assistant turn without `<think>`, diverging from the slot's KV cache state
234
+ * and forcing full prompt re-processing (#3528). Default: auto-detected
235
+ * (loopback/private baseUrl or local provider id with thinking-enabled
236
+ * models).
237
+ */
238
+ replayReasoningContent?: boolean;
239
+ /**
240
+ * Send `preserve_thinking: true` so the Qwen3.6+ chat template renders
241
+ * `<think>...</think>` markup for EVERY assistant turn (not just turns
242
+ * after the last user message). Without it, the template strips the think
243
+ * block from older assistant turns:
244
+ *
245
+ * ```jinja
246
+ * {%- if (preserve_thinking is defined and preserve_thinking is true)
247
+ * or (loop.index0 > ns.last_query_index) %}
248
+ * <|im_start|>assistant\n<think>\n{rc}\n</think>\n\n{content}
249
+ * {%- else %}
250
+ * <|im_start|>assistant\n{content}
251
+ * ```
252
+ *
253
+ * The cache from the original generation has `<think>...</think>` tokens,
254
+ * so once a new user message arrives the prior assistant turns become
255
+ * "older" and the stripped re-render diverges — full prompt re-processing
256
+ * on SWA models (#3541). Default: auto-detected (Qwen thinking format on
257
+ * a local llama.cpp-style backend, paired with `replayReasoningContent`).
258
+ * Non-Qwen templates ignore the flag, so the auto-detection is safe.
259
+ */
260
+ qwenPreserveThinking?: boolean;
225
261
  /** Whether assistant tool-call messages must include non-empty content. Default: false. */
226
262
  requiresAssistantContentForToolCalls?: boolean;
227
263
  /** Whether the provider supports the `tool_choice` parameter. Default: true. */
@@ -433,6 +469,8 @@ export interface ResolvedOpenAISharedCompat {
433
469
  requiresReasoningContentForToolCalls: boolean;
434
470
  requiresReasoningContentForAllAssistantTurns: boolean;
435
471
  allowsSyntheticReasoningContentForToolCalls: boolean;
472
+ replayReasoningContent: boolean;
473
+ qwenPreserveThinking: boolean;
436
474
  requiresThinkingAsText: boolean;
437
475
  requiresMistralToolIds: boolean;
438
476
  requiresToolResultName: boolean;
@@ -482,6 +520,8 @@ export type ResolvedOpenAICompat = ResolvedOpenAISharedCompat &
482
520
  | "requiresReasoningContentForToolCalls"
483
521
  | "requiresReasoningContentForAllAssistantTurns"
484
522
  | "allowsSyntheticReasoningContentForToolCalls"
523
+ | "replayReasoningContent"
524
+ | "qwenPreserveThinking"
485
525
  | "requiresThinkingAsText"
486
526
  | "requiresMistralToolIds"
487
527
  | "requiresToolResultName"
@@ -0,0 +1,42 @@
1
+ export const COREWEAVE_PROJECT_HEADER = "OpenAI-Project" as const;
2
+
3
+ export interface CoreWeaveProjectEnv {
4
+ [key: string]: string | undefined;
5
+ COREWEAVE_PROJECT?: string;
6
+ WANDB_INFERENCE_PROJECT?: string;
7
+ WANDB_ENTITY?: string;
8
+ WANDB_PROJECT?: string;
9
+ }
10
+
11
+ function cleanEnvValue(value: string | undefined): string | undefined {
12
+ const trimmed = value?.trim();
13
+ return trimmed ? trimmed : undefined;
14
+ }
15
+
16
+ export function resolveCoreWeaveProject(env: CoreWeaveProjectEnv): string | undefined {
17
+ const explicitProject = cleanEnvValue(env.COREWEAVE_PROJECT) ?? cleanEnvValue(env.WANDB_INFERENCE_PROJECT);
18
+ if (explicitProject) {
19
+ return explicitProject;
20
+ }
21
+
22
+ const wandbProject = cleanEnvValue(env.WANDB_PROJECT);
23
+ if (!wandbProject) {
24
+ return undefined;
25
+ }
26
+ if (wandbProject.includes("/")) {
27
+ return wandbProject;
28
+ }
29
+
30
+ const wandbEntity = cleanEnvValue(env.WANDB_ENTITY);
31
+ return wandbEntity ? `${wandbEntity}/${wandbProject}` : undefined;
32
+ }
33
+
34
+ export function coreWeaveProjectHeaders(env: CoreWeaveProjectEnv): Record<string, string> | undefined {
35
+ const project = resolveCoreWeaveProject(env);
36
+ return project ? { [COREWEAVE_PROJECT_HEADER]: project } : undefined;
37
+ }
38
+
39
+ export function hasCoreWeaveProjectHeader(headers: Record<string, string>): boolean {
40
+ const normalized = COREWEAVE_PROJECT_HEADER.toLowerCase();
41
+ return Object.keys(headers).some(header => header.toLowerCase() === normalized);
42
+ }