diff options
Diffstat (limited to 'admin-panel/src/server/services/claude.service.ts')
| -rw-r--r-- | admin-panel/src/server/services/claude.service.ts | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/admin-panel/src/server/services/claude.service.ts b/admin-panel/src/server/services/claude.service.ts new file mode 100644 index 0000000..b9aae37 --- /dev/null +++ b/admin-panel/src/server/services/claude.service.ts @@ -0,0 +1,47 @@ +import Anthropic from '@anthropic-ai/sdk'; + +let client: Anthropic | null = null; + +function getClient(): Anthropic { + if (!client) { + const apiKey = process.env.ANTHROPIC_API_KEY; + if (!apiKey) throw new Error('ANTHROPIC_API_KEY not configured'); + client = new Anthropic({ apiKey }); + } + return client; +} + +export interface ClaudeResponse { + content: string; + tokensUsed: number; + model: string; +} + +export async function callClaude(opts: { + model: string; + systemPrompt: string; + userMessage: string; + maxTokens?: number; +}): Promise<ClaudeResponse> { + const anthropic = getClient(); + + const response = await anthropic.messages.create({ + model: opts.model, + max_tokens: opts.maxTokens || 8192, + system: opts.systemPrompt, + messages: [{ role: 'user', content: opts.userMessage }], + }); + + const content = response.content + .filter(block => block.type === 'text') + .map(block => (block as { type: 'text'; text: string }).text) + .join('\n'); + + const tokensUsed = (response.usage?.input_tokens || 0) + (response.usage?.output_tokens || 0); + + return { + content, + tokensUsed, + model: opts.model, + }; +} |
