pit-manager
Version:
Centralized prompt management system for Human Behavior AI agents
138 lines • 5.65 kB
JavaScript
;
/**
* Anthropic provider implementation for TypeScript.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AnthropicProvider = void 0;
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
const exceptions_1 = require("../core/exceptions");
const base_1 = require("./base");
class AnthropicProvider extends base_1.BaseProvider {
client;
// Anthropic pricing per 1K tokens (as of 2024)
static PRICING = {
'claude-3-opus-20240229': { input: 0.015, output: 0.075 },
'claude-3-sonnet-20240229': { input: 0.003, output: 0.015 },
'claude-3-haiku-20240307': { input: 0.00025, output: 0.00125 },
'claude-3-5-sonnet-20241022': { input: 0.003, output: 0.015 },
'claude-3-5-haiku-20241022': { input: 0.001, output: 0.005 },
// Legacy models
'claude-2.1': { input: 0.008, output: 0.024 },
'claude-2.0': { input: 0.008, output: 0.024 },
'claude-instant-1.2': { input: 0.0008, output: 0.0024 }
};
constructor(apiKey, config = {}) {
super(apiKey, config);
if (!this.apiKey) {
throw new exceptions_1.APIKeyError('Anthropic API key is required');
}
this.client = new sdk_1.default({ apiKey: this.apiKey });
}
get name() {
return 'anthropic';
}
get supportedModels() {
return Object.keys(AnthropicProvider.PRICING);
}
async chatCompletion(model, messages, options = {}) {
if (!this.supportsModel(model)) {
const available = this.supportedModels.join(', ');
throw new exceptions_1.ProviderError(`Model ${model} not supported by Anthropic. Available: ${available}`);
}
try {
// Convert PIT messages to Anthropic format
// Anthropic requires system message to be separate
let systemMessage;
const anthropicMessages = [];
for (const msg of messages) {
if (msg.role === 'system') {
systemMessage = typeof msg.content === 'string' ? msg.content : msg.content.text || '';
}
else {
// For now, Anthropic doesn't support multimodal in the same way
// Convert to text-only
const textContent = typeof msg.content === 'string'
? msg.content
: msg.content.text || '';
anthropicMessages.push({
role: msg.role,
content: textContent
});
}
}
// Build request parameters
const requestParams = {
model,
messages: anthropicMessages,
max_tokens: options.maxTokens || 1024 // Required by Anthropic
};
if (systemMessage) {
requestParams.system = systemMessage;
}
if (options.temperature !== undefined) {
requestParams.temperature = options.temperature;
}
// Add any additional options
Object.keys(options).forEach(key => {
if (!['temperature', 'maxTokens', 'responseFormat'].includes(key)) {
requestParams[key] = options[key];
}
});
// Make API call
const startTime = new Date();
const response = await this.client.messages.create(requestParams);
const endTime = new Date();
// Calculate latency
const latency = endTime.getTime() - startTime.getTime();
// Extract response data
let content = '';
for (const contentBlock of response.content) {
if (contentBlock.type === 'text') {
content += contentBlock.text;
}
}
// Extract usage
const tokenUsage = {
input: response.usage.input_tokens,
output: response.usage.output_tokens,
total: response.usage.input_tokens + response.usage.output_tokens
};
// Calculate cost
const cost = this.calculateCost(model, tokenUsage);
return {
content,
tokens: tokenUsage,
model,
provider: this.name,
latency,
cost,
timestamp: startTime,
finishReason: response.stop_reason || undefined,
rawResponse: response
};
}
catch (error) {
if (error.type === 'rate_limit_error') {
throw new exceptions_1.RateLimitError(`Anthropic rate limit exceeded: ${error.message}`);
}
if (error.status >= 400) {
throw new exceptions_1.ProviderError(`Anthropic API error: ${error.message}`);
}
throw new exceptions_1.ProviderError(`Unexpected error calling Anthropic: ${error.message}`);
}
}
calculateCost(model, tokens) {
const pricing = AnthropicProvider.PRICING[model];
if (!pricing) {
return 0.0;
}
const inputCost = (tokens.input / 1000) * pricing.input;
const outputCost = (tokens.output / 1000) * pricing.output;
return inputCost + outputCost;
}
}
exports.AnthropicProvider = AnthropicProvider;
//# sourceMappingURL=anthropic.js.map