diff --git a/src/agents/fireworks-models.ts b/src/agents/fireworks-models.ts index a4a30cb9a..556a5d70a 100644 --- a/src/agents/fireworks-models.ts +++ b/src/agents/fireworks-models.ts @@ -1,8 +1,6 @@ import type { ModelDefinitionConfig } from "../config/types.js"; export const FIREWORKS_BASE_URL = "https://api.fireworks.ai/inference/v1"; -export const FIREWORKS_API_BASE_URL = "https://api.fireworks.ai"; -export const FIREWORKS_ACCOUNT_ID = "fireworks"; export const FIREWORKS_DEFAULT_MODEL_ID = "accounts/fireworks/models/deepseek-v3p2"; export const FIREWORKS_DEFAULT_MODEL_REF = `fireworks/${FIREWORKS_DEFAULT_MODEL_ID}`; @@ -18,7 +16,6 @@ export const FIREWORKS_DEFAULT_COST = { /** * Static catalog of Fireworks AI serverless models. * - * This catalog serves as a fallback when the Fireworks API is unreachable. * Only includes LLM models (no image generation), non-deprecated models, * and models that support serverless inference. * @@ -61,17 +58,17 @@ export const FIREWORKS_MODEL_CATALOG = [ { id: "accounts/fireworks/models/deepseek-v3p2", name: "DeepSeek V3.2", - reasoning: true, + reasoning: false, input: ["text"] as const, contextWindow: 163840, maxTokens: 8192, }, - // GLM models + // GLM models - both support "advanced thinking controls" { id: "accounts/fireworks/models/glm-4p6", name: "GLM-4.6", - reasoning: false, + reasoning: true, input: ["text"] as const, contextWindow: 202752, maxTokens: 8192, @@ -85,11 +82,11 @@ export const FIREWORKS_MODEL_CATALOG = [ maxTokens: 8192, }, - // OpenAI gpt-oss models + // OpenAI gpt-oss models - designed for "powerful reasoning, agentic tasks" { id: "accounts/fireworks/models/gpt-oss-120b", name: "OpenAI gpt-oss-120b", - reasoning: false, + reasoning: true, input: ["text"] as const, contextWindow: 131072, maxTokens: 8192, @@ -97,7 +94,7 @@ export const FIREWORKS_MODEL_CATALOG = [ { id: "accounts/fireworks/models/gpt-oss-20b", name: "OpenAI gpt-oss-20b", - reasoning: false, + reasoning: true, input: ["text"] as const, contextWindow: 131072, maxTokens: 8192, @@ -132,11 +129,11 @@ export const FIREWORKS_MODEL_CATALOG = [ maxTokens: 8192, }, - // MiniMax models + // MiniMax models - "long-thinking" and "complex reasoning tasks" { id: "accounts/fireworks/models/minimax-m2", name: "MiniMax-M2", - reasoning: false, + reasoning: true, input: ["text"] as const, contextWindow: 196608, maxTokens: 8192, @@ -144,7 +141,7 @@ export const FIREWORKS_MODEL_CATALOG = [ { id: "accounts/fireworks/models/minimax-m2p1", name: "MiniMax-M2.1", - reasoning: false, + reasoning: true, input: ["text"] as const, contextWindow: 204800, maxTokens: 8192, @@ -244,130 +241,9 @@ export function buildFireworksModelDefinition(entry: FireworksCatalogEntry): Mod }; } -// Fireworks API response types -interface FireworksModel { - name: string; // Full resource name: accounts/fireworks/models/ - displayName?: string; - description?: string; - contextLength?: number; - kind?: string; // HF_BASE_MODEL, FLUMINA_BASE_MODEL, etc. - supportsImageInput?: boolean; - supportsTools?: boolean; - supportsServerless?: boolean; - deprecationDate?: { year: number; month: number; day: number } | null; -} - -interface FireworksModelsResponse { - models: FireworksModel[]; - nextPageToken?: string; -} - -function isDeprecated( - deprecationDate?: { year: number; month: number; day: number } | null, -): boolean { - if (!deprecationDate) return false; - const { year, month, day } = deprecationDate; - const depDate = new Date(year, month - 1, day); - return depDate < new Date(); -} - -function isLlmModel(model: FireworksModel): boolean { - // Skip image generation models (FLUX, etc.) - they use FLUMINA_BASE_MODEL kind - // and have contextLength of 0 - if (model.kind === "FLUMINA_BASE_MODEL") return false; - if (!model.contextLength || model.contextLength === 0) return false; - return true; -} - /** - * Discover serverless LLM models from Fireworks API with fallback to static catalog. + * Returns Fireworks models from the static catalog. */ -export async function discoverFireworksModels(params?: { - apiKey?: string; -}): Promise { - // Skip API discovery in test environment - if (process.env.NODE_ENV === "test" || process.env.VITEST) { - return FIREWORKS_MODEL_CATALOG.map(buildFireworksModelDefinition); - } - - const apiKey = params?.apiKey ?? process.env.FIREWORKS_API_KEY; - if (!apiKey) { - console.warn("[fireworks-models] No API key available, using static catalog"); - return FIREWORKS_MODEL_CATALOG.map(buildFireworksModelDefinition); - } - - try { - const allModels: FireworksModel[] = []; - let pageToken: string | undefined; - - // Paginate through results - do { - const url = new URL(`${FIREWORKS_API_BASE_URL}/v1/accounts/${FIREWORKS_ACCOUNT_ID}/models`); - url.searchParams.set("filter", "supports_serverless=true"); - url.searchParams.set("pageSize", "200"); - if (pageToken) { - url.searchParams.set("pageToken", pageToken); - } - - const response = await fetch(url.toString(), { - headers: { Authorization: `Bearer ${apiKey}` }, - signal: AbortSignal.timeout(10000), - }); - - if (!response.ok) { - console.warn( - `[fireworks-models] Failed to list models: HTTP ${response.status}, using static catalog`, - ); - return FIREWORKS_MODEL_CATALOG.map(buildFireworksModelDefinition); - } - - const data = (await response.json()) as FireworksModelsResponse; - allModels.push(...(data.models ?? [])); - pageToken = data.nextPageToken; - } while (pageToken); - - // Filter and build model definitions - const catalogById = new Map( - FIREWORKS_MODEL_CATALOG.map((m) => [m.id, m]), - ); - const models: ModelDefinitionConfig[] = []; - - for (const apiModel of allModels) { - // Skip deprecated models - if (isDeprecated(apiModel.deprecationDate)) continue; - // Skip non-LLM models (image gen, etc.) - if (!isLlmModel(apiModel)) continue; - - // Use the full name as the ID (accounts/fireworks/models/) - const id = apiModel.name; - const catalogEntry = catalogById.get(id); - - if (catalogEntry) { - // Use catalog metadata for known models - models.push(buildFireworksModelDefinition(catalogEntry)); - } else { - // Create definition for newly discovered models not in catalog - const isReasoning = - id.toLowerCase().includes("r1") || - id.toLowerCase().includes("thinking") || - id.toLowerCase().includes("reasoning") || - (apiModel.description?.toLowerCase().includes("reasoning") ?? false); - - models.push({ - id, - name: apiModel.displayName ?? id.replace(/^accounts\/fireworks\/models\//, ""), - reasoning: isReasoning, - input: apiModel.supportsImageInput ? ["text", "image"] : ["text"], - cost: FIREWORKS_DEFAULT_COST, - contextWindow: apiModel.contextLength ?? 128000, - maxTokens: 8192, - }); - } - } - - return models.length > 0 ? models : FIREWORKS_MODEL_CATALOG.map(buildFireworksModelDefinition); - } catch (error) { - console.warn(`[fireworks-models] Discovery failed: ${String(error)}, using static catalog`); - return FIREWORKS_MODEL_CATALOG.map(buildFireworksModelDefinition); - } +export function discoverFireworksModels(): ModelDefinitionConfig[] { + return FIREWORKS_MODEL_CATALOG.map(buildFireworksModelDefinition); } diff --git a/src/agents/models-config.providers.ts b/src/agents/models-config.providers.ts index 52271ecf9..592313d63 100644 --- a/src/agents/models-config.providers.ts +++ b/src/agents/models-config.providers.ts @@ -351,8 +351,8 @@ async function buildVeniceProvider(): Promise { }; } -async function buildFireworksProvider(apiKey?: string): Promise { - const models = await discoverFireworksModels({ apiKey }); +function buildFireworksProvider(): ProviderConfig { + const models = discoverFireworksModels(); return { baseUrl: FIREWORKS_BASE_URL, api: "openai-completions", @@ -416,7 +416,7 @@ export async function resolveImplicitProviders(params: { resolveEnvApiKeyVarName("fireworks") ?? resolveApiKeyFromProfiles({ provider: "fireworks", store: authStore }); if (fireworksKey) { - providers.fireworks = { ...(await buildFireworksProvider(fireworksKey)), apiKey: fireworksKey }; + providers.fireworks = { ...buildFireworksProvider(), apiKey: fireworksKey }; } const qwenProfiles = listProfilesForProvider(authStore, "qwen-portal");