1 line
6.0 KiB
JSON
1 line
6.0 KiB
JSON
{"repo": "caiomioto2/meta-ads-saas", "files": {"packages/ai/src/agent/llm-provider.ts": {"c2b0a6c2516752ef3410cd31ac7400d8f1169759": {"t": 1785745577.4681075, "n": 5604, "h": "5c5eca975ae35c80", "c": "import {\n createAnthropic as anthropic,\n type AnthropicProvider,\n} from \"@ai-sdk/anthropic\";\nimport {\n createDeepSeek as deepseek,\n type DeepSeekProvider,\n} from \"@ai-sdk/deepseek\";\nimport {\n createGoogleGenerativeAI as google,\n type GoogleGenerativeAIProvider,\n} from \"@ai-sdk/google\";\nimport { createOpenAI as openai, type OpenAIProvider } from \"@ai-sdk/openai\";\nimport { createXai as xai, type XaiProvider } from \"@ai-sdk/xai\";\nimport { createOpenRouter as openrouter } from \"@openrouter/ai-sdk-provider\";\nimport type { LanguageModel } from \"ai\";\n\ninterface AIGatewayOptions {\n accountId: string;\n gatewayId: string;\n provider: string;\n envs: Record<string, string>;\n bypassOpenRouter?: boolean;\n bypassGateway?: boolean;\n apiKey?: string;\n metadata?: Record<string, string>;\n}\n\nconst aiGatewayForProvider = ({\n accountId,\n gatewayId,\n provider,\n}: AIGatewayOptions) =>\n `https://gateway.ai.cloudflare.com/v1/${accountId}/${gatewayId}/${provider}`;\n\ntype ProviderFactory = (\n opts: AIGatewayOptions,\n) => (model: string) => { llm: LanguageModel; tokenLimit: number };\n\ntype NativeLLMCreator = <\n TOpts extends {\n baseURL?: string;\n apiKey: string;\n headers?: Record<string, string>;\n },\n>(\n opts: TOpts,\n) => (model: string) => LanguageModel;\n\ntype ModelsOf<TProvider extends (model: string) => LanguageModel> =\n Parameters<TProvider>[0];\n\ntype Provider = {\n creator: NativeLLMCreator;\n envVarName: string;\n supportsOpenRouter?: boolean;\n /** Maps openrouter model name to native model name so we can use the api directly, bypassing openrouter. */\n mapOpenRouterModel?: Record<string, string>;\n tokenLimit?: Record<string | \"default\", number>;\n};\n/**\n * Supported providers for the AI Gateway\n */\nexport const providers: Record<string, Provider> = {\n anthropic: {\n supportsOpenRouter: false, // generateObject fails when using openrouter.\n creator: anthropic,\n envVarName: \"ANTHROPIC_API_KEY\",\n mapOpenRouterModel: {\n \"claude-sonnet-4.5\": \"claude-sonnet-4-5-20250929\",\n \"claude-haiku-4.5\": \"claude-haiku-4-5-20251001\",\n \"claude-sonnet-4\": \"claude-sonnet-4-20250514\",\n \"claude-3.7-sonnet:thinking\": \"claude-3-7-sonnet-latest\",\n } satisfies Partial<Record<string, ModelsOf<AnthropicProvider>>>,\n tokenLimit: {\n default: 1_000_000,\n \"claude-sonnet-4.5\": 1_000_000,\n \"claude-haiku-4.5\": 200_000,\n \"claude-sonnet-4\": 200_000,\n \"claude-3.7-sonnet:thinking\": 200_000,\n \"claude-3-5-sonnet-latest\": 200_000,\n } satisfies Partial<\n Record<ModelsOf<AnthropicProvider> | \"default\", number>\n >,\n },\n google: {\n creator: google,\n envVarName: \"GOOGLE_API_KEY\",\n tokenLimit: {\n default: 200_000,\n \"gemini-2.5-pro-preview-03-25\": 1_000_000,\n \"gemini-3-pro-preview\": 1_048_576,\n } satisfies Partial<\n Record<ModelsOf<GoogleGenerativeAIProvider> | \"default\", number>\n >,\n },\n openai: {\n creator: openai,\n envVarName: \"OPENAI_API_KEY\",\n tokenLimit: {\n default: 200_000,\n \"gpt-5.1-codex\": 400_000,\n \"gpt-4.1-nano\": 1_047_576,\n \"gpt-4.1-mini\": 1_047_576,\n \"gpt-4.1\": 1_047_576,\n \"o3-mini-high\": 200_000,\n } satisfies Partial<Record<ModelsOf<OpenAIProvider> | \"default\", number>>,\n },\n deepseek: {\n creator: deepseek,\n envVarName: \"DEEPSEEK_API_KEY\",\n tokenLimit: {\n default: 200_000,\n } satisfies Partial<Record<ModelsOf<DeepSeekProvider> | \"default\", number>>,\n },\n \"x-ai\": {\n creator: xai,\n envVarName: \"XAI_API_KEY\",\n tokenLimit: {\n default: 200_000,\n \"grok-3-beta\": 131_072,\n } satisfies Partial<Record<ModelsOf<XaiProvider> | \"default\", number>>,\n },\n} as const;\n\nconst OPENROUTER_HEADERS = {\n \"HTTP-Referer\": \"https://decocms.com\",\n \"X-Title\": \"Deco\",\n};\n\nconst modelLimit = (provider: Provider, model: string) =>\n provider.tokenLimit?.[model] ?? provider.tokenLimit?.default ?? 200_000;\n\nexport const createLLMProvider: ProviderFactory = (opts) => {\n const provider = providers[opts.provider];\n if (!provider) {\n throw new Error(`Provider ${opts.provider} not supported`);\n }\n\n const supportsOpenRouter = provider.supportsOpenRouter !== false;\n const openRouterApiKey = opts.envs[\"OPENROUTER_API_KEY\"];\n if (\n !supportsOpenRouter ||\n !openRouterApiKey ||\n opts.bypassOpenRouter ||\n opts.apiKey\n ) {\n const creator = provider.creator({\n apiKey: opts.apiKey ?? opts.envs[provider.envVarName],\n baseURL: opts.bypassGateway ? undefined : aiGatewayForProvider(opts),\n headers: opts.metadata\n ? {\n \"cf-aig-metadata\": JSON.stringify(opts.metadata),\n }\n : undefined,\n });\n return (model: string) => {\n model =\n opts.bypassOpenRouter || provider.supportsOpenRouter === false\n ? (provider.mapOpenRouterModel?.[model] ?? model)\n : model;\n return { llm: creator(model), tokenLimit: modelLimit(provider, model) };\n };\n }\n\n const openRouterProvider = openrouter({\n apiKey: openRouterApiKey,\n headers: opts.metadata\n ? {\n ...OPENROUTER_HEADERS,\n \"cf-aig-metadata\": JSON.stringify(opts.metadata),\n }\n : undefined,\n baseURL: opts.bypassGateway\n ? undefined\n : aiGatewayForProvider({ ...opts, provider: \"openrouter\" }),\n });\n\n const creator = (model: string) =>\n openRouterProvider(`${opts.provider}/${model}`);\n return (model: string) => {\n return {\n llm: creator(model),\n tokenLimit: modelLimit(\n provider,\n provider.mapOpenRouterModel?.[model] ?? model,\n ),\n };\n };\n};\n"}}}} |