Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | // Copyright 2026 ForgeKit Contributors // SPDX-License-Identifier: Apache-2.0 // https://github.com/SubhanshuMG/ForgeKit import * as https from 'https'; import { AIProvider, ProjectSpec, Template } from '../../types'; import { buildSystemPrompt, parseAIResponse } from './shared'; export class AnthropicProvider implements AIProvider { name = 'anthropic'; private apiKey: string; private model: string; constructor(apiKey: string, model?: string) { this.apiKey = apiKey; this.model = model || 'claude-sonnet-4-6'; } async generateProjectSpec(description: string, templates: Template[]): Promise<ProjectSpec> { const systemPrompt = buildSystemPrompt(templates); const payload = JSON.stringify({ model: this.model, max_tokens: 500, system: systemPrompt, messages: [ { role: 'user', content: description }, ], }); const response = await this.callAPI(payload); // eslint-disable-next-line @typescript-eslint/no-explicit-any const content = (response as any).content?.[0]?.text; Iif (!content) { throw new Error('Anthropic returned an empty response. Please try again.'); } return parseAIResponse(content, templates); } private callAPI(payload: string): Promise<Record<string, unknown>> { return new Promise((resolve, reject) => { const req = https.request( { hostname: 'api.anthropic.com', path: '/v1/messages', method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': this.apiKey, 'anthropic-version': '2023-06-01', 'Content-Length': Buffer.byteLength(payload), }, }, (res) => { const chunks: Buffer[] = []; res.on('data', (chunk: Buffer) => chunks.push(chunk)); res.on('end', () => { const body = Buffer.concat(chunks).toString('utf-8'); Iif (res.statusCode && res.statusCode >= 400) { let message = `Anthropic API error (HTTP ${res.statusCode})`; try { const parsed = JSON.parse(body); Iif (parsed.error?.message) message = parsed.error.message; } catch { /* use default message */ } reject(new Error(message)); return; } try { resolve(JSON.parse(body)); } catch { reject(new Error('Failed to parse Anthropic response')); } }); res.on('error', reject); } ); req.on('error', reject); // Validate payload is well-formed JSON before sending to external API JSON.parse(payload); req.write(payload); req.end(); }); } } |