summaryrefslogtreecommitdiff
path: root/admin-panel/src/server/services/claude.service.ts
diff options
context:
space:
mode:
Diffstat (limited to 'admin-panel/src/server/services/claude.service.ts')
-rw-r--r--admin-panel/src/server/services/claude.service.ts47
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,
+ };
+}