Reference implementation for the Phoenix Architecture. Work in progress. aicoding.leaflet.pub/
ai coding crazy
at main 63 lines 1.7 kB view raw
1/** 2 * Anthropic (Claude) LLM Provider. 3 * 4 * Uses the Messages API via native fetch. 5 * Requires ANTHROPIC_API_KEY env var. 6 */ 7 8import type { LLMProvider, GenerateOptions } from './provider.js'; 9 10const API_URL = 'https://api.anthropic.com/v1/messages'; 11const API_VERSION = '2023-06-01'; 12 13export class AnthropicProvider implements LLMProvider { 14 readonly name = 'anthropic'; 15 readonly model: string; 16 private apiKey: string; 17 18 constructor(apiKey: string, model: string) { 19 this.apiKey = apiKey; 20 this.model = model; 21 } 22 23 async generate(prompt: string, options?: GenerateOptions): Promise<string> { 24 const body: Record<string, unknown> = { 25 model: this.model, 26 max_tokens: options?.maxTokens ?? 8192, 27 messages: [{ role: 'user', content: prompt }], 28 }; 29 30 if (options?.system) { 31 body.system = options.system; 32 } 33 if (options?.temperature !== undefined) { 34 body.temperature = options.temperature; 35 } 36 37 const res = await fetch(API_URL, { 38 method: 'POST', 39 headers: { 40 'Content-Type': 'application/json', 41 'x-api-key': this.apiKey, 42 'anthropic-version': API_VERSION, 43 }, 44 body: JSON.stringify(body), 45 }); 46 47 if (!res.ok) { 48 const text = await res.text(); 49 throw new Error(`Anthropic API error ${res.status}: ${text}`); 50 } 51 52 const data = await res.json() as { 53 content: Array<{ type: string; text: string }>; 54 }; 55 56 const textBlocks = data.content.filter(b => b.type === 'text'); 57 if (textBlocks.length === 0) { 58 throw new Error('Anthropic returned no text content'); 59 } 60 61 return textBlocks.map(b => b.text).join(''); 62 } 63}