UNPKG

shipdeck

Version:

Ship MVPs in 48 hours. Fix bugs in 30 seconds. The command deck for developers who ship.

344 lines (294 loc) 9.14 kB
/** * Anthropic API Integration for Shipdeck Ultimate * Complete production-ready integration with streaming, cost tracking, and agent execution */ const { AnthropicClient, MODEL_CONFIGS, DEFAULT_CONFIG } = require('./client'); const { AgentExecutor, AGENT_ROLES, ConversationContext } = require('./agent-executor'); const { ConfigManager } = require('./config-manager'); const { TokenManager, MODEL_LIMITS, TOKEN_ESTIMATION } = require('./token-manager'); /** * Main Anthropic Integration Class * Provides a unified interface for all Anthropic API operations */ class AnthropicIntegration { constructor(options = {}) { this.configManager = new ConfigManager(); // Initialize with config from file or options const config = this.configManager.getConfig(); const anthropicOptions = { apiKey: options.apiKey || config.anthropic?.apiKey || process.env.ANTHROPIC_API_KEY, model: options.model || config.anthropic?.model, config: { ...config.anthropic, ...options.config } }; this.client = new AnthropicClient(anthropicOptions); this.executor = new AgentExecutor({ anthropic: anthropicOptions, config: config.agents }); this.tokenManager = new TokenManager(this.client.model); // Track usage this._setupUsageTracking(); } /** * Setup automatic usage tracking */ _setupUsageTracking() { const originalCreateMessage = this.client.createMessage.bind(this.client); this.client.createMessage = async (...args) => { const result = await originalCreateMessage(...args); if (result.usage) { this.configManager.updateUsage({ inputTokens: result.usage.input_tokens, outputTokens: result.usage.output_tokens, requests: 1, cost: result._metadata?.estimatedCost || 0, errors: 0 }); } return result; }; } /** * Quick setup - configure API key and validate */ async setup(apiKey) { if (!apiKey) { throw new Error('API key is required for setup'); } // Set API key this.configManager.setApiKey(apiKey); // Update client with new key this.client.apiKey = apiKey; this.client.client = new (require('@anthropic-ai/sdk'))({ apiKey }); // Validate key const validation = await this.client.validateApiKey(); if (!validation.valid) { throw new Error(`API key validation failed: ${validation.error}`); } return { success: true, message: 'Anthropic API integration configured successfully', model: this.client.model, limits: this.tokenManager.getModelInfo() }; } /** * Execute an agent with prompt */ async execute(agentType, prompt, options = {}) { // Check daily limits const limitCheck = this.configManager.checkDailyLimit(); if (limitCheck.exceeded) { throw new Error(`Daily spending limit of $${limitCheck.limit} exceeded. Current usage: $${limitCheck.current.toFixed(4)}`); } if (limitCheck.warning && !options.ignoreWarning) { console.warn(`⚠️ Approaching daily limit: $${limitCheck.current.toFixed(4)} / $${limitCheck.limit}`); } return await this.executor.executeAgent(agentType, prompt, options); } /** * Execute agent with streaming response */ async executeStream(agentType, prompt, options = {}) { // Check daily limits const limitCheck = this.configManager.checkDailyLimit(); if (limitCheck.exceeded) { throw new Error(`Daily spending limit exceeded`); } return await this.executor.executeAgentStream(agentType, prompt, options); } /** * Execute multiple agents in parallel */ async executeParallel(agentTasks) { // Check limits for all tasks const limitCheck = this.configManager.checkDailyLimit(); if (limitCheck.exceeded) { throw new Error(`Daily spending limit exceeded`); } return await this.executor.executeAgentsParallel(agentTasks); } /** * Direct API call (for custom prompts) */ async call(messages, options = {}) { return await this.client.createMessage(messages, options); } /** * Direct streaming API call */ async callStream(messages, options = {}) { return await this.client.createStreamingMessage(messages, options); } /** * Estimate cost for operation */ estimateCost(agentType, prompt, options = {}) { return this.executor.estimateAgentCost(agentType, prompt, options); } /** * Get usage statistics */ getUsage() { return { client: this.client.getUsage(), config: this.configManager.getUsageSummary() }; } /** * Get available agents */ getAgents() { return this.executor.getAvailableAgents(); } /** * Get available models */ getModels() { return this.client.getAvailableModels(); } /** * Get configuration */ getConfig() { return this.configManager.getConfig(); } /** * Update configuration */ updateConfig(updates) { return this.configManager.updateConfig(updates); } /** * Set daily spending limit */ setDailyLimit(limitUSD, enabled = true) { return this.configManager.setDailyLimit(limitUSD, enabled); } /** * Reset usage statistics */ resetUsage() { this.client.resetUsage(); return this.configManager.resetUsageStats(); } /** * Health check - validate setup and connectivity */ async healthCheck() { const results = { apiKey: false, connectivity: false, config: false, usage: false, overall: false }; try { // Check API key results.apiKey = this.configManager.hasApiKey(); // Check connectivity if (results.apiKey) { const validation = await this.client.validateApiKey(); results.connectivity = validation.valid; } // Check config const configValidation = this.configManager.validateConfig(); results.config = configValidation.valid; results.configIssues = configValidation.issues; // Check usage limits const limitCheck = this.configManager.checkDailyLimit(); results.usage = !limitCheck.exceeded; results.usageInfo = limitCheck; // Overall status results.overall = results.apiKey && results.connectivity && results.config && results.usage; } catch (error) { results.error = error.message; } return results; } /** * Generate MVP workflow - specialized 48-hour development flow */ async generateMVP(requirements, options = {}) { const mvpFlow = [ { agent: 'backend-architect', prompt: `Design the backend architecture for this MVP: ${requirements}. Focus on rapid deployment and scalability.`, options: { sessionId: 'mvp-backend' } }, { agent: 'frontend-developer', prompt: `Create the frontend structure for this MVP: ${requirements}. Prioritize user experience and rapid iteration.`, options: { sessionId: 'mvp-frontend' } }, { agent: 'test-writer-fixer', prompt: `Generate comprehensive test suite for MVP: ${requirements}. Focus on critical paths and user flows.`, options: { sessionId: 'mvp-tests' } }, { agent: 'devops-automator', prompt: `Create deployment pipeline for MVP: ${requirements}. Enable continuous deployment and monitoring.`, options: { sessionId: 'mvp-deployment' } } ]; const parallel = options.parallel !== false; // Default to parallel if (parallel) { return await this.executeParallel(mvpFlow); } else { const results = []; for (const task of mvpFlow) { const result = await this.execute(task.agent, task.prompt, task.options); results.push({ success: true, agent: task.agent, result }); } return results; } } } /** * Quick factory function for common use cases */ function createAnthropicIntegration(options = {}) { return new AnthropicIntegration(options); } // Export for CommonJS module.exports = AnthropicIntegration; module.exports.AnthropicIntegration = AnthropicIntegration; module.exports.createAnthropicIntegration = createAnthropicIntegration; /** * Utility function to get API key from various sources */ function getApiKey() { const configManager = new ConfigManager(); return configManager.getApiKey(false) || process.env.ANTHROPIC_API_KEY; } /** * Validate API key format */ function validateApiKeyFormat(apiKey) { return apiKey && typeof apiKey === 'string' && apiKey.startsWith('sk-ant-'); } module.exports = { // Main classes AnthropicIntegration, AnthropicClient, AgentExecutor, ConfigManager, TokenManager, ConversationContext, // Constants MODEL_CONFIGS, DEFAULT_CONFIG, AGENT_ROLES, MODEL_LIMITS, TOKEN_ESTIMATION, // Utility functions createAnthropicIntegration, getApiKey, validateApiKeyFormat, // Default export default: AnthropicIntegration };