UNPKG

prompt-version-manager

Version:

Centralized prompt management system for Human Behavior AI agents

242 lines 8.28 kB
"use strict"; /** * Native structured output support for different LLM providers in TypeScript */ Object.defineProperty(exports, "__esModule", { value: true }); exports.StructuredOutputHandler = void 0; class StructuredOutputHandler { /** * Prepare structured output configuration for OpenAI */ prepareOpenAIStructured(schema) { // Determine the actual JSON schema to use let jsonSchema; if (this.isStructuredOutput(schema)) { if (schema.schema) { jsonSchema = schema.schema; } else if (schema.type) { // Type/class provided - use directly (for beta API with parse) return { response_format: schema.type, useBeta: true }; } else { // StructuredOutput but no schema or type throw new Error("StructuredOutput must have either 'schema' or 'type' property"); } } else { // Plain object is treated as JSON schema jsonSchema = schema; } // Use beta API with JSON schema return { response_format: { type: "json_schema", json_schema: { name: "structured_response", schema: jsonSchema } }, useBeta: true }; } /** * Prepare structured output configuration for Gemini */ prepareGeminiStructured(schema) { let jsonSchema; if (this.isStructuredOutput(schema) && schema.schema) { jsonSchema = schema.schema; } else if (this.isStructuredOutput(schema) && schema.type) { // Convert type to JSON schema (simplified) jsonSchema = this.typeToJsonSchema(schema.type); } else { jsonSchema = schema; } // Convert JSON schema to Gemini format const geminiSchema = this.jsonToGeminiSchema(jsonSchema); return { responseMimeType: 'application/json', responseSchema: geminiSchema }; } /** * Prepare structured output configuration for Claude */ prepareClaudeStructured(schema, toolName = 'generate_output') { let jsonSchema; if (this.isStructuredOutput(schema) && schema.schema) { jsonSchema = schema.schema; } else if (this.isStructuredOutput(schema) && schema.type) { // Convert type to JSON schema (simplified) jsonSchema = this.typeToJsonSchema(schema.type); } else { jsonSchema = schema; } // Use custom name if provided if (this.isStructuredOutput(schema) && schema.name) { toolName = schema.name; } // Create tool definition const tool = { name: toolName, description: `Generate structured output according to schema`, input_schema: jsonSchema }; return { tools: [tool], tool_choice: { type: 'tool', name: toolName } }; } /** * Parse OpenAI structured response */ parseOpenAIResponse(response, _schema) { if (response.choices?.[0]?.message?.parsed) { // Beta API with parsing return response.choices[0].message.parsed; } else { // Regular JSON response const content = response.choices?.[0]?.message?.content || ''; try { const data = JSON.parse(content); return data; } catch (e) { return content; } } } /** * Parse Gemini structured response */ parseGeminiResponse(response, _schema) { try { // Try different ways to extract the text content const text = response.content || response.text || response.rawResponse?.text || response.candidates?.[0]?.content?.parts?.[0]?.text || ''; if (!text) { return ''; } const data = JSON.parse(text); return data; } catch (e) { return response.content || response.text || ''; } } /** * Parse Claude structured response from tool use */ parseClaudeResponse(response, _schema) { // Check for tool use in response if (response.content) { for (const content of response.content) { if (content.type === 'tool_use') { return content.input; } } } // Fallback to text content if (response.content?.[0]?.text) { return response.content[0].text; } return ''; } /** * Check if value is a StructuredOutput interface (not a plain JSON schema) */ isStructuredOutput(value) { // Check if it's a StructuredOutput interface vs plain JSON schema // StructuredOutput has .schema, .type (class/function), or .name // JSON schema has .type (string like "object", "string", etc.) if (!value) return false; // If it has a 'schema' property, it's definitely a StructuredOutput if (value.schema !== undefined) return true; // If it has a 'name' property, it's probably a StructuredOutput if (value.name !== undefined) return true; // For 'type' property, we need to distinguish between: // - StructuredOutput.type (should be a class/function) // - JSON schema type (should be a string like "object", "array", etc.) if (value.type !== undefined) { // If type is a string matching JSON schema types, it's a plain JSON schema if (typeof value.type === 'string' && ['object', 'array', 'string', 'number', 'integer', 'boolean', 'null'].includes(value.type)) { return false; } // Otherwise, assume it's a StructuredOutput with a type/class return true; } return false; } /** * Convert a type/class to JSON schema (simplified) */ typeToJsonSchema(_type) { // This is a simplified version // In a real implementation, you'd introspect the type return { type: 'object', properties: {}, required: [] }; } /** * Convert JSON schema to Gemini schema format */ jsonToGeminiSchema(jsonSchema) { const convertType = (jsonType) => { const typeMap = { 'string': 'STRING', 'number': 'NUMBER', 'integer': 'INTEGER', 'boolean': 'BOOLEAN', 'array': 'ARRAY', 'object': 'OBJECT' }; return typeMap[jsonType] || 'STRING'; }; const convertSchema = (schema) => { if (!schema.type) { return schema; } const geminiSchema = { type: convertType(schema.type) }; // Handle object properties if (schema.type === 'object' && schema.properties) { geminiSchema.properties = {}; for (const [propName, propSchema] of Object.entries(schema.properties)) { geminiSchema.properties[propName] = convertSchema(propSchema); } if (schema.required) { geminiSchema.required = schema.required; } } // Handle arrays else if (schema.type === 'array' && schema.items) { geminiSchema.items = convertSchema(schema.items); } // Add description if present if (schema.description) { geminiSchema.description = schema.description; } return geminiSchema; }; return convertSchema(jsonSchema); } } exports.StructuredOutputHandler = StructuredOutputHandler; //# sourceMappingURL=structured-output.js.map