/**
* AI Provider Registry
*
* Defines available AI providers and models.
* - Workers AI: Free edge models (no API key needed)
* - External: Via AI Gateway with BYOK (API keys in Cloudflare dashboard)
*/
export interface ProviderInfo {
name: string;
description: string;
models: string[];
requiresApiKey: boolean;
}
/**
* Available AI providers
*
* Workers AI models use @cf/ prefix and run on the edge for free.
* External providers require API keys configured in AI Gateway.
*/
export const PROVIDERS: Record<string, ProviderInfo> = {
// Workers AI - Free edge models (no API key needed)
// Models with ⚡ support function calling
cloudflare: {
name: 'Cloudflare Workers AI',
description: 'Free edge AI models with function calling support',
requiresApiKey: false,
models: [
// Function calling models only (verified from CF docs Jan 2026)
// https://developers.cloudflare.com/workers-ai/features/function-calling/
'@cf/meta/llama-4-scout-17b-16e-instruct', // Llama 4 Scout - newest!
'@cf/meta/llama-3.3-70b-instruct-fp8-fast', // Llama 3.3 70B
'@cf/ibm-granite/granite-4.0-h-micro', // IBM Granite 4.0
'@cf/qwen/qwen3-30b-a3b-fp8', // Qwen 3 (NOT 2.5!)
'@cf/mistralai/mistral-small-3.1-24b-instruct', // Mistral Small 3.1
'@hf/nousresearch/hermes-2-pro-mistral-7b', // Hermes 2 Pro
],
},
// External providers via AI Gateway (require BYOK setup)
openai: {
name: 'OpenAI',
description: 'GPT models via AI Gateway',
requiresApiKey: true,
models: [
'gpt-4o',
'gpt-4o-mini',
'gpt-4-turbo',
'o1',
'o1-mini',
],
},
anthropic: {
name: 'Anthropic',
description: 'Claude models via AI Gateway',
requiresApiKey: true,
models: [
'claude-sonnet-4-5-20250929',
'claude-3-7-sonnet-20250219',
'claude-3-5-sonnet-20241022',
'claude-3-5-haiku-20241022',
],
},
'google-ai-studio': {
name: 'Google AI Studio',
description: 'Gemini models via AI Gateway',
requiresApiKey: true,
models: [
'gemini-2.5-pro',
'gemini-2.5-flash',
'gemini-2.0-flash',
],
},
groq: {
name: 'Groq',
description: 'Fast inference via AI Gateway',
requiresApiKey: true,
models: [
'llama-3.3-70b-versatile',
'mixtral-8x7b-32768',
],
},
// Extended providers (via AI Gateway)
mistral: {
name: 'Mistral AI',
description: 'Mistral models via AI Gateway',
requiresApiKey: true,
models: [
'mistral-large-latest',
'mistral-small-latest',
],
},
deepseek: {
name: 'DeepSeek',
description: 'DeepSeek models via AI Gateway',
requiresApiKey: true,
models: [
'deepseek-chat',
'deepseek-coder',
],
},
cohere: {
name: 'Cohere',
description: 'Cohere models via AI Gateway',
requiresApiKey: true,
models: [
'command-r-plus',
'command-r',
],
},
grok: {
name: 'xAI (Grok)',
description: 'Grok models via AI Gateway',
requiresApiKey: true,
models: [
'grok-2',
'grok-2-mini',
],
},
};
/**
* Models that support tool calling / function calling
* Workers AI models verified from: https://developers.cloudflare.com/workers-ai/features/function-calling/
*/
export const TOOL_CAPABLE_MODELS: string[] = [
// Workers AI - Function calling models (verified Jan 2026)
'@cf/meta/llama-4-scout-17b-16e-instruct', // Llama 4 Scout
'@cf/meta/llama-3.3-70b-instruct-fp8-fast', // Llama 3.3 70B
'@cf/ibm-granite/granite-4.0-h-micro', // IBM Granite 4.0
'@cf/qwen/qwen3-30b-a3b-fp8', // Qwen 3 (NOT Qwen 2.5!)
'@cf/mistralai/mistral-small-3.1-24b-instruct', // Mistral Small 3.1
'@hf/nousresearch/hermes-2-pro-mistral-7b', // Hermes 2 Pro
// OpenAI
'gpt-4o',
'gpt-4o-mini',
'gpt-4-turbo',
// Anthropic
'claude-sonnet-4-5-20250929',
'claude-3-7-sonnet-20250219',
'claude-3-5-sonnet-20241022',
'claude-3-5-haiku-20241022',
// Google
'gemini-2.5-pro',
'gemini-2.5-flash',
'gemini-2.0-flash',
// Groq
'llama-3.3-70b-versatile',
// Mistral
'mistral-large-latest',
'mistral-small-latest',
// DeepSeek
'deepseek-chat',
// Cohere
'command-r-plus',
'command-r',
// xAI
'grok-2',
'grok-2-mini',
];
/**
* Default model for each provider
*/
export const DEFAULT_MODELS: Record<string, string> = {
cloudflare: '@cf/meta/llama-4-scout-17b-16e-instruct', // Llama 4 - best function calling
openai: 'gpt-4o-mini',
anthropic: 'claude-sonnet-4-5-20250929',
'google-ai-studio': 'gemini-2.5-flash',
groq: 'llama-3.3-70b-versatile',
mistral: 'mistral-large-latest',
deepseek: 'deepseek-chat',
cohere: 'command-r-plus',
grok: 'grok-2',
};
/**
* Parse a model ID to extract provider and model name
*
* Conventions:
* - @cf/vendor/model-name → Workers AI (provider: cloudflare)
* - provider/model-name → External via AI Gateway
* - Just model-name → Assumes cloudflare if starts with @cf, otherwise openai
*/
export function parseModelId(modelId: string): { provider: string; model: string } {
// Workers AI models (both @cf/ and @hf/ prefixes)
if (modelId.startsWith('@cf/') || modelId.startsWith('@hf/')) {
return { provider: 'cloudflare', model: modelId };
}
// External provider format: provider/model
if (modelId.includes('/')) {
const [provider, ...rest] = modelId.split('/');
return { provider, model: rest.join('/') };
}
// Default to openai for bare model names
return { provider: 'openai', model: modelId };
}
/**
* Get all available providers
*/
export function getAllProviders(): Array<{ id: string } & ProviderInfo> {
return Object.entries(PROVIDERS).map(([id, info]) => ({ id, ...info }));
}
/**
* Get providers that don't require API keys (can be used immediately)
*/
export function getFreeProviders(): Array<{ id: string } & ProviderInfo> {
return getAllProviders().filter(p => !p.requiresApiKey);
}