feat(catalog): integrated baseten provider and updated model definitions
- Implement Baseten provider support with authentication and dynamic model discovery. - Register Baseten in the model catalog and provider priority order. - Expand model definitions with new DeepSeek, Kimi, NVIDIA, and Claude variants. - Update model configurations, cost data, and provider-specific metadata.
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Added support for Baseten as an AI provider
|
||||
|
||||
## [16.3.3] - 2026-07-02
|
||||
|
||||
### Added
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { createApiKeyLogin } from "./api-key-login";
|
||||
import type { OAuthLoginCallbacks } from "./oauth/types";
|
||||
import type { ProviderDefinition } from "./types";
|
||||
|
||||
export const loginBaseten = createApiKeyLogin({
|
||||
providerLabel: "Baseten",
|
||||
authUrl: "https://app.baseten.co/settings/api_keys",
|
||||
instructions: "Copy your API key from the Baseten dashboard",
|
||||
promptMessage: "Paste your Baseten API key",
|
||||
placeholder: "bt_...",
|
||||
validation: {
|
||||
kind: "models-endpoint",
|
||||
provider: "Baseten",
|
||||
modelsUrl: "https://inference.baseten.co/v1/models",
|
||||
},
|
||||
});
|
||||
|
||||
export const basetenProvider = {
|
||||
id: "baseten",
|
||||
name: "Baseten",
|
||||
login: (cb: OAuthLoginCallbacks) => loginBaseten(cb),
|
||||
} as const satisfies ProviderDefinition;
|
||||
@@ -4,6 +4,7 @@ import { alibabaCodingPlanProvider } from "./alibaba-coding-plan";
|
||||
import { amazonBedrockProvider } from "./amazon-bedrock";
|
||||
import { anthropicProvider } from "./anthropic";
|
||||
import { azureProvider } from "./azure";
|
||||
import { basetenProvider } from "./baseten";
|
||||
import { cerebrasProvider } from "./cerebras";
|
||||
import { cloudflareAiGatewayProvider } from "./cloudflare-ai-gateway";
|
||||
import { coreWeaveProvider } from "./coreweave";
|
||||
@@ -105,6 +106,7 @@ const ALL = [
|
||||
deepseekProvider,
|
||||
moonshotProvider,
|
||||
cerebrasProvider,
|
||||
basetenProvider,
|
||||
fireworksProvider,
|
||||
togetherProvider,
|
||||
nvidiaProvider,
|
||||
|
||||
@@ -2,6 +2,20 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Added Baseten as a supported model provider
|
||||
- Added support for new models from Baseten, including DeepSeek V4 Pro and Kimi series
|
||||
- Added new Devin agent models: Claude 5 Fable variants
|
||||
- Added new Github Copilot models: Kimi K2.7 Code and MAI-Code-1-Flash
|
||||
- Added Poolside Laguna XS 2.1 models via Kilo and OpenRouter providers
|
||||
- Added support for Claude Fable 5 (Free) via Zenmux provider
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated priority ordering to include Baseten
|
||||
- Updated pricing and limits for various existing models in the catalog
|
||||
|
||||
## [16.3.3] - 2026-07-02
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -187,7 +187,11 @@ function applyGlobalModelsDevFallback(
|
||||
const providerScopedKeys = new Set(modelsDevModels.map(model => `${model.provider}/${model.id}`));
|
||||
const globalReferences = createGlobalModelsDevReferenceMap(modelsDevModels);
|
||||
return models.map(model => {
|
||||
if (providerScopedKeys.has(`${model.provider}/${model.id}`) || model.provider === "devin") {
|
||||
if (
|
||||
providerScopedKeys.has(`${model.provider}/${model.id}`) ||
|
||||
model.provider === "devin" ||
|
||||
model.provider === "baseten"
|
||||
) {
|
||||
return model;
|
||||
}
|
||||
const reference = globalReferences.get(model.id);
|
||||
|
||||
@@ -47,6 +47,7 @@ export const KNOWN_HOSTS = {
|
||||
xai: { providers: ["xai"], urlMarkers: ["api.x.ai"] },
|
||||
mistral: { providers: ["mistral"], urlMarkers: ["mistral.ai"] },
|
||||
together: { providers: ["together"], urlMarkers: ["api.together.xyz"] },
|
||||
baseten: { providers: ["baseten"], urlMarkers: ["baseten.co"] },
|
||||
/** URL-only on purpose: the `fireworks`/`firepass` providers route per-model and not every model is Fireworks-shaped. */
|
||||
fireworks: { urlMarkers: ["fireworks.ai"] },
|
||||
groq: { providers: ["groq"], urlMarkers: ["api.groq.com"] },
|
||||
|
||||
@@ -20,6 +20,7 @@ const DEFAULT_MODEL_PROVIDER_ORDER = [
|
||||
// High-quality aggregators / hosted inference providers.
|
||||
"fireworks",
|
||||
"cerebras",
|
||||
"baseten",
|
||||
"openrouter",
|
||||
"aimlapi",
|
||||
"together",
|
||||
|
||||
+707
-102
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,7 @@ import {
|
||||
aimlApiModelManagerOptions,
|
||||
alibabaCodingPlanModelManagerOptions,
|
||||
anthropicModelManagerOptions,
|
||||
basetenModelManagerOptions,
|
||||
cerebrasModelManagerOptions,
|
||||
cloudflareAiGatewayModelManagerOptions,
|
||||
coreWeaveModelManagerOptions,
|
||||
@@ -73,6 +74,14 @@ export const CATALOG_PROVIDERS = [
|
||||
createModelManagerOptions: (config: ModelManagerConfig) => alibabaCodingPlanModelManagerOptions(config),
|
||||
catalogDiscovery: { label: "Alibaba Coding Plan" },
|
||||
},
|
||||
{
|
||||
id: "baseten",
|
||||
defaultModel: "moonshotai/Kimi-K2.7-Code",
|
||||
envVars: ["BASETEN_API_KEY"],
|
||||
createModelManagerOptions: (config: ModelManagerConfig) => basetenModelManagerOptions(config),
|
||||
dynamicModelsAuthoritative: true,
|
||||
catalogDiscovery: { label: "Baseten" },
|
||||
},
|
||||
{
|
||||
id: "amazon-bedrock",
|
||||
defaultModel: "us.anthropic.claude-opus-4-8",
|
||||
|
||||
@@ -2551,6 +2551,103 @@ export function veniceModelManagerOptions(
|
||||
};
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 14.5 Baseten
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export interface BasetenModelManagerConfig {
|
||||
apiKey?: string;
|
||||
baseUrl?: string;
|
||||
fetch?: FetchImpl;
|
||||
}
|
||||
|
||||
export function basetenModelManagerOptions(
|
||||
config?: BasetenModelManagerConfig,
|
||||
): ModelManagerOptions<"openai-completions"> {
|
||||
const apiKey = config?.apiKey;
|
||||
const baseUrl = config?.baseUrl ?? "https://inference.baseten.co/v1";
|
||||
const references = createBundledReferenceMap<"openai-completions">("baseten");
|
||||
return {
|
||||
providerId: "baseten",
|
||||
dynamicModelsAuthoritative: true,
|
||||
...(apiKey && {
|
||||
fetchDynamicModels: () =>
|
||||
fetchOpenAICompatibleModels({
|
||||
api: "openai-completions",
|
||||
provider: "baseten",
|
||||
baseUrl,
|
||||
apiKey,
|
||||
mapModel: (entry, defaults) => {
|
||||
const reference = references.get(defaults.id);
|
||||
const raw = entry as Record<string, unknown> & {
|
||||
supported_features?: unknown;
|
||||
input_modalities?: unknown;
|
||||
pricing?: Record<string, unknown>;
|
||||
};
|
||||
const features = Array.isArray(raw.supported_features) ? raw.supported_features : [];
|
||||
const modalities = Array.isArray(raw.input_modalities) ? raw.input_modalities : [];
|
||||
|
||||
const isBasetenNativeReasoning =
|
||||
defaults.id === "openai/gpt-oss-120b" ||
|
||||
defaults.id === "deepseek-ai/DeepSeek-V4-Pro" ||
|
||||
defaults.id === "zai-org/GLM-5.2";
|
||||
const reasoning =
|
||||
isBasetenNativeReasoning &&
|
||||
(features.includes("reasoning") || features.includes("reasoning_effort"));
|
||||
const supportsTools = features.includes("tools") ? undefined : false;
|
||||
const vision = modalities.includes("image") || (reference?.input.includes("image") ?? false);
|
||||
|
||||
const pricing = raw.pricing ?? {};
|
||||
const cost = {
|
||||
input: toPositiveNumber(pricing.prompt, 0) * 1_000_000,
|
||||
output: toPositiveNumber(pricing.completion, 0) * 1_000_000,
|
||||
cacheRead: toPositiveNumber(pricing.input_cache_read, 0) * 1_000_000,
|
||||
cacheWrite: 0,
|
||||
};
|
||||
|
||||
const contextWindow = toPositiveNumber(
|
||||
raw.context_length,
|
||||
reference?.contextWindow ?? defaults.contextWindow,
|
||||
);
|
||||
const maxTokens = toPositiveNumber(
|
||||
raw.max_completion_tokens,
|
||||
reference?.maxTokens ?? defaults.maxTokens,
|
||||
);
|
||||
|
||||
const baseModel = mapWithBundledReference(entry, defaults, reference);
|
||||
|
||||
const isEffortReasoning = defaults.id === "openai/gpt-oss-120b" || defaults.id === "zai-org/GLM-5.2";
|
||||
const thinking = isEffortReasoning
|
||||
? {
|
||||
mode: "effort" as const,
|
||||
efforts: [Effort.Minimal, Effort.Low, Effort.Medium, Effort.High, Effort.XHigh],
|
||||
effortMap: {
|
||||
minimal: "high",
|
||||
low: "high",
|
||||
medium: "high",
|
||||
high: "high",
|
||||
xhigh: "max",
|
||||
},
|
||||
}
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
...baseModel,
|
||||
reasoning,
|
||||
input: vision ? ["text", "image"] : ["text"],
|
||||
cost,
|
||||
contextWindow,
|
||||
maxTokens,
|
||||
...(thinking ? { thinking } : {}),
|
||||
...(supportsTools === false ? { supportsTools } : {}),
|
||||
};
|
||||
},
|
||||
fetch: config?.fetch,
|
||||
}),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 15. Together
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { basetenModelManagerOptions } from "@oh-my-pi/pi-catalog/provider-models/openai-compat";
|
||||
import type { FetchImpl } from "@oh-my-pi/pi-catalog/types";
|
||||
|
||||
describe("Baseten provider discovery", () => {
|
||||
test("discovers Baseten models with custom metadata", async () => {
|
||||
const calls: Array<{ url: string; authorization: string | null }> = [];
|
||||
const fetchMock: FetchImpl = async (input: string | URL | Request, init?: RequestInit) => {
|
||||
const headers = new Headers(init?.headers);
|
||||
calls.push({
|
||||
url: String(input),
|
||||
authorization: headers.get("authorization"),
|
||||
});
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
data: [
|
||||
{
|
||||
id: "moonshotai/Kimi-K2.7-Code",
|
||||
object: "model",
|
||||
name: "Kimi K2.7 Code",
|
||||
context_length: 262000,
|
||||
max_completion_tokens: 262000,
|
||||
supported_features: ["tools", "json_mode", "structured_outputs", "reasoning"],
|
||||
input_modalities: ["text", "image"],
|
||||
pricing: {
|
||||
prompt: "0.00000095",
|
||||
completion: "0.000004",
|
||||
input_cache_read: "0.00000016",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "deepseek-ai/DeepSeek-V4-Pro",
|
||||
object: "model",
|
||||
name: "DeepSeek V4 Pro",
|
||||
context_length: 262144,
|
||||
max_completion_tokens: 262144,
|
||||
supported_features: ["tools", "json_mode", "structured_outputs", "reasoning"],
|
||||
input_modalities: ["text"],
|
||||
pricing: {
|
||||
prompt: "0.00000174",
|
||||
completion: "0.00000348",
|
||||
input_cache_read: "0.000000145",
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
{ status: 200, headers: { "content-type": "application/json" } },
|
||||
);
|
||||
};
|
||||
|
||||
const options = basetenModelManagerOptions({ apiKey: "baseten-test-key", fetch: fetchMock });
|
||||
const models = await options.fetchDynamicModels?.();
|
||||
|
||||
expect(calls).toEqual([
|
||||
{
|
||||
url: "https://inference.baseten.co/v1/models",
|
||||
authorization: "Bearer baseten-test-key",
|
||||
},
|
||||
]);
|
||||
|
||||
const kimi = models?.find(model => model.id === "moonshotai/Kimi-K2.7-Code");
|
||||
expect(kimi).toBeDefined();
|
||||
expect(kimi).toMatchObject({
|
||||
provider: "baseten",
|
||||
api: "openai-completions",
|
||||
name: "Kimi K2.7 Code",
|
||||
reasoning: false,
|
||||
input: ["text", "image"],
|
||||
contextWindow: 262000,
|
||||
maxTokens: 262000,
|
||||
cost: {
|
||||
input: 0.95,
|
||||
output: 4,
|
||||
cacheRead: 0.16,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const deepseek = models?.find(model => model.id === "deepseek-ai/DeepSeek-V4-Pro");
|
||||
expect(deepseek).toBeDefined();
|
||||
expect(deepseek).toMatchObject({
|
||||
provider: "baseten",
|
||||
api: "openai-completions",
|
||||
name: "DeepSeek V4 Pro",
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
contextWindow: 262144,
|
||||
maxTokens: 262144,
|
||||
cost: {
|
||||
input: 1.74,
|
||||
output: 3.48,
|
||||
cacheRead: 0.145,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user