UNPKG

route-claudecode

Version:

Advanced routing and transformation system for Claude Code outputs to multiple AI providers

144 lines 7.09 kB
"use strict"; /** * Anthropic Request Validator * Validates incoming requests against Anthropic API specification */ Object.defineProperty(exports, "__esModule", { value: true }); exports.validateAnthropicRequest = validateAnthropicRequest; const types_1 = require("@/types"); function validateAnthropicRequest(request) { if (!request || typeof request !== 'object') { throw new types_1.ValidationError('Request must be an object'); } // Required fields if (!request.model || typeof request.model !== 'string') { throw new types_1.ValidationError('Model is required and must be a string'); } if (!request.messages || !Array.isArray(request.messages)) { throw new types_1.ValidationError('Messages are required and must be an array'); } if (request.messages.length === 0) { throw new types_1.ValidationError('At least one message is required'); } // Validate messages for (let i = 0; i < request.messages.length; i++) { const message = request.messages[i]; if (!message || typeof message !== 'object') { throw new types_1.ValidationError(`Message at index ${i} must be an object`); } if (!message.role || typeof message.role !== 'string') { throw new types_1.ValidationError(`Message at index ${i} must have a role`); } if (!['user', 'assistant', 'system'].includes(message.role)) { throw new types_1.ValidationError(`Invalid role "${message.role}" at message index ${i}`); } if (message.content === undefined || message.content === null) { throw new types_1.ValidationError(`Message at index ${i} must have content`); } // Validate content format if (typeof message.content !== 'string' && !Array.isArray(message.content)) { throw new types_1.ValidationError(`Message content at index ${i} must be string or array`); } if (Array.isArray(message.content)) { validateContentBlocks(message.content, i); } } // Optional field validation if (request.system !== undefined) { if (!Array.isArray(request.system)) { throw new types_1.ValidationError('System must be an array'); } for (let i = 0; i < request.system.length; i++) { const systemMsg = request.system[i]; if (!systemMsg || typeof systemMsg !== 'object') { throw new types_1.ValidationError(`System message at index ${i} must be an object`); } if (systemMsg.type !== 'text') { throw new types_1.ValidationError(`System message at index ${i} must have type "text"`); } if (!systemMsg.text || typeof systemMsg.text !== 'string') { throw new types_1.ValidationError(`System message at index ${i} must have text field`); } } } if (request.tools !== undefined) { if (!Array.isArray(request.tools)) { throw new types_1.ValidationError('Tools must be an array'); } for (let i = 0; i < request.tools.length; i++) { const tool = request.tools[i]; if (!tool || typeof tool !== 'object') { throw new types_1.ValidationError(`Tool at index ${i} must be an object`); } if (!tool.name || typeof tool.name !== 'string') { throw new types_1.ValidationError(`Tool at index ${i} must have a name`); } if (!tool.description || typeof tool.description !== 'string') { throw new types_1.ValidationError(`Tool at index ${i} must have a description`); } if (!tool.input_schema || typeof tool.input_schema !== 'object') { throw new types_1.ValidationError(`Tool at index ${i} must have input_schema`); } } } // Validate optional numeric fields if (request.max_tokens !== undefined) { if (typeof request.max_tokens !== 'number' || request.max_tokens <= 0) { throw new types_1.ValidationError('max_tokens must be a positive number'); } } if (request.temperature !== undefined) { if (typeof request.temperature !== 'number' || request.temperature < 0 || request.temperature > 1) { throw new types_1.ValidationError('temperature must be a number between 0 and 1'); } } if (request.stream !== undefined && typeof request.stream !== 'boolean') { throw new types_1.ValidationError('stream must be a boolean'); } return true; } function validateContentBlocks(content, messageIndex) { for (let i = 0; i < content.length; i++) { const block = content[i]; if (!block || typeof block !== 'object') { throw new types_1.ValidationError(`Content block at index ${i} in message ${messageIndex} must be an object`); } if (!block.type || typeof block.type !== 'string') { throw new types_1.ValidationError(`Content block at index ${i} in message ${messageIndex} must have a type`); } switch (block.type) { case 'text': if (!block.text || typeof block.text !== 'string') { throw new types_1.ValidationError(`Text block at index ${i} in message ${messageIndex} must have text field`); } break; case 'tool_use': if (!block.id || typeof block.id !== 'string') { throw new types_1.ValidationError(`Tool use block at index ${i} in message ${messageIndex} must have id`); } if (!block.name || typeof block.name !== 'string') { throw new types_1.ValidationError(`Tool use block at index ${i} in message ${messageIndex} must have name`); } if (block.input === undefined) { throw new types_1.ValidationError(`Tool use block at index ${i} in message ${messageIndex} must have input`); } break; case 'tool_result': if (!block.tool_use_id || typeof block.tool_use_id !== 'string') { throw new types_1.ValidationError(`Tool result block at index ${i} in message ${messageIndex} must have tool_use_id`); } if (block.content === undefined) { throw new types_1.ValidationError(`Tool result block at index ${i} in message ${messageIndex} must have content`); } break; case 'image': if (!block.source || typeof block.source !== 'object') { throw new types_1.ValidationError(`Image block at index ${i} in message ${messageIndex} must have source`); } break; default: throw new types_1.ValidationError(`Unknown content block type "${block.type}" at index ${i} in message ${messageIndex}`); } } } //# sourceMappingURL=validator.js.map