game-analysis-types
Version:
Common TypeScript types and utilities for game analysis tools.
169 lines • 6.45 kB
JavaScript
/**
* Implementation of the Claude AI model strategy
*/
export class ClaudeModelStrategy {
config;
constructor(config) {
this.config = config;
}
/**
* Get the model configuration
* @returns The model config
*/
getConfig() {
return this.config;
}
/**
* Generate text using Claude API (fulfills AIModelStrategy interface)
* @param request - The AI request with prompt and options
* @returns The AI response
*/
async generate(request) {
if (!this.config.apiEndpoint) {
throw new Error('Claude API endpoint is not configured.');
}
const headers = {
'Content-Type': 'application/json',
'x-api-key': this.config.apiKey,
'anthropic-version': '2023-06-01'
};
const body = {
model: this.config.model,
max_tokens: request.options?.maxTokens || this.config.maxTokens,
temperature: request.options?.temperature || this.config.temperature,
messages: [
...(request.options?.systemPrompt ? [{ role: 'system', content: request.options.systemPrompt }] : []),
{ role: 'user', content: request.prompt }
]
};
try {
const response = await fetch(this.config.apiEndpoint, {
method: 'POST',
headers,
body: JSON.stringify(body)
});
if (!response.ok) {
throw new Error(`Claude API error: ${response.status} ${response.statusText}`);
}
const result = await response.json();
return {
content: result.content[0].text,
model: this.config.model,
tokenUsage: {
input: result.usage.input_tokens,
output: result.usage.output_tokens,
total: result.usage.input_tokens + result.usage.output_tokens
},
cost: this.calculateCost(result.usage.input_tokens, result.usage.output_tokens),
metadata: {
id: result.id,
model: result.model,
type: 'claude'
}
};
}
catch (error) {
console.error('Claude API generate error:', error);
throw new Error(`Failed to generate with Claude: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Analyze text using Claude API
* @param request - The AI request with prompt and options
* @returns The AI response
*/
async analyze(request) {
if (!this.config.apiEndpoint) {
throw new Error('Claude API endpoint is not configured.');
}
const headers = {
'Content-Type': 'application/json',
'x-api-key': this.config.apiKey,
'anthropic-version': '2023-06-01'
};
const body = {
model: this.config.model,
max_tokens: request.options?.maxTokens || this.config.maxTokens,
temperature: request.options?.temperature || this.config.temperature,
messages: [
...(request.options?.systemPrompt ? [{ role: 'system', content: request.options.systemPrompt }] : []),
{ role: 'user', content: request.prompt }
]
};
try {
const response = await fetch(this.config.apiEndpoint, {
method: 'POST',
headers,
body: JSON.stringify(body)
});
if (!response.ok) {
throw new Error(`Claude API error: ${response.status} ${response.statusText}`);
}
const result = await response.json();
return {
content: result.content[0].text,
model: this.config.model,
tokenUsage: {
input: result.usage.input_tokens,
output: result.usage.output_tokens,
total: result.usage.input_tokens + result.usage.output_tokens
},
cost: this.calculateCost(result.usage.input_tokens, result.usage.output_tokens),
metadata: {
id: result.id,
model: result.model,
type: 'claude'
}
};
}
catch (error) {
console.error('Claude API error:', error);
throw new Error(`Failed to analyze with Claude: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Check if the Claude API is available
* @returns True if the API is available and the key is valid
*/
async isAvailable() {
if (!this.config.apiKey) {
return false; // Cannot check availability without API key
}
if (!this.config.apiEndpoint) {
// Cannot check availability without endpoint, treat as unavailable or throw?
// Let's treat as unavailable for now.
console.warn('Claude API endpoint is not configured. Cannot check availability.');
return false;
}
// Check if API key is valid
try {
const response = await fetch(`${this.config.apiEndpoint}/models`, {
method: 'GET',
headers: {
'x-api-key': this.config.apiKey,
'anthropic-version': '2023-06-01'
}
});
return response.ok;
}
catch (error) {
console.error('Claude availability check failed:', error);
return false;
}
}
/**
* Calculate the cost of the API call based on token usage
* @param inputTokens - Number of input tokens
* @param outputTokens - Number of output tokens
* @returns The cost of the API call in USD
*/
calculateCost(inputTokens, outputTokens) {
// Use costs from config, defaulting to 0 if not provided
const inputCostPer1K = this.config.inputCostPer1K || 0;
const outputCostPer1K = this.config.outputCostPer1K || 0;
const inputCost = (inputTokens / 1000) * inputCostPer1K;
const outputCost = (outputTokens / 1000) * outputCostPer1K;
return inputCost + outputCost;
}
}
//# sourceMappingURL=claude.js.map