@reactive-agents/llm-provider 0.1.0
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/LICENSE +21 -0
- package/README.md +108 -0
- package/dist/index.d.ts +542 -0
- package/dist/index.js +1683 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/errors.ts","../src/llm-service.ts","../src/llm-config.ts","../src/prompt-manager.ts","../src/token-counter.ts","../src/providers/anthropic.ts","../src/retry.ts","../src/providers/openai.ts","../src/providers/local.ts","../src/providers/gemini.ts","../src/testing.ts","../src/structured-output.ts","../src/runtime.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\n// ─── LLM Provider Type ───\n\nexport const LLMProviderType = Schema.Literal(\n \"anthropic\",\n \"openai\",\n \"ollama\",\n \"gemini\",\n \"custom\",\n);\nexport type LLMProvider = Schema.Schema.Type<typeof LLMProviderType>;\n\n// ─── Embedding Configuration ───\n\nexport const EmbeddingConfigSchema = Schema.Struct({\n model: Schema.String,\n dimensions: Schema.Number,\n provider: Schema.Literal(\"openai\", \"ollama\"),\n batchSize: Schema.optional(Schema.Number),\n});\n\nexport type EmbeddingConfig = Schema.Schema.Type<typeof EmbeddingConfigSchema>;\n\nexport const DefaultEmbeddingConfig: EmbeddingConfig = {\n model: \"text-embedding-3-small\",\n dimensions: 1536,\n provider: \"openai\",\n batchSize: 100,\n};\n\n// ─── Model Configuration ───\n\nexport const ModelConfigSchema = Schema.Struct({\n provider: LLMProviderType,\n model: Schema.String,\n maxTokens: Schema.optional(Schema.Number),\n temperature: Schema.optional(Schema.Number),\n topP: Schema.optional(Schema.Number),\n stopSequences: Schema.optional(Schema.Array(Schema.String)),\n});\n\nexport type ModelConfig = Schema.Schema.Type<typeof ModelConfigSchema>;\n\n// ─── Model Presets ───\n\nexport const ModelPresets = {\n \"claude-haiku\": {\n provider: \"anthropic\" as const,\n model: \"claude-3-5-haiku-20241022\",\n costPer1MInput: 1.0,\n costPer1MOutput: 5.0,\n maxContext: 200_000,\n quality: 0.6,\n },\n \"claude-sonnet\": {\n provider: \"anthropic\" as const,\n model: \"claude-sonnet-4-20250514\",\n costPer1MInput: 3.0,\n costPer1MOutput: 15.0,\n maxContext: 200_000,\n quality: 0.85,\n },\n \"claude-sonnet-4-5\": {\n provider: \"anthropic\" as const,\n model: \"claude-sonnet-4-5-20250929\",\n costPer1MInput: 3.0,\n costPer1MOutput: 15.0,\n maxContext: 200_000,\n quality: 0.9,\n },\n \"claude-opus\": {\n provider: \"anthropic\" as const,\n model: \"claude-opus-4-20250514\",\n costPer1MInput: 15.0,\n costPer1MOutput: 75.0,\n maxContext: 1_000_000,\n quality: 1.0,\n },\n \"gpt-4o-mini\": {\n provider: \"openai\" as const,\n model: \"gpt-4o-mini\",\n costPer1MInput: 0.15,\n costPer1MOutput: 0.6,\n maxContext: 128_000,\n quality: 0.55,\n },\n \"gpt-4o\": {\n provider: \"openai\" as const,\n model: \"gpt-4o\",\n costPer1MInput: 2.5,\n costPer1MOutput: 10.0,\n maxContext: 128_000,\n quality: 0.8,\n },\n \"gemini-2.0-flash\": {\n provider: \"gemini\" as const,\n model: \"gemini-2.0-flash\",\n costPer1MInput: 0.1,\n costPer1MOutput: 0.4,\n maxContext: 1_000_000,\n quality: 0.75,\n },\n \"gemini-2.5-pro\": {\n provider: \"gemini\" as const,\n model: \"gemini-2.5-pro-preview-03-25\",\n costPer1MInput: 1.25,\n costPer1MOutput: 10.0,\n maxContext: 1_000_000,\n quality: 0.95,\n },\n} as const;\n\nexport type ModelPresetName = keyof typeof ModelPresets;\n\n// ─── Cache Control (Anthropic Prompt Caching) ───\n\nexport const CacheControlSchema = Schema.Struct({\n type: Schema.Literal(\"ephemeral\"),\n});\n\nexport type CacheControl = Schema.Schema.Type<typeof CacheControlSchema>;\n\n// ─── Content Blocks ───\n\nexport const ImageSourceSchema = Schema.Struct({\n type: Schema.Literal(\"base64\", \"url\"),\n media_type: Schema.Literal(\n \"image/png\",\n \"image/jpeg\",\n \"image/gif\",\n \"image/webp\",\n ),\n data: Schema.String,\n});\n\nexport type ImageSource = Schema.Schema.Type<typeof ImageSourceSchema>;\n\nexport const TextContentBlockSchema = Schema.Struct({\n type: Schema.Literal(\"text\"),\n text: Schema.String,\n cache_control: Schema.optional(CacheControlSchema),\n});\n\nexport const ImageContentBlockSchema = Schema.Struct({\n type: Schema.Literal(\"image\"),\n source: ImageSourceSchema,\n});\n\nexport const ToolUseContentBlockSchema = Schema.Struct({\n type: Schema.Literal(\"tool_use\"),\n id: Schema.String,\n name: Schema.String,\n input: Schema.Unknown,\n});\n\nexport const ToolResultContentBlockSchema = Schema.Struct({\n type: Schema.Literal(\"tool_result\"),\n tool_use_id: Schema.String,\n content: Schema.String,\n});\n\nexport type ContentBlock =\n | {\n readonly type: \"text\";\n readonly text: string;\n readonly cache_control?: CacheControl;\n }\n | { readonly type: \"image\"; readonly source: ImageSource }\n | {\n readonly type: \"tool_use\";\n readonly id: string;\n readonly name: string;\n readonly input: unknown;\n }\n | {\n readonly type: \"tool_result\";\n readonly tool_use_id: string;\n readonly content: string;\n };\n\n// ─── Cacheable Content Block ───\n\nexport type CacheableContentBlock = {\n readonly type: \"text\";\n readonly text: string;\n readonly cache_control: CacheControl;\n};\n\n/**\n * Helper — wrap text in a cacheable content block.\n * Non-Anthropic providers silently ignore `cache_control`.\n */\nexport const makeCacheable = (text: string): CacheableContentBlock => ({\n type: \"text\",\n text,\n cache_control: { type: \"ephemeral\" },\n});\n\n// ─── Message Types ───\n\nexport type LLMMessage =\n | { readonly role: \"system\"; readonly content: string }\n | {\n readonly role: \"user\";\n readonly content: string | readonly ContentBlock[];\n }\n | {\n readonly role: \"assistant\";\n readonly content: string | readonly ContentBlock[];\n };\n\n// ─── Token Usage ───\n\nexport const TokenUsageSchema = Schema.Struct({\n inputTokens: Schema.Number,\n outputTokens: Schema.Number,\n totalTokens: Schema.Number,\n estimatedCost: Schema.Number,\n});\n\nexport type TokenUsage = Schema.Schema.Type<typeof TokenUsageSchema>;\n\n// ─── Stop Reason ───\n\nexport const StopReasonSchema = Schema.Literal(\n \"end_turn\",\n \"max_tokens\",\n \"stop_sequence\",\n \"tool_use\",\n);\n\nexport type StopReason = Schema.Schema.Type<typeof StopReasonSchema>;\n\n// ─── Tool Definition ───\n\nexport const ToolDefinitionSchema = Schema.Struct({\n name: Schema.String,\n description: Schema.String,\n inputSchema: Schema.Record({ key: Schema.String, value: Schema.Unknown }),\n});\n\nexport type ToolDefinition = Schema.Schema.Type<typeof ToolDefinitionSchema>;\n\n// ─── Tool Call ───\n\nexport const ToolCallSchema = Schema.Struct({\n id: Schema.String,\n name: Schema.String,\n input: Schema.Unknown,\n});\n\nexport type ToolCall = Schema.Schema.Type<typeof ToolCallSchema>;\n\n// ─── Completion Request ───\n\nexport type CompletionRequest = {\n readonly messages: readonly LLMMessage[];\n readonly model?: ModelConfig;\n readonly maxTokens?: number;\n readonly temperature?: number;\n readonly stopSequences?: readonly string[];\n readonly tools?: readonly ToolDefinition[];\n readonly systemPrompt?: string;\n};\n\n// ─── Completion Response ───\n\nexport const CompletionResponseSchema = Schema.Struct({\n content: Schema.String,\n stopReason: StopReasonSchema,\n usage: TokenUsageSchema,\n model: Schema.String,\n toolCalls: Schema.optional(Schema.Array(ToolCallSchema)),\n});\n\nexport type CompletionResponse = Schema.Schema.Type<\n typeof CompletionResponseSchema\n>;\n\n// ─── Stream Events ───\n\nexport type StreamEvent =\n | { readonly type: \"text_delta\"; readonly text: string }\n | {\n readonly type: \"tool_use_start\";\n readonly id: string;\n readonly name: string;\n }\n | { readonly type: \"tool_use_delta\"; readonly input: string }\n | { readonly type: \"content_complete\"; readonly content: string }\n | { readonly type: \"usage\"; readonly usage: TokenUsage }\n | { readonly type: \"error\"; readonly error: string };\n\n// ─── Structured Output Config ───\n\nexport type StructuredCompletionRequest<A> = CompletionRequest & {\n readonly outputSchema: Schema.Schema<A>;\n readonly retryOnParseFail?: boolean;\n readonly maxParseRetries?: number;\n};\n\n// ─── Truncation Strategy ───\n\nexport type TruncationStrategy =\n | \"drop-oldest\"\n | \"summarize-middle\"\n | \"sliding-window\"\n | \"importance-based\";\n","import { Data } from \"effect\";\nimport type { LLMProvider } from \"./types.js\";\n\n/**\n * General LLM error — catch-all for unexpected provider failures.\n */\nexport class LLMError extends Data.TaggedError(\"LLMError\")<{\n readonly message: string;\n readonly provider: LLMProvider;\n readonly cause?: unknown;\n}> {}\n\n/**\n * Rate limit exceeded — includes retry-after hint.\n */\nexport class LLMRateLimitError extends Data.TaggedError(\"LLMRateLimitError\")<{\n readonly message: string;\n readonly provider: LLMProvider;\n readonly retryAfterMs: number;\n}> {}\n\n/**\n * Request timeout.\n */\nexport class LLMTimeoutError extends Data.TaggedError(\"LLMTimeoutError\")<{\n readonly message: string;\n readonly provider: LLMProvider;\n readonly timeoutMs: number;\n}> {}\n\n/**\n * Structured output parse failure.\n */\nexport class LLMParseError extends Data.TaggedError(\"LLMParseError\")<{\n readonly message: string;\n readonly rawOutput: string;\n readonly expectedSchema: string;\n}> {}\n\n/**\n * Context window overflow — too many tokens for the model.\n */\nexport class LLMContextOverflowError extends Data.TaggedError(\n \"LLMContextOverflowError\",\n)<{\n readonly message: string;\n readonly tokenCount: number;\n readonly maxTokens: number;\n}> {}\n\n/**\n * Union of all LLM error types.\n */\nexport type LLMErrors =\n | LLMError\n | LLMRateLimitError\n | LLMTimeoutError\n | LLMParseError\n | LLMContextOverflowError;\n","import { Effect, Context, type Stream } from \"effect\";\nimport type {\n CompletionRequest,\n CompletionResponse,\n StreamEvent,\n StructuredCompletionRequest,\n LLMMessage,\n ModelConfig,\n} from \"./types.js\";\nimport type { LLMErrors } from \"./errors.js\";\n\n/**\n * Core LLM service — all LLM interactions go through this.\n * Layers 3, 4, 5, and 10 depend on this.\n */\nexport class LLMService extends Context.Tag(\"LLMService\")<\n LLMService,\n {\n /**\n * Complete a prompt (non-streaming).\n * Returns full response after generation completes.\n */\n readonly complete: (\n request: CompletionRequest,\n ) => Effect.Effect<CompletionResponse, LLMErrors>;\n\n /**\n * Stream a completion. Returns an Effect that yields a Stream of events.\n * Use for real-time UI updates (collaborative mode).\n */\n readonly stream: (\n request: CompletionRequest,\n ) => Effect.Effect<Stream.Stream<StreamEvent, LLMErrors>, LLMErrors>;\n\n /**\n * Complete with structured output.\n * Parses LLM response into a typed object using Effect Schema.\n * Retries with parse error feedback if parsing fails.\n */\n readonly completeStructured: <A>(\n request: StructuredCompletionRequest<A>,\n ) => Effect.Effect<A, LLMErrors>;\n\n /**\n * Generate embeddings for text.\n *\n * This is the SOLE embedding source for the entire framework.\n * Anthropic has no embeddings API — routes to OpenAI or Ollama\n * per LLMConfig.embeddingConfig.\n */\n readonly embed: (\n texts: readonly string[],\n model?: string,\n ) => Effect.Effect<readonly number[][], LLMErrors>;\n\n /**\n * Count tokens for a set of messages.\n * Used for context window management.\n */\n readonly countTokens: (\n messages: readonly LLMMessage[],\n ) => Effect.Effect<number, LLMErrors>;\n\n /**\n * Get current model configuration.\n */\n readonly getModelConfig: () => Effect.Effect<ModelConfig, never>;\n }\n>() {}\n","import { Context, Layer } from \"effect\";\nimport type { LLMProvider, EmbeddingConfig } from \"./types.js\";\n\n/**\n * LLM configuration — provided via environment or config file.\n */\nexport class LLMConfig extends Context.Tag(\"LLMConfig\")<\n LLMConfig,\n {\n readonly defaultProvider: LLMProvider;\n readonly defaultModel: string;\n readonly anthropicApiKey?: string;\n readonly openaiApiKey?: string;\n readonly googleApiKey?: string;\n readonly ollamaEndpoint?: string;\n /**\n * Embedding configuration. Anthropic has no embeddings API;\n * embeddings route to OpenAI (default) or Ollama.\n * This is the SOLE embedding config for the entire framework.\n */\n readonly embeddingConfig: EmbeddingConfig;\n /**\n * Enable Anthropic prompt caching.\n * When true, memory context injections are wrapped in\n * `cache_control: { type: \"ephemeral\" }` blocks.\n */\n readonly supportsPromptCaching: boolean;\n readonly maxRetries: number;\n readonly timeoutMs: number;\n readonly defaultMaxTokens: number;\n readonly defaultTemperature: number;\n }\n>() {}\n\n/**\n * Build LLMConfig from environment variables.\n */\nexport const LLMConfigFromEnv = Layer.succeed(\n LLMConfig,\n LLMConfig.of({\n defaultProvider: \"anthropic\",\n defaultModel:\n process.env.LLM_DEFAULT_MODEL ?? \"claude-sonnet-4-20250514\",\n anthropicApiKey: process.env.ANTHROPIC_API_KEY,\n openaiApiKey: process.env.OPENAI_API_KEY,\n googleApiKey: process.env.GOOGLE_API_KEY,\n ollamaEndpoint:\n process.env.OLLAMA_ENDPOINT ?? \"http://localhost:11434\",\n embeddingConfig: {\n model: process.env.EMBEDDING_MODEL ?? \"text-embedding-3-small\",\n dimensions: Number(process.env.EMBEDDING_DIMENSIONS ?? 1536),\n provider:\n (process.env.EMBEDDING_PROVIDER as \"openai\" | \"ollama\") ?? \"openai\",\n batchSize: 100,\n },\n supportsPromptCaching: (\n process.env.LLM_DEFAULT_MODEL ?? \"claude-sonnet-4-20250514\"\n ).startsWith(\"claude\"),\n maxRetries: Number(process.env.LLM_MAX_RETRIES ?? 3),\n timeoutMs: Number(process.env.LLM_TIMEOUT_MS ?? 30_000),\n defaultMaxTokens: 4096,\n defaultTemperature: Number(process.env.LLM_DEFAULT_TEMPERATURE ?? 0.7),\n }),\n);\n","import { Effect, Context, Layer } from \"effect\";\nimport type { LLMMessage, TruncationStrategy } from \"./types.js\";\nimport type { LLMErrors } from \"./errors.js\";\nimport { estimateTokenCount } from \"./token-counter.js\";\n\n/**\n * Manages context window budgets.\n * Ensures prompts don't exceed model limits.\n * Implements truncation strategies.\n */\nexport class PromptManager extends Context.Tag(\"PromptManager\")<\n PromptManager,\n {\n /**\n * Build a prompt within token budget.\n * Automatically truncates conversation history if needed.\n */\n readonly buildPrompt: (options: {\n readonly systemPrompt: string;\n readonly messages: readonly LLMMessage[];\n readonly reserveOutputTokens: number;\n readonly maxContextTokens: number;\n readonly truncationStrategy: TruncationStrategy;\n }) => Effect.Effect<readonly LLMMessage[], LLMErrors>;\n\n /**\n * Check if messages fit within context window.\n */\n readonly fitsInContext: (\n messages: readonly LLMMessage[],\n maxTokens: number,\n ) => Effect.Effect<boolean, LLMErrors>;\n }\n>() {}\n\n/**\n * Live PromptManager that uses heuristic token counting\n * and applies truncation strategies.\n */\nexport const PromptManagerLive = Layer.succeed(\n PromptManager,\n PromptManager.of({\n buildPrompt: (options) =>\n Effect.gen(function* () {\n const {\n systemPrompt,\n messages,\n reserveOutputTokens,\n maxContextTokens,\n truncationStrategy,\n } = options;\n\n const budget = maxContextTokens - reserveOutputTokens;\n\n // Always keep the system prompt\n const systemMessage: LLMMessage = {\n role: \"system\",\n content: systemPrompt,\n };\n const systemTokens = yield* estimateTokenCount([systemMessage]);\n\n if (systemTokens >= budget) {\n // System prompt alone exceeds budget — return just it (truncated scenario)\n return [systemMessage];\n }\n\n const remainingBudget = budget - systemTokens;\n\n // Apply truncation strategy\n const truncated = yield* applyTruncation(\n messages,\n remainingBudget,\n truncationStrategy,\n );\n\n return [systemMessage, ...truncated];\n }),\n\n fitsInContext: (messages, maxTokens) =>\n Effect.gen(function* () {\n const count = yield* estimateTokenCount(messages);\n return count <= maxTokens;\n }),\n }),\n);\n\n/**\n * Apply truncation strategy to fit messages within token budget.\n */\nconst applyTruncation = (\n messages: readonly LLMMessage[],\n budget: number,\n strategy: TruncationStrategy,\n): Effect.Effect<readonly LLMMessage[], never> =>\n Effect.gen(function* () {\n const totalTokens = yield* estimateTokenCount(messages);\n\n if (totalTokens <= budget) {\n return messages;\n }\n\n switch (strategy) {\n case \"drop-oldest\": {\n // Remove messages from the beginning until we fit\n const result: LLMMessage[] = [];\n let usedTokens = 0;\n\n // Work backwards — keep most recent messages\n for (let i = messages.length - 1; i >= 0; i--) {\n const msgTokens = yield* estimateTokenCount([messages[i]!]);\n if (usedTokens + msgTokens <= budget) {\n result.unshift(messages[i]!);\n usedTokens += msgTokens;\n } else {\n break;\n }\n }\n return result;\n }\n\n case \"sliding-window\": {\n // Keep last N messages that fit\n const result: LLMMessage[] = [];\n let usedTokens = 0;\n\n for (let i = messages.length - 1; i >= 0; i--) {\n const msgTokens = yield* estimateTokenCount([messages[i]!]);\n if (usedTokens + msgTokens <= budget) {\n result.unshift(messages[i]!);\n usedTokens += msgTokens;\n } else {\n break;\n }\n }\n return result;\n }\n\n case \"summarize-middle\":\n case \"importance-based\":\n // For Phase 1: fall back to sliding-window behavior\n // Full implementation requires LLM calls (circular dependency)\n {\n const result: LLMMessage[] = [];\n let usedTokens = 0;\n\n // Keep first message (often has important context)\n if (messages.length > 0) {\n const firstTokens = yield* estimateTokenCount([messages[0]!]);\n if (firstTokens <= budget) {\n result.push(messages[0]!);\n usedTokens += firstTokens;\n }\n }\n\n // Fill from the end\n const tail: LLMMessage[] = [];\n for (let i = messages.length - 1; i >= 1; i--) {\n const msgTokens = yield* estimateTokenCount([messages[i]!]);\n if (usedTokens + msgTokens <= budget) {\n tail.unshift(messages[i]!);\n usedTokens += msgTokens;\n } else {\n break;\n }\n }\n\n return [...result, ...tail];\n }\n }\n });\n","import { Effect } from \"effect\";\nimport type { LLMMessage } from \"./types.js\";\n\n/**\n * Estimate token count for messages.\n * Uses a simple heuristic: ~4 characters per token for English text.\n * This is used as a fallback when the provider's token counting API is unavailable.\n */\nexport const estimateTokenCount = (\n messages: readonly LLMMessage[],\n): Effect.Effect<number, never> =>\n Effect.sync(() => {\n let totalChars = 0;\n\n for (const msg of messages) {\n if (typeof msg.content === \"string\") {\n totalChars += msg.content.length;\n } else {\n // Content blocks\n for (const block of msg.content) {\n if (block.type === \"text\") {\n totalChars += block.text.length;\n } else if (block.type === \"tool_result\") {\n totalChars += block.content.length;\n } else if (block.type === \"tool_use\") {\n totalChars += JSON.stringify(block.input).length;\n }\n // Images not counted in token estimation\n }\n }\n // Add overhead for role/message framing (~4 tokens per message)\n totalChars += 16;\n }\n\n return Math.ceil(totalChars / 4);\n });\n\n/**\n * Calculate cost in USD given token counts and model name.\n */\nexport const calculateCost = (\n inputTokens: number,\n outputTokens: number,\n model: string,\n): number => {\n // Cost per 1M tokens lookup\n const costMap: Record<string, { input: number; output: number }> = {\n \"claude-3-5-haiku-20241022\": { input: 1.0, output: 5.0 },\n \"claude-sonnet-4-20250514\": { input: 3.0, output: 15.0 },\n \"claude-sonnet-4-5-20250929\": { input: 3.0, output: 15.0 },\n \"claude-opus-4-20250514\": { input: 15.0, output: 75.0 },\n \"gpt-4o-mini\": { input: 0.15, output: 0.6 },\n \"gpt-4o\": { input: 2.5, output: 10.0 },\n \"gemini-2.0-flash\": { input: 0.1, output: 0.4 },\n \"gemini-2.5-pro-preview-03-25\": { input: 1.25, output: 10.0 },\n \"gemini-embedding-001\": { input: 0.0, output: 0.0 },\n };\n\n const costs = costMap[model] ?? { input: 3.0, output: 15.0 };\n return (\n (inputTokens / 1_000_000) * costs.input +\n (outputTokens / 1_000_000) * costs.output\n );\n};\n","import { Effect, Layer, Stream, Schema } from \"effect\";\nimport { LLMService } from \"../llm-service.js\";\nimport { LLMConfig } from \"../llm-config.js\";\nimport {\n LLMError,\n LLMTimeoutError,\n LLMParseError,\n LLMRateLimitError,\n} from \"../errors.js\";\nimport type {\n LLMErrors } from \"../errors.js\";\nimport type {\n CompletionResponse,\n StreamEvent,\n LLMMessage,\n ContentBlock,\n} from \"../types.js\";\nimport { calculateCost, estimateTokenCount } from \"../token-counter.js\";\nimport { retryPolicy } from \"../retry.js\";\n\n// ─── Anthropic Message Conversion Helpers ───\n\ntype AnthropicRole = \"user\" | \"assistant\";\n\ntype AnthropicContentBlock =\n | { type: \"text\"; text: string; cache_control?: { type: \"ephemeral\" } }\n | { type: \"image\"; source: { type: string; media_type: string; data: string } }\n | { type: \"tool_use\"; id: string; name: string; input: unknown }\n | { type: \"tool_result\"; tool_use_id: string; content: string };\n\ntype AnthropicMessage = {\n role: AnthropicRole;\n content: string | AnthropicContentBlock[];\n};\n\nconst toAnthropicMessages = (\n messages: readonly LLMMessage[],\n): AnthropicMessage[] =>\n messages\n .filter((m) => m.role !== \"system\")\n .map((m) => ({\n role: m.role as AnthropicRole,\n content:\n typeof m.content === \"string\"\n ? m.content\n : (m.content as readonly ContentBlock[]).map(\n (b) => b as unknown as AnthropicContentBlock,\n ),\n }));\n\nconst toAnthropicTool = (tool: {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n}) => ({\n name: tool.name,\n description: tool.description,\n input_schema: {\n type: \"object\" as const,\n ...tool.inputSchema,\n },\n});\n\nconst toEffectError = (error: unknown, provider: \"anthropic\"): LLMErrors => {\n const err = error as { status?: number; message?: string; headers?: Record<string, string> };\n if (err.status === 429) {\n const retryAfter = err.headers?.[\"retry-after\"];\n return new LLMRateLimitError({\n message: err.message ?? \"Rate limit exceeded\",\n provider,\n retryAfterMs: retryAfter ? Number(retryAfter) * 1000 : 60_000,\n });\n }\n return new LLMError({\n message: err.message ?? String(error),\n provider,\n cause: error,\n });\n};\n\n// ─── Anthropic Provider Layer ───\n\nexport const AnthropicProviderLive = Layer.effect(\n LLMService,\n Effect.gen(function* () {\n const config = yield* LLMConfig;\n\n // Lazy-load the SDK to avoid hard dependency if not using Anthropic\n const createClient = () => {\n // Dynamic import is handled in Effect.tryPromise\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const Anthropic = require(\"@anthropic-ai/sdk\").default;\n return new Anthropic({ apiKey: config.anthropicApiKey });\n };\n\n let _client: ReturnType<typeof createClient> | null = null;\n const getClient = () => {\n if (!_client) _client = createClient();\n return _client;\n };\n\n return LLMService.of({\n complete: (request) =>\n Effect.gen(function* () {\n const client = getClient();\n const model = request.model?.model ?? config.defaultModel;\n\n const response = yield* Effect.tryPromise({\n try: () =>\n (client as { messages: { create: (opts: unknown) => Promise<unknown> } }).messages.create({\n model,\n max_tokens: request.maxTokens ?? config.defaultMaxTokens,\n temperature: request.temperature ?? config.defaultTemperature,\n system: request.systemPrompt,\n messages: toAnthropicMessages(request.messages),\n stop_sequences: request.stopSequences\n ? [...request.stopSequences]\n : undefined,\n tools: request.tools?.map(toAnthropicTool),\n }),\n catch: (error) => toEffectError(error, \"anthropic\"),\n });\n\n return mapAnthropicResponse(response as AnthropicRawResponse, model);\n }).pipe(\n Effect.retry(retryPolicy),\n Effect.timeout(\"30 seconds\"),\n Effect.catchTag(\"TimeoutException\", () =>\n Effect.fail(\n new LLMTimeoutError({\n message: \"LLM request timed out\",\n provider: \"anthropic\",\n timeoutMs: 30_000,\n }),\n ),\n ),\n ),\n\n stream: (request) =>\n Effect.gen(function* () {\n const client = getClient();\n const model = request.model?.model ?? config.defaultModel;\n\n return Stream.async<StreamEvent, LLMErrors>((emit) => {\n const stream = (client as { messages: { stream: (opts: unknown) => { on: (event: string, cb: (...args: unknown[]) => void) => void } } }).messages.stream({\n model,\n max_tokens: request.maxTokens ?? config.defaultMaxTokens,\n temperature: request.temperature ?? config.defaultTemperature,\n system: request.systemPrompt,\n messages: toAnthropicMessages(request.messages),\n });\n\n stream.on(\"text\", (text: unknown) => {\n emit.single({ type: \"text_delta\", text: text as string });\n });\n\n stream.on(\"finalMessage\", (message: unknown) => {\n const msg = message as AnthropicRawResponse;\n const content = msg.content\n .filter(\n (b: { type: string }): b is { type: \"text\"; text: string } =>\n b.type === \"text\",\n )\n .map((b: { text: string }) => b.text)\n .join(\"\");\n\n emit.single({ type: \"content_complete\", content });\n emit.single({\n type: \"usage\",\n usage: {\n inputTokens: msg.usage.input_tokens,\n outputTokens: msg.usage.output_tokens,\n totalTokens:\n msg.usage.input_tokens + msg.usage.output_tokens,\n estimatedCost: calculateCost(\n msg.usage.input_tokens,\n msg.usage.output_tokens,\n model,\n ),\n },\n });\n emit.end();\n });\n\n stream.on(\"error\", (error: unknown) => {\n const err = error as { message?: string };\n emit.fail(\n new LLMError({\n message: err.message ?? String(error),\n provider: \"anthropic\",\n cause: error,\n }),\n );\n });\n });\n }),\n\n completeStructured: (request) =>\n Effect.gen(function* () {\n const schemaStr = JSON.stringify(\n Schema.encodedSchema(request.outputSchema),\n null,\n 2,\n );\n\n const messagesWithFormat: LLMMessage[] = [\n ...request.messages,\n {\n role: \"user\" as const,\n content: `\\nRespond with ONLY valid JSON matching this schema:\\n${schemaStr}\\n\\nNo markdown, no code fences, just raw JSON.`,\n },\n ];\n\n let lastError: unknown = null;\n const maxRetries = request.maxParseRetries ?? 2;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const msgs =\n attempt === 0\n ? messagesWithFormat\n : [\n ...messagesWithFormat,\n {\n role: \"assistant\" as const,\n content: String(lastError),\n },\n {\n role: \"user\" as const,\n content: `That response was not valid JSON. The parse error was: ${String(lastError)}. Please try again with valid JSON only.`,\n },\n ];\n\n const completeResult = yield* Effect.tryPromise({\n try: () => {\n const client = getClient();\n return (client as { messages: { create: (opts: unknown) => Promise<unknown> } }).messages.create({\n model: request.model?.model ?? config.defaultModel,\n max_tokens:\n request.maxTokens ?? config.defaultMaxTokens,\n temperature: request.temperature ?? config.defaultTemperature,\n system: request.systemPrompt,\n messages: toAnthropicMessages(msgs),\n });\n },\n catch: (error) => toEffectError(error, \"anthropic\"),\n });\n\n const response = mapAnthropicResponse(\n completeResult as AnthropicRawResponse,\n request.model?.model ?? config.defaultModel,\n );\n\n try {\n const parsed = JSON.parse(response.content);\n const decoded = Schema.decodeUnknownEither(\n request.outputSchema,\n )(parsed);\n\n if (decoded._tag === \"Right\") {\n return decoded.right;\n }\n lastError = decoded.left;\n } catch (e) {\n lastError = e;\n }\n }\n\n return yield* Effect.fail(\n new LLMParseError({\n message: `Failed to parse structured output after ${maxRetries + 1} attempts`,\n rawOutput: String(lastError),\n expectedSchema: schemaStr,\n }),\n );\n }),\n\n embed: (texts, model) =>\n Effect.tryPromise({\n try: async () => {\n const embeddingModel = model ?? config.embeddingConfig.model;\n const embProvider = config.embeddingConfig.provider;\n\n if (embProvider === \"openai\") {\n const { default: OpenAI } = await import(\"openai\");\n const openaiClient = new OpenAI({\n apiKey: config.openaiApiKey,\n });\n const batchSize = config.embeddingConfig.batchSize ?? 100;\n const results: number[][] = [];\n\n for (let i = 0; i < texts.length; i += batchSize) {\n const batch = texts.slice(i, i + batchSize);\n const response = await openaiClient.embeddings.create({\n model: embeddingModel,\n input: [...batch],\n dimensions: config.embeddingConfig.dimensions,\n });\n results.push(\n ...response.data.map(\n (d: { embedding: number[] }) => d.embedding,\n ),\n );\n }\n\n return results;\n }\n\n // Ollama embeddings\n const endpoint =\n config.ollamaEndpoint ?? \"http://localhost:11434\";\n return Promise.all(\n [...texts].map(async (text) => {\n const res = await fetch(`${endpoint}/api/embed`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n model: embeddingModel,\n input: text,\n }),\n });\n const data = (await res.json()) as {\n embeddings: number[][];\n };\n return data.embeddings[0]!;\n }),\n );\n },\n catch: (error) =>\n new LLMError({\n message: `Embedding failed: ${error}`,\n provider: \"anthropic\",\n cause: error,\n }),\n }),\n\n countTokens: (messages) =>\n Effect.gen(function* () {\n return yield* estimateTokenCount(messages);\n }),\n\n getModelConfig: () =>\n Effect.succeed({\n provider: \"anthropic\" as const,\n model: config.defaultModel,\n }),\n });\n }),\n);\n\n// ─── Anthropic Response Mapping ───\n\ntype AnthropicRawResponse = {\n content: Array<\n | { type: \"text\"; text: string }\n | { type: \"tool_use\"; id: string; name: string; input: unknown }\n >;\n stop_reason: string;\n usage: { input_tokens: number; output_tokens: number };\n model: string;\n};\n\nconst mapAnthropicResponse = (\n response: AnthropicRawResponse,\n model: string,\n): CompletionResponse => {\n const textContent = response.content\n .filter(\n (b): b is { type: \"text\"; text: string } => b.type === \"text\",\n )\n .map((b) => b.text)\n .join(\"\");\n\n const toolCalls = response.content\n .filter(\n (\n b,\n ): b is {\n type: \"tool_use\";\n id: string;\n name: string;\n input: unknown;\n } => b.type === \"tool_use\",\n )\n .map((b) => ({\n id: b.id,\n name: b.name,\n input: b.input,\n }));\n\n const stopReason =\n response.stop_reason === \"end_turn\"\n ? (\"end_turn\" as const)\n : response.stop_reason === \"max_tokens\"\n ? (\"max_tokens\" as const)\n : response.stop_reason === \"stop_sequence\"\n ? (\"stop_sequence\" as const)\n : response.stop_reason === \"tool_use\"\n ? (\"tool_use\" as const)\n : (\"end_turn\" as const);\n\n return {\n content: textContent,\n stopReason,\n usage: {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n totalTokens:\n response.usage.input_tokens + response.usage.output_tokens,\n estimatedCost: calculateCost(\n response.usage.input_tokens,\n response.usage.output_tokens,\n model,\n ),\n },\n model: response.model ?? model,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n };\n};\n","import { Schedule } from \"effect\";\nimport type { LLMErrors } from \"./errors.js\";\n\n/**\n * Retry policy for LLM calls.\n * Handles rate limits with exponential backoff.\n * Only retries on rate limit and timeout errors.\n */\nexport const retryPolicy = Schedule.intersect(\n Schedule.recurs(3),\n Schedule.exponential(\"1 second\", 2.0),\n).pipe(\n Schedule.whileInput<LLMErrors>(\n (error) =>\n error._tag === \"LLMRateLimitError\" || error._tag === \"LLMTimeoutError\",\n ),\n);\n\n// ─── Circuit Breaker ───\n\nexport type CircuitBreakerConfig = {\n readonly failureThreshold: number;\n readonly cooldownMs: number;\n readonly halfOpenRequests: number;\n};\n\nexport const defaultCircuitBreakerConfig: CircuitBreakerConfig = {\n failureThreshold: 5,\n cooldownMs: 30_000,\n halfOpenRequests: 1,\n};\n","import { Effect, Layer, Stream, Schema } from \"effect\";\nimport { LLMService } from \"../llm-service.js\";\nimport { LLMConfig } from \"../llm-config.js\";\nimport {\n LLMError,\n LLMTimeoutError,\n LLMParseError,\n LLMRateLimitError,\n} from \"../errors.js\";\nimport type { LLMErrors } from \"../errors.js\";\nimport type {\n CompletionResponse,\n StreamEvent,\n LLMMessage,\n} from \"../types.js\";\nimport { calculateCost, estimateTokenCount } from \"../token-counter.js\";\nimport { retryPolicy } from \"../retry.js\";\n\n// ─── OpenAI Message Conversion ───\n\ntype OpenAIMessage = {\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n};\n\nconst toOpenAIMessages = (\n messages: readonly LLMMessage[],\n): OpenAIMessage[] =>\n messages.map((m) => ({\n role: m.role,\n content:\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter(\n (b): b is { type: \"text\"; text: string } => b.type === \"text\",\n )\n .map((b) => b.text)\n .join(\"\"),\n }));\n\nconst toEffectError = (error: unknown, provider: \"openai\"): LLMErrors => {\n const err = error as { status?: number; message?: string };\n if (err.status === 429) {\n return new LLMRateLimitError({\n message: err.message ?? \"Rate limit exceeded\",\n provider,\n retryAfterMs: 60_000,\n });\n }\n return new LLMError({\n message: err.message ?? String(error),\n provider,\n cause: error,\n });\n};\n\n// ─── OpenAI Provider Layer ───\n\nexport const OpenAIProviderLive = Layer.effect(\n LLMService,\n Effect.gen(function* () {\n const config = yield* LLMConfig;\n\n const createClient = () => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const OpenAI = require(\"openai\").default;\n return new OpenAI({ apiKey: config.openaiApiKey });\n };\n\n let _client: ReturnType<typeof createClient> | null = null;\n const getClient = () => {\n if (!_client) _client = createClient();\n return _client;\n };\n\n const defaultModel = config.defaultModel.startsWith(\"claude\")\n ? \"gpt-4o\"\n : config.defaultModel;\n\n return LLMService.of({\n complete: (request) =>\n Effect.gen(function* () {\n const client = getClient();\n const model = request.model?.model ?? defaultModel;\n\n const response = yield* Effect.tryPromise({\n try: () =>\n (client as { chat: { completions: { create: (opts: unknown) => Promise<unknown> } } }).chat.completions.create({\n model,\n max_tokens: request.maxTokens ?? config.defaultMaxTokens,\n temperature: request.temperature ?? config.defaultTemperature,\n messages: toOpenAIMessages(request.messages),\n stop: request.stopSequences\n ? [...request.stopSequences]\n : undefined,\n }),\n catch: (error) => toEffectError(error, \"openai\"),\n });\n\n return mapOpenAIResponse(response as OpenAIRawResponse, model);\n }).pipe(\n Effect.retry(retryPolicy),\n Effect.timeout(\"30 seconds\"),\n Effect.catchTag(\"TimeoutException\", () =>\n Effect.fail(\n new LLMTimeoutError({\n message: \"LLM request timed out\",\n provider: \"openai\",\n timeoutMs: 30_000,\n }),\n ),\n ),\n ),\n\n stream: (request) =>\n Effect.gen(function* () {\n const client = getClient();\n const model = request.model?.model ?? defaultModel;\n\n return Stream.async<StreamEvent, LLMErrors>((emit) => {\n const doStream = async () => {\n try {\n const stream = await (client as { chat: { completions: { create: (opts: unknown) => Promise<AsyncIterable<unknown>> } } }).chat.completions.create({\n model,\n max_tokens:\n request.maxTokens ?? config.defaultMaxTokens,\n temperature:\n request.temperature ?? config.defaultTemperature,\n messages: toOpenAIMessages(request.messages),\n stream: true,\n });\n\n let fullContent = \"\";\n\n for await (const chunk of stream as AsyncIterable<{\n choices: Array<{\n delta: { content?: string };\n finish_reason?: string;\n }>;\n usage?: { prompt_tokens: number; completion_tokens: number };\n }>) {\n const delta = chunk.choices[0]?.delta?.content;\n if (delta) {\n fullContent += delta;\n emit.single({ type: \"text_delta\", text: delta });\n }\n\n if (chunk.choices[0]?.finish_reason) {\n emit.single({\n type: \"content_complete\",\n content: fullContent,\n });\n\n const inputTokens = chunk.usage?.prompt_tokens ?? 0;\n const outputTokens =\n chunk.usage?.completion_tokens ?? 0;\n emit.single({\n type: \"usage\",\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n estimatedCost: calculateCost(\n inputTokens,\n outputTokens,\n model,\n ),\n },\n });\n emit.end();\n }\n }\n } catch (error) {\n const err = error as { message?: string };\n emit.fail(\n new LLMError({\n message: err.message ?? String(error),\n provider: \"openai\",\n cause: error,\n }),\n );\n }\n };\n void doStream();\n });\n }),\n\n completeStructured: (request) =>\n Effect.gen(function* () {\n const schemaStr = JSON.stringify(\n Schema.encodedSchema(request.outputSchema),\n null,\n 2,\n );\n\n const messagesWithFormat: LLMMessage[] = [\n ...request.messages,\n {\n role: \"user\" as const,\n content: `\\nRespond with ONLY valid JSON matching this schema:\\n${schemaStr}\\n\\nNo markdown, no code fences, just raw JSON.`,\n },\n ];\n\n let lastError: unknown = null;\n const maxRetries = request.maxParseRetries ?? 2;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const msgs =\n attempt === 0\n ? messagesWithFormat\n : [\n ...messagesWithFormat,\n {\n role: \"assistant\" as const,\n content: String(lastError),\n },\n {\n role: \"user\" as const,\n content: `That response was not valid JSON. The parse error was: ${String(lastError)}. Please try again with valid JSON only.`,\n },\n ];\n\n const client = getClient();\n const completeResult = yield* Effect.tryPromise({\n try: () =>\n (client as { chat: { completions: { create: (opts: unknown) => Promise<unknown> } } }).chat.completions.create({\n model: request.model?.model ?? defaultModel,\n max_tokens:\n request.maxTokens ?? config.defaultMaxTokens,\n temperature:\n request.temperature ?? config.defaultTemperature,\n messages: toOpenAIMessages(msgs),\n }),\n catch: (error) => toEffectError(error, \"openai\"),\n });\n\n const response = mapOpenAIResponse(\n completeResult as OpenAIRawResponse,\n request.model?.model ?? defaultModel,\n );\n\n try {\n const parsed = JSON.parse(response.content);\n const decoded = Schema.decodeUnknownEither(\n request.outputSchema,\n )(parsed);\n\n if (decoded._tag === \"Right\") {\n return decoded.right;\n }\n lastError = decoded.left;\n } catch (e) {\n lastError = e;\n }\n }\n\n return yield* Effect.fail(\n new LLMParseError({\n message: `Failed to parse structured output after ${maxRetries + 1} attempts`,\n rawOutput: String(lastError),\n expectedSchema: schemaStr,\n }),\n );\n }),\n\n embed: (texts, model) =>\n Effect.tryPromise({\n try: async () => {\n const client = getClient();\n const embeddingModel =\n model ?? config.embeddingConfig.model;\n const batchSize = config.embeddingConfig.batchSize ?? 100;\n const results: number[][] = [];\n\n for (let i = 0; i < texts.length; i += batchSize) {\n const batch = texts.slice(i, i + batchSize);\n const response = await (client as { embeddings: { create: (opts: unknown) => Promise<{ data: Array<{ embedding: number[] }> }> } }).embeddings.create({\n model: embeddingModel,\n input: [...batch],\n dimensions: config.embeddingConfig.dimensions,\n });\n results.push(\n ...response.data.map(\n (d: { embedding: number[] }) => d.embedding,\n ),\n );\n }\n\n return results;\n },\n catch: (error) =>\n new LLMError({\n message: `Embedding failed: ${error}`,\n provider: \"openai\",\n cause: error,\n }),\n }),\n\n countTokens: (messages) =>\n Effect.gen(function* () {\n return yield* estimateTokenCount(messages);\n }),\n\n getModelConfig: () =>\n Effect.succeed({\n provider: \"openai\" as const,\n model: defaultModel,\n }),\n });\n }),\n);\n\n// ─── OpenAI Response Mapping ───\n\ntype OpenAIRawResponse = {\n choices: Array<{\n message: { content: string; role: string };\n finish_reason: string;\n }>;\n usage: { prompt_tokens: number; completion_tokens: number; total_tokens: number };\n model: string;\n};\n\nconst mapOpenAIResponse = (\n response: OpenAIRawResponse,\n model: string,\n): CompletionResponse => {\n const content = response.choices[0]?.message?.content ?? \"\";\n\n const stopReason =\n response.choices[0]?.finish_reason === \"stop\"\n ? (\"end_turn\" as const)\n : response.choices[0]?.finish_reason === \"length\"\n ? (\"max_tokens\" as const)\n : (\"end_turn\" as const);\n\n return {\n content,\n stopReason,\n usage: {\n inputTokens: response.usage?.prompt_tokens ?? 0,\n outputTokens: response.usage?.completion_tokens ?? 0,\n totalTokens: response.usage?.total_tokens ?? 0,\n estimatedCost: calculateCost(\n response.usage?.prompt_tokens ?? 0,\n response.usage?.completion_tokens ?? 0,\n model,\n ),\n },\n model: response.model ?? model,\n };\n};\n","import { Effect, Layer, Stream, Schema } from \"effect\";\nimport { LLMService } from \"../llm-service.js\";\nimport { LLMConfig } from \"../llm-config.js\";\nimport { LLMError, LLMTimeoutError, LLMParseError } from \"../errors.js\";\nimport type { LLMErrors } from \"../errors.js\";\nimport type {\n CompletionResponse,\n StreamEvent,\n LLMMessage,\n} from \"../types.js\";\nimport { estimateTokenCount } from \"../token-counter.js\";\nimport { retryPolicy } from \"../retry.js\";\n\n// ─── Ollama Message Conversion ───\n\ntype OllamaMessage = {\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n};\n\nconst toOllamaMessages = (\n messages: readonly LLMMessage[],\n): OllamaMessage[] =>\n messages.map((m) => ({\n role: m.role,\n content:\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter(\n (b): b is { type: \"text\"; text: string } => b.type === \"text\",\n )\n .map((b) => b.text)\n .join(\"\"),\n }));\n\n// ─── Ollama / Local Provider Layer ───\n\nexport const LocalProviderLive = Layer.effect(\n LLMService,\n Effect.gen(function* () {\n const config = yield* LLMConfig;\n const endpoint = config.ollamaEndpoint ?? \"http://localhost:11434\";\n const defaultModel = config.defaultModel.startsWith(\"claude\") ||\n config.defaultModel.startsWith(\"gpt\")\n ? \"llama3\"\n : config.defaultModel;\n\n return LLMService.of({\n complete: (request) =>\n Effect.gen(function* () {\n const model = request.model?.model ?? defaultModel;\n\n const response = yield* Effect.tryPromise({\n try: async () => {\n const res = await fetch(`${endpoint}/api/chat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n model,\n messages: toOllamaMessages(request.messages),\n stream: false,\n options: {\n temperature:\n request.temperature ?? config.defaultTemperature,\n num_predict:\n request.maxTokens ?? config.defaultMaxTokens,\n stop: request.stopSequences\n ? [...request.stopSequences]\n : undefined,\n },\n }),\n });\n\n if (!res.ok) {\n throw new Error(\n `Ollama request failed: ${res.status} ${res.statusText}`,\n );\n }\n\n return (await res.json()) as OllamaRawResponse;\n },\n catch: (error) =>\n new LLMError({\n message: `Ollama request failed: ${error}`,\n provider: \"ollama\",\n cause: error,\n }),\n });\n\n const content = response.message?.content ?? \"\";\n const inputTokens = response.prompt_eval_count ?? 0;\n const outputTokens = response.eval_count ?? 0;\n\n return {\n content,\n stopReason: response.done_reason === \"stop\"\n ? (\"end_turn\" as const)\n : response.done_reason === \"length\"\n ? (\"max_tokens\" as const)\n : (\"end_turn\" as const),\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n estimatedCost: 0, // Local models are free\n },\n model: response.model ?? model,\n } satisfies CompletionResponse;\n }).pipe(\n Effect.retry(retryPolicy),\n Effect.timeout(\"60 seconds\"),\n Effect.catchTag(\"TimeoutException\", () =>\n Effect.fail(\n new LLMTimeoutError({\n message: \"Local LLM request timed out\",\n provider: \"ollama\",\n timeoutMs: 60_000,\n }),\n ),\n ),\n ),\n\n stream: (request) =>\n Effect.gen(function* () {\n const model = request.model?.model ?? defaultModel;\n\n return Stream.async<StreamEvent, LLMErrors>((emit) => {\n const doStream = async () => {\n try {\n const res = await fetch(`${endpoint}/api/chat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n model,\n messages: toOllamaMessages(request.messages),\n stream: true,\n options: {\n temperature:\n request.temperature ?? config.defaultTemperature,\n num_predict:\n request.maxTokens ?? config.defaultMaxTokens,\n },\n }),\n });\n\n if (!res.ok || !res.body) {\n throw new Error(`Ollama stream failed: ${res.status}`);\n }\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const lines = decoder\n .decode(value, { stream: true })\n .split(\"\\n\")\n .filter(Boolean);\n\n for (const line of lines) {\n const parsed = JSON.parse(line) as {\n message?: { content: string };\n done: boolean;\n prompt_eval_count?: number;\n eval_count?: number;\n };\n\n if (parsed.message?.content) {\n fullContent += parsed.message.content;\n emit.single({\n type: \"text_delta\",\n text: parsed.message.content,\n });\n }\n\n if (parsed.done) {\n emit.single({\n type: \"content_complete\",\n content: fullContent,\n });\n emit.single({\n type: \"usage\",\n usage: {\n inputTokens: parsed.prompt_eval_count ?? 0,\n outputTokens: parsed.eval_count ?? 0,\n totalTokens:\n (parsed.prompt_eval_count ?? 0) +\n (parsed.eval_count ?? 0),\n estimatedCost: 0,\n },\n });\n emit.end();\n }\n }\n }\n } catch (error) {\n const err = error as { message?: string };\n emit.fail(\n new LLMError({\n message: err.message ?? String(error),\n provider: \"ollama\",\n cause: error,\n }),\n );\n }\n };\n void doStream();\n });\n }),\n\n completeStructured: (request) =>\n Effect.gen(function* () {\n const schemaStr = JSON.stringify(\n Schema.encodedSchema(request.outputSchema),\n null,\n 2,\n );\n\n const messagesWithFormat: LLMMessage[] = [\n ...request.messages,\n {\n role: \"user\" as const,\n content: `\\nRespond with ONLY valid JSON matching this schema:\\n${schemaStr}\\n\\nNo markdown, no code fences, just raw JSON.`,\n },\n ];\n\n let lastError: unknown = null;\n const maxRetries = request.maxParseRetries ?? 2;\n\n // Use self-reference via the service itself\n const llm: { complete: typeof LLMService.Service[\"complete\"] } = {\n complete: (req) =>\n Effect.gen(function* () {\n const model = req.model?.model ?? defaultModel;\n const res = yield* Effect.tryPromise({\n try: async () => {\n const resp = await fetch(`${endpoint}/api/chat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n model,\n messages: toOllamaMessages(req.messages),\n stream: false,\n options: {\n temperature:\n req.temperature ?? config.defaultTemperature,\n num_predict:\n req.maxTokens ?? config.defaultMaxTokens,\n },\n }),\n });\n return (await resp.json()) as OllamaRawResponse;\n },\n catch: (error) =>\n new LLMError({\n message: `Ollama request failed: ${error}`,\n provider: \"ollama\",\n cause: error,\n }),\n });\n const content = res.message?.content ?? \"\";\n const inputTokens = res.prompt_eval_count ?? 0;\n const outputTokens = res.eval_count ?? 0;\n return {\n content,\n stopReason: \"end_turn\" as const,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n estimatedCost: 0,\n },\n model: res.model ?? model,\n } satisfies CompletionResponse;\n }),\n };\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const msgs =\n attempt === 0\n ? messagesWithFormat\n : [\n ...messagesWithFormat,\n {\n role: \"assistant\" as const,\n content: String(lastError),\n },\n {\n role: \"user\" as const,\n content: `That response was not valid JSON. The parse error was: ${String(lastError)}. Please try again with valid JSON only.`,\n },\n ];\n\n const response = yield* llm.complete({\n ...request,\n messages: msgs,\n });\n\n try {\n const parsed = JSON.parse(response.content);\n const decoded = Schema.decodeUnknownEither(\n request.outputSchema,\n )(parsed);\n\n if (decoded._tag === \"Right\") {\n return decoded.right;\n }\n lastError = decoded.left;\n } catch (e) {\n lastError = e;\n }\n }\n\n return yield* Effect.fail(\n new LLMParseError({\n message: `Failed to parse structured output after ${maxRetries + 1} attempts`,\n rawOutput: String(lastError),\n expectedSchema: schemaStr,\n }),\n );\n }),\n\n embed: (texts, model) =>\n Effect.tryPromise({\n try: async () => {\n const embeddingModel =\n model ?? config.embeddingConfig.model ?? \"nomic-embed-text\";\n return Promise.all(\n [...texts].map(async (text) => {\n const res = await fetch(`${endpoint}/api/embed`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n model: embeddingModel,\n input: text,\n }),\n });\n const data = (await res.json()) as {\n embeddings: number[][];\n };\n return data.embeddings[0]!;\n }),\n );\n },\n catch: (error) =>\n new LLMError({\n message: `Embedding failed: ${error}`,\n provider: \"ollama\",\n cause: error,\n }),\n }),\n\n countTokens: (messages) =>\n Effect.gen(function* () {\n return yield* estimateTokenCount(messages);\n }),\n\n getModelConfig: () =>\n Effect.succeed({\n provider: \"ollama\" as const,\n model: defaultModel,\n }),\n });\n }),\n);\n\n// ─── Ollama Raw Response ───\n\ntype OllamaRawResponse = {\n model: string;\n message?: { content: string; role: string };\n done: boolean;\n done_reason?: string;\n prompt_eval_count?: number;\n eval_count?: number;\n};\n","import { Effect, Layer, Stream, Schema } from \"effect\";\nimport { LLMService } from \"../llm-service.js\";\nimport { LLMConfig } from \"../llm-config.js\";\nimport {\n LLMError,\n LLMTimeoutError,\n LLMParseError,\n LLMRateLimitError,\n} from \"../errors.js\";\nimport type { LLMErrors } from \"../errors.js\";\nimport type {\n CompletionResponse,\n StreamEvent,\n LLMMessage,\n ContentBlock,\n} from \"../types.js\";\nimport { calculateCost, estimateTokenCount } from \"../token-counter.js\";\nimport { retryPolicy } from \"../retry.js\";\n\n// ─── Gemini Message Conversion Helpers ───\n\ntype GeminiPart =\n | { text: string }\n | { functionCall: { name: string; args: unknown } }\n | { functionResponse: { name: string; response: unknown } };\n\ntype GeminiContent = {\n role: \"user\" | \"model\";\n parts: GeminiPart[];\n};\n\nconst toGeminiContents = (messages: readonly LLMMessage[]): GeminiContent[] => {\n const result: GeminiContent[] = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue; // handled via config.systemInstruction\n\n const role = msg.role === \"assistant\" ? \"model\" : \"user\";\n\n if (typeof msg.content === \"string\") {\n result.push({ role, parts: [{ text: msg.content }] });\n } else {\n const parts: GeminiPart[] = [];\n for (const block of msg.content as readonly ContentBlock[]) {\n if (block.type === \"text\") {\n parts.push({ text: block.text });\n } else if (block.type === \"tool_use\") {\n parts.push({\n functionCall: { name: block.name, args: block.input },\n });\n } else if (block.type === \"tool_result\") {\n parts.push({\n functionResponse: {\n name: \"tool\",\n response: { content: block.content },\n },\n });\n }\n // images not converted — Gemini multimodal requires separate file URIs\n }\n if (parts.length > 0) {\n result.push({ role, parts });\n }\n }\n }\n\n return result;\n};\n\nconst extractSystemPrompt = (\n messages: readonly LLMMessage[],\n): string | undefined => {\n const sys = messages.find((m) => m.role === \"system\");\n if (!sys) return undefined;\n return typeof sys.content === \"string\" ? sys.content : undefined;\n};\n\nconst toGeminiTools = (\n tools: { name: string; description: string; inputSchema: Record<string, unknown> }[],\n) =>\n tools.length === 0\n ? undefined\n : [\n {\n functionDeclarations: tools.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: { type: \"object\", ...t.inputSchema },\n })),\n },\n ];\n\nconst toEffectError = (error: unknown): LLMErrors => {\n const err = error as { status?: number; code?: number; message?: string };\n if (err.status === 429 || err.code === 429) {\n return new LLMRateLimitError({\n message: err.message ?? \"Rate limit exceeded\",\n provider: \"gemini\",\n retryAfterMs: 60_000,\n });\n }\n return new LLMError({\n message: err.message ?? String(error),\n provider: \"gemini\",\n cause: error,\n });\n};\n\n// ─── Gemini Response Types ───\n\ntype GeminiUsage = {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n totalTokenCount?: number;\n};\n\ntype GeminiFunctionCall = { name: string; args: unknown };\n\ntype GeminiRawResponse = {\n text: string;\n functionCalls?: GeminiFunctionCall[];\n usageMetadata?: GeminiUsage;\n};\n\n// ─── Response Mapper ───\n\nconst mapGeminiResponse = (\n response: GeminiRawResponse,\n model: string,\n): CompletionResponse => {\n const toolCalls = response.functionCalls?.map((fc, i) => ({\n id: `call_${i}`,\n name: fc.name,\n input: fc.args,\n }));\n\n const inputTokens = response.usageMetadata?.promptTokenCount ?? 0;\n const outputTokens = response.usageMetadata?.candidatesTokenCount ?? 0;\n\n return {\n content: response.text ?? \"\",\n stopReason: toolCalls?.length ? \"tool_use\" : \"end_turn\",\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n estimatedCost: calculateCost(inputTokens, outputTokens, model),\n },\n model,\n toolCalls: toolCalls?.length ? toolCalls : undefined,\n };\n};\n\n// ─── Gemini Provider Layer ───\n\nexport const GeminiProviderLive = Layer.effect(\n LLMService,\n Effect.gen(function* () {\n const config = yield* LLMConfig;\n\n // ─── Lazy-load the SDK via dynamic import (interceptable by mock.module) ───\n\n type GoogleGenAIClient = {\n models: {\n generateContent: (opts: unknown) => Promise<GeminiRawResponse>;\n generateContentStream: (opts: unknown) => Promise<\n AsyncIterable<{\n text: string;\n usageMetadata?: GeminiUsage;\n }>\n >;\n embedContent: (opts: unknown) => Promise<{\n embeddings: Array<{ values: number[] }>;\n }>;\n };\n };\n\n type GoogleGenAIModule = {\n GoogleGenAI: new (opts: { apiKey?: string }) => GoogleGenAIClient;\n };\n\n let _clientPromise: Promise<GoogleGenAIClient> | null = null;\n const getClient = (): Promise<GoogleGenAIClient> => {\n if (!_clientPromise) {\n _clientPromise = (\n import(\"@google/genai\") as Promise<GoogleGenAIModule>\n ).then(({ GoogleGenAI }) => new GoogleGenAI({ apiKey: config.googleApiKey }));\n }\n return _clientPromise;\n };\n\n const buildGeminiConfig = (opts: {\n maxTokens?: number;\n temperature?: number;\n systemPrompt?: string;\n stopSequences?: readonly string[];\n tools?: readonly { name: string; description: string; inputSchema: Record<string, unknown> }[];\n }) => {\n const cfg: Record<string, unknown> = {\n maxOutputTokens: opts.maxTokens ?? config.defaultMaxTokens,\n temperature: opts.temperature ?? config.defaultTemperature,\n };\n const sys = opts.systemPrompt;\n if (sys) cfg.systemInstruction = sys;\n if (opts.stopSequences?.length) cfg.stopSequences = [...opts.stopSequences];\n if (opts.tools?.length) {\n cfg.tools = toGeminiTools([...opts.tools]);\n }\n return cfg;\n };\n\n return LLMService.of({\n complete: (request) =>\n Effect.gen(function* () {\n const client = yield* Effect.promise(() => getClient());\n const model = request.model?.model ?? config.defaultModel;\n const contents = toGeminiContents(request.messages);\n const systemPrompt =\n extractSystemPrompt(request.messages) ?? request.systemPrompt;\n\n const response = yield* Effect.tryPromise({\n try: () =>\n client.models.generateContent({\n model,\n contents,\n config: buildGeminiConfig({\n maxTokens: request.maxTokens,\n temperature: request.temperature,\n systemPrompt,\n stopSequences: request.stopSequences,\n tools: request.tools,\n }),\n }),\n catch: toEffectError,\n });\n\n return mapGeminiResponse(response, model);\n }).pipe(\n Effect.retry(retryPolicy),\n Effect.timeout(\"30 seconds\"),\n Effect.catchTag(\"TimeoutException\", () =>\n Effect.fail(\n new LLMTimeoutError({\n message: \"LLM request timed out\",\n provider: \"gemini\",\n timeoutMs: 30_000,\n }),\n ),\n ),\n ),\n\n stream: (request) =>\n Effect.gen(function* () {\n const model = request.model?.model ?? config.defaultModel;\n const contents = toGeminiContents(request.messages);\n const systemPrompt =\n extractSystemPrompt(request.messages) ?? request.systemPrompt;\n\n return Stream.async<StreamEvent, LLMErrors>((emit) => {\n void (async () => {\n try {\n const client = await getClient();\n const stream = await client.models.generateContentStream({\n model,\n contents,\n config: buildGeminiConfig({\n maxTokens: request.maxTokens,\n temperature: request.temperature,\n systemPrompt,\n }),\n });\n\n let fullContent = \"\";\n let inputTokens = 0;\n let outputTokens = 0;\n\n for await (const chunk of stream) {\n if (chunk.text) {\n emit.single({ type: \"text_delta\", text: chunk.text });\n fullContent += chunk.text;\n }\n if (chunk.usageMetadata) {\n inputTokens = chunk.usageMetadata.promptTokenCount ?? 0;\n outputTokens =\n chunk.usageMetadata.candidatesTokenCount ?? 0;\n }\n }\n\n emit.single({ type: \"content_complete\", content: fullContent });\n emit.single({\n type: \"usage\",\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n estimatedCost: calculateCost(inputTokens, outputTokens, model),\n },\n });\n emit.end();\n } catch (error) {\n const err = error as { message?: string };\n emit.fail(\n new LLMError({\n message: err.message ?? String(error),\n provider: \"gemini\",\n cause: error,\n }),\n );\n }\n })();\n });\n }),\n\n completeStructured: (request) =>\n Effect.gen(function* () {\n const schemaStr = JSON.stringify(\n Schema.encodedSchema(request.outputSchema),\n null,\n 2,\n );\n\n const messagesWithFormat: LLMMessage[] = [\n ...request.messages,\n {\n role: \"user\" as const,\n content: `\\nRespond with ONLY valid JSON matching this schema:\\n${schemaStr}\\n\\nNo markdown, no code fences, just raw JSON.`,\n },\n ];\n\n let lastError: unknown = null;\n const maxRetries = request.maxParseRetries ?? 2;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const msgs =\n attempt === 0\n ? messagesWithFormat\n : [\n ...messagesWithFormat,\n {\n role: \"assistant\" as const,\n content: String(lastError),\n },\n {\n role: \"user\" as const,\n content: `That response was not valid JSON. The parse error was: ${String(lastError)}. Please try again with valid JSON only.`,\n },\n ];\n\n const client = yield* Effect.promise(() => getClient());\n const model = request.model?.model ?? config.defaultModel;\n\n const response = yield* Effect.tryPromise({\n try: () =>\n client.models.generateContent({\n model,\n contents: toGeminiContents(msgs),\n config: buildGeminiConfig({\n maxTokens: request.maxTokens,\n temperature: request.temperature,\n systemPrompt: request.systemPrompt,\n }),\n }),\n catch: toEffectError,\n });\n\n const mapped = mapGeminiResponse(response, model);\n\n try {\n const parsed = JSON.parse(mapped.content);\n const decoded = Schema.decodeUnknownEither(\n request.outputSchema,\n )(parsed);\n\n if (decoded._tag === \"Right\") {\n return decoded.right;\n }\n lastError = decoded.left;\n } catch (e) {\n lastError = e;\n }\n }\n\n return yield* Effect.fail(\n new LLMParseError({\n message: `Failed to parse structured output after ${maxRetries + 1} attempts`,\n rawOutput: String(lastError),\n expectedSchema: schemaStr,\n }),\n );\n }),\n\n embed: (texts, model) =>\n Effect.tryPromise({\n try: async () => {\n const client = await getClient();\n const embeddingModel = model ?? \"gemini-embedding-001\";\n\n const result = await client.models.embedContent({\n model: embeddingModel,\n contents: [...texts],\n config: {\n outputDimensionality: config.embeddingConfig.dimensions,\n },\n });\n\n return result.embeddings.map((e) => e.values);\n },\n catch: (error) =>\n new LLMError({\n message: `Embedding failed: ${error}`,\n provider: \"gemini\",\n cause: error,\n }),\n }),\n\n countTokens: (messages) =>\n Effect.gen(function* () {\n return yield* estimateTokenCount(messages);\n }),\n\n getModelConfig: () =>\n Effect.succeed({\n provider: \"gemini\" as const,\n model: config.defaultModel,\n }),\n });\n }),\n);\n","import { Effect, Layer, Stream, Schema } from \"effect\";\nimport { LLMService } from \"./llm-service.js\";\nimport type {\n CompletionResponse,\n StreamEvent,\n LLMMessage,\n} from \"./types.js\";\nimport type { LLMErrors } from \"./errors.js\";\n\n/**\n * Create a deterministic test LLM service.\n * Returns responses based on pattern matching against prompt content.\n *\n * Usage:\n * ```ts\n * const layer = TestLLMServiceLayer({\n * \"capital of France\": \"Paris\",\n * \"plan\": '{\"goal\":\"test\",\"steps\":[]}',\n * });\n * ```\n */\nexport const TestLLMService = (\n responses: Record<string, string>,\n): typeof LLMService.Service => ({\n complete: (request) =>\n Effect.gen(function* () {\n const lastMessage = request.messages[request.messages.length - 1];\n const content =\n lastMessage && typeof lastMessage.content === \"string\"\n ? lastMessage.content\n : \"\";\n\n // Also check systemPrompt for pattern matching\n const systemPrompt =\n typeof (request as any).systemPrompt === \"string\"\n ? (request as any).systemPrompt\n : \"\";\n const searchText = `${content} ${systemPrompt}`;\n\n // Match against registered patterns\n for (const [pattern, response] of Object.entries(responses)) {\n if (pattern.length > 0 && searchText.includes(pattern)) {\n return {\n content: response,\n stopReason: \"end_turn\" as const,\n usage: {\n inputTokens: Math.ceil(content.length / 4),\n outputTokens: Math.ceil(response.length / 4),\n totalTokens:\n Math.ceil(content.length / 4) +\n Math.ceil(response.length / 4),\n estimatedCost: 0,\n },\n model: \"test-model\",\n } satisfies CompletionResponse;\n }\n }\n\n // Default response\n return {\n content: \"Test response\",\n stopReason: \"end_turn\" as const,\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n estimatedCost: 0,\n },\n model: \"test-model\",\n } satisfies CompletionResponse;\n }),\n\n stream: (_request) =>\n Effect.succeed(\n Stream.make(\n { type: \"text_delta\" as const, text: \"Test \" } satisfies StreamEvent,\n { type: \"text_delta\" as const, text: \"response\" } satisfies StreamEvent,\n {\n type: \"content_complete\" as const,\n content: \"Test response\",\n } satisfies StreamEvent,\n {\n type: \"usage\" as const,\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n estimatedCost: 0,\n },\n } satisfies StreamEvent,\n ) as Stream.Stream<StreamEvent, LLMErrors>,\n ),\n\n completeStructured: (request) =>\n Effect.gen(function* () {\n const lastMessage = request.messages[request.messages.length - 1];\n const content =\n lastMessage && typeof lastMessage.content === \"string\"\n ? lastMessage.content\n : \"\";\n\n // Try to find a matching response\n let responseContent = \"Test response\";\n for (const [pattern, response] of Object.entries(responses)) {\n if (content.includes(pattern)) {\n responseContent = response;\n break;\n }\n }\n\n const parsed = JSON.parse(responseContent);\n return Schema.decodeUnknownSync(request.outputSchema)(parsed);\n }),\n\n embed: (texts) =>\n Effect.succeed(\n texts.map(() => new Array(768).fill(0).map(() => Math.random())),\n ),\n\n countTokens: (messages) =>\n Effect.succeed(\n messages.reduce(\n (sum, m) =>\n sum +\n (typeof m.content === \"string\"\n ? Math.ceil(m.content.length / 4)\n : 100),\n 0,\n ),\n ),\n\n getModelConfig: () =>\n Effect.succeed({\n provider: \"anthropic\" as const,\n model: \"test-model\",\n }),\n});\n\n/**\n * Create a test Layer for LLMService with optional pattern-matched responses.\n */\nexport const TestLLMServiceLayer = (\n responses: Record<string, string> = {},\n) => Layer.succeed(LLMService, LLMService.of(TestLLMService(responses)));\n","import { Schema } from \"effect\";\n\n// ─── Common Schemas for Reasoning Strategies ───\n\n/**\n * Schema for ReAct action parsing.\n */\nexport const ReActActionSchema = Schema.Struct({\n thought: Schema.String,\n action: Schema.optional(\n Schema.Struct({\n tool: Schema.String,\n input: Schema.Unknown,\n }),\n ),\n finalAnswer: Schema.optional(Schema.String),\n isComplete: Schema.Boolean,\n});\n\nexport type ReActAction = Schema.Schema.Type<typeof ReActActionSchema>;\n\n/**\n * Schema for plan generation.\n */\nexport const PlanSchema = Schema.Struct({\n goal: Schema.String,\n steps: Schema.Array(\n Schema.Struct({\n id: Schema.Number,\n description: Schema.String,\n tool: Schema.optional(Schema.String),\n dependsOn: Schema.optional(Schema.Array(Schema.Number)),\n estimatedDuration: Schema.optional(Schema.String),\n }),\n ),\n});\n\nexport type Plan = Schema.Schema.Type<typeof PlanSchema>;\n\n/**\n * Schema for reflection output.\n */\nexport const ReflectionSchema = Schema.Struct({\n taskAccomplished: Schema.Boolean,\n confidence: Schema.Number,\n strengths: Schema.Array(Schema.String),\n weaknesses: Schema.Array(Schema.String),\n needsRefinement: Schema.Boolean,\n refinementSuggestions: Schema.optional(Schema.Array(Schema.String)),\n});\n\nexport type Reflection = Schema.Schema.Type<typeof ReflectionSchema>;\n\n/**\n * Schema for strategy selection.\n */\nexport const StrategySelectionSchema = Schema.Struct({\n selectedStrategy: Schema.String,\n reasoning: Schema.String,\n confidence: Schema.Number,\n alternativeStrategies: Schema.Array(\n Schema.Struct({\n strategy: Schema.String,\n whyNot: Schema.String,\n }),\n ),\n});\n\nexport type StrategySelection = Schema.Schema.Type<\n typeof StrategySelectionSchema\n>;\n\n/**\n * Schema for thought evaluation (Tree-of-Thought).\n */\nexport const ThoughtEvaluationSchema = Schema.Struct({\n score: Schema.Number,\n reasoning: Schema.String,\n strengths: Schema.Array(Schema.String),\n weaknesses: Schema.Array(Schema.String),\n shouldExpand: Schema.Boolean,\n});\n\nexport type ThoughtEvaluation = Schema.Schema.Type<\n typeof ThoughtEvaluationSchema\n>;\n\n/**\n * Schema for task complexity analysis.\n */\nexport const ComplexityAnalysisSchema = Schema.Struct({\n score: Schema.Number,\n factors: Schema.Array(\n Schema.Struct({\n factor: Schema.String,\n weight: Schema.Number,\n reasoning: Schema.String,\n }),\n ),\n recommendedStrategy: Schema.String,\n recommendedModel: Schema.String,\n});\n\nexport type ComplexityAnalysis = Schema.Schema.Type<\n typeof ComplexityAnalysisSchema\n>;\n","import { Layer } from \"effect\";\nimport { LLMConfig, LLMConfigFromEnv } from \"./llm-config.js\";\nimport { AnthropicProviderLive } from \"./providers/anthropic.js\";\nimport { OpenAIProviderLive } from \"./providers/openai.js\";\nimport { LocalProviderLive } from \"./providers/local.js\";\nimport { GeminiProviderLive } from \"./providers/gemini.js\";\nimport { PromptManagerLive } from \"./prompt-manager.js\";\nimport { TestLLMServiceLayer } from \"./testing.js\";\n\n/**\n * Create the LLM provider layer for a specific provider.\n * Uses env vars for configuration by default.\n */\nexport const createLLMProviderLayer = (\n provider: \"anthropic\" | \"openai\" | \"ollama\" | \"gemini\" | \"test\" = \"anthropic\",\n testResponses?: Record<string, string>,\n) => {\n if (provider === \"test\") {\n return Layer.mergeAll(\n TestLLMServiceLayer(testResponses ?? {}),\n PromptManagerLive,\n );\n }\n\n const configLayer = LLMConfigFromEnv;\n\n const providerLayer =\n provider === \"anthropic\"\n ? AnthropicProviderLive\n : provider === \"openai\"\n ? OpenAIProviderLive\n : provider === \"gemini\"\n ? GeminiProviderLive\n : LocalProviderLive;\n\n return Layer.mergeAll(\n providerLayer.pipe(Layer.provide(configLayer)),\n PromptManagerLive,\n );\n};\n\n/**\n * LLM layer with custom config (for programmatic use).\n */\nexport const createLLMProviderLayerWithConfig = (\n config: typeof LLMConfig.Service,\n provider: \"anthropic\" | \"openai\" | \"ollama\" | \"gemini\" = \"anthropic\",\n) => {\n const configLayer = Layer.succeed(LLMConfig, config);\n\n const providerLayer =\n provider === \"anthropic\"\n ? AnthropicProviderLive\n : provider === \"openai\"\n ? OpenAIProviderLive\n : provider === \"gemini\"\n ? GeminiProviderLive\n : LocalProviderLive;\n\n return Layer.mergeAll(\n providerLayer.pipe(Layer.provide(configLayer)),\n PromptManagerLive,\n );\n};\n"],"mappings":"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","names":["Context","Effect","Context","Layer","Effect","Context","Layer","Effect","Effect","Layer","Schema","Layer","Effect","Schema","Effect","Layer","Stream","Schema","toEffectError","Layer","Effect","Stream","Schema","Effect","Layer","Stream","Schema","Layer","Effect","Stream","Schema","Effect","Layer","Stream","Schema","toEffectError","Layer","Effect","Stream","Schema","Effect","Layer","Stream","Schema","Effect","Stream","Schema","Layer","Schema","Layer","Layer"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reactive-agents/llm-provider",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsup --config ../../tsup.config.base.ts",
|
|
9
|
+
"typecheck": "tsc --noEmit",
|
|
10
|
+
"test": "bun test",
|
|
11
|
+
"test:watch": "bun test --watch"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"effect": "^3.10.0",
|
|
15
|
+
"@reactive-agents/core": "0.1.0"
|
|
16
|
+
},
|
|
17
|
+
"optionalDependencies": {
|
|
18
|
+
"@anthropic-ai/sdk": "^0.30.0",
|
|
19
|
+
"openai": "^4.70.0",
|
|
20
|
+
"@google/genai": "^1.0.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@google/genai": "^1.42.0",
|
|
24
|
+
"bun-types": "latest",
|
|
25
|
+
"typescript": "^5.7.0"
|
|
26
|
+
},
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/tylerjrbuell/reactive-agents-ts.git",
|
|
31
|
+
"directory": "packages/llm-provider"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"README.md",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
41
|
+
"exports": {
|
|
42
|
+
".": {
|
|
43
|
+
"types": "./dist/index.d.ts",
|
|
44
|
+
"import": "./dist/index.js",
|
|
45
|
+
"default": "./dist/index.js"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"description": "LLM provider adapters for Reactive Agents — Anthropic, OpenAI, Ollama, and test providers",
|
|
49
|
+
"homepage": "https://tylerjrbuell.github.io/reactive-agents-ts/",
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://github.com/tylerjrbuell/reactive-agents-ts/issues"
|
|
52
|
+
}
|
|
53
|
+
}
|