Files

1 line
15 KiB
JSON

{"repo": "autumnsgrove/grovescout", "files": {"src/lib/server/agents/providers.ts": {"fa8b769b876212b8c79bcc5f4da4605874ba5d1f": {"t": 1785745578.6558294, "n": 4997, "h": "4de9317276ebf615", "c": "// Scout - AI Provider Abstraction\n// Supports multiple AI providers (Claude, DeepSeek, Kimi, Cloudflare AI) with a common interface.\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport type { Message } from '@anthropic-ai/sdk/resources/messages.mjs';\n\nexport type ProviderName = 'claude' | 'deepseek' | 'kimi' | 'cloudflare-ai';\n\nexport interface GenerateOptions {\n\tmodel: string;\n\tsystem?: string;\n\tmessages: Array<{ role: 'user' | 'assistant'; content: string }>;\n\tmax_tokens: number;\n\ttemperature?: number;\n}\n\nexport interface ProviderResponse {\n\tcontent: string;\n\tusage: {\n\t\tinput_tokens: number;\n\t\toutput_tokens: number;\n\t};\n}\n\nexport interface AIProvider {\n\tsupportsTools: boolean;\n\tgenerate(options: GenerateOptions): Promise<ProviderResponse>;\n\tgenerateWithTools?(options: GenerateOptions & { tools: any }): Promise<ProviderResponse>;\n}\n\n// Anthropic (Claude) Provider\nexport class AnthropicProvider implements AIProvider {\n\tsupportsTools = true;\n\tprivate client: Anthropic;\n\n\tconstructor(apiKey: string) {\n\t\tthis.client = new Anthropic({ apiKey });\n\t}\n\n\tasync generate(options: GenerateOptions): Promise<ProviderResponse> {\n\t\tconst response = await this.client.messages.create({\n\t\t\tmodel: options.model,\n\t\t\tsystem: options.system,\n\t\t\tmessages: options.messages as any,\n\t\t\tmax_tokens: options.max_tokens,\n\t\t\ttemperature: options.temperature,\n\t\t});\n\n\t\tconst content = response.content[0];\n\t\tif (content.type !== 'text') {\n\t\t\tthrow new Error('Non-text response from Anthropic');\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: content.text,\n\t\t\tusage: {\n\t\t\t\tinput_tokens: response.usage.input_tokens,\n\t\t\t\toutput_tokens: response.usage.output_tokens,\n\t\t\t},\n\t\t};\n\t}\n\n\t// Anthropic supports tool use, but we'll keep it simple for now\n\tasync generateWithTools(options: GenerateOptions & { tools: any }): Promise<ProviderResponse> {\n\t\t// Implement tool calling if needed\n\t\tthrow new Error('Tool calling not yet implemented for Anthropic');\n\t}\n}\n\n// DeepSeek Provider - OpenAI-compatible API\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/chat/completions';\n\nexport class DeepSeekProvider implements AIProvider {\n\tsupportsTools = true;\n\tprivate apiKey: string;\n\n\tconstructor(apiKey: string) {\n\t\tif (!apiKey) {\n\t\t\tthrow new Error('DeepSeek API key not provided');\n\t\t}\n\t\tthis.apiKey = apiKey;\n\t}\n\n\tasync generate(options: GenerateOptions): Promise<ProviderResponse> {\n\t\tconst messages: Array<{ role: string; content: string }> = [];\n\n\t\tif (options.system) {\n\t\t\tmessages.push({ role: 'system', content: options.system });\n\t\t}\n\n\t\tfor (const msg of options.messages) {\n\t\t\tmessages.push({ role: msg.role, content: msg.content });\n\t\t}\n\n\t\tconst response = await fetch(DEEPSEEK_API_URL, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t'Authorization': `Bearer ${this.apiKey}`,\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tmodel: options.model || 'deepseek-chat',\n\t\t\t\tmessages,\n\t\t\t\tmax_tokens: options.max_tokens,\n\t\t\t\ttemperature: options.temperature ?? 0.7,\n\t\t\t}),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst errorText = await response.text();\n\t\t\tthrow new Error(`DeepSeek API error: ${response.status} - ${errorText.slice(0, 200)}`);\n\t\t}\n\n\t\tconst data = await response.json() as DeepSeekResponse;\n\n\t\tconst content = data.choices?.[0]?.message?.content || '';\n\n\t\treturn {\n\t\t\tcontent,\n\t\t\tusage: {\n\t\t\t\tinput_tokens: data.usage?.prompt_tokens || 0,\n\t\t\t\toutput_tokens: data.usage?.completion_tokens || 0,\n\t\t\t},\n\t\t};\n\t}\n}\n\ninterface DeepSeekResponse {\n\tid: string;\n\tobject: string;\n\tcreated: number;\n\tmodel: string;\n\tchoices: Array<{\n\t\tindex: number;\n\t\tmessage: {\n\t\t\trole: string;\n\t\t\tcontent: string | null;\n\t\t};\n\t\tfinish_reason: string;\n\t}>;\n\tusage: {\n\t\tprompt_tokens: number;\n\t\tcompletion_tokens: number;\n\t\ttotal_tokens: number;\n\t};\n}\n\n// Kimi Provider (placeholder)\nexport class KimiProvider implements AIProvider {\n\tsupportsTools = false;\n\tprivate apiKey: string;\n\n\tconstructor(apiKey: string) {\n\t\tthis.apiKey = apiKey;\n\t}\n\n\tasync generate(options: GenerateOptions): Promise<ProviderResponse> {\n\t\tthrow new Error('Kimi provider not yet implemented');\n\t}\n}\n\n// Cloudflare AI Provider (placeholder)\nexport class CloudflareAIProvider implements AIProvider {\n\tsupportsTools = false;\n\tprivate accountId: string;\n\tprivate apiToken: string;\n\n\tconstructor(accountId: string, apiToken: string) {\n\t\tthis.accountId = accountId;\n\t\tthis.apiToken = apiToken;\n\t}\n\n\tasync generate(options: GenerateOptions): Promise<ProviderResponse> {\n\t\tthrow new Error('Cloudflare AI provider not yet implemented');\n\t}\n}\n\n// Provider factory\nexport function getProvider(name: ProviderName, env: any): AIProvider {\n\tswitch (name) {\n\t\tcase 'claude':\n\t\t\treturn new AnthropicProvider(env.ANTHROPIC_API_KEY);\n\t\tcase 'deepseek':\n\t\t\treturn new DeepSeekProvider(env.DEEPSEEK_API_KEY || '');\n\t\tcase 'kimi':\n\t\t\treturn new KimiProvider(env.KIMI_API_KEY || '');\n\t\tcase 'cloudflare-ai':\n\t\t\treturn new CloudflareAIProvider(env.CLOUDFLARE_ACCOUNT_ID || '', env.CLOUDFLARE_API_TOKEN || '');\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown provider: ${name}`);\n\t}\n}"}, "e8e18719593b93dbabf5634cedaaf4b68dad58ca": {"t": 1785754420.41148, "n": 4997, "h": "4de9317276ebf615", "c": "// Scout - AI Provider Abstraction\n// Supports multiple AI providers (Claude, DeepSeek, Kimi, Cloudflare AI) with a common interface.\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport type { Message } from '@anthropic-ai/sdk/resources/messages.mjs';\n\nexport type ProviderName = 'claude' | 'deepseek' | 'kimi' | 'cloudflare-ai';\n\nexport interface GenerateOptions {\n\tmodel: string;\n\tsystem?: string;\n\tmessages: Array<{ role: 'user' | 'assistant'; content: string }>;\n\tmax_tokens: number;\n\ttemperature?: number;\n}\n\nexport interface ProviderResponse {\n\tcontent: string;\n\tusage: {\n\t\tinput_tokens: number;\n\t\toutput_tokens: number;\n\t};\n}\n\nexport interface AIProvider {\n\tsupportsTools: boolean;\n\tgenerate(options: GenerateOptions): Promise<ProviderResponse>;\n\tgenerateWithTools?(options: GenerateOptions & { tools: any }): Promise<ProviderResponse>;\n}\n\n// Anthropic (Claude) Provider\nexport class AnthropicProvider implements AIProvider {\n\tsupportsTools = true;\n\tprivate client: Anthropic;\n\n\tconstructor(apiKey: string) {\n\t\tthis.client = new Anthropic({ apiKey });\n\t}\n\n\tasync generate(options: GenerateOptions): Promise<ProviderResponse> {\n\t\tconst response = await this.client.messages.create({\n\t\t\tmodel: options.model,\n\t\t\tsystem: options.system,\n\t\t\tmessages: options.messages as any,\n\t\t\tmax_tokens: options.max_tokens,\n\t\t\ttemperature: options.temperature,\n\t\t});\n\n\t\tconst content = response.content[0];\n\t\tif (content.type !== 'text') {\n\t\t\tthrow new Error('Non-text response from Anthropic');\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: content.text,\n\t\t\tusage: {\n\t\t\t\tinput_tokens: response.usage.input_tokens,\n\t\t\t\toutput_tokens: response.usage.output_tokens,\n\t\t\t},\n\t\t};\n\t}\n\n\t// Anthropic supports tool use, but we'll keep it simple for now\n\tasync generateWithTools(options: GenerateOptions & { tools: any }): Promise<ProviderResponse> {\n\t\t// Implement tool calling if needed\n\t\tthrow new Error('Tool calling not yet implemented for Anthropic');\n\t}\n}\n\n// DeepSeek Provider - OpenAI-compatible API\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/chat/completions';\n\nexport class DeepSeekProvider implements AIProvider {\n\tsupportsTools = true;\n\tprivate apiKey: string;\n\n\tconstructor(apiKey: string) {\n\t\tif (!apiKey) {\n\t\t\tthrow new Error('DeepSeek API key not provided');\n\t\t}\n\t\tthis.apiKey = apiKey;\n\t}\n\n\tasync generate(options: GenerateOptions): Promise<ProviderResponse> {\n\t\tconst messages: Array<{ role: string; content: string }> = [];\n\n\t\tif (options.system) {\n\t\t\tmessages.push({ role: 'system', content: options.system });\n\t\t}\n\n\t\tfor (const msg of options.messages) {\n\t\t\tmessages.push({ role: msg.role, content: msg.content });\n\t\t}\n\n\t\tconst response = await fetch(DEEPSEEK_API_URL, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t'Authorization': `Bearer ${this.apiKey}`,\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tmodel: options.model || 'deepseek-chat',\n\t\t\t\tmessages,\n\t\t\t\tmax_tokens: options.max_tokens,\n\t\t\t\ttemperature: options.temperature ?? 0.7,\n\t\t\t}),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst errorText = await response.text();\n\t\t\tthrow new Error(`DeepSeek API error: ${response.status} - ${errorText.slice(0, 200)}`);\n\t\t}\n\n\t\tconst data = await response.json() as DeepSeekResponse;\n\n\t\tconst content = data.choices?.[0]?.message?.content || '';\n\n\t\treturn {\n\t\t\tcontent,\n\t\t\tusage: {\n\t\t\t\tinput_tokens: data.usage?.prompt_tokens || 0,\n\t\t\t\toutput_tokens: data.usage?.completion_tokens || 0,\n\t\t\t},\n\t\t};\n\t}\n}\n\ninterface DeepSeekResponse {\n\tid: string;\n\tobject: string;\n\tcreated: number;\n\tmodel: string;\n\tchoices: Array<{\n\t\tindex: number;\n\t\tmessage: {\n\t\t\trole: string;\n\t\t\tcontent: string | null;\n\t\t};\n\t\tfinish_reason: string;\n\t}>;\n\tusage: {\n\t\tprompt_tokens: number;\n\t\tcompletion_tokens: number;\n\t\ttotal_tokens: number;\n\t};\n}\n\n// Kimi Provider (placeholder)\nexport class KimiProvider implements AIProvider {\n\tsupportsTools = false;\n\tprivate apiKey: string;\n\n\tconstructor(apiKey: string) {\n\t\tthis.apiKey = apiKey;\n\t}\n\n\tasync generate(options: GenerateOptions): Promise<ProviderResponse> {\n\t\tthrow new Error('Kimi provider not yet implemented');\n\t}\n}\n\n// Cloudflare AI Provider (placeholder)\nexport class CloudflareAIProvider implements AIProvider {\n\tsupportsTools = false;\n\tprivate accountId: string;\n\tprivate apiToken: string;\n\n\tconstructor(accountId: string, apiToken: string) {\n\t\tthis.accountId = accountId;\n\t\tthis.apiToken = apiToken;\n\t}\n\n\tasync generate(options: GenerateOptions): Promise<ProviderResponse> {\n\t\tthrow new Error('Cloudflare AI provider not yet implemented');\n\t}\n}\n\n// Provider factory\nexport function getProvider(name: ProviderName, env: any): AIProvider {\n\tswitch (name) {\n\t\tcase 'claude':\n\t\t\treturn new AnthropicProvider(env.ANTHROPIC_API_KEY);\n\t\tcase 'deepseek':\n\t\t\treturn new DeepSeekProvider(env.DEEPSEEK_API_KEY || '');\n\t\tcase 'kimi':\n\t\t\treturn new KimiProvider(env.KIMI_API_KEY || '');\n\t\tcase 'cloudflare-ai':\n\t\t\treturn new CloudflareAIProvider(env.CLOUDFLARE_ACCOUNT_ID || '', env.CLOUDFLARE_API_TOKEN || '');\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown provider: ${name}`);\n\t}\n}"}, "f24cb579c32e980ed48af8f8ba347408919d9c6d": {"t": 1785754424.657006, "n": 3574, "h": "7ccf6705a91a4137", "c": "// Scout - AI Provider Abstraction\n// Supports multiple AI providers (Claude, DeepSeek, Kimi, Cloudflare AI) with a common interface.\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport type { Message } from '@anthropic-ai/sdk/resources/messages.mjs';\n\nexport type ProviderName = 'claude' | 'deepseek' | 'kimi' | 'cloudflare-ai';\n\nexport interface GenerateOptions {\n\tmodel: string;\n\tsystem?: string;\n\tmessages: Array<{ role: 'user' | 'assistant'; content: string }>;\n\tmax_tokens: number;\n\ttemperature?: number;\n}\n\nexport interface ProviderResponse {\n\tcontent: string;\n\tusage: {\n\t\tinput_tokens: number;\n\t\toutput_tokens: number;\n\t};\n}\n\nexport interface AIProvider {\n\tsupportsTools: boolean;\n\tgenerate(options: GenerateOptions): Promise<ProviderResponse>;\n\tgenerateWithTools?(options: GenerateOptions & { tools: any }): Promise<ProviderResponse>;\n}\n\n// Anthropic (Claude) Provider\nexport class AnthropicProvider implements AIProvider {\n\tsupportsTools = true;\n\tprivate client: Anthropic;\n\n\tconstructor(apiKey: string) {\n\t\tthis.client = new Anthropic({ apiKey });\n\t}\n\n\tasync generate(options: GenerateOptions): Promise<ProviderResponse> {\n\t\tconst response = await this.client.messages.create({\n\t\t\tmodel: options.model,\n\t\t\tsystem: options.system,\n\t\t\tmessages: options.messages as any,\n\t\t\tmax_tokens: options.max_tokens,\n\t\t\ttemperature: options.temperature,\n\t\t});\n\n\t\tconst content = response.content[0];\n\t\tif (content.type !== 'text') {\n\t\t\tthrow new Error('Non-text response from Anthropic');\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: content.text,\n\t\t\tusage: {\n\t\t\t\tinput_tokens: response.usage.input_tokens,\n\t\t\t\toutput_tokens: response.usage.output_tokens,\n\t\t\t},\n\t\t};\n\t}\n\n\t// Anthropic supports tool use, but we'll keep it simple for now\n\tasync generateWithTools(options: GenerateOptions & { tools: any }): Promise<ProviderResponse> {\n\t\t// Implement tool calling if needed\n\t\tthrow new Error('Tool calling not yet implemented for Anthropic');\n\t}\n}\n\n// DeepSeek Provider (placeholder)\nexport class DeepSeekProvider implements AIProvider {\n\tsupportsTools = false;\n\tprivate apiKey: string;\n\n\tconstructor(apiKey: string) {\n\t\tthis.apiKey = apiKey;\n\t}\n\n\tasync generate(options: GenerateOptions): Promise<ProviderResponse> {\n\t\t// TODO: Implement DeepSeek API call\n\t\tthrow new Error('DeepSeek provider not yet implemented');\n\t}\n}\n\n// Kimi Provider (placeholder)\nexport class KimiProvider implements AIProvider {\n\tsupportsTools = false;\n\tprivate apiKey: string;\n\n\tconstructor(apiKey: string) {\n\t\tthis.apiKey = apiKey;\n\t}\n\n\tasync generate(options: GenerateOptions): Promise<ProviderResponse> {\n\t\tthrow new Error('Kimi provider not yet implemented');\n\t}\n}\n\n// Cloudflare AI Provider (placeholder)\nexport class CloudflareAIProvider implements AIProvider {\n\tsupportsTools = false;\n\tprivate accountId: string;\n\tprivate apiToken: string;\n\n\tconstructor(accountId: string, apiToken: string) {\n\t\tthis.accountId = accountId;\n\t\tthis.apiToken = apiToken;\n\t}\n\n\tasync generate(options: GenerateOptions): Promise<ProviderResponse> {\n\t\tthrow new Error('Cloudflare AI provider not yet implemented');\n\t}\n}\n\n// Provider factory\nexport function getProvider(name: ProviderName, env: any): AIProvider {\n\tswitch (name) {\n\t\tcase 'claude':\n\t\t\treturn new AnthropicProvider(env.ANTHROPIC_API_KEY);\n\t\tcase 'deepseek':\n\t\t\treturn new DeepSeekProvider(env.DEEPSEEK_API_KEY || '');\n\t\tcase 'kimi':\n\t\t\treturn new KimiProvider(env.KIMI_API_KEY || '');\n\t\tcase 'cloudflare-ai':\n\t\t\treturn new CloudflareAIProvider(env.CLOUDFLARE_ACCOUNT_ID || '', env.CLOUDFLARE_API_TOKEN || '');\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown provider: ${name}`);\n\t}\n}"}}}}