feat(ai): add CoreWeave Serverless Inference provider

This commit is contained in:
Lance Tuller
2026-06-23 10:50:49 -04:00
parent 683877f924
commit efdcadf0d5
17 changed files with 1242 additions and 2 deletions
+1
View File
@@ -77,6 +77,7 @@
- Fixed OpenRouter Anthropic models on the Responses path omitting `cache_control`, so prompt caching engages without forcing Chat Completions. ([#3397](https://github.com/can1357/oh-my-pi/issues/3397))
- Fixed OpenRouter Anthropic Responses follow-up requests replaying prior reasoning items with stale signatures, which caused HTTP 400 `Invalid signature in thinking block` errors after a thinking turn. ([#3399](https://github.com/can1357/oh-my-pi/issues/3399))
- Fixed OpenRouter Anthropic models on the Responses path omitting `cache_control`, so prompt caching engages without forcing Chat Completions. `cacheRetention: "long"` now upgrades the breakpoint to `ttl: "1h"`. ([#3397](https://github.com/can1357/oh-my-pi/issues/3397))
- Added CoreWeave Serverless Inference provider login support via `COREWEAVE_API_KEY` and `WANDB_API_KEY` fallback.
## [16.1.16] - 2026-06-23
@@ -13,6 +13,11 @@ import type {
ResolvedOpenAISharedCompat,
VercelGatewayRouting,
} from "@oh-my-pi/pi-catalog/types";
import {
COREWEAVE_PROJECT_HEADER,
coreWeaveProjectHeaders,
hasCoreWeaveProjectHeader,
} from "@oh-my-pi/pi-catalog/wire/coreweave";
import { parseGitHubCopilotApiKey } from "@oh-my-pi/pi-catalog/wire/github-copilot";
import { $env, extractHttpStatusFromError, logger, structuredCloneJSON } from "@oh-my-pi/pi-utils";
import {
@@ -141,6 +146,16 @@ function resolveSakanaRequestBaseUrl(): string | undefined {
return normalizeSakanaRequestBaseUrl($env.SAKANA_BASE_URL) ?? normalizeSakanaRequestBaseUrl($env.FUGU_BASE_URL);
}
function applyCoreWeaveProjectHeader(headers: Record<string, string>): void {
if (hasCoreWeaveProjectHeader(headers)) {
return;
}
const projectHeaders = coreWeaveProjectHeaders($env);
if (projectHeaders) {
headers[COREWEAVE_PROJECT_HEADER] = projectHeaders[COREWEAVE_PROJECT_HEADER];
}
}
export function resolveOpenAIRequestSetup(
model: OpenAIRequestSetupModel,
options: OpenAIRequestSetupOptions,
@@ -160,6 +175,9 @@ export function resolveOpenAIRequestSetup(
Object.assign(headers, getOpenRouterHeaders());
}
Object.assign(headers, options.extraHeaders);
if (model.provider === "coreweave") {
applyCoreWeaveProjectHeader(headers);
}
if (options.prependHeaders) {
headers = { ...options.prependHeaders(), ...headers };
}
@@ -31,6 +31,7 @@ type ModelsEndpointValidation = {
kind: "models-endpoint";
provider: string;
modelsUrl: string;
headers?: Record<string, string> | (() => Record<string, string> | undefined);
};
export type ApiKeyLoginConfig = {
@@ -98,6 +99,7 @@ export function createApiKeyLogin(config: ApiKeyLoginConfig): (options: OAuthCon
provider: config.validation.provider,
apiKey: trimmed,
modelsUrl: config.validation.modelsUrl,
headers: config.validation.headers,
signal: options.signal,
fetch: options.fetch,
});
@@ -21,6 +21,7 @@ type ModelListValidationOptions = {
provider: string;
apiKey: string;
modelsUrl: string;
headers?: Record<string, string> | (() => Record<string, string> | undefined);
signal?: AbortSignal;
fetch?: FetchImpl;
};
@@ -32,6 +33,12 @@ function normalizeAnthropicCompatibleBaseUrl(baseUrl: string): string {
return trimmed.endsWith("/v1") ? trimmed.slice(0, -3) : trimmed;
}
function resolveValidationHeaders(
headers: Record<string, string> | (() => Record<string, string> | undefined) | undefined,
): Record<string, string> | undefined {
return typeof headers === "function" ? headers() : headers;
}
/**
* Validate an API key against an OpenAI-compatible chat completions endpoint.
*
@@ -129,6 +136,7 @@ export async function validateApiKeyAgainstModelsEndpoint(options: ModelListVali
const response = await fetchImpl(options.modelsUrl, {
method: "GET",
headers: {
...(resolveValidationHeaders(options.headers) ?? {}),
Authorization: `Bearer ${options.apiKey}`,
},
signal,
+38
View File
@@ -0,0 +1,38 @@
import { coreWeaveProjectHeaders } from "@oh-my-pi/pi-catalog/wire/coreweave";
import { $env } from "@oh-my-pi/pi-utils";
import { createApiKeyLogin } from "./api-key-login";
import type { OAuthLoginCallbacks } from "./oauth/types";
import type { ProviderDefinition } from "./types";
const PROJECT_SETUP_INSTRUCTIONS =
"Create or select a CoreWeave Serverless Inference project, set COREWEAVE_PROJECT=<team>/<project> for the OpenAI-Project header, then copy your API key from account settings";
function requireCoreWeaveProjectHeaders(): Record<string, string> {
const headers = coreWeaveProjectHeaders($env);
if (!headers) {
throw new Error(
"CoreWeave Serverless Inference requires OpenAI-Project. Set COREWEAVE_PROJECT=<team>/<project> before running /login coreweave.",
);
}
return headers;
}
export const loginCoreWeave = createApiKeyLogin({
providerLabel: "CoreWeave Serverless Inference",
authUrl: "https://wandb.ai/settings",
instructions: PROJECT_SETUP_INSTRUCTIONS,
promptMessage: "Paste your CoreWeave Serverless Inference API key",
placeholder: "api-key",
validation: {
kind: "models-endpoint",
provider: "CoreWeave Serverless Inference",
modelsUrl: "https://api.inference.wandb.ai/v1/models",
headers: requireCoreWeaveProjectHeaders,
},
});
export const coreWeaveProvider = {
id: "coreweave",
name: "CoreWeave Serverless Inference",
login: (cb: OAuthLoginCallbacks) => loginCoreWeave(cb),
} as const satisfies ProviderDefinition;
+2
View File
@@ -6,6 +6,7 @@ import { anthropicProvider } from "./anthropic";
import { azureProvider } from "./azure";
import { cerebrasProvider } from "./cerebras";
import { cloudflareAiGatewayProvider } from "./cloudflare-ai-gateway";
import { coreWeaveProvider } from "./coreweave";
import { cursorProvider } from "./cursor";
import { deepseekProvider } from "./deepseek";
import { devinProvider } from "./devin";
@@ -112,6 +113,7 @@ const ALL = [
syntheticProvider,
nanogptProvider,
waferServerlessProvider,
coreWeaveProvider,
vercelAiGatewayProvider,
cloudflareAiGatewayProvider,
litellmProvider,
+103
View File
@@ -0,0 +1,103 @@
import { afterEach, describe, expect, test, vi } from "bun:test";
import { loginCoreWeave } from "@oh-my-pi/pi-ai/registry/coreweave";
import type { FetchImpl } from "@oh-my-pi/pi-ai/types";
const COREWEAVE_ENV_KEYS = ["COREWEAVE_PROJECT", "WANDB_INFERENCE_PROJECT", "WANDB_ENTITY", "WANDB_PROJECT"] as const;
const ORIGINAL_ENV = new Map(COREWEAVE_ENV_KEYS.map(key => [key, Bun.env[key]]));
function restoreCoreWeaveEnv(): void {
for (const key of COREWEAVE_ENV_KEYS) {
const value = ORIGINAL_ENV.get(key);
if (value === undefined) {
delete Bun.env[key];
} else {
Bun.env[key] = value;
}
}
}
afterEach(() => {
restoreCoreWeaveEnv();
vi.restoreAllMocks();
});
describe("CoreWeave Serverless Inference login", () => {
test("validates API key against the models endpoint with the project header", async () => {
Bun.env.COREWEAVE_PROJECT = "team/project";
delete Bun.env.WANDB_INFERENCE_PROJECT;
delete Bun.env.WANDB_ENTITY;
delete Bun.env.WANDB_PROJECT;
const fetchMock: FetchImpl = vi.fn(async (input: string | URL | Request, init?: RequestInit) => {
const url = typeof input === "string" ? input : input.toString();
expect(url).toBe("https://api.inference.wandb.ai/v1/models");
expect(init?.method).toBe("GET");
expect(init?.headers).toEqual({
"OpenAI-Project": "team/project",
Authorization: "Bearer coreweave-test-key",
});
return new Response(JSON.stringify({ object: "list", data: [] }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
});
const authMessages: string[] = [];
const apiKey = await loginCoreWeave({
onAuth: auth => {
if (auth.instructions) {
authMessages.push(auth.instructions);
}
},
onPrompt: async () => " coreweave-test-key ",
fetch: fetchMock,
});
expect(apiKey).toBe("coreweave-test-key");
expect(authMessages[0]).toContain("COREWEAVE_PROJECT=<team>/<project>");
expect(authMessages[0]).toContain("OpenAI-Project");
expect(fetchMock).toHaveBeenCalledTimes(1);
});
test("requires a project header before validating the API key", async () => {
delete Bun.env.COREWEAVE_PROJECT;
delete Bun.env.WANDB_INFERENCE_PROJECT;
delete Bun.env.WANDB_ENTITY;
delete Bun.env.WANDB_PROJECT;
const fetchMock: FetchImpl = vi.fn(async () => {
return new Response(JSON.stringify({ object: "list", data: [] }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
});
await expect(
loginCoreWeave({
onPrompt: async () => "coreweave-test-key",
fetch: fetchMock,
}),
).rejects.toThrow("Set COREWEAVE_PROJECT=<team>/<project>");
expect(fetchMock).toHaveBeenCalledTimes(0);
});
test("surfaces validation errors from the CoreWeave Serverless Inference models endpoint", async () => {
Bun.env.COREWEAVE_PROJECT = "team/project";
delete Bun.env.WANDB_INFERENCE_PROJECT;
delete Bun.env.WANDB_ENTITY;
delete Bun.env.WANDB_PROJECT;
const fetchMock: FetchImpl = vi.fn(async () => {
return new Response("Unauthorized", {
status: 401,
headers: { "Content-Type": "text/plain" },
});
});
await expect(
loginCoreWeave({
onPrompt: async () => "coreweave-test-key",
fetch: fetchMock,
}),
).rejects.toThrow("CoreWeave Serverless Inference API key validation failed (401)");
});
});
@@ -0,0 +1,69 @@
import { afterEach, describe, expect, test } from "bun:test";
import { resolveOpenAIRequestSetup } from "@oh-my-pi/pi-ai/providers/openai-shared";
const COREWEAVE_ENV_KEYS = ["COREWEAVE_PROJECT", "WANDB_INFERENCE_PROJECT", "WANDB_ENTITY", "WANDB_PROJECT"] as const;
const ORIGINAL_ENV = new Map(COREWEAVE_ENV_KEYS.map(key => [key, Bun.env[key]]));
function restoreCoreWeaveEnv(): void {
for (const key of COREWEAVE_ENV_KEYS) {
const value = ORIGINAL_ENV.get(key);
if (value === undefined) {
delete Bun.env[key];
} else {
Bun.env[key] = value;
}
}
}
afterEach(() => {
restoreCoreWeaveEnv();
});
describe("CoreWeave Serverless Inference project header", () => {
const coreWeaveModel = {
provider: "coreweave",
id: "zai-org/GLM-5.2",
baseUrl: "https://api.inference.wandb.ai/v1",
};
test("adds OpenAI-Project from COREWEAVE_PROJECT", () => {
Bun.env.COREWEAVE_PROJECT = "team/project";
delete Bun.env.WANDB_INFERENCE_PROJECT;
delete Bun.env.WANDB_ENTITY;
delete Bun.env.WANDB_PROJECT;
const setup = resolveOpenAIRequestSetup(coreWeaveModel, {
apiKey: "coreweave-key",
messages: [],
});
expect(setup.headers["OpenAI-Project"]).toBe("team/project");
});
test("builds OpenAI-Project from W&B entity and project fallbacks", () => {
delete Bun.env.COREWEAVE_PROJECT;
delete Bun.env.WANDB_INFERENCE_PROJECT;
Bun.env.WANDB_ENTITY = "wandb-team";
Bun.env.WANDB_PROJECT = "inference-project";
const setup = resolveOpenAIRequestSetup(coreWeaveModel, {
apiKey: "coreweave-key",
messages: [],
});
expect(setup.headers["OpenAI-Project"]).toBe("wandb-team/inference-project");
});
test("preserves an explicit request project header", () => {
Bun.env.COREWEAVE_PROJECT = "team/project";
const setup = resolveOpenAIRequestSetup(coreWeaveModel, {
apiKey: "coreweave-key",
extraHeaders: { "openai-project": "explicit/team" },
messages: [],
});
expect(setup.headers["openai-project"]).toBe("explicit/team");
expect(setup.headers["OpenAI-Project"]).toBeUndefined();
});
});
@@ -14,11 +14,13 @@ import { getEnvApiKey } from "@oh-my-pi/pi-ai/stream";
const FIXTURE_SOURCE = "provider-registry-test";
const ENV_KEYS = [
"COREWEAVE_API_KEY",
"ZENMUX_API_KEY",
"EXA_API_KEY",
"XAI_OAUTH_TOKEN",
"UMANS_AI_CODING_PLAN_API_KEY",
"LLAMA_CPP_API_KEY",
"WANDB_API_KEY",
] as const;
const originalEnv = new Map(ENV_KEYS.map(key => [key, Bun.env[key]]));
@@ -52,6 +54,11 @@ describe("provider registry auth surface", () => {
test("multi-var catalog env fallback picks names in order", () => {
Bun.env.XAI_OAUTH_TOKEN = "xai-oauth-env";
expect(getEnvApiKey("xai-oauth")).toBe("xai-oauth-env");
Bun.env.WANDB_API_KEY = "wandb-env";
expect(getEnvApiKey("coreweave")).toBe("wandb-env");
Bun.env.COREWEAVE_API_KEY = "coreweave-env";
expect(getEnvApiKey("coreweave")).toBe("coreweave-env");
});
test("login list contains loginable providers and excludes env-only model providers", () => {
+1
View File
@@ -25,6 +25,7 @@
- Fixed the Umans GLM-5.2 thinking-level picker collapsing to a single `high` tier after dynamic discovery: the `max` upstream level now resolves to the internal `xhigh` effort, the picker shows both `high` and `xhigh`, and the metadata maps `xhigh` back to Umans's native `max` wire tier. ([#3192](https://github.com/can1357/oh-my-pi/issues/3192))
- Fixed GitHub Copilot business and enterprise endpoints accepting image inputs that they reject with `400 vision is not supported`. The Copilot `/models` response advertises `capabilities.supports.vision = true` for Claude/GPT chat models on every host, but only the canonical personal endpoint (`https://api.githubcopilot.com`) actually serves them; `githubCopilotModelManagerOptions` now forces `input: ["text"]` whenever discovery resolves to a non-personal base URL, and `mergeDynamicModel` honours the dynamic value (instead of OR-upgrading) when the merged endpoint differs from the bundled reference. ([#3387](https://github.com/can1357/oh-my-pi/issues/3387))
- Fixed OpenRouter Anthropic compat to strip Responses reasoning history during replay so signed thinking blocks are not sent back to routed Anthropic providers. ([#3399](https://github.com/can1357/oh-my-pi/issues/3399))
- Added CoreWeave Serverless Inference as an OpenAI-compatible provider with models.dev-backed bundled catalog metadata.
## [16.1.14] - 2026-06-22
+1 -1
View File
@@ -62,7 +62,7 @@ const packageRoot = path.join(import.meta.dir, "..");
* and never written to models.json.
*/
const DISCOVERY_ONLY_PROVIDERS = new Set(["ollama", "vllm", "lm-studio", "litellm"]);
const RETIRED_PROVIDERS = new Set(["wafer-pass"]);
const RETIRED_PROVIDERS = new Set(["wafer-pass", "wandb"]);
async function resolveProviderApiKey(providerId: string, catalog: CatalogDiscoveryConfig): Promise<string | undefined> {
for (const envVar of catalog.envVars ?? []) {
+1
View File
@@ -12,5 +12,6 @@ export * from "./types";
export * from "./utils";
export * from "./variant-collapse";
export * from "./wire/codex";
export * from "./wire/coreweave";
export * from "./wire/gemini-headers";
export * from "./wire/github-copilot";
+780
View File
@@ -13487,6 +13487,786 @@
}
}
},
"coreweave": {
"deepseek-ai/DeepSeek-V3.1": {
"id": "deepseek-ai/DeepSeek-V3.1",
"name": "DeepSeek V3.1",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0.55,
"output": 1.65,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 161000,
"maxTokens": 161000
},
"deepseek-ai/DeepSeek-V4-Flash": {
"id": "deepseek-ai/DeepSeek-V4-Flash",
"name": "DeepSeek V4 Flash",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 1048576,
"maxTokens": 384000,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high",
"xhigh"
],
"effortMap": {
"minimal": "high",
"low": "high",
"medium": "high",
"high": "high",
"xhigh": "max"
}
}
},
"deepseek-ai/DeepSeek-V4-Pro": {
"id": "deepseek-ai/DeepSeek-V4-Pro",
"name": "DeepSeek V4 Pro",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 1048576,
"maxTokens": 393216,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high",
"xhigh"
],
"effortMap": {
"minimal": "high",
"low": "high",
"medium": "high",
"high": "high",
"xhigh": "max"
}
}
},
"google/gemma-4-31B-it": {
"id": "google/gemma-4-31B-it",
"name": "Gemma 4 31B Instruct",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 131072,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high",
"xhigh"
]
}
},
"ibm-granite/granite-4.1-8b": {
"id": "ibm-granite/granite-4.1-8b",
"name": "Granite 4.1 8B",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 131072
},
"JetBrains/Mellum2-12B-A2.5B-Instruct": {
"id": "JetBrains/Mellum2-12B-A2.5B-Instruct",
"name": "JetBrains/Mellum2-12B-A2.5B-Instruct",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": null,
"maxTokens": null
},
"meta-llama/Llama-3.1-70B-Instruct": {
"id": "meta-llama/Llama-3.1-70B-Instruct",
"name": "Llama 3.1 70B",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0.8,
"output": 0.8,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 128000,
"maxTokens": 128000
},
"meta-llama/Llama-3.1-8B-Instruct": {
"id": "meta-llama/Llama-3.1-8B-Instruct",
"name": "Meta-Llama-3.1-8B-Instruct",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text"
],
"cost": {
"input": 0.22,
"output": 0.22,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 128000,
"maxTokens": 128000,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high",
"xhigh"
]
}
},
"meta-llama/Llama-3.3-70B-Instruct": {
"id": "meta-llama/Llama-3.3-70B-Instruct",
"name": "Llama-3.3-70B-Instruct",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text"
],
"cost": {
"input": 0.71,
"output": 0.71,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 128000,
"maxTokens": 128000,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high",
"xhigh"
]
}
},
"meta-llama/Llama-4-Scout-17B-16E-Instruct": {
"id": "meta-llama/Llama-4-Scout-17B-16E-Instruct",
"name": "Llama 4 Scout 17B 16E Instruct",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0.17,
"output": 0.66,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 64000,
"maxTokens": 64000,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high",
"xhigh"
]
}
},
"microsoft/Phi-4-mini-instruct": {
"id": "microsoft/Phi-4-mini-instruct",
"name": "Phi-4-mini-instruct",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text"
],
"cost": {
"input": 0.08,
"output": 0.35,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 128000,
"maxTokens": 128000,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high",
"xhigh"
]
}
},
"MiniMaxAI/MiniMax-M2.5": {
"id": "MiniMaxAI/MiniMax-M2.5",
"name": "MiniMax M2.5",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0.3,
"output": 1.2,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 196608,
"maxTokens": 196608
},
"moonshotai/Kimi-K2.5": {
"id": "moonshotai/Kimi-K2.5",
"name": "Kimi K2.5",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0.5,
"output": 2.85,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 262144,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high",
"xhigh"
]
}
},
"moonshotai/Kimi-K2.6": {
"id": "moonshotai/Kimi-K2.6",
"name": "Kimi-K2.6",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 262144,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high",
"xhigh"
]
}
},
"moonshotai/Kimi-K2.7-Code": {
"id": "moonshotai/Kimi-K2.7-Code",
"name": "Kimi K2.7 Code",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 262144,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high",
"xhigh"
]
}
},
"nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-FP8": {
"id": "nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-FP8",
"name": "NVIDIA Nemotron 3 Super 120B",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0.2,
"output": 0.8,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 262144
},
"nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B": {
"id": "nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B",
"name": "nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": null,
"maxTokens": null
},
"openai/gpt-oss-120b": {
"id": "openai/gpt-oss-120b",
"name": "gpt-oss-120b",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0.15,
"output": 0.6,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 131072
},
"openai/gpt-oss-20b": {
"id": "openai/gpt-oss-20b",
"name": "gpt-oss-20b",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0.05,
"output": 0.2,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 131072
},
"OpenPipe/Qwen3-14B-Instruct": {
"id": "OpenPipe/Qwen3-14B-Instruct",
"name": "OpenPipe Qwen3 14B Instruct",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0.05,
"output": 0.22,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 32768,
"maxTokens": 32768
},
"Qwen/Qwen3-235B-A22B-Instruct-2507": {
"id": "Qwen/Qwen3-235B-A22B-Instruct-2507",
"name": "Qwen3 235B A22B Instruct 2507",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0.1,
"output": 0.1,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 262144
},
"Qwen/Qwen3-235B-A22B-Thinking-2507": {
"id": "Qwen/Qwen3-235B-A22B-Thinking-2507",
"name": "Qwen3-235B-A22B-Thinking-2507",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text"
],
"cost": {
"input": 0.1,
"output": 0.1,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 262144,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high"
],
"requiresEffort": true
}
},
"Qwen/Qwen3-30B-A3B-Instruct-2507": {
"id": "Qwen/Qwen3-30B-A3B-Instruct-2507",
"name": "Qwen3 30B A3B Instruct 2507",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0.1,
"output": 0.3,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 262144
},
"Qwen/Qwen3-Coder-480B-A35B-Instruct": {
"id": "Qwen/Qwen3-Coder-480B-A35B-Instruct",
"name": "Qwen3-Coder-480B-A35B-Instruct",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 1,
"output": 1.5,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 262144
},
"Qwen/Qwen3.5-27B": {
"id": "Qwen/Qwen3.5-27B",
"name": "Qwen3.5 27B",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 65536,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high"
]
}
},
"Qwen/Qwen3.5-35B-A3B": {
"id": "Qwen/Qwen3.5-35B-A3B",
"name": "Qwen3.5 35B-A3B",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 65536,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high"
]
}
},
"Qwen/Qwen3.6-27B": {
"id": "Qwen/Qwen3.6-27B",
"name": "Qwen3.6 27B",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 65536,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high"
]
}
},
"Qwen/Qwen3.6-35B-A3B": {
"id": "Qwen/Qwen3.6-35B-A3B",
"name": "Qwen3.6 35B-A3B",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 65536,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high"
]
}
},
"zai-org/GLM-5-FP8": {
"id": "zai-org/GLM-5-FP8",
"name": "GLM 5",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 1,
"output": 3.2,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 200000,
"maxTokens": 200000
},
"zai-org/GLM-5.1": {
"id": "zai-org/GLM-5.1",
"name": "GLM-5.1",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text"
],
"cost": {
"input": 1.4,
"output": 4.4,
"cacheRead": 0.26,
"cacheWrite": 0
},
"contextWindow": 200000,
"maxTokens": 131072,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high",
"xhigh"
]
}
},
"zai-org/GLM-5.2": {
"id": "zai-org/GLM-5.2",
"name": "GLM-5.2",
"api": "openai-completions",
"provider": "coreweave",
"baseUrl": "https://api.inference.wandb.ai/v1",
"reasoning": true,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 164000,
"thinking": {
"mode": "effort",
"efforts": [
"minimal",
"low",
"medium",
"high",
"xhigh"
]
}
}
},
"cursor": {
"claude-4.5-opus-high": {
"id": "claude-4.5-opus-high",
@@ -14,6 +14,7 @@ import {
anthropicModelManagerOptions,
cerebrasModelManagerOptions,
cloudflareAiGatewayModelManagerOptions,
coreWeaveModelManagerOptions,
deepseekModelManagerOptions,
firepassModelManagerOptions,
fireworksModelManagerOptions,
@@ -375,6 +376,13 @@ export const CATALOG_PROVIDERS = [
oauthProvider: "wafer-serverless",
},
},
{
id: "coreweave",
defaultModel: "openai/gpt-oss-120b",
envVars: ["COREWEAVE_API_KEY", "WANDB_API_KEY"],
createModelManagerOptions: (config: ModelManagerConfig) => coreWeaveModelManagerOptions(config),
catalogDiscovery: { label: "CoreWeave Serverless Inference" },
},
{
id: "xai",
defaultModel: "grok-4-fast-non-reasoning",
@@ -10,6 +10,7 @@ import type { ModelManagerOptions } from "../model-manager";
import { getBundledModels } from "../models";
import type { Api, FetchImpl, Model, ModelSpec, Provider, ThinkingConfig } from "../types";
import { isAnthropicOAuthToken, isRecord, toBoolean, toNumber, toPositiveNumber } from "../utils";
import { coreWeaveProjectHeaders } from "../wire/coreweave";
import {
COPILOT_API_HEADERS,
getGitHubCopilotBaseUrl,
@@ -470,7 +471,19 @@ function isLikelyNanoGptTextModelId(id: string): boolean {
return !NANO_GPT_NON_TEXT_MODEL_TOKENS.some(token => normalized.includes(token));
}
type SimpleProviderConfig = { apiKey?: string; baseUrl?: string; fetch?: FetchImpl };
type SimpleProviderDiscoveryHeaders = Record<string, string> | (() => Record<string, string> | undefined);
type SimpleProviderConfig = {
apiKey?: string;
baseUrl?: string;
fetch?: FetchImpl;
headers?: SimpleProviderDiscoveryHeaders;
};
function resolveSimpleProviderHeaders(
headers: SimpleProviderDiscoveryHeaders | undefined,
): Record<string, string> | undefined {
return typeof headers === "function" ? headers() : headers;
}
export function createSimpleOpenAICompletionsOptions(
providerId: Parameters<typeof getBundledModels>[0],
@@ -489,6 +502,7 @@ export function createSimpleOpenAICompletionsOptions(
provider: providerId,
baseUrl,
apiKey,
headers: resolveSimpleProviderHeaders(config?.headers),
mapModel: (entry, defaults) => {
const reference = references.get(defaults.id);
return mapWithBundledReference(entry, defaults, reference);
@@ -516,6 +530,7 @@ function createSimpleOpenAIResponsesOptions(
provider: providerId,
baseUrl,
apiKey,
headers: resolveSimpleProviderHeaders(config?.headers),
mapModel: (entry, defaults) => {
const reference = references.get(defaults.id);
return mapWithBundledReference(entry, defaults, reference);
@@ -2480,6 +2495,25 @@ export function togetherModelManagerOptions(
return createSimpleOpenAICompletionsOptions("together", "https://api.together.xyz/v1", config);
}
// ---------------------------------------------------------------------------
// 15.5 CoreWeave Serverless Inference
// ---------------------------------------------------------------------------
export interface CoreWeaveModelManagerConfig {
apiKey?: string;
baseUrl?: string;
fetch?: FetchImpl;
}
export function coreWeaveModelManagerOptions(
config?: CoreWeaveModelManagerConfig,
): ModelManagerOptions<"openai-completions"> {
return createSimpleOpenAICompletionsOptions("coreweave", "https://api.inference.wandb.ai/v1", {
...config,
headers: () => coreWeaveProjectHeaders(Bun.env),
});
}
// ---------------------------------------------------------------------------
// 16. Moonshot
// ---------------------------------------------------------------------------
@@ -3653,6 +3687,8 @@ const MODELS_DEV_PROVIDER_DESCRIPTORS_CORE: readonly ModelsDevProviderDescriptor
openAiCompletionsDescriptor("cerebras", "cerebras", "https://api.cerebras.ai/v1"),
// --- Together ---
openAiCompletionsDescriptor("togetherai", "together", "https://api.together.xyz/v1"),
// --- CoreWeave Serverless Inference ---
openAiCompletionsDescriptor("wandb", "coreweave", "https://api.inference.wandb.ai/v1"),
// --- NVIDIA ---
openAiCompletionsDescriptor("nvidia", "nvidia", "https://integrate.api.nvidia.com/v1", {
defaultContextWindow: 131072,
+42
View File
@@ -0,0 +1,42 @@
export const COREWEAVE_PROJECT_HEADER = "OpenAI-Project" as const;
export interface CoreWeaveProjectEnv {
[key: string]: string | undefined;
COREWEAVE_PROJECT?: string;
WANDB_INFERENCE_PROJECT?: string;
WANDB_ENTITY?: string;
WANDB_PROJECT?: string;
}
function cleanEnvValue(value: string | undefined): string | undefined {
const trimmed = value?.trim();
return trimmed ? trimmed : undefined;
}
export function resolveCoreWeaveProject(env: CoreWeaveProjectEnv): string | undefined {
const explicitProject = cleanEnvValue(env.COREWEAVE_PROJECT) ?? cleanEnvValue(env.WANDB_INFERENCE_PROJECT);
if (explicitProject) {
return explicitProject;
}
const wandbProject = cleanEnvValue(env.WANDB_PROJECT);
if (!wandbProject) {
return undefined;
}
if (wandbProject.includes("/")) {
return wandbProject;
}
const wandbEntity = cleanEnvValue(env.WANDB_ENTITY);
return wandbEntity ? `${wandbEntity}/${wandbProject}` : undefined;
}
export function coreWeaveProjectHeaders(env: CoreWeaveProjectEnv): Record<string, string> | undefined {
const project = resolveCoreWeaveProject(env);
return project ? { [COREWEAVE_PROJECT_HEADER]: project } : undefined;
}
export function hasCoreWeaveProjectHeader(headers: Record<string, string>): boolean {
const normalized = COREWEAVE_PROJECT_HEADER.toLowerCase();
return Object.keys(headers).some(header => header.toLowerCase() === normalized);
}
@@ -0,0 +1,124 @@
import { afterEach, describe, expect, test, vi } from "bun:test";
import { getBundledModels } from "@oh-my-pi/pi-catalog/models";
import { DEFAULT_MODEL_PER_PROVIDER, PROVIDER_DESCRIPTORS } from "@oh-my-pi/pi-catalog/provider-models/descriptors";
import {
coreWeaveModelManagerOptions,
MODELS_DEV_PROVIDER_DESCRIPTORS,
mapModelsDevToModels,
} from "@oh-my-pi/pi-catalog/provider-models/openai-compat";
import type { FetchImpl } from "@oh-my-pi/pi-catalog/types";
const COREWEAVE_ENV_KEYS = ["COREWEAVE_PROJECT", "WANDB_INFERENCE_PROJECT", "WANDB_ENTITY", "WANDB_PROJECT"] as const;
const ORIGINAL_ENV = new Map(COREWEAVE_ENV_KEYS.map(key => [key, Bun.env[key]]));
function restoreCoreWeaveEnv(): void {
for (const key of COREWEAVE_ENV_KEYS) {
const value = ORIGINAL_ENV.get(key);
if (value === undefined) {
delete Bun.env[key];
} else {
Bun.env[key] = value;
}
}
}
afterEach(() => {
restoreCoreWeaveEnv();
vi.restoreAllMocks();
});
describe("CoreWeave Serverless Inference provider support", () => {
test("registers descriptor, default model, environment key, and bundled models", () => {
const descriptor = PROVIDER_DESCRIPTORS.find(item => item.providerId === "coreweave");
expect(descriptor).toBeDefined();
expect(descriptor?.defaultModel).toBe("openai/gpt-oss-120b");
expect(descriptor?.catalogDiscovery?.label).toBe("CoreWeave Serverless Inference");
expect(descriptor?.catalogDiscovery?.envVars).toEqual(["COREWEAVE_API_KEY", "WANDB_API_KEY"]);
expect(DEFAULT_MODEL_PER_PROVIDER.coreweave).toBe("openai/gpt-oss-120b");
const bundled = getBundledModels("coreweave");
expect(bundled.find(model => model.id === "openai/gpt-oss-120b")).toMatchObject({
api: "openai-completions",
provider: "coreweave",
baseUrl: "https://api.inference.wandb.ai/v1",
});
});
test("discovers dynamic models with the CoreWeave project header", async () => {
Bun.env.COREWEAVE_PROJECT = "team/project";
delete Bun.env.WANDB_INFERENCE_PROJECT;
delete Bun.env.WANDB_ENTITY;
delete Bun.env.WANDB_PROJECT;
const calls: Array<{ url: string; authorization: string | null; project: string | null }> = [];
const fetchMock: FetchImpl = vi.fn(async (input: string | URL | Request, init?: RequestInit) => {
const headers = new Headers(init?.headers);
calls.push({
url: input.toString(),
authorization: headers.get("authorization"),
project: headers.get("openai-project"),
});
return new Response(
JSON.stringify({
data: [{ id: "openai/gpt-oss-120b", name: "GPT OSS 120B" }, { id: "meta-llama/Llama-3.1-8B-Instruct" }],
}),
{
status: 200,
headers: { "Content-Type": "application/json" },
},
);
}) as unknown as FetchImpl;
const options = coreWeaveModelManagerOptions({ apiKey: "coreweave-test-key", fetch: fetchMock });
const models = await options.fetchDynamicModels?.();
expect(options.providerId).toBe("coreweave");
expect(calls).toEqual([
{
url: "https://api.inference.wandb.ai/v1/models",
authorization: "Bearer coreweave-test-key",
project: "team/project",
},
]);
expect(models?.find(model => model.id === "openai/gpt-oss-120b")).toMatchObject({
id: "openai/gpt-oss-120b",
name: "GPT OSS 120B",
api: "openai-completions",
provider: "coreweave",
baseUrl: "https://api.inference.wandb.ai/v1",
});
});
test("maps models.dev wandb metadata into OpenAI chat completions models", () => {
const mapped = mapModelsDevToModels(
{
wandb: {
models: {
"openai/gpt-oss-120b": {
id: "openai/gpt-oss-120b",
name: "GPT OSS 120B",
tool_call: true,
reasoning: true,
modalities: { input: ["text"] },
limit: { context: 131072, output: 32768 },
cost: { input: 0.15, output: 0.6 },
},
},
},
},
MODELS_DEV_PROVIDER_DESCRIPTORS,
);
expect(mapped.find(model => model.provider === "coreweave")).toMatchObject({
id: "openai/gpt-oss-120b",
name: "GPT OSS 120B",
api: "openai-completions",
provider: "coreweave",
baseUrl: "https://api.inference.wandb.ai/v1",
reasoning: true,
contextWindow: 131072,
maxTokens: 32768,
cost: { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 },
});
});
});