@startsimpli/llm 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/types.ts","../src/providers/openai.ts","../src/providers/anthropic.ts","../src/providers/mock.ts","../src/utils/json-extraction.ts","../src/utils/http-status.ts","../src/utils/retry.ts","../src/service.ts"],"names":["MODEL_COSTS","DEFAULTS","validation","ZodError"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * LLM error codes for classifying provider failures.\n */\nexport type LLMErrorCode =\n | 'RATE_LIMITED'\n | 'AUTHENTICATION_ERROR'\n | 'INVALID_REQUEST'\n | 'CONTEXT_LENGTH_EXCEEDED'\n | 'CONTENT_FILTERED'\n | 'SERVICE_UNAVAILABLE'\n | 'TIMEOUT'\n | 'PARSE_ERROR'\n | 'UNKNOWN_ERROR';\n\n/**\n * Typed error for LLM provider failures.\n * Carries a machine-readable code and a retryable flag so callers can\n * decide whether to retry or surface the error to the user.\n */\nexport class LLMProviderError extends Error {\n constructor(\n message: string,\n public readonly code: LLMErrorCode,\n public readonly retryable: boolean = false,\n public readonly statusCode?: number,\n public readonly provider?: string\n ) {\n super(message);\n this.name = 'LLMProviderError';\n }\n}\n","import type { ZodError } from 'zod';\n\n/**\n * Token usage statistics returned by every provider call.\n */\nexport interface TokenUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\n/**\n * Raw response envelope from an LLM provider.\n */\nexport interface LLMResponse {\n /** The raw text content from the LLM */\n content: string;\n /** Token usage statistics */\n usage: TokenUsage;\n /** Model identifier used for generation */\n model: string;\n /** Response ID for debugging/logging */\n responseId?: string;\n /** Finish reason (e.g., 'stop', 'length', 'content_filter') */\n finishReason?: string;\n}\n\n/**\n * Options passed through to the provider for a single generation call.\n */\nexport interface GenerateOptions {\n /** Model to use (provider-specific) */\n model?: string;\n /** Temperature for response randomness (0-1) */\n temperature?: number;\n /** Maximum tokens in response */\n maxTokens?: number;\n /** Request timeout in milliseconds */\n timeout?: number;\n /** Arbitrary extra data the caller wants to thread through (e.g. domain preferences) */\n extra?: Record<string, unknown>;\n}\n\n/**\n * Provider configuration — everything needed to construct a provider instance.\n */\nexport interface ProviderConfig {\n apiKey: string;\n baseUrl?: string;\n defaultModel?: string;\n defaultTemperature?: number;\n defaultMaxTokens?: number;\n timeoutMs?: number;\n}\n\n/**\n * Result of attempting to extract JSON from an LLM response string.\n */\nexport interface JsonExtractionResult {\n success: boolean;\n json?: unknown;\n error?: string;\n raw: string;\n}\n\n/**\n * Generic validation result — parameterized over the domain data type.\n */\nexport interface ValidationResult<T> {\n valid: boolean;\n data?: T;\n zodError?: ZodError;\n errors?: string[];\n}\n\n/**\n * Configuration for the generic LLMService.\n */\nexport interface LLMServiceConfig {\n /** Maximum number of retry attempts for validation failures */\n maxRetries?: number;\n /** Preferred provider (will fallback to available if not configured) */\n preferredProvider?: 'openai' | 'anthropic' | 'mock';\n /** Default model override */\n defaultModel?: string;\n /** Default temperature */\n defaultTemperature?: number;\n /** Default max tokens */\n defaultMaxTokens?: number;\n}\n\n/**\n * Default LLM configuration values.\n * Apps can override these via LLMServiceConfig or environment variables.\n */\nexport const LLM_DEFAULTS = {\n openaiModel: 'gpt-4o-mini',\n anthropicModel: 'claude-sonnet-4-20250514',\n /**\n * Default sampling temperature.\n * Note: base gpt-5 models (gpt-5, gpt-5.1, gpt-5.2) require temperature=1.0\n * and the OpenAI provider enforces this automatically.\n */\n temperature: 0.7,\n maxTokens: 8192,\n timeoutMs: 60000,\n} as const;\n","/**\n * OpenAI Provider Implementation\n *\n * Uses native fetch to minimize dependencies.\n * Supports GPT-5.x, GPT-4o models, and custom fine-tuned models.\n *\n * To use a custom fine-tuned model:\n * 1. Set OPENAI_MODEL or LLM_MODEL to your fine-tuned model ID (e.g., \"ft:gpt-4o-2024-08-06:org:name:id\")\n * 2. Fine-tuned models will use the configured temperature setting (not forced to 1.0 like base gpt-5)\n */\n\nimport type { ILLMProvider } from './interface';\nimport type { LLMResponse, GenerateOptions, ProviderConfig } from '../types';\nimport { LLM_DEFAULTS } from '../types';\nimport { LLMProviderError } from '../errors';\nimport type { LLMErrorCode } from '../errors';\n\ninterface OpenAIMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\ninterface OpenAIRequest {\n model: string;\n messages: OpenAIMessage[];\n temperature?: number;\n max_tokens?: number;\n response_format?: { type: 'json_object' | 'text' };\n}\n\ninterface OpenAIResponse {\n id: string;\n object: string;\n created: number;\n model: string;\n choices: Array<{\n index: number;\n message: { role: string; content: string };\n finish_reason: string;\n }>;\n usage: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n };\n}\n\ninterface OpenAIErrorResponse {\n error: {\n message: string;\n type: string;\n code?: string;\n param?: string;\n };\n}\n\nconst OPENAI_MODELS = [\n 'gpt-5.2',\n 'gpt-5.1',\n 'gpt-5',\n 'gpt-4o',\n 'gpt-4o-mini',\n] as const;\n\nconst MODEL_COSTS: Record<string, { input: number; output: number }> = {\n 'gpt-5.2': { input: 0.005, output: 0.015 },\n 'gpt-5.1': { input: 0.005, output: 0.015 },\n 'gpt-5': { input: 0.005, output: 0.015 },\n 'gpt-4o': { input: 0.0025, output: 0.01 },\n 'gpt-4o-mini': { input: 0.00015, output: 0.0006 },\n};\n\nconst DEFAULTS = {\n baseUrl: 'https://api.openai.com/v1',\n model: LLM_DEFAULTS.openaiModel,\n temperature: LLM_DEFAULTS.temperature,\n maxTokens: LLM_DEFAULTS.maxTokens,\n timeoutMs: LLM_DEFAULTS.timeoutMs,\n};\n\nexport class OpenAIProvider implements ILLMProvider {\n readonly name = 'openai';\n readonly availableModels = OPENAI_MODELS;\n readonly defaultModel: string;\n\n private readonly config: Required<ProviderConfig>;\n\n constructor(config: ProviderConfig) {\n this.config = {\n apiKey: config.apiKey,\n baseUrl: config.baseUrl ?? DEFAULTS.baseUrl,\n defaultModel: config.defaultModel ?? DEFAULTS.model,\n defaultTemperature: config.defaultTemperature ?? DEFAULTS.temperature,\n defaultMaxTokens: config.defaultMaxTokens ?? DEFAULTS.maxTokens,\n timeoutMs: config.timeoutMs ?? DEFAULTS.timeoutMs,\n };\n this.defaultModel = this.config.defaultModel;\n }\n\n isAvailable(): boolean {\n return Boolean(this.config.apiKey);\n }\n\n async generate(\n userPrompt: string,\n systemPrompt: string,\n options?: GenerateOptions\n ): Promise<LLMResponse> {\n if (!this.isAvailable()) {\n throw new LLMProviderError(\n 'OpenAI API key not configured',\n 'AUTHENTICATION_ERROR',\n false,\n undefined,\n this.name\n );\n }\n\n const model = options?.model ?? this.config.defaultModel;\n // Base gpt-5 models require temperature=1.0, but fine-tuned models use configured temperature\n const isBaseGpt5 = model === 'gpt-5' || model === 'gpt-5.1' || model === 'gpt-5.2';\n const isFineTuned = model.startsWith('ft:');\n const temperature = isBaseGpt5 && !isFineTuned\n ? 1.0\n : (options?.temperature ?? this.config.defaultTemperature);\n const maxTokens = options?.maxTokens ?? this.config.defaultMaxTokens;\n const timeout = options?.timeout ?? this.config.timeoutMs;\n\n const requestBody: OpenAIRequest = {\n model,\n messages: [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n temperature,\n max_tokens: maxTokens,\n response_format: { type: 'json_object' },\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(`${this.config.baseUrl}/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.config.apiKey}`,\n },\n body: JSON.stringify(requestBody),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({\n error: { message: 'Unknown error' },\n }))) as OpenAIErrorResponse;\n throw this.handleApiError(response.status, errorData);\n }\n\n const data = (await response.json()) as OpenAIResponse;\n\n if (!data.choices?.[0]?.message?.content) {\n throw new LLMProviderError(\n 'Empty response from OpenAI',\n 'UNKNOWN_ERROR',\n true,\n undefined,\n this.name\n );\n }\n\n return {\n content: data.choices[0].message.content,\n usage: {\n promptTokens: data.usage.prompt_tokens,\n completionTokens: data.usage.completion_tokens,\n totalTokens: data.usage.total_tokens,\n },\n model: data.model,\n responseId: data.id,\n finishReason: data.choices[0].finish_reason,\n };\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof LLMProviderError) {\n throw error;\n }\n\n if (error instanceof Error && error.name === 'AbortError') {\n throw new LLMProviderError(\n `Request timed out after ${timeout}ms`,\n 'TIMEOUT',\n true,\n undefined,\n this.name\n );\n }\n\n throw new LLMProviderError(\n `OpenAI request failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'UNKNOWN_ERROR',\n true,\n undefined,\n this.name\n );\n }\n }\n\n estimateCost(\n promptTokens: number,\n completionTokens: number,\n model?: string\n ): number | undefined {\n const costs = MODEL_COSTS[model ?? this.config.defaultModel];\n if (!costs) return undefined;\n return (promptTokens / 1000) * costs.input + (completionTokens / 1000) * costs.output;\n }\n\n private handleApiError(\n statusCode: number,\n errorResponse: OpenAIErrorResponse\n ): LLMProviderError {\n const message = errorResponse.error?.message ?? 'Unknown OpenAI error';\n const errorType = errorResponse.error?.type ?? '';\n const errorCode = errorResponse.error?.code ?? '';\n\n let code: LLMErrorCode;\n let retryable = false;\n\n if (statusCode === 401) {\n code = 'AUTHENTICATION_ERROR';\n } else if (statusCode === 429) {\n code = 'RATE_LIMITED';\n retryable = true;\n } else if (statusCode === 400) {\n if (errorCode === 'context_length_exceeded') {\n code = 'CONTEXT_LENGTH_EXCEEDED';\n } else if (errorType === 'invalid_request_error') {\n code = 'INVALID_REQUEST';\n } else {\n code = 'UNKNOWN_ERROR';\n }\n } else if (statusCode === 403) {\n code = errorCode === 'content_filter' ? 'CONTENT_FILTERED' : 'AUTHENTICATION_ERROR';\n } else if (statusCode >= 500) {\n code = 'SERVICE_UNAVAILABLE';\n retryable = true;\n } else {\n code = 'UNKNOWN_ERROR';\n }\n\n return new LLMProviderError(message, code, retryable, statusCode, this.name);\n }\n}\n\n/**\n * Create an OpenAI provider from environment variables.\n * Returns null if OPENAI_API_KEY is not set.\n */\nexport function createOpenAIProvider(): OpenAIProvider | null {\n const apiKey = process.env.OPENAI_API_KEY;\n if (!apiKey) return null;\n\n return new OpenAIProvider({\n apiKey,\n baseUrl: process.env.OPENAI_BASE_URL,\n defaultModel: process.env.OPENAI_MODEL,\n });\n}\n","/**\n * Anthropic Provider Implementation\n *\n * Uses native fetch to minimize dependencies.\n * Supports Claude 4 and Claude 3.x models.\n */\n\nimport type { ILLMProvider } from './interface';\nimport type { LLMResponse, GenerateOptions, ProviderConfig } from '../types';\nimport { LLM_DEFAULTS } from '../types';\nimport { LLMProviderError } from '../errors';\nimport type { LLMErrorCode } from '../errors';\n\ninterface AnthropicMessage {\n role: 'user' | 'assistant';\n content: string;\n}\n\ninterface AnthropicRequest {\n model: string;\n max_tokens: number;\n messages: AnthropicMessage[];\n system?: string;\n temperature?: number;\n}\n\ninterface AnthropicResponse {\n id: string;\n type: 'message';\n role: 'assistant';\n content: Array<{ type: 'text'; text: string }>;\n model: string;\n stop_reason: 'end_turn' | 'max_tokens' | 'stop_sequence' | null;\n usage: {\n input_tokens: number;\n output_tokens: number;\n };\n}\n\ninterface AnthropicErrorResponse {\n type: 'error';\n error: {\n type: string;\n message: string;\n };\n}\n\nconst ANTHROPIC_MODELS = [\n 'claude-opus-4-6',\n 'claude-opus-4-20250514',\n 'claude-sonnet-4-6',\n 'claude-sonnet-4-20250514',\n 'claude-3-5-sonnet-20241022',\n 'claude-3-5-haiku-20241022',\n 'claude-3-opus-20240229',\n 'claude-3-sonnet-20240229',\n 'claude-3-haiku-20240307',\n] as const;\n\nconst MODEL_COSTS: Record<string, { input: number; output: number }> = {\n 'claude-opus-4-6': { input: 0.015, output: 0.075 },\n 'claude-opus-4-20250514': { input: 0.015, output: 0.075 },\n 'claude-sonnet-4-6': { input: 0.003, output: 0.015 },\n 'claude-sonnet-4-20250514': { input: 0.003, output: 0.015 },\n 'claude-3-5-sonnet-20241022': { input: 0.003, output: 0.015 },\n 'claude-3-5-haiku-20241022': { input: 0.0008, output: 0.004 },\n 'claude-3-opus-20240229': { input: 0.015, output: 0.075 },\n 'claude-3-sonnet-20240229': { input: 0.003, output: 0.015 },\n 'claude-3-haiku-20240307': { input: 0.00025, output: 0.00125 },\n};\n\nconst DEFAULTS = {\n baseUrl: 'https://api.anthropic.com/v1',\n model: LLM_DEFAULTS.anthropicModel,\n temperature: LLM_DEFAULTS.temperature,\n maxTokens: LLM_DEFAULTS.maxTokens,\n timeoutMs: LLM_DEFAULTS.timeoutMs,\n apiVersion: '2023-06-01',\n};\n\nexport class AnthropicProvider implements ILLMProvider {\n readonly name = 'anthropic';\n readonly availableModels = ANTHROPIC_MODELS;\n readonly defaultModel: string;\n\n private readonly config: Required<ProviderConfig>;\n private readonly apiVersion: string;\n\n constructor(config: ProviderConfig, apiVersion?: string) {\n this.config = {\n apiKey: config.apiKey,\n baseUrl: config.baseUrl ?? DEFAULTS.baseUrl,\n defaultModel: config.defaultModel ?? DEFAULTS.model,\n defaultTemperature: config.defaultTemperature ?? DEFAULTS.temperature,\n defaultMaxTokens: config.defaultMaxTokens ?? DEFAULTS.maxTokens,\n timeoutMs: config.timeoutMs ?? DEFAULTS.timeoutMs,\n };\n this.defaultModel = this.config.defaultModel;\n this.apiVersion = apiVersion ?? DEFAULTS.apiVersion;\n }\n\n isAvailable(): boolean {\n return Boolean(this.config.apiKey);\n }\n\n async generate(\n userPrompt: string,\n systemPrompt: string,\n options?: GenerateOptions\n ): Promise<LLMResponse> {\n if (!this.isAvailable()) {\n throw new LLMProviderError(\n 'Anthropic API key not configured',\n 'AUTHENTICATION_ERROR',\n false,\n undefined,\n this.name\n );\n }\n\n const model = options?.model ?? this.config.defaultModel;\n const temperature = options?.temperature ?? this.config.defaultTemperature;\n const maxTokens = options?.maxTokens ?? this.config.defaultMaxTokens;\n const timeout = options?.timeout ?? this.config.timeoutMs;\n\n // Wrap user prompt to request JSON output\n const jsonWrappedPrompt = `${userPrompt}\n\nPlease respond with a valid JSON object only. Do not include any text before or after the JSON.`;\n\n const requestBody: AnthropicRequest = {\n model,\n max_tokens: maxTokens,\n messages: [{ role: 'user', content: jsonWrappedPrompt }],\n system: systemPrompt,\n temperature,\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(`${this.config.baseUrl}/messages`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.config.apiKey,\n 'anthropic-version': this.apiVersion,\n },\n body: JSON.stringify(requestBody),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({\n error: { type: 'unknown', message: 'Unknown error' },\n }))) as AnthropicErrorResponse;\n throw this.handleApiError(response.status, errorData);\n }\n\n const data = (await response.json()) as AnthropicResponse;\n\n const textContent = data.content.find((c) => c.type === 'text');\n if (!textContent?.text) {\n throw new LLMProviderError(\n 'Empty response from Anthropic',\n 'UNKNOWN_ERROR',\n true,\n undefined,\n this.name\n );\n }\n\n return {\n content: textContent.text,\n usage: {\n promptTokens: data.usage.input_tokens,\n completionTokens: data.usage.output_tokens,\n totalTokens: data.usage.input_tokens + data.usage.output_tokens,\n },\n model: data.model,\n responseId: data.id,\n finishReason: data.stop_reason ?? undefined,\n };\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof LLMProviderError) {\n throw error;\n }\n\n if (error instanceof Error && error.name === 'AbortError') {\n throw new LLMProviderError(\n `Request timed out after ${timeout}ms`,\n 'TIMEOUT',\n true,\n undefined,\n this.name\n );\n }\n\n throw new LLMProviderError(\n `Anthropic request failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'UNKNOWN_ERROR',\n true,\n undefined,\n this.name\n );\n }\n }\n\n estimateCost(\n promptTokens: number,\n completionTokens: number,\n model?: string\n ): number | undefined {\n const costs = MODEL_COSTS[model ?? this.config.defaultModel];\n if (!costs) return undefined;\n return (promptTokens / 1000) * costs.input + (completionTokens / 1000) * costs.output;\n }\n\n private handleApiError(\n statusCode: number,\n errorResponse: AnthropicErrorResponse\n ): LLMProviderError {\n const message = errorResponse.error?.message ?? 'Unknown Anthropic error';\n const errorType = errorResponse.error?.type ?? '';\n\n let code: LLMErrorCode;\n let retryable = false;\n\n if (statusCode === 401) {\n code = 'AUTHENTICATION_ERROR';\n } else if (statusCode === 429) {\n code = 'RATE_LIMITED';\n retryable = true;\n } else if (statusCode === 400) {\n if (errorType === 'invalid_request_error') {\n code = (message.includes('token') || message.includes('length'))\n ? 'CONTEXT_LENGTH_EXCEEDED'\n : 'INVALID_REQUEST';\n } else {\n code = 'UNKNOWN_ERROR';\n }\n } else if (statusCode === 403) {\n code = 'AUTHENTICATION_ERROR';\n } else if (statusCode === 529 || statusCode >= 500) {\n code = 'SERVICE_UNAVAILABLE';\n retryable = true;\n } else {\n code = 'UNKNOWN_ERROR';\n }\n\n return new LLMProviderError(message, code, retryable, statusCode, this.name);\n }\n}\n\n/**\n * Create an Anthropic provider from environment variables.\n * Returns null if ANTHROPIC_API_KEY is not set.\n */\nexport function createAnthropicProvider(): AnthropicProvider | null {\n const apiKey = process.env.ANTHROPIC_API_KEY;\n if (!apiKey) return null;\n\n return new AnthropicProvider({\n apiKey,\n baseUrl: process.env.ANTHROPIC_BASE_URL,\n defaultModel: process.env.ANTHROPIC_MODEL,\n });\n}\n","/**\n * Mock LLM Provider for Testing\n *\n * Provides deterministic responses for testing.\n * Can simulate errors, delays, and custom responses.\n */\n\nimport type { ILLMProvider } from './interface';\nimport type { LLMResponse, GenerateOptions } from '../types';\nimport { LLMProviderError } from '../errors';\n\nexport interface MockBehavior {\n /** Delay before responding (ms) */\n delay?: number;\n /** Simulate an error */\n error?: {\n code: 'RATE_LIMITED' | 'SERVICE_UNAVAILABLE' | 'CONTENT_FILTERED' | 'TIMEOUT';\n message: string;\n };\n /** Return invalid JSON (for validation retry testing) */\n returnInvalidJson?: boolean;\n /** Custom response content string */\n customResponse?: string;\n}\n\n// Global mock behavior that can be set in tests\nlet mockBehavior: MockBehavior = {};\n\n/**\n * Set mock behavior for testing.\n */\nexport function setMockBehavior(behavior: MockBehavior) {\n mockBehavior = behavior;\n}\n\n/**\n * Reset mock behavior to defaults.\n */\nexport function resetMockBehavior() {\n mockBehavior = {};\n}\n\n/**\n * Default valid JSON response for when no custom response is configured.\n * Returns a minimal valid JSON object — domain-specific schemas should override via customResponse.\n */\nfunction getDefaultResponse(): string {\n return JSON.stringify({ mock: true, timestamp: new Date().toISOString() });\n}\n\n/**\n * Default invalid JSON response for testing validation retries.\n */\nfunction getInvalidResponse(): string {\n return JSON.stringify({ incomplete: true });\n}\n\nexport class MockLLMProvider implements ILLMProvider {\n readonly name = 'mock';\n readonly availableModels = ['mock-model-1', 'mock-model-2'] as const;\n readonly defaultModel = 'mock-model-1';\n\n private callCount = 0;\n\n async generate(\n _userPrompt: string,\n _systemPrompt: string,\n _options?: GenerateOptions\n ): Promise<LLMResponse> {\n this.callCount++;\n\n if (mockBehavior.error) {\n throw new LLMProviderError(\n mockBehavior.error.message,\n mockBehavior.error.code,\n mockBehavior.error.code === 'RATE_LIMITED',\n mockBehavior.error.code === 'RATE_LIMITED' ? 429 : 503,\n 'mock'\n );\n }\n\n if (mockBehavior.delay) {\n await new Promise((resolve) => setTimeout(resolve, mockBehavior.delay));\n }\n\n if (mockBehavior.customResponse) {\n return {\n content: mockBehavior.customResponse,\n usage: { promptTokens: 100, completionTokens: 500, totalTokens: 600 },\n model: this.defaultModel,\n responseId: `mock-${this.callCount}`,\n finishReason: 'stop',\n };\n }\n\n if (mockBehavior.returnInvalidJson) {\n return {\n content: getInvalidResponse(),\n usage: { promptTokens: 100, completionTokens: 200, totalTokens: 300 },\n model: this.defaultModel,\n responseId: `mock-${this.callCount}`,\n finishReason: 'stop',\n };\n }\n\n return {\n content: getDefaultResponse(),\n usage: { promptTokens: 150, completionTokens: 800, totalTokens: 950 },\n model: this.defaultModel,\n responseId: `mock-${this.callCount}`,\n finishReason: 'stop',\n };\n }\n\n isAvailable(): boolean {\n return true;\n }\n\n estimateCost(\n promptTokens: number,\n completionTokens: number,\n _model?: string\n ): number {\n return (promptTokens + completionTokens) * 0.00001;\n }\n\n getCallCount(): number {\n return this.callCount;\n }\n\n resetCallCount(): void {\n this.callCount = 0;\n }\n}\n","import type { JsonExtractionResult } from '../types';\n\n/**\n * Extract a JSON object from LLM response content.\n *\n * Tries three strategies in order:\n * 1. Direct JSON.parse of the trimmed content\n * 2. Extract from markdown code blocks (```json ... ```)\n * 3. Find JSON object boundaries ({ ... })\n */\nexport function extractJson(content: string): JsonExtractionResult {\n const trimmed = content.trim();\n\n // Strategy 1: direct parse\n try {\n const json = JSON.parse(trimmed);\n return { success: true, json, raw: trimmed };\n } catch {\n // continue to extraction strategies\n }\n\n // Strategy 2: markdown code blocks\n const codeBlockMatch = trimmed.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?```/);\n if (codeBlockMatch) {\n try {\n const json = JSON.parse(codeBlockMatch[1].trim());\n return { success: true, json, raw: codeBlockMatch[1].trim() };\n } catch (e) {\n return {\n success: false,\n error: `JSON in code block is invalid: ${e instanceof Error ? e.message : 'Parse error'}`,\n raw: trimmed,\n };\n }\n }\n\n // Strategy 3: find JSON object boundaries\n const firstBrace = trimmed.indexOf('{');\n const lastBrace = trimmed.lastIndexOf('}');\n\n if (firstBrace !== -1 && lastBrace > firstBrace) {\n const jsonCandidate = trimmed.slice(firstBrace, lastBrace + 1);\n try {\n const json = JSON.parse(jsonCandidate);\n return { success: true, json, raw: jsonCandidate };\n } catch (e) {\n return {\n success: false,\n error: `Found JSON-like content but it's invalid: ${e instanceof Error ? e.message : 'Parse error'}`,\n raw: trimmed,\n };\n }\n }\n\n return {\n success: false,\n error: 'No valid JSON object found in response',\n raw: trimmed,\n };\n}\n","import type { LLMErrorCode } from '../errors'\n\n/**\n * Maps an LLM error code to an HTTP status code.\n * Use this in Next.js API routes to return appropriate HTTP responses\n * when an LLM generation call fails.\n */\nexport function llmErrorToHttpStatus(code: LLMErrorCode | string): number {\n switch (code) {\n case 'RATE_LIMITED':\n return 429\n case 'CONTENT_FILTERED':\n case 'INVALID_REQUEST':\n return 400\n case 'AUTHENTICATION_ERROR':\n case 'SERVICE_UNAVAILABLE':\n return 503\n case 'TIMEOUT':\n return 504\n case 'CONTEXT_LENGTH_EXCEEDED':\n return 422\n default:\n return 500\n }\n}\n","import type { ZodError } from 'zod';\n\n/**\n * Build a correction prompt for schema validation errors.\n *\n * Domain-agnostic: accepts the raw previous response and a ZodError,\n * formats them into a prompt asking the LLM to fix specific field errors.\n */\nexport function buildSchemaErrorCorrectionPrompt(\n previousResponse: string,\n zodError: ZodError\n): string {\n const errorDetails = zodError.errors\n .map((e) => {\n const path = e.path.length > 0 ? e.path.join('.') : 'root';\n return `- Path \"${path}\": ${e.message}`;\n })\n .join('\\n');\n\n return `Your previous response contained JSON that did not conform to the required schema.\n\n## Previous Response\n\n\\`\\`\\`json\n${previousResponse}\n\\`\\`\\`\n\n## Validation Errors\n\nThe following schema validation errors were found:\n\n${errorDetails}\n\n## Instructions\n\nPlease generate a corrected JSON response that:\n1. Fixes ALL the validation errors listed above\n2. Maintains the same content and intent\n3. Follows the exact schema structure required\n4. Contains ONLY valid JSON with no text before or after\n\nCommon fixes needed:\n- Ensure all required fields are present\n- Check that enum values match the schema exactly\n- Verify number fields contain numbers, not strings\n- Ensure arrays are not empty where minimum length is 1\n- Check that nested objects have all required properties\n\nRespond with ONLY the corrected JSON object.`;\n}\n\n/**\n * Build a correction prompt for JSON parsing errors.\n *\n * Domain-agnostic: accepts the raw response and a parse error message.\n */\nexport function buildParseErrorCorrectionPrompt(\n previousResponse: string,\n parseError: string\n): string {\n const truncatedResponse =\n previousResponse.length > 2000\n ? previousResponse.slice(0, 2000) + '\\n... [truncated]'\n : previousResponse;\n\n return `Your previous response could not be parsed as valid JSON.\n\n## Previous Response (excerpt)\n\n\\`\\`\\`\n${truncatedResponse}\n\\`\\`\\`\n\n## Parse Error\n\n${parseError}\n\n## Instructions\n\nPlease generate a valid JSON response that:\n1. Contains ONLY the JSON object - no markdown, no explanations\n2. Does not wrap the JSON in code blocks\n3. Uses proper JSON syntax (double quotes for strings, no trailing commas)\n4. Properly escapes any special characters in strings\n\nCommon JSON issues:\n- Using single quotes instead of double quotes\n- Trailing commas after the last item in arrays/objects\n- Unescaped special characters in strings (\\\\n, \\\\t, \\\\\\\", etc.)\n- Missing commas between object properties\n- Extra text before or after the JSON\n\nRespond with ONLY the corrected JSON object.`;\n}\n\n/**\n * Build a generic retry prompt when all corrections have failed.\n *\n * Domain-agnostic: just re-states the original request and asks for a simpler output.\n */\nexport function buildGenericRetryPrompt(\n originalPrompt: string,\n attemptNumber: number\n): string {\n return `The previous attempt to generate a response encountered issues. This is attempt ${attemptNumber}.\n\n## Original Request\n\n${originalPrompt}\n\n## Instructions\n\nPlease generate a fresh response that:\n1. Follows the exact JSON schema structure\n2. Contains only valid, parseable JSON\n3. Includes all required fields\n4. Has accurate data throughout\n\nFocus on generating a complete, valid response rather than a complex one. A simpler response that is fully valid is better than a complex one with errors.\n\nRespond with ONLY the JSON object.`;\n}\n","/**\n * Generic LLM Service\n *\n * Orchestrates provider selection, generation, JSON extraction,\n * schema validation, and retry logic. Parameterized over <TOutput>\n * so domain-specific schemas (Pattern, Recipe, etc.) stay in their apps.\n */\n\nimport type { ZodSchema } from 'zod';\nimport { ZodError } from 'zod';\nimport type { ILLMProvider } from './providers/interface';\nimport type {\n LLMResponse,\n GenerateOptions,\n LLMServiceConfig,\n ValidationResult,\n} from './types';\nimport { LLM_DEFAULTS } from './types';\nimport { LLMProviderError } from './errors';\nimport { extractJson } from './utils/json-extraction';\nimport {\n buildSchemaErrorCorrectionPrompt,\n buildParseErrorCorrectionPrompt,\n buildGenericRetryPrompt,\n} from './utils/retry';\nimport { OpenAIProvider, createOpenAIProvider } from './providers/openai';\nimport { AnthropicProvider, createAnthropicProvider } from './providers/anthropic';\nimport { MockLLMProvider } from './providers/mock';\n\n/**\n * Metadata about a generation attempt (tokens, model, retries).\n */\nexport interface GenerationMetadata {\n model: string;\n promptTokens: number;\n completionTokens: number;\n validationAttempts: number;\n}\n\n/**\n * Result of a validated generation. The caller checks `success` to narrow the union.\n */\nexport type GenerationResult<TOutput> =\n | {\n success: true;\n data: TOutput;\n metadata: GenerationMetadata;\n }\n | {\n success: false;\n error: { code: string; message: string; retryable: boolean };\n metadata?: GenerationMetadata;\n };\n\nconst DEFAULT_CONFIG: Required<LLMServiceConfig> = {\n maxRetries: 2,\n preferredProvider: 'openai',\n defaultModel: '',\n defaultTemperature: LLM_DEFAULTS.temperature,\n defaultMaxTokens: LLM_DEFAULTS.maxTokens,\n};\n\n/**\n * Generic LLM service. Consumers supply:\n * - A Zod schema for output validation\n * - Prompt builders for their domain\n *\n * The service handles provider selection, retries, JSON extraction, and validation.\n */\nexport class LLMService<TOutput> {\n private readonly config: Required<LLMServiceConfig>;\n private readonly providers: Map<string, ILLMProvider> = new Map();\n\n constructor(config?: LLMServiceConfig) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.initializeProviders();\n }\n\n private initializeProviders(): void {\n // Mock provider for testing\n if (process.env.LLM_PROVIDER === 'mock') {\n this.providers.set('mock', new MockLLMProvider());\n return;\n }\n\n const openai = createOpenAIProvider();\n if (openai) this.providers.set('openai', openai);\n\n const anthropic = createAnthropicProvider();\n if (anthropic) this.providers.set('anthropic', anthropic);\n }\n\n private getProvider(): ILLMProvider {\n // Try preferred first\n const preferred = this.providers.get(this.config.preferredProvider);\n if (preferred?.isAvailable()) return preferred;\n\n // Fallback to any available\n for (const provider of this.providers.values()) {\n if (provider.isAvailable()) return provider;\n }\n\n throw new LLMProviderError(\n 'No LLM providers available. Please configure OPENAI_API_KEY or ANTHROPIC_API_KEY.',\n 'AUTHENTICATION_ERROR',\n false\n );\n }\n\n /** Check if any LLM provider is available. */\n isAvailable(): boolean {\n for (const provider of this.providers.values()) {\n if (provider.isAvailable()) return true;\n }\n return false;\n }\n\n /** Get list of available provider names. */\n getAvailableProviders(): string[] {\n const available: string[] = [];\n for (const [name, provider] of this.providers.entries()) {\n if (provider.isAvailable()) available.push(name);\n }\n return available;\n }\n\n /**\n * Simple chat-style generation with no schema validation.\n * Returns the raw LLM response.\n */\n async chat(\n userPrompt: string,\n systemPrompt: string,\n options?: GenerateOptions\n ): Promise<LLMResponse> {\n const provider = this.getProvider();\n const generateOptions: GenerateOptions = {\n temperature: options?.temperature ?? this.config.defaultTemperature,\n maxTokens: options?.maxTokens ?? this.config.defaultMaxTokens,\n ...options,\n };\n\n return provider.generate(userPrompt, systemPrompt, generateOptions);\n }\n\n /**\n * Generate structured output validated against a Zod schema.\n *\n * @param userPrompt - User's request\n * @param systemPrompt - System instructions\n * @param schema - Zod schema to validate the parsed JSON against\n * @param options - Generation options\n */\n async generate(\n userPrompt: string,\n systemPrompt: string,\n schema: ZodSchema<TOutput>,\n options?: GenerateOptions\n ): Promise<GenerationResult<TOutput>> {\n const provider = this.getProvider();\n\n const genOptions: GenerateOptions = {\n model: this.config.defaultModel || undefined,\n temperature: this.config.defaultTemperature,\n maxTokens: this.config.defaultMaxTokens,\n ...options,\n };\n\n let lastError: Error | undefined;\n let lastResponse: LLMResponse | undefined;\n let validationAttempts = 0;\n\n // Initial generation\n try {\n lastResponse = await provider.generate(userPrompt, systemPrompt, genOptions);\n validationAttempts++;\n\n const extraction = extractJson(lastResponse.content);\n if (!extraction.success) {\n // JSON parse error — try correction\n const result = await this.retryWithCorrection(\n provider,\n userPrompt,\n systemPrompt,\n lastResponse,\n 'parse',\n extraction.error!,\n schema,\n genOptions,\n validationAttempts\n );\n if (result.data) {\n return this.buildSuccess(result.data, result.response ?? lastResponse, result.attempts);\n }\n lastError = new Error(extraction.error);\n validationAttempts = result.attempts;\n } else {\n // Validate against schema\n const validation = this.validate(extraction.json, schema);\n if (validation.valid && validation.data) {\n return this.buildSuccess(validation.data, lastResponse, validationAttempts);\n }\n\n // Schema validation error — try correction\n const result = await this.retryWithCorrection(\n provider,\n userPrompt,\n systemPrompt,\n lastResponse,\n 'schema',\n validation.zodError!,\n schema,\n genOptions,\n validationAttempts\n );\n if (result.data) {\n return this.buildSuccess(result.data, result.response ?? lastResponse, result.attempts);\n }\n lastError = validation.zodError;\n validationAttempts = result.attempts;\n }\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n }\n\n // All retries exhausted\n return this.buildError(lastError ?? new Error('Unknown error'), lastResponse, validationAttempts);\n }\n\n /**\n * Register an additional provider instance (useful for custom/third-party providers).\n */\n registerProvider(name: string, provider: ILLMProvider): void {\n this.providers.set(name, provider);\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private async retryWithCorrection(\n provider: ILLMProvider,\n originalPrompt: string,\n systemPrompt: string,\n previousResponse: LLMResponse,\n errorType: 'parse' | 'schema',\n error: string | ZodError,\n schema: ZodSchema<TOutput>,\n options: GenerateOptions,\n currentAttempts: number\n ): Promise<{ data?: TOutput; response?: LLMResponse; attempts: number }> {\n let attempts = currentAttempts;\n\n for (let retry = 0; retry < this.config.maxRetries; retry++) {\n attempts++;\n\n try {\n const correctionPrompt =\n errorType === 'parse'\n ? buildParseErrorCorrectionPrompt(previousResponse.content, error as string)\n : buildSchemaErrorCorrectionPrompt(previousResponse.content, error as ZodError);\n\n const response = await provider.generate(correctionPrompt, systemPrompt, options);\n const extraction = extractJson(response.content);\n\n if (!extraction.success) {\n // Still failing — try generic retry on last attempt\n if (retry === this.config.maxRetries - 1) {\n const genericPrompt = buildGenericRetryPrompt(originalPrompt, attempts);\n const finalResponse = await provider.generate(genericPrompt, systemPrompt, options);\n attempts++;\n\n const finalExtraction = extractJson(finalResponse.content);\n if (finalExtraction.success) {\n const validation = this.validate(finalExtraction.json, schema);\n if (validation.valid && validation.data) {\n return { data: validation.data, response: finalResponse, attempts };\n }\n }\n }\n continue;\n }\n\n const validation = this.validate(extraction.json, schema);\n if (validation.valid && validation.data) {\n return { data: validation.data, response, attempts };\n }\n\n // Update error for next retry\n if (validation.zodError) {\n previousResponse = response;\n error = validation.zodError;\n errorType = 'schema';\n }\n } catch {\n // Provider error during retry — continue to next attempt\n }\n }\n\n return { attempts };\n }\n\n private validate(data: unknown, schema: ZodSchema<TOutput>): ValidationResult<TOutput> {\n const result = schema.safeParse(data);\n if (result.success) {\n return { valid: true, data: result.data };\n }\n return {\n valid: false,\n zodError: result.error,\n errors: result.error.errors.map((e) => `${e.path.join('.')}: ${e.message}`),\n };\n }\n\n private buildSuccess(\n data: TOutput,\n response: LLMResponse,\n validationAttempts: number\n ): GenerationResult<TOutput> {\n return {\n success: true,\n data,\n metadata: {\n model: response.model,\n promptTokens: response.usage.promptTokens,\n completionTokens: response.usage.completionTokens,\n validationAttempts,\n },\n };\n }\n\n private buildError(\n error: Error,\n response?: LLMResponse,\n validationAttempts?: number\n ): GenerationResult<TOutput> {\n const isProviderError = error instanceof LLMProviderError;\n\n let code = 'GENERATION_FAILED';\n let retryable = false;\n\n if (isProviderError) {\n code = error.code;\n retryable = error.retryable;\n } else if (error instanceof ZodError) {\n code = 'VALIDATION_FAILED';\n retryable = true;\n }\n\n const result: GenerationResult<TOutput> = {\n success: false,\n error: { code, message: error.message, retryable },\n };\n\n if (response) {\n result.metadata = {\n model: response.model,\n promptTokens: response.usage.promptTokens,\n completionTokens: response.usage.completionTokens,\n validationAttempts: validationAttempts ?? 1,\n };\n }\n\n return result;\n }\n}\n"]}