llmist 1.1.0 → 1.2.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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/model-shortcuts.ts","../src/gadgets/schema-validator.ts","../src/gadgets/registry.ts","../src/core/prompt-config.ts","../src/core/constants.ts","../src/core/messages.ts","../src/logging/logger.ts","../src/gadgets/schema-to-json.ts","../src/gadgets/gadget.ts","../src/gadgets/create-gadget.ts","../src/gadgets/output-viewer.ts","../src/agent/gadget-output-store.ts","../src/agent/conversation-manager.ts","../src/agent/event-handlers.ts","../src/gadgets/exceptions.ts","../src/gadgets/error-formatter.ts","../src/gadgets/executor.ts","../src/gadgets/block-params.ts","../src/gadgets/parser.ts","../src/agent/hook-validators.ts","../src/agent/stream-processor.ts","../src/providers/anthropic-models.ts","../src/providers/base-provider.ts","../src/providers/constants.ts","../src/providers/utils.ts","../src/providers/anthropic.ts","../src/providers/gemini-models.ts","../src/providers/gemini.ts","../src/providers/openai-models.ts","../src/providers/openai.ts","../src/providers/discovery.ts","../src/core/model-registry.ts","../src/core/options.ts","../src/core/quick-methods.ts","../src/agent/agent-internal-key.ts","../src/agent/agent.ts","../src/agent/builder.ts","../src/core/client.ts"],"sourcesContent":["/**\n * Model shortcuts and aliases for more expressive DX.\n *\n * This module provides convenient aliases for common model names,\n * allowing developers to use short, memorable names instead of\n * verbose provider:model-id formats.\n *\n * @example\n * ```typescript\n * // Instead of:\n * model: \"openai:gpt-5-nano\"\n *\n * // You can use:\n * model: \"gpt5-nano\"\n * // or even:\n * model: \"gpt-5-nano\" // Auto-detects provider\n * ```\n */\n\n/**\n * Map of common model aliases to their full provider:model-id format.\n */\nexport const MODEL_ALIASES: Record<string, string> = {\n // OpenAI aliases\n gpt4: \"openai:gpt-4o\",\n gpt4o: \"openai:gpt-4o\",\n gpt5: \"openai:gpt-5\",\n \"gpt5-mini\": \"openai:gpt-5-mini\",\n \"gpt5-nano\": \"openai:gpt-5-nano\",\n\n // Anthropic aliases\n sonnet: \"anthropic:claude-sonnet-4-5\",\n \"claude-sonnet\": \"anthropic:claude-sonnet-4-5\",\n haiku: \"anthropic:claude-haiku-4-5\",\n \"claude-haiku\": \"anthropic:claude-haiku-4-5\",\n opus: \"anthropic:claude-opus-4-5\",\n \"claude-opus\": \"anthropic:claude-opus-4-5\",\n\n // Gemini aliases\n flash: \"gemini:gemini-2.0-flash\",\n \"gemini-flash\": \"gemini:gemini-2.0-flash\",\n \"gemini-pro\": \"gemini:gemini-2.5-pro\",\n pro: \"gemini:gemini-2.5-pro\",\n};\n\n/**\n * Options for resolveModel function.\n */\nexport interface ResolveModelOptions {\n /**\n * If true, throw an error for unknown model names instead of falling back to OpenAI.\n * This helps catch typos like \"gp4\" instead of \"gpt4\".\n * Default: false\n */\n strict?: boolean;\n\n /**\n * If true, suppress warnings for unknown model names.\n * Default: false\n */\n silent?: boolean;\n}\n\n/**\n * Known model name patterns for validation.\n * These patterns help detect typos and unknown models.\n */\nconst KNOWN_MODEL_PATTERNS = [\n /^gpt-?\\d/i, // gpt-4, gpt-3.5, gpt4, etc.\n /^claude-?\\d/i, // claude-3, claude-2, etc.\n /^gemini-?(\\d|pro|flash)/i, // gemini-2.0, gemini-pro, gemini-flash, etc.\n /^o\\d/i, // OpenAI o1, o3, etc.\n];\n\n/**\n * Check if a model name matches known patterns.\n *\n * @param model - Model name to check\n * @returns True if the model matches a known pattern\n */\nfunction isKnownModelPattern(model: string): boolean {\n const normalized = model.toLowerCase();\n\n // Check if it's a known alias\n if (MODEL_ALIASES[normalized]) {\n return true;\n }\n\n // Check against known patterns\n return KNOWN_MODEL_PATTERNS.some((pattern) => pattern.test(model));\n}\n\n/**\n * Resolves a model name to its full provider:model format.\n *\n * Supports:\n * - Direct aliases: 'gpt5', 'sonnet', 'flash'\n * - Auto-detection: 'gpt-5-nano' → 'openai:gpt-5-nano'\n * - Pass-through: 'openai:gpt-5' → 'openai:gpt-5'\n *\n * Warnings:\n * - Logs a warning when an unknown model name falls back to OpenAI\n * - Use { strict: true } to throw an error instead\n * - Use { silent: true } to suppress warnings\n *\n * @param model - Model name or alias\n * @param options - Resolution options\n * @returns Full provider:model-id string\n *\n * @example\n * ```typescript\n * resolveModel('gpt5') // → 'openai:gpt-5'\n * resolveModel('sonnet') // → 'anthropic:claude-sonnet-4-5'\n * resolveModel('gpt-5-nano') // → 'openai:gpt-5-nano'\n * resolveModel('openai:gpt-5') // → 'openai:gpt-5' (passthrough)\n * resolveModel('claude-3-5-sonnet') // → 'anthropic:claude-3-5-sonnet'\n *\n * // Typo detection\n * resolveModel('gp5') // ⚠️ Warning: Unknown model 'gp5', falling back to 'openai:gp5'\n *\n * // Strict mode (throws on typos)\n * resolveModel('gp5', { strict: true }) // ❌ Error: Unknown model 'gp5'\n * ```\n */\nexport function resolveModel(model: string, options: ResolveModelOptions = {}): string {\n // Already has provider prefix - pass through\n if (model.includes(\":\")) {\n return model;\n }\n\n // Check if it's a known alias\n const normalized = model.toLowerCase();\n if (MODEL_ALIASES[normalized]) {\n return MODEL_ALIASES[normalized];\n }\n\n // Smart detection by model name patterns\n const modelLower = model.toLowerCase();\n\n // OpenAI models start with 'gpt'\n if (modelLower.startsWith(\"gpt\")) {\n return `openai:${model}`;\n }\n\n // Anthropic models start with 'claude'\n if (modelLower.startsWith(\"claude\")) {\n return `anthropic:${model}`;\n }\n\n // Gemini models start with 'gemini'\n if (modelLower.startsWith(\"gemini\")) {\n return `gemini:${model}`;\n }\n\n // OpenAI o-series models (o1, o3, etc.)\n if (modelLower.match(/^o\\d/)) {\n return `openai:${model}`;\n }\n\n // Unknown model: validate and warn/error\n if (!isKnownModelPattern(model)) {\n if (options.strict) {\n throw new Error(\n `Unknown model '${model}'. Did you mean one of: gpt4, sonnet, haiku, flash? ` +\n `Use explicit provider prefix like 'openai:${model}' to bypass this check.`,\n );\n }\n\n if (!options.silent) {\n console.warn(\n `⚠️ Unknown model '${model}', falling back to 'openai:${model}'. ` +\n `This might be a typo. Did you mean: gpt4, gpt5, gpt5-nano, sonnet, haiku, flash? ` +\n `Use { strict: true } to error on unknown models, or { silent: true } to suppress this warning.`,\n );\n }\n }\n\n // Default: assume OpenAI for unknown models\n // This provides a reasonable fallback for most cases\n return `openai:${model}`;\n}\n\n/**\n * Check if a model string is already in provider:model format.\n *\n * @param model - Model string to check\n * @returns True if the model has a provider prefix\n *\n * @example\n * ```typescript\n * hasProviderPrefix('openai:gpt-4o') // → true\n * hasProviderPrefix('gpt4') // → false\n * hasProviderPrefix('claude-3-5-sonnet') // → false\n * ```\n */\nexport function hasProviderPrefix(model: string): boolean {\n return model.includes(\":\");\n}\n\n/**\n * Extract the provider from a full model string.\n *\n * @param model - Full model string (provider:model-id)\n * @returns Provider name, or undefined if no prefix\n *\n * @example\n * ```typescript\n * getProvider('openai:gpt-4o') // → 'openai'\n * getProvider('anthropic:claude') // → 'anthropic'\n * getProvider('gpt4') // → undefined\n * ```\n */\nexport function getProvider(model: string): string | undefined {\n const separatorIndex = model.indexOf(\":\");\n if (separatorIndex === -1) {\n return undefined;\n }\n return model.slice(0, separatorIndex);\n}\n\n/**\n * Extract the model ID from a full model string.\n *\n * @param model - Full model string (provider:model-id)\n * @returns Model ID, or the original string if no prefix\n *\n * @example\n * ```typescript\n * getModelId('openai:gpt-4o') // → 'gpt-4o'\n * getModelId('anthropic:claude') // → 'claude'\n * getModelId('gpt4') // → 'gpt4'\n * ```\n */\nexport function getModelId(model: string): string {\n const separatorIndex = model.indexOf(\":\");\n if (separatorIndex === -1) {\n return model;\n }\n return model.slice(separatorIndex + 1);\n}\n","import type { ZodTypeAny } from \"zod\";\nimport * as z from \"zod\";\n\n/**\n * Validates that a Zod schema doesn't contain z.unknown() which produces\n * incomplete JSON schemas without type information.\n *\n * @param schema - The Zod schema to validate\n * @param gadgetName - Name of the gadget (for error messages)\n * @throws Error if z.unknown() is detected with helpful suggestions\n */\nexport function validateGadgetSchema(schema: ZodTypeAny, gadgetName: string): void {\n let jsonSchema;\n try {\n jsonSchema = z.toJSONSchema(schema, { target: \"draft-7\" });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(\n `Gadget \"${gadgetName}\" has a schema that cannot be serialized to JSON Schema.\\n` +\n `This usually happens with unsupported patterns like:\\n` +\n `- z.record() - use z.object({}).passthrough() instead\\n` +\n `- Complex transforms or custom refinements\\n` +\n `- Circular references\\n` +\n `\\n` +\n `Original error: ${errorMessage}\\n` +\n `\\n` +\n `Only use schema patterns that Zod v4's native toJSONSchema() supports.`,\n );\n }\n const issues = findUnknownTypes(jsonSchema);\n\n if (issues.length > 0) {\n const fieldList = issues.join(\", \");\n throw new Error(\n `Gadget \"${gadgetName}\" uses z.unknown() which produces incomplete schemas.\\n` +\n `Problematic fields: ${fieldList}\\n` +\n `\\n` +\n `z.unknown() doesn't generate type information in JSON Schema, making it unclear\\n` +\n `to the LLM what data structure to provide.\\n` +\n `\\n` +\n `Suggestions:\\n` +\n `- Use z.object({}).passthrough() for flexible objects\\n` +\n `- Use z.record(z.string()) for key-value objects with string values\\n` +\n `- Define specific structure if possible\\n` +\n `\\n` +\n `Example fixes:\\n` +\n ` // ❌ Bad\\n` +\n ` content: z.unknown()\\n` +\n `\\n` +\n ` // ✅ Good\\n` +\n ` content: z.object({}).passthrough() // for flexible objects\\n` +\n ` content: z.record(z.string()) // for key-value objects\\n` +\n ` content: z.array(z.string()) // for arrays of strings\\n`,\n );\n }\n}\n\n/**\n * Recursively searches a JSON Schema for properties without type information,\n * which indicates z.unknown() usage.\n *\n * @param schema - JSON Schema object to search\n * @param path - Current path in schema (for error reporting)\n * @returns Array of problematic field paths\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction findUnknownTypes(schema: any, path: string[] = []): string[] {\n const issues: string[] = [];\n\n if (!schema || typeof schema !== \"object\") {\n return issues;\n }\n\n // Check if we're in a definitions block\n if (schema.definitions) {\n for (const defSchema of Object.values(schema.definitions)) {\n issues.push(...findUnknownTypes(defSchema, []));\n }\n }\n\n // Check properties of objects\n if (schema.properties) {\n for (const [propName, propSchema] of Object.entries(schema.properties)) {\n const propPath = [...path, propName];\n\n // Check if this property has no type information\n if (hasNoType(propSchema)) {\n issues.push(propPath.join(\".\") || propName);\n }\n\n // Recursively check nested properties\n issues.push(...findUnknownTypes(propSchema, propPath));\n }\n }\n\n // Check array items\n if (schema.items) {\n const itemPath = [...path, \"[]\"];\n if (hasNoType(schema.items)) {\n issues.push(itemPath.join(\".\"));\n }\n issues.push(...findUnknownTypes(schema.items, itemPath));\n }\n\n // Check anyOf/oneOf/allOf unions\n if (schema.anyOf) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema.anyOf.forEach((subSchema: any, index: number) => {\n issues.push(...findUnknownTypes(subSchema, [...path, `anyOf[${index}]`]));\n });\n }\n\n if (schema.oneOf) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema.oneOf.forEach((subSchema: any, index: number) => {\n issues.push(...findUnknownTypes(subSchema, [...path, `oneOf[${index}]`]));\n });\n }\n\n if (schema.allOf) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema.allOf.forEach((subSchema: any, index: number) => {\n issues.push(...findUnknownTypes(subSchema, [...path, `allOf[${index}]`]));\n });\n }\n\n return issues;\n}\n\n/**\n * Checks if a schema property has no type information.\n * This indicates z.unknown() usage.\n *\n * A property has \"no type\" if it:\n * - Is an object\n * - Has no \"type\" field\n * - Has no \"$ref\" (reference to definition)\n * - Has no \"anyOf\", \"oneOf\", or \"allOf\" (union types)\n * - Has only \"description\" or is empty\n *\n * @param prop - Property schema to check\n * @returns true if property has no type information\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction hasNoType(prop: any): boolean {\n if (!prop || typeof prop !== \"object\") {\n return false;\n }\n\n const hasType = prop.type !== undefined;\n const hasRef = prop.$ref !== undefined;\n const hasUnion = prop.anyOf !== undefined || prop.oneOf !== undefined || prop.allOf !== undefined;\n\n // If it has any type information, it's fine\n if (hasType || hasRef || hasUnion) {\n return false;\n }\n\n // Check if it only has description and/or other non-type metadata\n const keys = Object.keys(prop);\n const metadataKeys = [\"description\", \"title\", \"default\", \"examples\"];\n const hasOnlyMetadata = keys.every((key) => metadataKeys.includes(key));\n\n // If it only has metadata or is empty (besides metadata), it's missing type info\n return hasOnlyMetadata || keys.length === 0;\n}\n","import type { BaseGadget } from \"./gadget.js\";\nimport { validateGadgetSchema } from \"./schema-validator.js\";\n\n// Type for gadget constructor\nexport type GadgetClass = new (...args: unknown[]) => BaseGadget;\n\n// Type for gadget or gadget class\nexport type GadgetOrClass = BaseGadget | GadgetClass;\n\nexport class GadgetRegistry {\n private readonly gadgets = new Map<string, BaseGadget>();\n\n /**\n * Creates a registry from an array of gadget classes or instances,\n * or an object mapping names to gadgets.\n *\n * @param gadgets - Array of gadgets/classes or object with custom names\n * @returns New GadgetRegistry with all gadgets registered\n *\n * @example\n * ```typescript\n * // From array of classes\n * const registry = GadgetRegistry.from([Calculator, Weather]);\n *\n * // From array of instances\n * const registry = GadgetRegistry.from([new Calculator(), new Weather()]);\n *\n * // From object with custom names\n * const registry = GadgetRegistry.from({\n * calc: Calculator,\n * weather: new Weather({ apiKey: \"...\" })\n * });\n * ```\n */\n static from(gadgets: GadgetOrClass[] | Record<string, GadgetOrClass>): GadgetRegistry {\n const registry = new GadgetRegistry();\n\n if (Array.isArray(gadgets)) {\n // Array of gadgets or classes\n registry.registerMany(gadgets);\n } else {\n // Object with custom names\n for (const [name, gadget] of Object.entries(gadgets)) {\n const instance = typeof gadget === \"function\" ? new gadget() : gadget;\n registry.register(name, instance);\n }\n }\n\n return registry;\n }\n\n /**\n * Registers multiple gadgets at once from an array.\n *\n * @param gadgets - Array of gadget instances or classes\n * @returns This registry for chaining\n *\n * @example\n * ```typescript\n * registry.registerMany([Calculator, Weather, Email]);\n * registry.registerMany([new Calculator(), new Weather()]);\n * ```\n */\n registerMany(gadgets: GadgetOrClass[]): this {\n for (const gadget of gadgets) {\n const instance = typeof gadget === \"function\" ? new gadget() : gadget;\n this.registerByClass(instance);\n }\n return this;\n }\n\n // Register a gadget by name\n register(name: string, gadget: BaseGadget): void {\n const normalizedName = name.toLowerCase();\n if (this.gadgets.has(normalizedName)) {\n throw new Error(`Gadget '${name}' is already registered`);\n }\n\n // Validate schema if present\n if (gadget.parameterSchema) {\n validateGadgetSchema(gadget.parameterSchema, name);\n }\n\n this.gadgets.set(normalizedName, gadget);\n }\n\n // Register a gadget using its name property or class name\n registerByClass(gadget: BaseGadget): void {\n const name = gadget.name ?? gadget.constructor.name;\n this.register(name, gadget);\n }\n\n // Get gadget by name (case-insensitive)\n get(name: string): BaseGadget | undefined {\n return this.gadgets.get(name.toLowerCase());\n }\n\n // Check if gadget exists (case-insensitive)\n has(name: string): boolean {\n return this.gadgets.has(name.toLowerCase());\n }\n\n // Get all registered gadget names\n getNames(): string[] {\n return Array.from(this.gadgets.keys());\n }\n\n // Get all gadgets for instruction generation\n getAll(): BaseGadget[] {\n return Array.from(this.gadgets.values());\n }\n\n // Unregister gadget (useful for testing, case-insensitive)\n unregister(name: string): boolean {\n return this.gadgets.delete(name.toLowerCase());\n }\n\n // Clear all gadgets (useful for testing)\n clear(): void {\n this.gadgets.clear();\n }\n}\n","/**\n * Context provided to prompt template functions for rendering dynamic content.\n */\nexport interface PromptContext {\n /** Custom gadget start prefix */\n startPrefix: string;\n /** Custom gadget end prefix */\n endPrefix: string;\n /** Custom argument prefix for block format */\n argPrefix: string;\n /** Number of gadgets being registered */\n gadgetCount: number;\n /** Names of all gadgets */\n gadgetNames: string[];\n}\n\n/**\n * Template that can be either a static string or a function that renders based on context.\n */\nexport type PromptTemplate = string | ((context: PromptContext) => string);\n\n/**\n * Configuration for customizing all prompts used internally by llmist.\n *\n * Each field can be either a string (static text) or a function that receives\n * context and returns a string (for dynamic content).\n *\n * @example\n * ```typescript\n * const customConfig: PromptConfig = {\n * mainInstruction: \"USE ONLY THE GADGET MARKERS BELOW:\",\n * criticalUsage: \"Important: Follow the exact format shown.\",\n * rules: (ctx) => [\n * \"Always use the markers to invoke gadgets\",\n * \"Never use function calling\",\n * `You have ${ctx.gadgetCount} gadgets available`\n * ]\n * };\n * ```\n */\nexport interface PromptConfig {\n /**\n * Main instruction block that appears at the start of the gadget system prompt.\n * Default emphasizes using text markers instead of function calling.\n */\n mainInstruction?: PromptTemplate;\n\n /**\n * Critical usage instruction that appears in the usage section.\n * Default emphasizes the exact format requirement.\n */\n criticalUsage?: PromptTemplate;\n\n /**\n * Format description for the block parameter format.\n * Default uses the configured argPrefix dynamically.\n */\n formatDescription?: PromptTemplate;\n\n /**\n * Rules that appear in the rules section.\n * Can be an array of strings or a function that returns an array.\n * Default includes rules about not using function calling.\n */\n rules?: PromptTemplate | string[] | ((context: PromptContext) => string[]);\n\n /**\n * Custom examples to show in the examples section.\n * If provided, replaces the default examples entirely.\n * Should be a function that returns formatted example strings.\n */\n customExamples?: (context: PromptContext) => string;\n}\n\n/**\n * Default prompt templates used by llmist.\n */\nexport const DEFAULT_PROMPTS: Required<\n Omit<PromptConfig, \"rules\" | \"customExamples\"> & {\n rules: (context: PromptContext) => string[];\n customExamples: null;\n }\n> = {\n mainInstruction: [\n \"⚠️ CRITICAL: RESPOND ONLY WITH GADGET INVOCATIONS\",\n \"DO NOT use function calling or tool calling\",\n \"You must output the exact text markers shown below in plain text.\",\n \"EACH MARKER MUST START WITH A NEWLINE.\",\n ].join(\"\\n\"),\n\n criticalUsage: \"INVOKE gadgets using the markers - do not describe what you want to do.\",\n\n formatDescription: (ctx) =>\n `Parameters using ${ctx.argPrefix}name markers (value on next line(s), no escaping needed)`,\n\n rules: () => [\n \"Output ONLY plain text with the exact markers - never use function/tool calling\",\n \"You can invoke multiple gadgets in a single response\",\n \"For dependent gadgets, invoke the first one and wait for the result\",\n ],\n\n customExamples: null,\n};\n\n/**\n * Resolve a prompt template to a string using the given context.\n */\nexport function resolvePromptTemplate(\n template: PromptTemplate | undefined,\n defaultValue: PromptTemplate,\n context: PromptContext,\n): string {\n const resolved = template ?? defaultValue;\n return typeof resolved === \"function\" ? resolved(context) : resolved;\n}\n\n/**\n * Resolve rules template to an array of strings.\n */\nexport function resolveRulesTemplate(\n rules: PromptConfig[\"rules\"] | undefined,\n context: PromptContext,\n): string[] {\n const resolved = rules ?? DEFAULT_PROMPTS.rules;\n\n if (Array.isArray(resolved)) {\n return resolved;\n }\n\n if (typeof resolved === \"function\") {\n const result = resolved(context);\n return Array.isArray(result) ? result : [result];\n }\n\n return [resolved];\n}\n","// Gadget marker constants\nexport const GADGET_START_PREFIX = \"!!!GADGET_START:\";\nexport const GADGET_END_PREFIX = \"!!!GADGET_END\";\nexport const GADGET_ARG_PREFIX = \"!!!ARG:\";\n\n// Default configuration values\nexport const DEFAULT_MAX_TOKENS = 1024;\nexport const DEFAULT_MAX_ITERATIONS = 10;\n\n// Gadget output limiting defaults\n/** Default: gadget output limiting is enabled */\nexport const DEFAULT_GADGET_OUTPUT_LIMIT = true;\n\n/** Default: limit gadget output to 15% of context window */\nexport const DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT = 15;\n\n/** Approximate characters per token for limit calculation */\nexport const CHARS_PER_TOKEN = 4;\n\n/** Fallback context window size if model is not in registry */\nexport const FALLBACK_CONTEXT_WINDOW = 128_000;\n","import type { BaseGadget } from \"../gadgets/gadget.js\";\nimport { GADGET_ARG_PREFIX, GADGET_END_PREFIX, GADGET_START_PREFIX } from \"./constants.js\";\nimport type { PromptConfig } from \"./prompt-config.js\";\nimport { DEFAULT_PROMPTS, resolvePromptTemplate, resolveRulesTemplate } from \"./prompt-config.js\";\n\nexport type LLMRole = \"system\" | \"user\" | \"assistant\";\n\nexport interface LLMMessage {\n role: LLMRole;\n content: string;\n name?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport class LLMMessageBuilder {\n private readonly messages: LLMMessage[] = [];\n private startPrefix: string = GADGET_START_PREFIX;\n private endPrefix: string = GADGET_END_PREFIX;\n private argPrefix: string = GADGET_ARG_PREFIX;\n private promptConfig: PromptConfig;\n\n constructor(promptConfig?: PromptConfig) {\n this.promptConfig = promptConfig ?? {};\n }\n\n /**\n * Set custom prefixes for gadget markers.\n * Used to configure history builder to match system prompt markers.\n */\n withPrefixes(startPrefix: string, endPrefix: string, argPrefix?: string): this {\n this.startPrefix = startPrefix;\n this.endPrefix = endPrefix;\n if (argPrefix) {\n this.argPrefix = argPrefix;\n }\n return this;\n }\n\n addSystem(content: string, metadata?: Record<string, unknown>): this {\n this.messages.push({ role: \"system\", content, metadata });\n return this;\n }\n\n addGadgets(\n gadgets: BaseGadget[],\n options?: { startPrefix?: string; endPrefix?: string; argPrefix?: string },\n ): this {\n // Store custom prefixes for later use in addGadgetCall\n if (options?.startPrefix) {\n this.startPrefix = options.startPrefix;\n }\n if (options?.endPrefix) {\n this.endPrefix = options.endPrefix;\n }\n if (options?.argPrefix) {\n this.argPrefix = options.argPrefix;\n }\n\n const context = {\n startPrefix: this.startPrefix,\n endPrefix: this.endPrefix,\n argPrefix: this.argPrefix,\n gadgetCount: gadgets.length,\n gadgetNames: gadgets.map((g) => g.name ?? g.constructor.name),\n };\n\n const parts: string[] = [];\n\n // Use configurable main instruction\n const mainInstruction = resolvePromptTemplate(\n this.promptConfig.mainInstruction,\n DEFAULT_PROMPTS.mainInstruction,\n context,\n );\n parts.push(mainInstruction);\n\n parts.push(this.buildGadgetsSection(gadgets));\n parts.push(this.buildUsageSection(context));\n\n this.messages.push({ role: \"system\", content: parts.join(\"\") });\n return this;\n }\n\n private buildGadgetsSection(gadgets: BaseGadget[]): string {\n const parts: string[] = [];\n parts.push(\"\\n\\nAVAILABLE GADGETS\");\n parts.push(\"\\n=================\\n\");\n\n for (const gadget of gadgets) {\n const gadgetName = gadget.name ?? gadget.constructor.name;\n const instruction = gadget.getInstruction(this.argPrefix);\n\n // Parse instruction to separate description and schema\n const schemaMarker = \"\\n\\nInput Schema (BLOCK):\";\n const schemaIndex = instruction.indexOf(schemaMarker);\n\n const description = (\n schemaIndex !== -1 ? instruction.substring(0, schemaIndex) : instruction\n ).trim();\n const schema =\n schemaIndex !== -1 ? instruction.substring(schemaIndex + schemaMarker.length).trim() : \"\";\n\n parts.push(`\\nGADGET: ${gadgetName}`);\n parts.push(`\\n${description}`);\n if (schema) {\n parts.push(`\\n\\nPARAMETERS (BLOCK):\\n${schema}`);\n }\n parts.push(\"\\n\\n---\");\n }\n\n return parts.join(\"\");\n }\n\n private buildUsageSection(context: {\n startPrefix: string;\n endPrefix: string;\n argPrefix: string;\n gadgetCount: number;\n gadgetNames: string[];\n }): string {\n const parts: string[] = [];\n\n // Use configurable format description\n const formatDescription = resolvePromptTemplate(\n this.promptConfig.formatDescription,\n DEFAULT_PROMPTS.formatDescription,\n context,\n );\n\n parts.push(\"\\n\\nHOW TO INVOKE GADGETS\");\n parts.push(\"\\n=====================\\n\");\n\n // Use configurable critical usage instruction\n const criticalUsage = resolvePromptTemplate(\n this.promptConfig.criticalUsage,\n DEFAULT_PROMPTS.criticalUsage,\n context,\n );\n parts.push(`\\nCRITICAL: ${criticalUsage}\\n`);\n\n // Format section\n parts.push(\"\\nFORMAT:\");\n parts.push(`\\n 1. Start marker: ${this.startPrefix}gadget_name`);\n parts.push(`\\n 2. ${formatDescription}`);\n parts.push(`\\n 3. End marker: ${this.endPrefix}`);\n\n parts.push(this.buildExamplesSection(context));\n parts.push(this.buildRulesSection(context));\n\n parts.push(\"\\n\");\n\n return parts.join(\"\");\n }\n\n private buildExamplesSection(context: {\n startPrefix: string;\n endPrefix: string;\n argPrefix: string;\n gadgetCount: number;\n gadgetNames: string[];\n }): string {\n // Allow custom examples to completely replace default examples\n if (this.promptConfig.customExamples) {\n return this.promptConfig.customExamples(context);\n }\n\n const parts: string[] = [];\n\n // Single gadget example\n const singleExample = `${this.startPrefix}translate\n${this.argPrefix}from\nEnglish\n${this.argPrefix}to\nPolish\n${this.argPrefix}content\nParis is the capital of France: a beautiful city.\n${this.endPrefix}`;\n\n parts.push(`\\n\\nEXAMPLE (Single Gadget):\\n\\n${singleExample}`);\n\n // Multiple gadget example with multiline content\n const multipleExample = `${this.startPrefix}translate\n${this.argPrefix}from\nEnglish\n${this.argPrefix}to\nPolish\n${this.argPrefix}content\nParis is the capital of France: a beautiful city.\n${this.endPrefix}\n${this.startPrefix}analyze\n${this.argPrefix}type\neconomic_analysis\n${this.argPrefix}matter\nPolish Economy\n${this.argPrefix}question\nAnalyze the following:\n- Polish arms exports 2025\n- Economic implications\n${this.endPrefix}`;\n\n parts.push(`\\n\\nEXAMPLE (Multiple Gadgets):\\n\\n${multipleExample}`);\n\n // Block format syntax guide\n parts.push(`\n\nBLOCK FORMAT SYNTAX:\nBlock format uses ${this.argPrefix}name markers. Values are captured verbatim until the next marker.\n\n${this.argPrefix}filename\ncalculator.ts\n${this.argPrefix}code\nclass Calculator {\n private history: string[] = [];\n\n add(a: number, b: number): number {\n const result = a + b;\n this.history.push(\\`\\${a} + \\${b} = \\${result}\\`);\n return result;\n }\n}\n\nBLOCK FORMAT RULES:\n- Each parameter starts with ${this.argPrefix}parameterName on its own line\n- The value starts on the NEXT line after the marker\n- Value ends when the next ${this.argPrefix} or ${this.endPrefix} appears\n- NO escaping needed - write values exactly as they should appear\n- Perfect for code, JSON, markdown, or any content with special characters\n\nNESTED OBJECTS (use / separator):\n${this.argPrefix}config/timeout\n30\n${this.argPrefix}config/retries\n3\nProduces: { \"config\": { \"timeout\": \"30\", \"retries\": \"3\" } }\n\nARRAYS (use numeric indices):\n${this.argPrefix}items/0\nfirst\n${this.argPrefix}items/1\nsecond\nProduces: { \"items\": [\"first\", \"second\"] }`);\n\n return parts.join(\"\");\n }\n\n private buildRulesSection(context: {\n startPrefix: string;\n endPrefix: string;\n argPrefix: string;\n gadgetCount: number;\n gadgetNames: string[];\n }): string {\n const parts: string[] = [];\n parts.push(\"\\n\\nRULES:\");\n\n // Use configurable rules\n const rules = resolveRulesTemplate(this.promptConfig.rules, context);\n\n for (const rule of rules) {\n parts.push(`\\n - ${rule}`);\n }\n\n return parts.join(\"\");\n }\n\n addUser(content: string, metadata?: Record<string, unknown>): this {\n this.messages.push({ role: \"user\", content, metadata });\n return this;\n }\n\n addAssistant(content: string, metadata?: Record<string, unknown>): this {\n this.messages.push({ role: \"assistant\", content, metadata });\n return this;\n }\n\n addGadgetCall(gadget: string, parameters: Record<string, unknown>, result: string) {\n const paramStr = this.formatBlockParameters(parameters, \"\");\n\n // Assistant message with simplified gadget markers (no invocation ID)\n this.messages.push({\n role: \"assistant\",\n content: `${this.startPrefix}${gadget}\\n${paramStr}\\n${this.endPrefix}`,\n });\n\n // User message with result\n this.messages.push({\n role: \"user\",\n content: `Result: ${result}`,\n });\n\n return this;\n }\n\n /**\n * Format parameters as Block format with JSON Pointer paths.\n * Uses the configured argPrefix for consistency with system prompt.\n */\n private formatBlockParameters(\n params: Record<string, unknown>,\n prefix: string,\n ): string {\n const lines: string[] = [];\n\n for (const [key, value] of Object.entries(params)) {\n const fullPath = prefix ? `${prefix}/${key}` : key;\n\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n const itemPath = `${fullPath}/${index}`;\n if (typeof item === \"object\" && item !== null) {\n lines.push(this.formatBlockParameters(item as Record<string, unknown>, itemPath));\n } else {\n lines.push(`${this.argPrefix}${itemPath}`);\n lines.push(String(item));\n }\n });\n } else if (typeof value === \"object\" && value !== null) {\n lines.push(this.formatBlockParameters(value as Record<string, unknown>, fullPath));\n } else {\n lines.push(`${this.argPrefix}${fullPath}`);\n lines.push(String(value));\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n build(): LLMMessage[] {\n return [...this.messages];\n }\n}\n\nexport const isLLMMessage = (value: unknown): value is LLMMessage => {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n const message = value as Partial<LLMMessage>;\n return (\n (message.role === \"system\" || message.role === \"user\" || message.role === \"assistant\") &&\n typeof message.content === \"string\"\n );\n};\n","import { createWriteStream, mkdirSync, type WriteStream } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { type ILogObj, Logger } from \"tslog\";\n\nconst LEVEL_NAME_TO_ID: Record<string, number> = {\n silly: 0,\n trace: 1,\n debug: 2,\n info: 3,\n warn: 4,\n error: 5,\n fatal: 6,\n};\n\nfunction parseLogLevel(value?: string): number | undefined {\n if (!value) {\n return undefined;\n }\n\n const normalized = value.trim().toLowerCase();\n\n if (normalized === \"\") {\n return undefined;\n }\n\n const numericLevel = Number(normalized);\n if (Number.isFinite(numericLevel)) {\n return Math.max(0, Math.min(6, Math.floor(numericLevel)));\n }\n\n return LEVEL_NAME_TO_ID[normalized];\n}\n\n/**\n * Logger configuration options for the library.\n */\nexport interface LoggerOptions {\n /**\n * Log level: 0=silly, 1=trace, 2=debug, 3=info, 4=warn, 5=error, 6=fatal\n * @default 4 (warn)\n */\n minLevel?: number;\n\n /**\n * Output type: 'pretty' for development, 'json' for production\n * @default 'pretty'\n */\n type?: \"pretty\" | \"json\" | \"hidden\";\n\n /**\n * Logger name (appears in logs)\n */\n name?: string;\n\n /**\n * When true, reset (truncate) the log file instead of appending.\n * Useful for getting clean logs per session.\n * @default false\n */\n logReset?: boolean;\n}\n\n/**\n * Parses a boolean environment variable.\n */\nfunction parseEnvBoolean(value?: string): boolean | undefined {\n if (!value) return undefined;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"true\" || normalized === \"1\") return true;\n if (normalized === \"false\" || normalized === \"0\") return false;\n return undefined;\n}\n\n/**\n * Create a new logger instance for the library.\n *\n * @param options - Logger configuration options\n * @returns Configured Logger instance\n *\n * @example\n * ```typescript\n * // Development logger with pretty output\n * const logger = createLogger({ type: 'pretty', minLevel: 2 });\n *\n * // Production logger with JSON output\n * const logger = createLogger({ type: 'json', minLevel: 3 });\n *\n * // Silent logger for tests\n * const logger = createLogger({ type: 'hidden' });\n * ```\n */\nexport function createLogger(options: LoggerOptions = {}): Logger<ILogObj> {\n const envMinLevel = parseLogLevel(process.env.LLMIST_LOG_LEVEL);\n const envLogFile = process.env.LLMIST_LOG_FILE?.trim() ?? \"\";\n const envLogReset = parseEnvBoolean(process.env.LLMIST_LOG_RESET);\n\n const minLevel = options.minLevel ?? envMinLevel ?? 4;\n const defaultType = options.type ?? \"pretty\";\n const name = options.name ?? \"llmist\";\n // Priority: options > env var > default (false = append)\n const logReset = options.logReset ?? envLogReset ?? false;\n\n let logFileStream: WriteStream | undefined;\n let finalType = defaultType;\n\n if (envLogFile) {\n try {\n mkdirSync(dirname(envLogFile), { recursive: true });\n // Use \"w\" (write/truncate) when logReset is true, \"a\" (append) otherwise\n const flags = logReset ? \"w\" : \"a\";\n logFileStream = createWriteStream(envLogFile, { flags });\n finalType = \"hidden\";\n } catch (error) {\n console.error(\"Failed to initialize LLMIST_LOG_FILE output:\", error);\n }\n }\n\n const logger = new Logger<ILogObj>({\n name,\n minLevel,\n type: finalType,\n // Optimize for production\n hideLogPositionForProduction: finalType !== \"pretty\",\n // Pretty output settings\n prettyLogTemplate:\n finalType === \"pretty\"\n ? \"{{yyyy}}-{{mm}}-{{dd}} {{hh}}:{{MM}}:{{ss}}:{{ms}} {{logLevelName}} [{{name}}] \"\n : undefined,\n });\n\n if (logFileStream) {\n logger.attachTransport((logObj) => {\n logFileStream?.write(`${JSON.stringify(logObj)}\\n`);\n });\n }\n\n return logger;\n}\n\n/**\n * Default logger instance for the library.\n * Users can replace this with their own configured logger.\n */\nexport const defaultLogger = createLogger();\n","/**\n * Zod schema to JSON Schema conversion with instance mismatch detection.\n *\n * When consumers use their own `import { z } from \"zod\"` instead of\n * `import { z } from \"llmist\"`, the `.describe()` metadata can be lost\n * because Zod stores metadata on schema instances and `toJSONSchema()`\n * only reads from schemas created by the same Zod module instance.\n *\n * This module provides a `schemaToJSONSchema()` function that:\n * 1. Converts Zod schema to JSON Schema using the standard API\n * 2. Detects if descriptions were lost due to instance mismatch\n * 3. Logs a warning recommending `import { z } from \"llmist\"`\n * 4. Falls back to extracting descriptions from `schema._def`\n *\n * @module gadgets/schema-to-json\n */\n\nimport type { ZodTypeAny } from \"zod\";\nimport * as z from \"zod\";\nimport { defaultLogger } from \"../logging/logger.js\";\n\n/**\n * Convert a Zod schema to JSON Schema with description fallback.\n *\n * If descriptions exist in schema._def but are missing from the generated\n * JSON Schema (indicating a Zod instance mismatch), this function:\n * 1. Logs a warning recommending `import { z } from \"llmist\"`\n * 2. Extracts descriptions from _def and merges them into the JSON Schema\n *\n * @param schema - Zod schema to convert\n * @param options - Conversion options (target JSON Schema version)\n * @returns JSON Schema object with descriptions preserved\n *\n * @example\n * ```typescript\n * import { schemaToJSONSchema } from './schema-to-json.js';\n * import { z } from 'zod';\n *\n * const schema = z.object({\n * name: z.string().describe('User name'),\n * });\n *\n * const jsonSchema = schemaToJSONSchema(schema);\n * // { type: 'object', properties: { name: { type: 'string', description: 'User name' } } }\n * ```\n */\nexport function schemaToJSONSchema(\n schema: ZodTypeAny,\n options?: { target?: \"draft-7\" | \"draft-2020-12\" },\n): Record<string, unknown> {\n const jsonSchema = z.toJSONSchema(schema, options ?? { target: \"draft-7\" });\n\n // Check for instance mismatch by comparing _def descriptions with JSON schema\n const mismatches = detectDescriptionMismatch(schema, jsonSchema);\n\n if (mismatches.length > 0) {\n defaultLogger.warn(\n `Zod instance mismatch detected: ${mismatches.length} description(s) lost. ` +\n `For best results, use: import { z } from \"llmist\"`,\n );\n\n // Merge descriptions from _def into JSON schema\n return mergeDescriptions(schema, jsonSchema);\n }\n\n return jsonSchema;\n}\n\n/**\n * Detect if schema._def contains descriptions that are missing from JSON schema.\n * Returns array of paths where descriptions were lost.\n */\nfunction detectDescriptionMismatch(\n schema: ZodTypeAny,\n jsonSchema: Record<string, unknown>,\n): string[] {\n const mismatches: string[] = [];\n\n function checkSchema(zodSchema: ZodTypeAny, json: unknown, path: string): void {\n if (!zodSchema || typeof zodSchema !== \"object\") return;\n\n const def = zodSchema._def as unknown as Record<string, unknown> | undefined;\n const jsonObj = json as Record<string, unknown> | undefined;\n\n // Check if _def has description but JSON schema doesn't\n if (def?.description && !jsonObj?.description) {\n mismatches.push(path || \"root\");\n }\n\n // Recursively check object properties\n if (def?.typeName === \"ZodObject\" && def?.shape) {\n const shape =\n typeof def.shape === \"function\"\n ? (def.shape as () => Record<string, ZodTypeAny>)()\n : def.shape;\n for (const [key, fieldSchema] of Object.entries(shape as Record<string, ZodTypeAny>)) {\n const properties = jsonObj?.properties as Record<string, unknown> | undefined;\n const jsonProp = properties?.[key];\n checkSchema(fieldSchema, jsonProp, path ? `${path}.${key}` : key);\n }\n }\n\n // Check array items\n if (def?.typeName === \"ZodArray\" && def?.type) {\n checkSchema(def.type as ZodTypeAny, jsonObj?.items, path ? `${path}[]` : \"[]\");\n }\n\n // Check optional/nullable wrapped types\n if ((def?.typeName === \"ZodOptional\" || def?.typeName === \"ZodNullable\") && def?.innerType) {\n checkSchema(def.innerType as ZodTypeAny, json, path);\n }\n\n // Check default wrapped types\n if (def?.typeName === \"ZodDefault\" && def?.innerType) {\n checkSchema(def.innerType as ZodTypeAny, json, path);\n }\n }\n\n checkSchema(schema, jsonSchema, \"\");\n return mismatches;\n}\n\n/**\n * Merge descriptions from schema._def into JSON schema.\n * Returns a new JSON schema object with descriptions filled in from _def.\n */\nfunction mergeDescriptions(\n schema: ZodTypeAny,\n jsonSchema: Record<string, unknown>,\n): Record<string, unknown> {\n function merge(zodSchema: ZodTypeAny, json: unknown): unknown {\n if (!json || typeof json !== \"object\") return json;\n\n const def = zodSchema._def as unknown as Record<string, unknown> | undefined;\n const jsonObj = json as Record<string, unknown>;\n const merged: Record<string, unknown> = { ...jsonObj };\n\n // Copy description from _def if missing in JSON\n if (def?.description && !jsonObj.description) {\n merged.description = def.description;\n }\n\n // Recursively merge object properties\n if (def?.typeName === \"ZodObject\" && def?.shape && jsonObj.properties) {\n const shape =\n typeof def.shape === \"function\"\n ? (def.shape as () => Record<string, ZodTypeAny>)()\n : def.shape;\n const properties = jsonObj.properties as Record<string, unknown>;\n merged.properties = { ...properties };\n for (const [key, fieldSchema] of Object.entries(shape as Record<string, ZodTypeAny>)) {\n if (properties[key]) {\n (merged.properties as Record<string, unknown>)[key] = merge(fieldSchema, properties[key]);\n }\n }\n }\n\n // Merge array items\n if (def?.typeName === \"ZodArray\" && def?.type && jsonObj.items) {\n merged.items = merge(def.type as ZodTypeAny, jsonObj.items);\n }\n\n // Handle optional/nullable wrapped types\n if ((def?.typeName === \"ZodOptional\" || def?.typeName === \"ZodNullable\") && def?.innerType) {\n return merge(def.innerType as ZodTypeAny, json);\n }\n\n // Handle default wrapped types\n if (def?.typeName === \"ZodDefault\" && def?.innerType) {\n return merge(def.innerType as ZodTypeAny, json);\n }\n\n return merged;\n }\n\n return merge(schema, jsonSchema) as Record<string, unknown>;\n}\n","import type { ZodTypeAny } from \"zod\";\n\nimport { GADGET_ARG_PREFIX } from \"../core/constants.js\";\nimport { schemaToJSONSchema } from \"./schema-to-json.js\";\nimport { validateGadgetSchema } from \"./schema-validator.js\";\nimport type { GadgetExample } from \"./types.js\";\n\n/**\n * Format parameters object as Block format.\n * Uses JSON Pointer paths for nested structures.\n *\n * @param params - The parameters object to format\n * @param prefix - Path prefix for nested structures (internal use)\n * @param argPrefix - The argument prefix marker (defaults to GADGET_ARG_PREFIX)\n */\nfunction formatParamsAsBlock(\n params: Record<string, unknown>,\n prefix: string = \"\",\n argPrefix: string = GADGET_ARG_PREFIX,\n): string {\n const lines: string[] = [];\n\n for (const [key, value] of Object.entries(params)) {\n const fullPath = prefix ? `${prefix}/${key}` : key;\n\n if (Array.isArray(value)) {\n // Arrays: use numeric indices\n value.forEach((item, index) => {\n const itemPath = `${fullPath}/${index}`;\n if (typeof item === \"object\" && item !== null) {\n // Nested object in array\n lines.push(formatParamsAsBlock(item as Record<string, unknown>, itemPath, argPrefix));\n } else {\n lines.push(`${argPrefix}${itemPath}`);\n lines.push(String(item));\n }\n });\n } else if (typeof value === \"object\" && value !== null) {\n // Nested objects: recurse with path prefix\n lines.push(formatParamsAsBlock(value as Record<string, unknown>, fullPath, argPrefix));\n } else {\n // Simple values\n lines.push(`${argPrefix}${fullPath}`);\n lines.push(String(value));\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format JSON Schema as plain text description.\n * This avoids format confusion by presenting parameters in a neutral,\n * human-readable format that works equally well for JSON, YAML, TOML, or XML.\n */\nfunction formatSchemaAsPlainText(schema: Record<string, unknown>, indent = \"\"): string {\n const lines: string[] = [];\n const properties = (schema.properties || {}) as Record<string, unknown>;\n const required = (schema.required || []) as string[];\n\n for (const [key, prop] of Object.entries(properties)) {\n const propObj = prop as Record<string, unknown>;\n const type = propObj.type as string;\n const description = propObj.description as string | undefined;\n const isRequired = required.includes(key);\n const enumValues = propObj.enum as string[] | undefined;\n\n // Build the line\n let line = `${indent}- ${key}`;\n\n // Add type info\n if (type === \"array\") {\n const items = propObj.items as Record<string, unknown> | undefined;\n const itemType = items?.type || \"any\";\n line += ` (array of ${itemType})`;\n } else if (type === \"object\" && propObj.properties) {\n line += \" (object)\";\n } else {\n line += ` (${type})`;\n }\n\n // Add required marker\n if (isRequired) {\n line += \" [required]\";\n }\n\n // Add description\n if (description) {\n line += `: ${description}`;\n }\n\n // Add enum values if present\n if (enumValues) {\n line += ` - one of: ${enumValues.map((v) => `\"${v}\"`).join(\", \")}`;\n }\n\n lines.push(line);\n\n // Recurse for nested objects\n if (type === \"object\" && propObj.properties) {\n lines.push(formatSchemaAsPlainText(propObj, indent + \" \"));\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Internal base class for gadgets. Most users should use the `Gadget` class\n * (formerly TypedGadget) or `createGadget()` function instead, as they provide\n * better type safety and simpler APIs.\n *\n * @internal\n */\nexport abstract class BaseGadget {\n /**\n * The name of the gadget. Used for identification when LLM calls it.\n * If not provided, defaults to the class name.\n */\n name?: string;\n\n /**\n * Human-readable description of what the gadget does.\n */\n abstract description: string;\n\n /**\n * Optional Zod schema describing the expected input payload. When provided,\n * it will be validated before execution and transformed into a JSON Schema\n * representation that is surfaced to the LLM as part of the instructions.\n */\n parameterSchema?: ZodTypeAny;\n\n /**\n * Optional timeout in milliseconds for gadget execution.\n * If execution exceeds this timeout, a TimeoutException will be thrown.\n * If not set, the global defaultGadgetTimeoutMs from runtime options will be used.\n * Set to 0 or undefined to disable timeout for this gadget.\n */\n timeoutMs?: number;\n\n /**\n * Optional usage examples to help LLMs understand proper invocation.\n * Examples are rendered in getInstruction() alongside the schema.\n *\n * Note: Uses broader `unknown` type to allow typed examples from subclasses\n * while maintaining runtime compatibility.\n */\n examples?: GadgetExample<unknown>[];\n\n /**\n * Execute the gadget with the given parameters.\n * Can be synchronous or asynchronous.\n *\n * @param params - Parameters passed from the LLM\n * @returns Result as a string\n */\n abstract execute(params: Record<string, unknown>): string | Promise<string>;\n\n /**\n * Auto-generated instruction text for the LLM.\n * Combines name, description, and parameter schema into a formatted instruction.\n * @deprecated Use getInstruction() instead\n */\n get instruction(): string {\n return this.getInstruction();\n }\n\n /**\n * Generate instruction text for the LLM.\n * Combines name, description, and parameter schema into a formatted instruction.\n *\n * @param argPrefix - Optional custom argument prefix for block format examples\n * @returns Formatted instruction string\n */\n getInstruction(argPrefix?: string): string {\n const parts: string[] = [];\n\n // Add description\n parts.push(this.description);\n\n if (this.parameterSchema) {\n // Validate that the schema doesn't use z.unknown() and can be serialized\n const gadgetName = this.name ?? this.constructor.name;\n validateGadgetSchema(this.parameterSchema, gadgetName);\n\n const jsonSchema = schemaToJSONSchema(this.parameterSchema, {\n target: \"draft-7\",\n });\n\n // Use plain text schema description\n parts.push(\"\\n\\nParameters:\");\n parts.push(formatSchemaAsPlainText(jsonSchema));\n }\n\n // Render examples if present\n if (this.examples && this.examples.length > 0) {\n parts.push(\"\\n\\nExamples:\");\n\n // Use custom argPrefix if provided, otherwise use default\n const effectiveArgPrefix = argPrefix ?? GADGET_ARG_PREFIX;\n\n this.examples.forEach((example, index) => {\n // Add blank line between examples (but not before the first one)\n if (index > 0) {\n parts.push(\"\");\n }\n\n // Add comment if provided\n if (example.comment) {\n parts.push(`# ${example.comment}`);\n }\n\n // Render params in block format\n parts.push(\"Input:\");\n parts.push(formatParamsAsBlock(example.params as Record<string, unknown>, \"\", effectiveArgPrefix));\n\n // Render output if provided\n if (example.output !== undefined) {\n parts.push(\"Output:\");\n parts.push(example.output);\n }\n });\n }\n\n return parts.join(\"\\n\");\n }\n}\n","/**\n * Function-based gadget creation helper.\n *\n * For simple gadgets, use createGadget() instead of defining a class.\n * Parameters are automatically typed from the Zod schema.\n *\n * @example\n * ```typescript\n * const calculator = createGadget({\n * description: \"Performs arithmetic operations\",\n * schema: z.object({\n * operation: z.enum([\"add\", \"subtract\"]),\n * a: z.number(),\n * b: z.number(),\n * }),\n * execute: ({ operation, a, b }) => {\n * // Automatically typed!\n * return operation === \"add\" ? String(a + b) : String(a - b);\n * },\n * });\n * ```\n */\n\nimport type { ZodType } from \"zod\";\nimport { BaseGadget } from \"./gadget.js\";\nimport type { GadgetExample } from \"./types.js\";\n\n/**\n * Infer the TypeScript type from a Zod schema.\n */\ntype InferSchema<T> = T extends ZodType<infer U> ? U : never;\n\n/**\n * Configuration for creating a function-based gadget.\n */\nexport interface CreateGadgetConfig<TSchema extends ZodType> {\n /** Optional custom name (defaults to \"FunctionGadget\") */\n name?: string;\n\n /** Human-readable description of what the gadget does */\n description: string;\n\n /** Zod schema for parameter validation */\n schema: TSchema;\n\n /** Execution function with typed parameters */\n execute: (params: InferSchema<TSchema>) => string | Promise<string>;\n\n /** Optional timeout in milliseconds */\n timeoutMs?: number;\n\n /** Optional usage examples to help LLMs understand proper invocation */\n examples?: GadgetExample<InferSchema<TSchema>>[];\n}\n\n/**\n * Creates a gadget from a function (simpler than class-based approach).\n *\n * This is perfect for simple gadgets where you don't need the full\n * power of a class. Parameters are automatically typed from the schema.\n *\n * @param config - Configuration with execute function and schema\n * @returns Gadget instance ready to be registered\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n * import { createGadget } from 'llmist';\n *\n * // Simple calculator gadget\n * const calculator = createGadget({\n * description: \"Performs arithmetic operations\",\n * schema: z.object({\n * operation: z.enum([\"add\", \"subtract\", \"multiply\", \"divide\"]),\n * a: z.number().describe(\"First number\"),\n * b: z.number().describe(\"Second number\"),\n * }),\n * execute: ({ operation, a, b }) => {\n * // Parameters are automatically typed!\n * switch (operation) {\n * case \"add\": return String(a + b);\n * case \"subtract\": return String(a - b);\n * case \"multiply\": return String(a * b);\n * case \"divide\": return String(a / b);\n * }\n * },\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Async gadget with custom name and timeout\n * const weather = createGadget({\n * name: \"weather\",\n * description: \"Fetches current weather for a city\",\n * schema: z.object({\n * city: z.string().min(1).describe(\"City name\"),\n * }),\n * timeoutMs: 10000,\n * execute: async ({ city }) => {\n * const response = await fetch(`https://api.weather.com/${city}`);\n * const data = await response.json();\n * return `Weather in ${city}: ${data.description}, ${data.temp}°C`;\n * },\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Use with agent\n * const agent = LLMist.createAgent()\n * .withGadgets(calculator, weather)\n * .ask(\"What's the weather in Paris and what's 10 + 5?\");\n * ```\n */\nexport function createGadget<TSchema extends ZodType>(\n config: CreateGadgetConfig<TSchema>,\n): BaseGadget {\n class DynamicGadget extends BaseGadget {\n name = config.name;\n description = config.description;\n parameterSchema = config.schema;\n timeoutMs = config.timeoutMs;\n examples = config.examples;\n\n execute(params: Record<string, unknown>): string | Promise<string> {\n // Cast to inferred type and call user's function\n return config.execute(params as InferSchema<TSchema>);\n }\n }\n\n return new DynamicGadget();\n}\n","/**\n * GadgetOutputViewer - Browse stored outputs from gadgets that exceeded the size limit.\n *\n * When a gadget returns too much data, the output is stored and can be browsed\n * using this gadget with grep-like pattern filtering and line limiting.\n */\n\nimport { z } from \"zod\";\nimport type { GadgetOutputStore } from \"../agent/gadget-output-store.js\";\nimport { createGadget } from \"./create-gadget.js\";\n\n/**\n * Pattern filter configuration.\n */\ninterface PatternFilter {\n /** Regular expression to match */\n regex: string;\n /** true = keep matches, false = exclude matches */\n include: boolean;\n /** Context lines before match (like grep -B) */\n before: number;\n /** Context lines after match (like grep -A) */\n after: number;\n}\n\n/**\n * Apply a single pattern filter to lines.\n *\n * For include=true: keeps lines that match (with before/after context).\n * For include=false: removes lines that match.\n */\nfunction applyPattern(lines: string[], pattern: PatternFilter): string[] {\n const regex = new RegExp(pattern.regex);\n\n if (!pattern.include) {\n // Exclude mode: remove matching lines\n return lines.filter((line) => !regex.test(line));\n }\n\n // Include mode: keep matching lines with context\n const matchIndices = new Set<number>();\n\n // Find all matching line indices\n for (let i = 0; i < lines.length; i++) {\n if (regex.test(lines[i])) {\n // Add the matching line and its context\n const start = Math.max(0, i - pattern.before);\n const end = Math.min(lines.length - 1, i + pattern.after);\n for (let j = start; j <= end; j++) {\n matchIndices.add(j);\n }\n }\n }\n\n // Return lines at matching indices (preserving order)\n return lines.filter((_, index) => matchIndices.has(index));\n}\n\n/**\n * Apply multiple pattern filters in sequence (like piping through grep commands).\n */\nfunction applyPatterns(lines: string[], patterns: PatternFilter[]): string[] {\n let result = lines;\n for (const pattern of patterns) {\n result = applyPattern(result, pattern);\n }\n return result;\n}\n\n/**\n * Parse and apply a line limit string.\n *\n * Formats:\n * - \"100-\" → first 100 lines (slice 0 to 100)\n * - \"-25\" → last 25 lines (slice -25)\n * - \"50-100\" → lines 50-100 (1-indexed, so slice 49 to 100)\n */\nfunction applyLineLimit(lines: string[], limit: string): string[] {\n const trimmed = limit.trim();\n\n // Format: \"100-\" (first N lines)\n if (trimmed.endsWith(\"-\") && !trimmed.startsWith(\"-\")) {\n const n = parseInt(trimmed.slice(0, -1), 10);\n if (!isNaN(n) && n > 0) {\n return lines.slice(0, n);\n }\n }\n\n // Format: \"-25\" (last N lines)\n if (trimmed.startsWith(\"-\") && !trimmed.includes(\"-\", 1)) {\n const n = parseInt(trimmed, 10);\n if (!isNaN(n) && n < 0) {\n return lines.slice(n);\n }\n }\n\n // Format: \"50-100\" (range, 1-indexed)\n const rangeMatch = trimmed.match(/^(\\d+)-(\\d+)$/);\n if (rangeMatch) {\n const start = parseInt(rangeMatch[1], 10);\n const end = parseInt(rangeMatch[2], 10);\n if (!isNaN(start) && !isNaN(end) && start > 0 && end >= start) {\n // Convert from 1-indexed to 0-indexed\n return lines.slice(start - 1, end);\n }\n }\n\n // Invalid format - return unchanged\n return lines;\n}\n\n/**\n * Schema for pattern filter objects.\n */\nconst patternSchema = z.object({\n regex: z.string().describe(\"Regular expression to match\"),\n include: z\n .boolean()\n .default(true)\n .describe(\"true = keep matching lines, false = exclude matching lines\"),\n before: z\n .number()\n .int()\n .min(0)\n .default(0)\n .describe(\"Context lines before each match (like grep -B)\"),\n after: z\n .number()\n .int()\n .min(0)\n .default(0)\n .describe(\"Context lines after each match (like grep -A)\"),\n});\n\n/**\n * Create a GadgetOutputViewer gadget instance bound to a specific output store.\n *\n * This is a factory function because the gadget needs access to the output store,\n * which is created per-agent-run.\n *\n * @param store - The GadgetOutputStore to read outputs from\n * @returns A GadgetOutputViewer gadget instance\n *\n * @example\n * ```typescript\n * const store = new GadgetOutputStore();\n * const viewer = createGadgetOutputViewer(store);\n * registry.register(\"GadgetOutputViewer\", viewer);\n * ```\n */\nexport function createGadgetOutputViewer(store: GadgetOutputStore) {\n return createGadget({\n name: \"GadgetOutputViewer\",\n description:\n \"View stored output from gadgets that returned too much data. \" +\n \"Use patterns to filter lines (like grep) and limit to control output size. \" +\n \"Patterns are applied first in order, then the limit is applied to the result.\",\n schema: z.object({\n id: z.string().describe(\"ID of the stored output (from the truncation message)\"),\n patterns: z\n .array(patternSchema)\n .optional()\n .describe(\n \"Filter patterns applied in order (like piping through grep). \" +\n \"Each pattern can include or exclude lines with optional before/after context.\",\n ),\n limit: z\n .string()\n .optional()\n .describe(\n \"Line range to return after filtering. \" +\n \"Formats: '100-' (first 100), '-25' (last 25), '50-100' (lines 50-100)\",\n ),\n }),\n examples: [\n {\n comment: \"View first 50 lines of stored output\",\n params: { id: \"Search_abc12345\", limit: \"50-\" },\n },\n {\n comment: \"Filter for error lines with context\",\n params: {\n id: \"Search_abc12345\",\n patterns: [{ regex: \"error|Error|ERROR\", include: true, before: 2, after: 5 }],\n },\n },\n {\n comment: \"Exclude blank lines, then show first 100\",\n params: {\n id: \"Search_abc12345\",\n patterns: [{ regex: \"^\\\\s*$\", include: false, before: 0, after: 0 }],\n limit: \"100-\",\n },\n },\n {\n comment: \"Chain filters: find TODOs, exclude tests, limit to 50 lines\",\n params: {\n id: \"Search_abc12345\",\n patterns: [\n { regex: \"TODO\", include: true, before: 1, after: 1 },\n { regex: \"test|spec\", include: false, before: 0, after: 0 },\n ],\n limit: \"50-\",\n },\n },\n ],\n execute: ({ id, patterns, limit }) => {\n const stored = store.get(id);\n if (!stored) {\n return `Error: No stored output with id \"${id}\". Available IDs: ${store.getIds().join(\", \") || \"(none)\"}`;\n }\n\n let lines = stored.content.split(\"\\n\");\n\n // Step 1: Apply patterns in order (like piping through grep)\n if (patterns && patterns.length > 0) {\n lines = applyPatterns(\n lines,\n patterns.map((p) => ({\n regex: p.regex,\n include: p.include ?? true,\n before: p.before ?? 0,\n after: p.after ?? 0,\n })),\n );\n }\n\n // Step 2: Apply line limit AFTER all patterns\n if (limit) {\n lines = applyLineLimit(lines, limit);\n }\n\n // Return result with metadata\n const totalLines = stored.lineCount;\n const returnedLines = lines.length;\n\n if (returnedLines === 0) {\n return `No lines matched the filters. Original output had ${totalLines} lines.`;\n }\n\n const header =\n returnedLines < totalLines\n ? `[Showing ${returnedLines} of ${totalLines} lines]\\n`\n : `[Showing all ${totalLines} lines]\\n`;\n\n return header + lines.join(\"\\n\");\n },\n });\n}\n\n// Export helpers for testing\nexport { applyPattern, applyPatterns, applyLineLimit };\n","/**\n * Storage for large gadget outputs that exceed the configured limit.\n *\n * When a gadget returns more data than the configured limit, the output\n * is stored here and can be browsed later using GadgetOutputViewer.\n */\n\nimport { randomBytes } from \"node:crypto\";\n\n/**\n * Metadata and content for a stored gadget output.\n */\nexport interface StoredOutput {\n /** Unique identifier (e.g., \"Search_d34db33f\") */\n id: string;\n /** Name of the gadget that produced this output */\n gadgetName: string;\n /** Full output content */\n content: string;\n /** Size in bytes */\n byteSize: number;\n /** Number of lines */\n lineCount: number;\n /** When the output was stored */\n timestamp: Date;\n}\n\n/**\n * In-memory store for large gadget outputs.\n *\n * Outputs are stored with generated IDs in the format `{GadgetName}_{hex8}`.\n * The store is tied to an agent run and cleared when the agent completes.\n *\n * @example\n * ```typescript\n * const store = new GadgetOutputStore();\n * const id = store.store(\"Search\", largeOutput);\n * // id = \"Search_a1b2c3d4\"\n *\n * const stored = store.get(id);\n * console.log(stored?.lineCount); // 4200\n * ```\n */\nexport class GadgetOutputStore {\n private outputs = new Map<string, StoredOutput>();\n\n /**\n * Store a gadget output and return its ID.\n *\n * @param gadgetName - Name of the gadget that produced the output\n * @param content - Full output content to store\n * @returns Generated ID for retrieving the output later\n */\n store(gadgetName: string, content: string): string {\n const id = this.generateId(gadgetName);\n const encoder = new TextEncoder();\n\n const stored: StoredOutput = {\n id,\n gadgetName,\n content,\n byteSize: encoder.encode(content).length,\n lineCount: content.split(\"\\n\").length,\n timestamp: new Date(),\n };\n\n this.outputs.set(id, stored);\n return id;\n }\n\n /**\n * Retrieve a stored output by ID.\n *\n * @param id - The output ID (e.g., \"Search_d34db33f\")\n * @returns The stored output or undefined if not found\n */\n get(id: string): StoredOutput | undefined {\n return this.outputs.get(id);\n }\n\n /**\n * Check if an output exists.\n *\n * @param id - The output ID to check\n * @returns True if the output exists\n */\n has(id: string): boolean {\n return this.outputs.has(id);\n }\n\n /**\n * Get all stored output IDs.\n *\n * @returns Array of output IDs\n */\n getIds(): string[] {\n return Array.from(this.outputs.keys());\n }\n\n /**\n * Get the number of stored outputs.\n */\n get size(): number {\n return this.outputs.size;\n }\n\n /**\n * Clear all stored outputs.\n * Called when the agent run completes.\n */\n clear(): void {\n this.outputs.clear();\n }\n\n /**\n * Generate a unique ID for a stored output.\n * Format: {GadgetName}_{8 hex chars}\n */\n private generateId(gadgetName: string): string {\n const hex = randomBytes(4).toString(\"hex\");\n return `${gadgetName}_${hex}`;\n }\n}\n","/**\n * ConversationManager handles conversation state and message building.\n * Extracted from AgentLoop to follow Single Responsibility Principle.\n */\n\nimport { type LLMMessage, LLMMessageBuilder } from \"../core/messages.js\";\nimport type { IConversationManager } from \"./interfaces.js\";\n\n/**\n * Options for ConversationManager constructor.\n */\nexport interface ConversationManagerOptions {\n /** Custom gadget start marker prefix */\n startPrefix?: string;\n /** Custom gadget end marker prefix */\n endPrefix?: string;\n /** Custom argument prefix for block format */\n argPrefix?: string;\n}\n\n/**\n * Default implementation of IConversationManager.\n * Manages conversation history by building on top of base messages (system prompt, gadget instructions).\n */\nexport class ConversationManager implements IConversationManager {\n private readonly baseMessages: LLMMessage[];\n private readonly initialMessages: LLMMessage[];\n private readonly historyBuilder: LLMMessageBuilder;\n\n constructor(\n baseMessages: LLMMessage[],\n initialMessages: LLMMessage[],\n options: ConversationManagerOptions = {},\n ) {\n this.baseMessages = baseMessages;\n this.initialMessages = initialMessages;\n this.historyBuilder = new LLMMessageBuilder();\n\n // Apply custom prefixes if provided (must match system prompt markers)\n if (options.startPrefix && options.endPrefix) {\n this.historyBuilder.withPrefixes(options.startPrefix, options.endPrefix, options.argPrefix);\n }\n }\n\n addUserMessage(content: string): void {\n this.historyBuilder.addUser(content);\n }\n\n addAssistantMessage(content: string): void {\n this.historyBuilder.addAssistant(content);\n }\n\n addGadgetCall(gadgetName: string, parameters: Record<string, unknown>, result: string): void {\n this.historyBuilder.addGadgetCall(gadgetName, parameters, result);\n }\n\n getMessages(): LLMMessage[] {\n return [...this.baseMessages, ...this.initialMessages, ...this.historyBuilder.build()];\n }\n}\n","/**\n * Event handler sugar for cleaner event processing.\n *\n * Instead of verbose if/else chains, use named handlers\n * for each event type.\n *\n * @example\n * ```typescript\n * await agent.runWith({\n * onText: (content) => console.log(\"LLM:\", content),\n * onGadgetResult: (result) => console.log(\"Result:\", result.result),\n * });\n * ```\n */\n\nimport type { StreamEvent } from \"../gadgets/types.js\";\n\n/**\n * Named event handlers for different event types.\n */\nexport interface EventHandlers {\n /** Called when text is generated by the LLM */\n onText?: (content: string) => void | Promise<void>;\n\n /** Called when a gadget is about to be executed */\n onGadgetCall?: (call: {\n gadgetName: string;\n parameters?: Record<string, unknown>;\n parametersRaw: string;\n }) => void | Promise<void>;\n\n /** Called when a gadget execution completes */\n onGadgetResult?: (result: {\n gadgetName: string;\n result?: string;\n error?: string;\n parameters: Record<string, unknown>;\n }) => void | Promise<void>;\n\n /** Called when human input is required */\n onHumanInputRequired?: (data: { question: string; gadgetName: string }) => void | Promise<void>;\n\n /** Called for any other event type */\n onOther?: (event: StreamEvent) => void | Promise<void>;\n}\n\n/**\n * Helper to run an agent with named event handlers.\n *\n * @param agentGenerator - Agent's run() async generator\n * @param handlers - Named event handlers\n *\n * @example\n * ```typescript\n * await runWithHandlers(agent.run(), {\n * onText: (text) => console.log(\"LLM:\", text),\n * onGadgetResult: (result) => console.log(\"Result:\", result.result),\n * });\n * ```\n */\nexport async function runWithHandlers(\n agentGenerator: AsyncGenerator<StreamEvent>,\n handlers: EventHandlers,\n): Promise<void> {\n for await (const event of agentGenerator) {\n switch (event.type) {\n case \"text\":\n if (handlers.onText) {\n await handlers.onText(event.content);\n }\n break;\n\n case \"gadget_call\":\n if (handlers.onGadgetCall) {\n await handlers.onGadgetCall({\n gadgetName: event.call.gadgetName,\n parameters: event.call.parameters,\n parametersRaw: event.call.parametersRaw,\n });\n }\n break;\n\n case \"gadget_result\":\n if (handlers.onGadgetResult) {\n await handlers.onGadgetResult(event.result);\n }\n break;\n\n case \"human_input_required\":\n if (handlers.onHumanInputRequired) {\n await handlers.onHumanInputRequired({\n question: event.question,\n gadgetName: event.gadgetName,\n });\n }\n break;\n\n default:\n if (handlers.onOther) {\n await handlers.onOther(event);\n }\n break;\n }\n }\n}\n\n/**\n * Helper to collect events by type.\n *\n * @param agentGenerator - Agent's run() async generator\n * @param collect - Object specifying which event types to collect\n * @returns Object with collected events\n *\n * @example\n * ```typescript\n * const { text, gadgetResults } = await collectEvents(agent.run(), {\n * text: true,\n * gadgetResults: true,\n * });\n *\n * console.log(\"Full response:\", text.join(\"\"));\n * console.log(\"Gadget calls:\", gadgetResults.length);\n * ```\n */\nexport async function collectEvents(\n agentGenerator: AsyncGenerator<StreamEvent>,\n collect: {\n text?: boolean;\n gadgetCalls?: boolean;\n gadgetResults?: boolean;\n },\n): Promise<{\n text: string[];\n gadgetCalls: Array<{ gadgetName: string; parameters: Record<string, unknown> }>;\n gadgetResults: Array<{\n gadgetName: string;\n result?: string;\n error?: string;\n parameters: Record<string, unknown>;\n }>;\n}> {\n const result = {\n text: [] as string[],\n gadgetCalls: [] as Array<{ gadgetName: string; parameters: Record<string, unknown> }>,\n gadgetResults: [] as Array<{\n gadgetName: string;\n result?: string;\n error?: string;\n parameters: Record<string, unknown>;\n }>,\n };\n\n for await (const event of agentGenerator) {\n switch (event.type) {\n case \"text\":\n if (collect.text) {\n result.text.push(event.content);\n }\n break;\n\n case \"gadget_call\":\n if (collect.gadgetCalls && event.call.parameters) {\n result.gadgetCalls.push({\n gadgetName: event.call.gadgetName,\n parameters: event.call.parameters,\n });\n }\n break;\n\n case \"gadget_result\":\n if (collect.gadgetResults) {\n result.gadgetResults.push(event.result);\n }\n break;\n }\n }\n\n return result;\n}\n\n/**\n * Helper to collect only text from an agent run.\n *\n * @param agentGenerator - Agent's run() async generator\n * @returns Combined text response\n *\n * @example\n * ```typescript\n * const response = await collectText(agent.run());\n * console.log(response);\n * ```\n */\nexport async function collectText(agentGenerator: AsyncGenerator<StreamEvent>): Promise<string> {\n const chunks: string[] = [];\n\n for await (const event of agentGenerator) {\n if (event.type === \"text\") {\n chunks.push(event.content);\n }\n }\n\n return chunks.join(\"\");\n}\n","/**\n * Exception that gadgets can throw to signal the agent loop should terminate.\n *\n * When a gadget throws this exception, the agent loop will:\n * 1. Complete the current iteration\n * 2. Return the exception message as the gadget's result\n * 3. Exit the loop instead of continuing to the next iteration\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * class FinishGadget extends Gadget({\n * name: 'Finish',\n * description: 'Signals task completion',\n * schema: z.object({\n * message: z.string().optional(),\n * }),\n * }) {\n * execute(params: this['params']): string {\n * const message = params.message || 'Task completed';\n * throw new BreakLoopException(message);\n * }\n * }\n * ```\n */\nexport class BreakLoopException extends Error {\n constructor(message?: string) {\n super(message ?? \"Agent loop terminated by gadget\");\n this.name = \"BreakLoopException\";\n }\n}\n\n/**\n * Exception that gadgets can throw to request human input during execution.\n *\n * When a gadget throws this exception, the agent loop will:\n * 1. Pause execution and wait for human input\n * 2. If `onHumanInputRequired` callback is provided, call it and await the answer\n * 3. Return the user's answer as the gadget's result\n * 4. Continue the loop with the answer added to conversation history\n *\n * If no callback is provided, the loop will yield a `human_input_required` event\n * and the caller must handle it externally.\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * class AskUserGadget extends Gadget({\n * name: 'AskUser',\n * description: 'Ask the user a question and get their answer',\n * schema: z.object({\n * question: z.string().min(1, 'Question is required'),\n * }),\n * }) {\n * execute(params: this['params']): string {\n * throw new HumanInputException(params.question);\n * }\n * }\n * ```\n */\nexport class HumanInputException extends Error {\n public readonly question: string;\n\n constructor(question: string) {\n super(`Human input required: ${question}`);\n this.name = \"HumanInputException\";\n this.question = question;\n }\n}\n\n/**\n * Exception thrown when a gadget execution exceeds its timeout limit.\n *\n * When a gadget's execution time exceeds either:\n * - The gadget's own `timeoutMs` property, or\n * - The global `defaultGadgetTimeoutMs` configured in runtime/agent loop options\n *\n * The executor will automatically throw this exception and return it as an error.\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * class SlowApiGadget extends Gadget({\n * name: 'SlowApi',\n * description: 'Calls a slow external API',\n * timeoutMs: 5000, // 5 second timeout\n * schema: z.object({\n * endpoint: z.string(),\n * }),\n * }) {\n * async execute(params: this['params']): Promise<string> {\n * // If this takes longer than 5 seconds, execution will be aborted\n * const response = await fetch(params.endpoint);\n * return await response.text();\n * }\n * }\n * ```\n */\nexport class TimeoutException extends Error {\n public readonly timeoutMs: number;\n public readonly gadgetName: string;\n\n constructor(gadgetName: string, timeoutMs: number) {\n super(`Gadget '${gadgetName}' execution exceeded timeout of ${timeoutMs}ms`);\n this.name = \"TimeoutException\";\n this.gadgetName = gadgetName;\n this.timeoutMs = timeoutMs;\n }\n}\n","import type { ZodError } from \"zod\";\nimport { GADGET_ARG_PREFIX, GADGET_END_PREFIX, GADGET_START_PREFIX } from \"../core/constants.js\";\nimport type { BaseGadget } from \"./gadget.js\";\n\nexport interface ErrorFormatterOptions {\n /** Custom argument prefix for block format examples. Default: \"!!!ARG:\" */\n argPrefix?: string;\n /** Custom start prefix for block format examples. Default: \"!!!GADGET_START:\" */\n startPrefix?: string;\n /** Custom end prefix for block format examples. Default: \"!!!GADGET_END\" */\n endPrefix?: string;\n}\n\n/**\n * Formats gadget errors with helpful context for LLMs.\n *\n * This class generates error messages that include:\n * - Clear error description\n * - Full gadget usage instructions (via getInstruction())\n * - Block format reference for parse errors\n *\n * The goal is to help LLMs self-correct on subsequent invocation attempts.\n */\nexport class GadgetErrorFormatter {\n private readonly argPrefix: string;\n private readonly startPrefix: string;\n private readonly endPrefix: string;\n\n constructor(options: ErrorFormatterOptions = {}) {\n this.argPrefix = options.argPrefix ?? GADGET_ARG_PREFIX;\n this.startPrefix = options.startPrefix ?? GADGET_START_PREFIX;\n this.endPrefix = options.endPrefix ?? GADGET_END_PREFIX;\n }\n\n /**\n * Format a Zod validation error with full gadget instructions.\n *\n * @param gadgetName - Name of the gadget that was called\n * @param zodError - The Zod validation error\n * @param gadget - The gadget instance (for generating instructions)\n * @returns Formatted error message with usage instructions\n */\n formatValidationError(gadgetName: string, zodError: ZodError, gadget: BaseGadget): string {\n const parts: string[] = [];\n\n // Error header\n parts.push(`Error: Invalid parameters for '${gadgetName}':`);\n\n // Format each validation issue\n for (const issue of zodError.issues) {\n const path = issue.path.join(\".\") || \"root\";\n parts.push(` - ${path}: ${issue.message}`);\n }\n\n // Add gadget usage instructions\n parts.push(\"\");\n parts.push(\"Gadget Usage:\");\n parts.push(gadget.getInstruction(this.argPrefix));\n\n return parts.join(\"\\n\");\n }\n\n /**\n * Format a parse error with block format reference.\n *\n * @param gadgetName - Name of the gadget that was called\n * @param parseError - The parse error message\n * @param gadget - The gadget instance if found (for generating instructions)\n * @returns Formatted error message with format reference\n */\n formatParseError(gadgetName: string, parseError: string, gadget: BaseGadget | undefined): string {\n const parts: string[] = [];\n\n // Error header\n parts.push(`Error: Failed to parse parameters for '${gadgetName}':`);\n parts.push(` ${parseError}`);\n\n // Add gadget usage instructions if gadget exists\n if (gadget) {\n parts.push(\"\");\n parts.push(\"Gadget Usage:\");\n parts.push(gadget.getInstruction(this.argPrefix));\n }\n\n // Always add block format reference\n parts.push(\"\");\n parts.push(\"Block Format Reference:\");\n parts.push(` ${this.startPrefix}${gadgetName}`);\n parts.push(` ${this.argPrefix}parameterName`);\n parts.push(\" parameter value here\");\n parts.push(` ${this.endPrefix}`);\n\n return parts.join(\"\\n\");\n }\n\n /**\n * Format a registry error (gadget not found) with available gadgets list.\n *\n * @param gadgetName - Name of the gadget that was not found\n * @param availableGadgets - List of available gadget names\n * @returns Formatted error message with available gadgets\n */\n formatRegistryError(gadgetName: string, availableGadgets: string[]): string {\n const parts: string[] = [];\n\n // Error header\n parts.push(`Error: Gadget '${gadgetName}' not found.`);\n\n // List available gadgets\n if (availableGadgets.length > 0) {\n parts.push(\"\");\n parts.push(`Available gadgets: ${availableGadgets.join(\", \")}`);\n } else {\n parts.push(\"\");\n parts.push(\"No gadgets are currently registered.\");\n }\n\n return parts.join(\"\\n\");\n }\n}\n\n/**\n * Create a pre-configured error formatter instance.\n *\n * @param options - Formatter options\n * @returns Configured GadgetErrorFormatter instance\n */\nexport function createErrorFormatter(options: ErrorFormatterOptions = {}): GadgetErrorFormatter {\n return new GadgetErrorFormatter(options);\n}\n","import type { ILogObj, Logger } from \"tslog\";\nimport { createLogger } from \"../logging/logger.js\";\nimport { GadgetErrorFormatter, type ErrorFormatterOptions } from \"./error-formatter.js\";\nimport { BreakLoopException, HumanInputException, TimeoutException } from \"./exceptions.js\";\nimport type { GadgetRegistry } from \"./registry.js\";\nimport type { GadgetExecutionResult, ParsedGadgetCall } from \"./types.js\";\n\nexport class GadgetExecutor {\n private readonly logger: Logger<ILogObj>;\n private readonly errorFormatter: GadgetErrorFormatter;\n\n constructor(\n private readonly registry: GadgetRegistry,\n private readonly onHumanInputRequired?: (question: string) => Promise<string>,\n logger?: Logger<ILogObj>,\n private readonly defaultGadgetTimeoutMs?: number,\n errorFormatterOptions?: ErrorFormatterOptions,\n ) {\n this.logger = logger ?? createLogger({ name: \"llmist:executor\" });\n this.errorFormatter = new GadgetErrorFormatter(errorFormatterOptions);\n }\n\n /**\n * Creates a promise that rejects with a TimeoutException after the specified timeout.\n */\n private createTimeoutPromise(gadgetName: string, timeoutMs: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => {\n reject(new TimeoutException(gadgetName, timeoutMs));\n }, timeoutMs);\n });\n }\n\n // Execute a gadget call asynchronously\n async execute(call: ParsedGadgetCall): Promise<GadgetExecutionResult> {\n const startTime = Date.now();\n\n this.logger.debug(\"Executing gadget\", {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters: call.parameters,\n });\n\n const rawParameters: Record<string, unknown> = call.parameters ?? {};\n let validatedParameters: Record<string, unknown> = rawParameters;\n\n try {\n // Check if gadget exists\n const gadget = this.registry.get(call.gadgetName);\n if (!gadget) {\n this.logger.error(\"Gadget not found\", { gadgetName: call.gadgetName });\n const availableGadgets = this.registry.getNames();\n return {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters: call.parameters ?? {},\n error: this.errorFormatter.formatRegistryError(call.gadgetName, availableGadgets),\n executionTimeMs: Date.now() - startTime,\n };\n }\n\n // Check for parse errors\n if (call.parseError || !call.parameters) {\n this.logger.error(\"Gadget parameter parse error\", {\n gadgetName: call.gadgetName,\n parseError: call.parseError,\n rawParameters: call.parametersRaw,\n });\n const parseErrorMessage = call.parseError ?? \"Failed to parse parameters\";\n return {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters: {},\n error: this.errorFormatter.formatParseError(call.gadgetName, parseErrorMessage, gadget),\n executionTimeMs: Date.now() - startTime,\n };\n }\n\n if (gadget.parameterSchema) {\n const validationResult = gadget.parameterSchema.safeParse(rawParameters);\n if (!validationResult.success) {\n const validationError = this.errorFormatter.formatValidationError(\n call.gadgetName,\n validationResult.error,\n gadget,\n );\n this.logger.error(\"Gadget parameter validation failed\", {\n gadgetName: call.gadgetName,\n issueCount: validationResult.error.issues.length,\n });\n\n return {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters: rawParameters,\n error: validationError,\n executionTimeMs: Date.now() - startTime,\n };\n }\n\n validatedParameters = validationResult.data as Record<string, unknown>;\n }\n\n // Determine the timeout for this gadget\n // Priority: gadget's own timeoutMs > defaultGadgetTimeoutMs > no timeout\n const timeoutMs = gadget.timeoutMs ?? this.defaultGadgetTimeoutMs;\n\n // Execute gadget (handle both sync and async)\n let result: string;\n if (timeoutMs && timeoutMs > 0) {\n // Execute with timeout\n this.logger.debug(\"Executing gadget with timeout\", {\n gadgetName: call.gadgetName,\n timeoutMs,\n });\n result = await Promise.race([\n Promise.resolve(gadget.execute(validatedParameters)),\n this.createTimeoutPromise(call.gadgetName, timeoutMs),\n ]);\n } else {\n // Execute without timeout\n result = await Promise.resolve(gadget.execute(validatedParameters));\n }\n\n const executionTimeMs = Date.now() - startTime;\n this.logger.info(\"Gadget executed successfully\", {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n executionTimeMs,\n });\n\n this.logger.debug(\"Gadget result\", {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters: validatedParameters,\n result,\n executionTimeMs,\n });\n\n return {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters: validatedParameters,\n result,\n executionTimeMs,\n };\n } catch (error) {\n // Check if this is a BreakLoopException\n if (error instanceof BreakLoopException) {\n this.logger.info(\"Gadget requested loop termination\", {\n gadgetName: call.gadgetName,\n message: error.message,\n });\n return {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters: validatedParameters,\n result: error.message,\n breaksLoop: true,\n executionTimeMs: Date.now() - startTime,\n };\n }\n\n // Check if this is a TimeoutException\n if (error instanceof TimeoutException) {\n this.logger.error(\"Gadget execution timed out\", {\n gadgetName: call.gadgetName,\n timeoutMs: error.timeoutMs,\n executionTimeMs: Date.now() - startTime,\n });\n return {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters: validatedParameters,\n error: error.message,\n executionTimeMs: Date.now() - startTime,\n };\n }\n\n // Check if this is a HumanInputException\n if (error instanceof HumanInputException) {\n this.logger.info(\"Gadget requested human input\", {\n gadgetName: call.gadgetName,\n question: error.question,\n });\n\n // If callback is provided, call it and wait for answer\n if (this.onHumanInputRequired) {\n try {\n const answer = await this.onHumanInputRequired(error.question);\n this.logger.debug(\"Human input received\", {\n gadgetName: call.gadgetName,\n answerLength: answer.length,\n });\n return {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters: validatedParameters,\n result: answer,\n executionTimeMs: Date.now() - startTime,\n };\n } catch (inputError) {\n this.logger.error(\"Human input callback error\", {\n gadgetName: call.gadgetName,\n error: inputError instanceof Error ? inputError.message : String(inputError),\n });\n return {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters: validatedParameters,\n error: inputError instanceof Error ? inputError.message : String(inputError),\n executionTimeMs: Date.now() - startTime,\n };\n }\n }\n\n // No callback - return error since we can't get human input\n this.logger.warn(\"Human input required but no callback provided\", {\n gadgetName: call.gadgetName,\n });\n return {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters: validatedParameters,\n error: \"Human input required but not available (stdin is not interactive)\",\n executionTimeMs: Date.now() - startTime,\n };\n }\n\n const executionTimeMs = Date.now() - startTime;\n this.logger.error(\"Gadget execution failed\", {\n gadgetName: call.gadgetName,\n error: error instanceof Error ? error.message : String(error),\n executionTimeMs,\n });\n\n return {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters: validatedParameters,\n error: error instanceof Error ? error.message : String(error),\n executionTimeMs,\n };\n }\n }\n\n // Execute multiple gadget calls in parallel\n async executeAll(calls: ParsedGadgetCall[]): Promise<GadgetExecutionResult[]> {\n return Promise.all(calls.map((call) => this.execute(call)));\n }\n}\n","import { GADGET_ARG_PREFIX } from \"../core/constants.js\";\n\nexport interface BlockParseOptions {\n /** Prefix that declares an argument. Default: \"!!!ARG:\" */\n argPrefix?: string;\n}\n\n/**\n * Parse block format parameters into an object.\n *\n * Block format uses !!!ARG:pointer syntax where pointer is a JSON Pointer\n * path (without leading /) that defines where to place the value.\n *\n * Example input:\n * ```\n * !!!ARG:filename\n * calculator.ts\n * !!!ARG:config/timeout\n * 30\n * !!!ARG:items/0\n * first\n * ```\n *\n * Produces:\n * ```json\n * {\n * \"filename\": \"calculator.ts\",\n * \"config\": { \"timeout\": 30 },\n * \"items\": [\"first\"]\n * }\n * ```\n *\n * Single-line values are automatically coerced:\n * - \"true\" / \"false\" → boolean\n * - Numeric strings → number\n * - Multiline values always stay as strings (for code/content)\n *\n * @param content - Raw parameter content (after gadget name line, before end marker)\n * @param options - Parser options\n * @returns Parsed parameters object with coerced values\n * @throws Error if duplicate pointers or invalid array indices\n */\nexport function parseBlockParams(\n content: string,\n options?: BlockParseOptions\n): Record<string, unknown> {\n const argPrefix = options?.argPrefix ?? GADGET_ARG_PREFIX;\n const result: Record<string, unknown> = {};\n const seenPointers = new Set<string>();\n\n // Split content by arg prefix to get individual arg entries\n // First element will be empty or whitespace before first arg\n const parts = content.split(argPrefix);\n\n for (let i = 1; i < parts.length; i++) {\n const part = parts[i];\n\n // Find the pointer (first line) and value (rest)\n const newlineIndex = part.indexOf(\"\\n\");\n if (newlineIndex === -1) {\n // Arg with no value (just the pointer line)\n const pointer = part.trim();\n if (pointer) {\n if (seenPointers.has(pointer)) {\n throw new Error(`Duplicate pointer: ${pointer}`);\n }\n seenPointers.add(pointer);\n setByPointer(result, pointer, \"\");\n }\n continue;\n }\n\n const pointer = part.substring(0, newlineIndex).trim();\n let value = part.substring(newlineIndex + 1);\n\n // Strip single trailing newline if present (per spec)\n if (value.endsWith(\"\\n\")) {\n value = value.slice(0, -1);\n }\n\n if (!pointer) {\n continue; // Skip empty pointers\n }\n\n if (seenPointers.has(pointer)) {\n throw new Error(`Duplicate pointer: ${pointer}`);\n }\n seenPointers.add(pointer);\n\n setByPointer(result, pointer, value);\n }\n\n return result;\n}\n\n/**\n * Coerce a string value to its appropriate primitive type.\n * - \"true\" / \"false\" → boolean\n * - Numeric strings → number\n * - Everything else stays string\n *\n * Only coerces single-line values to avoid accidentally converting\n * code or multiline content that happens to look like a number/boolean.\n */\nfunction coerceValue(value: string): string | number | boolean {\n // Don't coerce multiline values - they're likely code/content\n if (value.includes(\"\\n\")) {\n return value;\n }\n\n const trimmed = value.trim();\n\n // Boolean coercion\n if (trimmed === \"true\") return true;\n if (trimmed === \"false\") return false;\n\n // Number coercion - only for values that look clearly numeric\n // Avoid coercing things like \"123abc\" or empty strings\n if (trimmed !== \"\" && /^-?\\d+(\\.\\d+)?$/.test(trimmed)) {\n const num = Number(trimmed);\n if (!isNaN(num) && isFinite(num)) {\n return num;\n }\n }\n\n return value;\n}\n\n/**\n * Set a value in an object using a JSON Pointer path (without leading /).\n *\n * Handles:\n * - Simple keys: \"name\" → { name: value }\n * - Nested paths: \"config/timeout\" → { config: { timeout: value } }\n * - Array indices: \"items/0\" → { items: [value] }\n *\n * Values are automatically coerced to appropriate types (boolean, number)\n * for single-line values.\n *\n * @param obj - Target object to modify\n * @param pointer - JSON Pointer path without leading /\n * @param value - Value to set (string that may be coerced)\n * @throws Error if array index gaps detected\n */\nfunction setByPointer(\n obj: Record<string, unknown>,\n pointer: string,\n value: string\n): void {\n const segments = pointer.split(\"/\");\n let current: Record<string, unknown> | unknown[] = obj;\n\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i];\n const nextSegment = segments[i + 1];\n const nextIsArrayIndex = /^\\d+$/.test(nextSegment);\n\n if (Array.isArray(current)) {\n const index = parseInt(segment, 10);\n if (isNaN(index) || index < 0) {\n throw new Error(`Invalid array index: ${segment}`);\n }\n // Validate no gaps\n if (index > current.length) {\n throw new Error(`Array index gap: expected ${current.length}, got ${index}`);\n }\n if (current[index] === undefined) {\n current[index] = nextIsArrayIndex ? [] : {};\n }\n current = current[index] as Record<string, unknown> | unknown[];\n } else {\n // current is an object\n const rec = current as Record<string, unknown>;\n if (rec[segment] === undefined) {\n rec[segment] = nextIsArrayIndex ? [] : {};\n }\n current = rec[segment] as Record<string, unknown> | unknown[];\n }\n }\n\n // Set the final value\n const lastSegment = segments[segments.length - 1];\n\n // Coerce the value to appropriate type\n const coercedValue = coerceValue(value);\n\n if (Array.isArray(current)) {\n const index = parseInt(lastSegment, 10);\n if (isNaN(index) || index < 0) {\n throw new Error(`Invalid array index: ${lastSegment}`);\n }\n // Validate no gaps\n if (index > current.length) {\n throw new Error(`Array index gap: expected ${current.length}, got ${index}`);\n }\n current[index] = coercedValue;\n } else {\n (current as Record<string, unknown>)[lastSegment] = coercedValue;\n }\n}\n","import { GADGET_ARG_PREFIX, GADGET_END_PREFIX, GADGET_START_PREFIX } from \"../core/constants.js\";\nimport type { StreamEvent } from \"./types.js\";\nimport { parseBlockParams } from \"./block-params.js\";\n\nexport type ParameterFormat = \"block\";\n\n\n/**\n * Strip markdown code fences from parameter content.\n * LLMs sometimes wrap their parameters in ```toml, ```yaml, ```json, or plain ``` blocks.\n * This function removes those fences to allow successful parsing.\n *\n * @internal Exported for testing only\n */\nexport function stripMarkdownFences(content: string): string {\n let cleaned = content.trim();\n\n // Pattern: ```toml, ```yaml, ```json, or just ``` at start (case-insensitive)\n const openingFence = /^```(?:toml|yaml|json)?\\s*\\n/i;\n // Pattern: ``` at end (with optional preceding newline)\n const closingFence = /\\n?```\\s*$/;\n\n // Strip opening fence if present\n cleaned = cleaned.replace(openingFence, \"\");\n // Strip closing fence if present\n cleaned = cleaned.replace(closingFence, \"\");\n\n return cleaned.trim();\n}\n\nexport interface StreamParserOptions {\n startPrefix?: string;\n endPrefix?: string;\n /** Prefix for block format arguments. Default: \"!!!ARG:\" */\n argPrefix?: string;\n}\n\n// Global counter for generating unique invocation IDs across all parser instances\nlet globalInvocationCounter = 0;\n\n/**\n * Reset the global invocation counter. Only use this in tests!\n * @internal\n */\nexport function resetGlobalInvocationCounter(): void {\n globalInvocationCounter = 0;\n}\n\nexport class StreamParser {\n private buffer = \"\";\n private lastReportedTextLength = 0;\n private readonly startPrefix: string;\n private readonly endPrefix: string;\n private readonly argPrefix: string;\n\n constructor(options: StreamParserOptions = {}) {\n this.startPrefix = options.startPrefix ?? GADGET_START_PREFIX;\n this.endPrefix = options.endPrefix ?? GADGET_END_PREFIX;\n this.argPrefix = options.argPrefix ?? GADGET_ARG_PREFIX;\n }\n\n private takeTextUntil(index: number): string | undefined {\n if (index <= this.lastReportedTextLength) {\n return undefined;\n }\n\n const segment = this.buffer.slice(this.lastReportedTextLength, index);\n this.lastReportedTextLength = index;\n\n return segment.trim().length > 0 ? segment : undefined;\n }\n\n /**\n * Parse gadget name, handling both old format (name:invocationId) and new format (just name).\n * For new format, generates a unique invocation ID.\n */\n private parseGadgetName(gadgetName: string): { actualName: string; invocationId: string } {\n if (gadgetName.includes(\":\")) {\n // Old format: gadgetName:invocationId - support for backward compatibility\n const parts = gadgetName.split(\":\");\n return { actualName: parts[0], invocationId: parts[1] };\n }\n // New format: just gadget name, generate unique ID\n return { actualName: gadgetName, invocationId: `gadget_${++globalInvocationCounter}` };\n }\n\n /**\n * Extract the error message from a parse error.\n * Preserves full message since the error formatter adds contextual help\n * that benefits from precise, detailed error information.\n */\n private extractParseError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n }\n\n /**\n * Parse parameter string using block format\n */\n private parseParameters(raw: string): {\n parameters?: Record<string, unknown>;\n parseError?: string;\n } {\n // Strip markdown code fences if LLM wrapped the parameters\n const cleaned = stripMarkdownFences(raw);\n\n try {\n return { parameters: parseBlockParams(cleaned, { argPrefix: this.argPrefix }) };\n } catch (error) {\n return { parseError: this.extractParseError(error) };\n }\n }\n\n // Feed a chunk of text and get parsed events\n *feed(chunk: string): Generator<StreamEvent> {\n this.buffer += chunk;\n\n let startIndex = 0;\n while (true) {\n // Find next gadget start marker\n const partStartIndex = this.buffer.indexOf(this.startPrefix, startIndex);\n if (partStartIndex === -1) break;\n\n // Yield any text before the gadget\n const textBefore = this.takeTextUntil(partStartIndex);\n if (textBefore !== undefined) {\n yield { type: \"text\", content: textBefore };\n }\n\n // Extract gadget name (no more invocation ID)\n const metadataStartIndex = partStartIndex + this.startPrefix.length;\n const metadataEndIndex = this.buffer.indexOf(\"\\n\", metadataStartIndex);\n if (metadataEndIndex === -1) break; // Wait for more data\n\n const gadgetName = this.buffer.substring(metadataStartIndex, metadataEndIndex).trim();\n const { actualName: actualGadgetName, invocationId } = this.parseGadgetName(gadgetName);\n\n const contentStartIndex = metadataEndIndex + 1;\n\n let partEndIndex: number;\n let endMarkerLength = 0;\n\n if (gadgetName.includes(\":\")) {\n // Old format - look for old format end marker\n const oldEndMarker = `${this.endPrefix + actualGadgetName}:${invocationId}`;\n partEndIndex = this.buffer.indexOf(oldEndMarker, contentStartIndex);\n if (partEndIndex === -1) break; // Wait for more data\n endMarkerLength = oldEndMarker.length;\n } else {\n // New format - look for end marker OR next start marker (implicit end)\n // If a next gadget starts BEFORE an end marker, use that as implicit terminator\n\n // Look for next gadget start (potential implicit end)\n const nextStartPos = this.buffer.indexOf(this.startPrefix, contentStartIndex);\n\n // Look for proper end marker\n let validEndPos = -1;\n let searchPos = contentStartIndex;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const endPos = this.buffer.indexOf(this.endPrefix, searchPos);\n if (endPos === -1) break;\n\n // Check if this is a standalone end marker or part of old format\n const afterEnd = this.buffer.substring(endPos + this.endPrefix.length);\n if (\n afterEnd.startsWith(\"\\n\") ||\n afterEnd.startsWith(\"\\r\") ||\n afterEnd.startsWith(this.startPrefix) ||\n afterEnd.length === 0\n ) {\n // It's a standalone end marker\n validEndPos = endPos;\n break;\n } else {\n // It might be old format, skip this one\n searchPos = endPos + this.endPrefix.length;\n }\n }\n\n // Decide which terminator to use:\n // - If next start comes before end marker, use next start (implicit end)\n // - Otherwise use the end marker if found\n if (nextStartPos !== -1 && (validEndPos === -1 || nextStartPos < validEndPos)) {\n // Found next gadget start before any end marker - implicit end\n partEndIndex = nextStartPos;\n endMarkerLength = 0; // Don't consume the next start marker\n } else if (validEndPos !== -1) {\n // Found proper end marker\n partEndIndex = validEndPos;\n endMarkerLength = this.endPrefix.length;\n } else {\n // Neither end marker nor next start found - wait for more data\n break;\n }\n }\n\n // Extract parameters\n const parametersRaw = this.buffer.substring(contentStartIndex, partEndIndex).trim();\n\n // Parse parameters according to configured format\n const { parameters, parseError } = this.parseParameters(parametersRaw);\n\n yield {\n type: \"gadget_call\",\n call: {\n gadgetName: actualGadgetName,\n invocationId,\n parametersRaw,\n parameters,\n parseError,\n },\n };\n\n // Move past this gadget\n startIndex = partEndIndex + endMarkerLength;\n\n this.lastReportedTextLength = startIndex;\n }\n\n // Keep unprocessed data in buffer\n if (startIndex > 0) {\n this.buffer = this.buffer.substring(startIndex);\n this.lastReportedTextLength = 0;\n }\n }\n\n // Finalize parsing and return remaining text or incomplete gadgets\n *finalize(): Generator<StreamEvent> {\n // Check if there's an incomplete gadget in the buffer\n const startIndex = this.buffer.indexOf(this.startPrefix, this.lastReportedTextLength);\n\n if (startIndex !== -1) {\n // There's an incomplete gadget - try to parse it\n const textBefore = this.takeTextUntil(startIndex);\n if (textBefore !== undefined) {\n yield { type: \"text\", content: textBefore };\n }\n\n // Extract gadget name\n const metadataStartIndex = startIndex + this.startPrefix.length;\n const metadataEndIndex = this.buffer.indexOf(\"\\n\", metadataStartIndex);\n\n if (metadataEndIndex !== -1) {\n const gadgetName = this.buffer.substring(metadataStartIndex, metadataEndIndex).trim();\n const { actualName: actualGadgetName, invocationId } = this.parseGadgetName(gadgetName);\n const contentStartIndex = metadataEndIndex + 1;\n\n // Extract parameters (everything after the newline to end of buffer)\n const parametersRaw = this.buffer.substring(contentStartIndex).trim();\n\n const { parameters, parseError } = this.parseParameters(parametersRaw);\n\n yield {\n type: \"gadget_call\",\n call: {\n gadgetName: actualGadgetName,\n invocationId,\n parametersRaw: parametersRaw,\n parameters,\n parseError,\n },\n };\n\n return;\n }\n }\n\n // No incomplete gadget - just emit remaining text\n const remainingText = this.takeTextUntil(this.buffer.length);\n if (remainingText !== undefined) {\n yield { type: \"text\", content: remainingText };\n }\n }\n\n // Reset parser state (note: global invocation counter is NOT reset to ensure unique IDs)\n reset(): void {\n this.buffer = \"\";\n this.lastReportedTextLength = 0;\n }\n}\n","/**\n * Runtime validators for hook action types.\n *\n * These validators ensure that controllers return valid action objects,\n * catching common mistakes like missing required fields.\n */\n\nimport type {\n AfterGadgetExecutionAction,\n AfterLLMCallAction,\n AfterLLMErrorAction,\n BeforeGadgetExecutionAction,\n BeforeLLMCallAction,\n} from \"./hooks.js\";\n\nexport class HookValidationError extends Error {\n constructor(hookName: string, message: string) {\n super(`Invalid action from ${hookName}: ${message}`);\n this.name = \"HookValidationError\";\n }\n}\n\n/**\n * Validate beforeLLMCall action.\n */\nexport function validateBeforeLLMCallAction(action: BeforeLLMCallAction): void {\n if (!action || typeof action !== \"object\" || !(\"action\" in action)) {\n throw new HookValidationError(\n \"beforeLLMCall\",\n \"Must return an action object with an 'action' field\",\n );\n }\n\n const actionType = action.action;\n if (actionType !== \"proceed\" && actionType !== \"skip\") {\n throw new HookValidationError(\n \"beforeLLMCall\",\n `Invalid action type: ${actionType}. Must be 'proceed' or 'skip'`,\n );\n }\n\n if (actionType === \"skip\" && !action.syntheticResponse) {\n throw new HookValidationError(\n \"beforeLLMCall\",\n \"When action is 'skip', syntheticResponse is required\",\n );\n }\n}\n\n/**\n * Validate afterLLMCall action.\n */\nexport function validateAfterLLMCallAction(action: AfterLLMCallAction): void {\n if (!action || typeof action !== \"object\" || !(\"action\" in action)) {\n throw new HookValidationError(\n \"afterLLMCall\",\n \"Must return an action object with an 'action' field\",\n );\n }\n\n const actionType = action.action;\n const validActions = [\"continue\", \"append_messages\", \"modify_and_continue\", \"append_and_modify\"];\n if (!validActions.includes(actionType)) {\n throw new HookValidationError(\n \"afterLLMCall\",\n `Invalid action type: ${actionType}. Must be one of: ${validActions.join(\", \")}`,\n );\n }\n\n if (actionType === \"append_messages\" || actionType === \"append_and_modify\") {\n if (!(\"messages\" in action) || !action.messages || !Array.isArray(action.messages)) {\n throw new HookValidationError(\n \"afterLLMCall\",\n `When action is '${actionType}', messages array is required`,\n );\n }\n\n if (action.messages.length === 0) {\n throw new HookValidationError(\n \"afterLLMCall\",\n `When action is '${actionType}', messages array must not be empty`,\n );\n }\n\n // Validate each message\n for (let i = 0; i < action.messages.length; i++) {\n const msg = action.messages[i];\n if (!msg || typeof msg !== \"object\") {\n throw new HookValidationError(\"afterLLMCall\", `Message at index ${i} must be an object`);\n }\n if (!msg.role || !msg.content) {\n throw new HookValidationError(\n \"afterLLMCall\",\n `Message at index ${i} must have 'role' and 'content' fields`,\n );\n }\n if (![\"system\", \"user\", \"assistant\"].includes(msg.role)) {\n throw new HookValidationError(\n \"afterLLMCall\",\n `Message at index ${i} has invalid role: ${msg.role}`,\n );\n }\n }\n }\n\n if (actionType === \"modify_and_continue\" || actionType === \"append_and_modify\") {\n if (!(\"modifiedMessage\" in action) || !action.modifiedMessage) {\n throw new HookValidationError(\n \"afterLLMCall\",\n `When action is '${actionType}', modifiedMessage is required`,\n );\n }\n }\n}\n\n/**\n * Validate afterLLMError action.\n */\nexport function validateAfterLLMErrorAction(action: AfterLLMErrorAction): void {\n if (!action || typeof action !== \"object\" || !(\"action\" in action)) {\n throw new HookValidationError(\n \"afterLLMError\",\n \"Must return an action object with an 'action' field\",\n );\n }\n\n const actionType = action.action;\n if (actionType !== \"rethrow\" && actionType !== \"recover\") {\n throw new HookValidationError(\n \"afterLLMError\",\n `Invalid action type: ${actionType}. Must be 'rethrow' or 'recover'`,\n );\n }\n\n if (actionType === \"recover\" && !action.fallbackResponse) {\n throw new HookValidationError(\n \"afterLLMError\",\n \"When action is 'recover', fallbackResponse is required\",\n );\n }\n}\n\n/**\n * Validate beforeGadgetExecution action.\n */\nexport function validateBeforeGadgetExecutionAction(action: BeforeGadgetExecutionAction): void {\n if (!action || typeof action !== \"object\" || !(\"action\" in action)) {\n throw new HookValidationError(\n \"beforeGadgetExecution\",\n \"Must return an action object with an 'action' field\",\n );\n }\n\n const actionType = action.action;\n if (actionType !== \"proceed\" && actionType !== \"skip\") {\n throw new HookValidationError(\n \"beforeGadgetExecution\",\n `Invalid action type: ${actionType}. Must be 'proceed' or 'skip'`,\n );\n }\n\n if (actionType === \"skip\" && !action.syntheticResult) {\n throw new HookValidationError(\n \"beforeGadgetExecution\",\n \"When action is 'skip', syntheticResult is required\",\n );\n }\n}\n\n/**\n * Validate afterGadgetExecution action.\n */\nexport function validateAfterGadgetExecutionAction(action: AfterGadgetExecutionAction): void {\n if (!action || typeof action !== \"object\" || !(\"action\" in action)) {\n throw new HookValidationError(\n \"afterGadgetExecution\",\n \"Must return an action object with an 'action' field\",\n );\n }\n\n const actionType = action.action;\n if (actionType !== \"continue\" && actionType !== \"recover\") {\n throw new HookValidationError(\n \"afterGadgetExecution\",\n `Invalid action type: ${actionType}. Must be 'continue' or 'recover'`,\n );\n }\n\n if (actionType === \"recover\" && !action.fallbackResult) {\n throw new HookValidationError(\n \"afterGadgetExecution\",\n \"When action is 'recover', fallbackResult is required\",\n );\n }\n}\n","/**\n * StreamProcessor: The heart of the new hooks architecture.\n *\n * Replaces the complex wiring between Agent, ResponseProcessor, and GadgetRuntime.\n * Owns ALL stream processing and hook coordination with a clean, predictable flow.\n */\n\nimport type { ILogObj, Logger } from \"tslog\";\nimport type { LLMStreamChunk, TokenUsage } from \"../core/options.js\";\nimport { GadgetExecutor } from \"../gadgets/executor.js\";\nimport { StreamParser } from \"../gadgets/parser.js\";\nimport type { GadgetRegistry } from \"../gadgets/registry.js\";\nimport type { GadgetExecutionResult, ParsedGadgetCall, StreamEvent } from \"../gadgets/types.js\";\nimport { createLogger } from \"../logging/logger.js\";\nimport {\n validateAfterGadgetExecutionAction,\n validateBeforeGadgetExecutionAction,\n} from \"./hook-validators.js\";\nimport type {\n AfterGadgetExecutionAction,\n AfterGadgetExecutionControllerContext,\n AgentHooks,\n BeforeGadgetExecutionAction,\n ChunkInterceptorContext,\n GadgetExecutionControllerContext,\n GadgetParameterInterceptorContext,\n GadgetResultInterceptorContext,\n MessageInterceptorContext,\n ObserveChunkContext,\n ObserveGadgetCompleteContext,\n ObserveGadgetStartContext,\n} from \"./hooks.js\";\n\n/**\n * Configuration for the StreamProcessor.\n */\nexport interface StreamProcessorOptions {\n /** Current iteration number */\n iteration: number;\n\n /** Gadget registry for execution */\n registry: GadgetRegistry;\n\n /** Custom gadget start prefix */\n gadgetStartPrefix?: string;\n\n /** Custom gadget end prefix */\n gadgetEndPrefix?: string;\n\n /** Custom argument prefix for block format */\n gadgetArgPrefix?: string;\n\n /** Hooks for lifecycle events */\n hooks?: AgentHooks;\n\n /** Logger instance */\n logger?: Logger<ILogObj>;\n\n /** Callback for human input */\n onHumanInputRequired?: (question: string) => Promise<string>;\n\n /** Whether to stop on gadget errors */\n stopOnGadgetError?: boolean;\n\n /** Custom error continuation logic */\n shouldContinueAfterError?: (context: {\n error: string;\n gadgetName: string;\n errorType: \"parse\" | \"validation\" | \"execution\";\n parameters?: Record<string, unknown>;\n }) => boolean | Promise<boolean>;\n\n /** Default gadget timeout */\n defaultGadgetTimeoutMs?: number;\n}\n\n/**\n * Result of stream processing.\n */\nexport interface StreamProcessingResult {\n /** All emitted events */\n outputs: StreamEvent[];\n\n /** Whether the loop should break */\n shouldBreakLoop: boolean;\n\n /** Whether any gadgets were executed */\n didExecuteGadgets: boolean;\n\n /** LLM finish reason */\n finishReason: string | null;\n\n /** Token usage (including cached token counts when available) */\n usage?: TokenUsage;\n\n /** The raw accumulated response text */\n rawResponse: string;\n\n /** The final message (after interceptors) */\n finalMessage: string;\n}\n\n/**\n * StreamProcessor: Coordinates all stream processing and hook execution.\n *\n * Execution order:\n * 1. Raw chunk arrives from LLM\n * 2. Interceptor: interceptRawChunk (transform raw text)\n * 3. Observer: onStreamChunk (logging)\n * 4. Parse for gadgets\n * 5. If gadget found:\n * a. Interceptor: interceptGadgetParameters (transform params)\n * b. Controller: beforeGadgetExecution (can skip)\n * c. Observer: onGadgetExecutionStart\n * d. Execute gadget\n * e. Interceptor: interceptGadgetResult (transform result)\n * f. Controller: afterGadgetExecution (can provide fallback)\n * g. Observer: onGadgetExecutionComplete\n * 6. If text chunk:\n * a. Interceptor: interceptTextChunk (transform display text)\n * b. Yield to user\n * 7. Stream complete\n * 8. Interceptor: interceptAssistantMessage (transform final message)\n */\nexport class StreamProcessor {\n private readonly iteration: number;\n private readonly registry: GadgetRegistry;\n private readonly hooks: AgentHooks;\n private readonly logger: Logger<ILogObj>;\n private readonly parser: StreamParser;\n private readonly executor: GadgetExecutor;\n private readonly stopOnGadgetError: boolean;\n private readonly shouldContinueAfterError?: (context: {\n error: string;\n gadgetName: string;\n errorType: \"parse\" | \"validation\" | \"execution\";\n parameters?: Record<string, unknown>;\n }) => boolean | Promise<boolean>;\n\n private accumulatedText = \"\";\n private shouldStopExecution = false;\n private observerFailureCount = 0;\n\n constructor(options: StreamProcessorOptions) {\n this.iteration = options.iteration;\n this.registry = options.registry;\n this.hooks = options.hooks ?? {};\n this.logger = options.logger ?? createLogger({ name: \"llmist:stream-processor\" });\n this.stopOnGadgetError = options.stopOnGadgetError ?? true;\n this.shouldContinueAfterError = options.shouldContinueAfterError;\n\n this.parser = new StreamParser({\n startPrefix: options.gadgetStartPrefix,\n endPrefix: options.gadgetEndPrefix,\n argPrefix: options.gadgetArgPrefix,\n });\n\n this.executor = new GadgetExecutor(\n options.registry,\n options.onHumanInputRequired,\n this.logger.getSubLogger({ name: \"executor\" }),\n options.defaultGadgetTimeoutMs,\n );\n }\n\n /**\n * Process an LLM stream and return structured results.\n */\n async process(stream: AsyncIterable<LLMStreamChunk>): Promise<StreamProcessingResult> {\n const outputs: StreamEvent[] = [];\n let finishReason: string | null = null;\n let usage: TokenUsage | undefined;\n let didExecuteGadgets = false;\n let shouldBreakLoop = false;\n\n // Process stream chunks\n for await (const chunk of stream) {\n // Capture metadata\n if (chunk.finishReason) finishReason = chunk.finishReason;\n if (chunk.usage) usage = chunk.usage;\n\n // Process text content if present\n let processedChunk = \"\";\n if (chunk.text) {\n // Step 1: Interceptor - Transform raw chunk\n processedChunk = chunk.text;\n if (this.hooks.interceptors?.interceptRawChunk) {\n const context: ChunkInterceptorContext = {\n iteration: this.iteration,\n accumulatedText: this.accumulatedText,\n logger: this.logger,\n };\n const intercepted = this.hooks.interceptors.interceptRawChunk(processedChunk, context);\n if (intercepted === null) {\n // Chunk suppressed\n processedChunk = \"\";\n } else {\n processedChunk = intercepted;\n }\n }\n\n // Accumulate text\n if (processedChunk) {\n this.accumulatedText += processedChunk;\n }\n }\n\n // Step 2: Observer - Observe chunk (called for text OR usage updates)\n if (this.hooks.observers?.onStreamChunk && (processedChunk || chunk.usage)) {\n const chunkObservers: Array<() => void | Promise<void>> = [];\n chunkObservers.push(async () => {\n const context: ObserveChunkContext = {\n iteration: this.iteration,\n rawChunk: processedChunk,\n accumulatedText: this.accumulatedText,\n usage,\n logger: this.logger,\n };\n await this.hooks.observers!.onStreamChunk!(context);\n });\n await this.runObserversInParallel(chunkObservers);\n }\n\n // Skip further processing if no text\n if (!processedChunk) {\n continue;\n }\n\n // Step 3: Parse and process events\n for (const event of this.parser.feed(processedChunk)) {\n const processedEvents = await this.processEvent(event);\n outputs.push(...processedEvents);\n\n // Check if any gadget was executed\n if (processedEvents.some((e) => e.type === \"gadget_result\")) {\n didExecuteGadgets = true;\n }\n\n // Check for loop termination signals\n for (const evt of processedEvents) {\n if (evt.type === \"gadget_result\" && evt.result.breaksLoop) {\n shouldBreakLoop = true;\n }\n }\n }\n\n // Break if we should stop execution\n if (this.shouldStopExecution) {\n this.logger.info(\"Breaking from LLM stream due to gadget error\");\n break;\n }\n }\n\n // Finalize parsing\n if (!this.shouldStopExecution) {\n for (const event of this.parser.finalize()) {\n const processedEvents = await this.processEvent(event);\n outputs.push(...processedEvents);\n\n if (processedEvents.some((e) => e.type === \"gadget_result\")) {\n didExecuteGadgets = true;\n }\n\n for (const evt of processedEvents) {\n if (evt.type === \"gadget_result\" && evt.result.breaksLoop) {\n shouldBreakLoop = true;\n }\n }\n }\n }\n\n // Step 4: Interceptor - Transform final message\n let finalMessage = this.accumulatedText;\n if (this.hooks.interceptors?.interceptAssistantMessage) {\n const context: MessageInterceptorContext = {\n iteration: this.iteration,\n rawResponse: this.accumulatedText,\n logger: this.logger,\n };\n finalMessage = this.hooks.interceptors.interceptAssistantMessage(finalMessage, context);\n }\n\n return {\n outputs,\n shouldBreakLoop,\n didExecuteGadgets,\n finishReason,\n usage,\n rawResponse: this.accumulatedText,\n finalMessage,\n };\n }\n\n /**\n * Process a single parsed event (text or gadget call).\n */\n private async processEvent(event: StreamEvent): Promise<StreamEvent[]> {\n if (event.type === \"text\") {\n return this.processTextEvent(event);\n } else if (event.type === \"gadget_call\") {\n return this.processGadgetCall(event.call);\n }\n return [event];\n }\n\n /**\n * Process a text event through interceptors.\n */\n private async processTextEvent(event: { type: \"text\"; content: string }): Promise<StreamEvent[]> {\n let content = event.content;\n\n // Interceptor: Transform text chunk\n if (this.hooks.interceptors?.interceptTextChunk) {\n const context: ChunkInterceptorContext = {\n iteration: this.iteration,\n accumulatedText: this.accumulatedText,\n logger: this.logger,\n };\n const intercepted = this.hooks.interceptors.interceptTextChunk(content, context);\n if (intercepted === null) {\n // Chunk suppressed\n return [];\n }\n content = intercepted;\n }\n\n return [{ type: \"text\", content }];\n }\n\n /**\n * Process a gadget call through the full lifecycle.\n */\n private async processGadgetCall(call: ParsedGadgetCall): Promise<StreamEvent[]> {\n // Check if we should skip due to previous error\n if (this.shouldStopExecution) {\n this.logger.debug(\"Skipping gadget execution due to previous error\", {\n gadgetName: call.gadgetName,\n });\n return [];\n }\n\n const events: StreamEvent[] = [];\n\n // Emit gadget call event\n events.push({ type: \"gadget_call\", call });\n\n // Check for parse errors\n if (call.parseError) {\n this.logger.warn(\"Gadget has parse error\", {\n gadgetName: call.gadgetName,\n error: call.parseError,\n rawParameters: call.parametersRaw,\n });\n\n const shouldContinue = await this.checkContinueAfterError(\n call.parseError,\n call.gadgetName,\n \"parse\",\n call.parameters,\n );\n\n if (!shouldContinue) {\n this.shouldStopExecution = true;\n }\n }\n\n // Step 1: Interceptor - Transform parameters\n let parameters = call.parameters ?? {};\n if (this.hooks.interceptors?.interceptGadgetParameters) {\n const context: GadgetParameterInterceptorContext = {\n iteration: this.iteration,\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n logger: this.logger,\n };\n parameters = this.hooks.interceptors.interceptGadgetParameters(parameters, context);\n }\n\n // Update call with intercepted parameters\n call.parameters = parameters;\n\n // Step 2: Controller - Before execution\n let shouldSkip = false;\n let syntheticResult: string | undefined;\n\n if (this.hooks.controllers?.beforeGadgetExecution) {\n const context: GadgetExecutionControllerContext = {\n iteration: this.iteration,\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters,\n logger: this.logger,\n };\n const action: BeforeGadgetExecutionAction =\n await this.hooks.controllers.beforeGadgetExecution(context);\n\n // Validate the action\n validateBeforeGadgetExecutionAction(action);\n\n if (action.action === \"skip\") {\n shouldSkip = true;\n syntheticResult = action.syntheticResult;\n this.logger.info(\"Controller skipped gadget execution\", {\n gadgetName: call.gadgetName,\n });\n }\n }\n\n // Step 3: Observer - Execution start\n const startObservers: Array<() => void | Promise<void>> = [];\n if (this.hooks.observers?.onGadgetExecutionStart) {\n startObservers.push(async () => {\n const context: ObserveGadgetStartContext = {\n iteration: this.iteration,\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters,\n logger: this.logger,\n };\n await this.hooks.observers!.onGadgetExecutionStart!(context);\n });\n }\n await this.runObserversInParallel(startObservers);\n\n // Step 4: Execute or use synthetic result\n let result: GadgetExecutionResult;\n if (shouldSkip) {\n result = {\n gadgetName: call.gadgetName,\n invocationId: call.invocationId,\n parameters,\n result: syntheticResult ?? \"Execution skipped\",\n executionTimeMs: 0,\n };\n } else {\n result = await this.executor.execute(call);\n }\n\n const originalResult = result.result;\n\n // Step 5: Interceptor - Transform result\n if (result.result && this.hooks.interceptors?.interceptGadgetResult) {\n const context: GadgetResultInterceptorContext = {\n iteration: this.iteration,\n gadgetName: result.gadgetName,\n invocationId: result.invocationId,\n parameters,\n executionTimeMs: result.executionTimeMs,\n logger: this.logger,\n };\n result.result = this.hooks.interceptors.interceptGadgetResult(result.result, context);\n }\n\n // Step 6: Controller - After execution\n if (this.hooks.controllers?.afterGadgetExecution) {\n const context: AfterGadgetExecutionControllerContext = {\n iteration: this.iteration,\n gadgetName: result.gadgetName,\n invocationId: result.invocationId,\n parameters,\n result: result.result,\n error: result.error,\n executionTimeMs: result.executionTimeMs,\n logger: this.logger,\n };\n const action: AfterGadgetExecutionAction =\n await this.hooks.controllers.afterGadgetExecution(context);\n\n // Validate the action\n validateAfterGadgetExecutionAction(action);\n\n if (action.action === \"recover\" && result.error) {\n this.logger.info(\"Controller recovered from gadget error\", {\n gadgetName: result.gadgetName,\n originalError: result.error,\n });\n result = {\n ...result,\n error: undefined,\n result: action.fallbackResult,\n };\n }\n }\n\n // Step 7: Observer - Execution complete\n const completeObservers: Array<() => void | Promise<void>> = [];\n if (this.hooks.observers?.onGadgetExecutionComplete) {\n completeObservers.push(async () => {\n const context: ObserveGadgetCompleteContext = {\n iteration: this.iteration,\n gadgetName: result.gadgetName,\n invocationId: result.invocationId,\n parameters,\n originalResult,\n finalResult: result.result,\n error: result.error,\n executionTimeMs: result.executionTimeMs,\n breaksLoop: result.breaksLoop,\n logger: this.logger,\n };\n await this.hooks.observers!.onGadgetExecutionComplete!(context);\n });\n }\n await this.runObserversInParallel(completeObservers);\n\n // Emit result event\n events.push({ type: \"gadget_result\", result });\n\n // Check if we should stop after error\n if (result.error) {\n const errorType = this.determineErrorType(call, result);\n const shouldContinue = await this.checkContinueAfterError(\n result.error,\n result.gadgetName,\n errorType,\n result.parameters,\n );\n\n if (!shouldContinue) {\n this.shouldStopExecution = true;\n }\n }\n\n return events;\n }\n\n /**\n * Safely execute an observer, catching and logging any errors.\n * Observers are non-critical, so errors are logged but don't crash the system.\n */\n private async safeObserve(fn: () => void | Promise<void>): Promise<void> {\n try {\n await fn();\n } catch (error) {\n this.observerFailureCount++;\n this.logger.error(\"Observer threw error (ignoring)\", {\n error: error instanceof Error ? error.message : String(error),\n failureCount: this.observerFailureCount,\n });\n }\n }\n\n /**\n * Execute multiple observers in parallel.\n * All observers run concurrently and failures are tracked but don't crash.\n */\n private async runObserversInParallel(\n observers: Array<() => void | Promise<void>>,\n ): Promise<void> {\n if (observers.length === 0) return;\n\n const results = await Promise.allSettled(\n observers.map((observer) => this.safeObserve(observer)),\n );\n\n // All errors are already logged in safeObserve, no need to handle rejected promises\n // This just ensures we wait for all observers to complete\n }\n\n /**\n * Check if execution should continue after an error.\n *\n * Returns true if we should continue processing subsequent gadgets, false if we should stop.\n *\n * Logic:\n * - If custom shouldContinueAfterError is provided, use it\n * - Otherwise, use stopOnGadgetError config:\n * - stopOnGadgetError=true → return false (stop execution)\n * - stopOnGadgetError=false → return true (continue execution)\n */\n private async checkContinueAfterError(\n error: string,\n gadgetName: string,\n errorType: \"parse\" | \"validation\" | \"execution\",\n parameters?: Record<string, unknown>,\n ): Promise<boolean> {\n // Custom error continuation logic takes precedence\n if (this.shouldContinueAfterError) {\n return await this.shouldContinueAfterError({\n error,\n gadgetName,\n errorType,\n parameters,\n });\n }\n\n // Default behavior based on stopOnGadgetError config\n // If stopOnGadgetError=true, we want to STOP (return false to stop continuing)\n // If stopOnGadgetError=false, we want to CONTINUE (return true to keep going)\n const shouldContinue = !this.stopOnGadgetError;\n\n this.logger.debug(\"Checking if should continue after error\", {\n error,\n gadgetName,\n errorType,\n stopOnGadgetError: this.stopOnGadgetError,\n shouldContinue,\n });\n\n return shouldContinue;\n }\n\n /**\n * Determine the type of error from a gadget execution.\n */\n private determineErrorType(\n call: ParsedGadgetCall,\n result: GadgetExecutionResult,\n ): \"parse\" | \"validation\" | \"execution\" {\n if (call.parseError) {\n return \"parse\";\n }\n if (result.error?.includes(\"Invalid parameters:\")) {\n return \"validation\";\n }\n return \"execution\";\n }\n}\n","/**\n * Anthropic Claude Model Specifications\n *\n * Model data for Anthropic Claude models including Sonnet and Opus variants\n * with their specifications, pricing, and capabilities.\n */\n\nimport type { ModelSpec } from \"../core/model-catalog.js\";\n\nexport const ANTHROPIC_MODELS: ModelSpec[] = [\n {\n provider: \"anthropic\",\n modelId: \"claude-sonnet-4-5-20250929\",\n displayName: \"Claude Sonnet 4.5\",\n contextWindow: 200_000,\n maxOutputTokens: 64_000,\n pricing: {\n input: 3.0,\n output: 15.0,\n cachedInput: 0.3,\n cacheWriteInput: 3.75,\n },\n knowledgeCutoff: \"2025-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n },\n metadata: {\n family: \"Claude 4\",\n releaseDate: \"2025-09-29\",\n notes: \"Smartest model for complex agents and coding. Extended thinking. 1M context in beta.\",\n },\n },\n {\n provider: \"anthropic\",\n modelId: \"claude-haiku-4-5-20251001\",\n displayName: \"Claude Haiku 4.5\",\n contextWindow: 200_000,\n maxOutputTokens: 64_000,\n pricing: {\n input: 1.0,\n output: 5.0,\n cachedInput: 0.1,\n cacheWriteInput: 1.25,\n },\n knowledgeCutoff: \"2025-02\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n },\n metadata: {\n family: \"Claude 4\",\n releaseDate: \"2025-10-01\",\n notes:\n \"Fastest model with near-frontier intelligence. Excellent for coding (73.3% SWE-bench).\",\n },\n },\n {\n provider: \"anthropic\",\n modelId: \"claude-sonnet-4-20250514\",\n displayName: \"Claude Sonnet 4\",\n contextWindow: 200_000,\n maxOutputTokens: 64_000,\n pricing: {\n input: 3.0,\n output: 15.0,\n cachedInput: 0.3,\n cacheWriteInput: 3.75,\n },\n knowledgeCutoff: \"2025-03\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n },\n metadata: {\n family: \"Claude 4\",\n releaseDate: \"2025-05-14\",\n notes: \"High performance with vision and extended thinking\",\n },\n },\n {\n provider: \"anthropic\",\n modelId: \"claude-3-7-sonnet-20250219\",\n displayName: \"Claude Sonnet 3.7\",\n contextWindow: 200_000,\n maxOutputTokens: 64_000,\n pricing: {\n input: 3.0,\n output: 15.0,\n cachedInput: 0.3,\n cacheWriteInput: 3.75,\n },\n knowledgeCutoff: \"2024-11\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n },\n metadata: {\n family: \"Claude 3\",\n releaseDate: \"2025-02-19\",\n notes: \"Legacy model - consider upgrading to Claude 4 family\",\n },\n },\n {\n provider: \"anthropic\",\n modelId: \"claude-opus-4-1-20250805\",\n displayName: \"Claude Opus 4.1\",\n contextWindow: 200_000,\n maxOutputTokens: 32_000,\n pricing: {\n input: 15.0,\n output: 75.0,\n cachedInput: 1.5,\n cacheWriteInput: 18.75,\n },\n knowledgeCutoff: \"2025-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n },\n metadata: {\n family: \"Claude 4\",\n releaseDate: \"2025-08-05\",\n notes: \"Exceptional for specialized reasoning tasks. Extended thinking support.\",\n },\n },\n {\n provider: \"anthropic\",\n modelId: \"claude-opus-4-20250514\",\n displayName: \"Claude Opus 4\",\n contextWindow: 200_000,\n maxOutputTokens: 32_000,\n pricing: {\n input: 15.0,\n output: 75.0,\n cachedInput: 1.5,\n cacheWriteInput: 18.75,\n },\n knowledgeCutoff: \"2025-03\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n },\n metadata: {\n family: \"Claude 4\",\n releaseDate: \"2025-05-14\",\n notes: \"Legacy Opus model - consider Opus 4.1 for improved reasoning\",\n },\n },\n {\n provider: \"anthropic\",\n modelId: \"claude-3-5-haiku-20241022\",\n displayName: \"Claude Haiku 3.5\",\n contextWindow: 200_000,\n maxOutputTokens: 8_192,\n pricing: {\n input: 0.8,\n output: 4.0,\n cachedInput: 0.08,\n cacheWriteInput: 1.0,\n },\n knowledgeCutoff: \"2024-07\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n },\n metadata: {\n family: \"Claude 3\",\n releaseDate: \"2024-10-22\",\n notes: \"Legacy model - upgrade to Haiku 4.5 for better performance\",\n },\n },\n {\n provider: \"anthropic\",\n modelId: \"claude-3-haiku-20240307\",\n displayName: \"Claude Haiku 3\",\n contextWindow: 200_000,\n maxOutputTokens: 4_096,\n pricing: {\n input: 0.25,\n output: 1.25,\n cachedInput: 0.025,\n cacheWriteInput: 0.3125,\n },\n knowledgeCutoff: \"2023-08\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n },\n metadata: {\n family: \"Claude 3\",\n releaseDate: \"2024-03-07\",\n notes: \"Legacy model - upgrade to Haiku 4.5 for better performance\",\n },\n },\n // Modern aliases (recommended by Anthropic)\n {\n provider: \"anthropic\",\n modelId: \"claude-haiku-4-5\",\n displayName: \"Claude Haiku 4.5\",\n contextWindow: 200_000,\n maxOutputTokens: 64_000,\n pricing: {\n input: 1.0,\n output: 5.0,\n cachedInput: 0.1,\n cacheWriteInput: 1.25,\n },\n knowledgeCutoff: \"2025-02\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n },\n metadata: {\n family: \"Claude 4\",\n releaseDate: \"2025-10-01\",\n notes: \"Alias for claude-haiku-4-5-20251001. Fastest model with near-frontier intelligence.\",\n },\n },\n {\n provider: \"anthropic\",\n modelId: \"claude-sonnet-4-5\",\n displayName: \"Claude Sonnet 4.5\",\n contextWindow: 200_000,\n maxOutputTokens: 64_000,\n pricing: {\n input: 3.0,\n output: 15.0,\n cachedInput: 0.3,\n cacheWriteInput: 3.75,\n },\n knowledgeCutoff: \"2025-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n },\n metadata: {\n family: \"Claude 4\",\n releaseDate: \"2025-09-29\",\n notes: \"Alias for claude-sonnet-4-5-20250929. Smartest model for complex agents and coding.\",\n },\n },\n {\n provider: \"anthropic\",\n modelId: \"claude-opus-4-5\",\n displayName: \"Claude Opus 4.5\",\n contextWindow: 200_000,\n maxOutputTokens: 64_000,\n pricing: {\n input: 5.0,\n output: 25.0,\n cachedInput: 0.5,\n cacheWriteInput: 6.25,\n },\n knowledgeCutoff: \"2025-03\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n },\n metadata: {\n family: \"Claude 4\",\n releaseDate: \"2025-11-24\",\n notes: \"Alias for claude-opus-4-5-20251124. Most powerful model for coding and computer use.\",\n },\n },\n];\n","/**\n * Base Provider Adapter\n *\n * Abstract base class for provider adapters that implements the Template Method pattern.\n * This class defines the skeleton of the streaming algorithm, leaving provider-specific\n * details to be implemented by concrete subclasses.\n *\n * The streaming workflow consists of four main steps:\n * 1. Prepare messages (optional transformation for provider-specific requirements)\n * 2. Build the request payload (provider-specific formatting)\n * 3. Execute the stream request (call the provider's SDK)\n * 4. Wrap the stream (transform provider-specific chunks into universal format)\n */\n\nimport type { LLMMessage } from \"../core/messages.js\";\nimport type { ModelSpec } from \"../core/model-catalog.js\";\nimport type { LLMGenerationOptions, LLMStream, ModelDescriptor } from \"../core/options.js\";\nimport type { ProviderAdapter } from \"./provider.js\";\n\nexport abstract class BaseProviderAdapter implements ProviderAdapter {\n abstract readonly providerId: string;\n\n constructor(protected readonly client: unknown) {}\n\n abstract supports(descriptor: ModelDescriptor): boolean;\n\n /**\n * Optionally provide model specifications for this provider.\n * This allows the model registry to discover available models and their capabilities.\n */\n getModelSpecs?(): ModelSpec[];\n\n /**\n * Template method that defines the skeleton of the streaming algorithm.\n * This orchestrates the four-step process without dictating provider-specific details.\n */\n async *stream(\n options: LLMGenerationOptions,\n descriptor: ModelDescriptor,\n spec?: ModelSpec,\n ): LLMStream {\n // Step 1: Prepare messages (can be overridden for special cases like Gemini)\n const preparedMessages = this.prepareMessages(options.messages);\n\n // Step 2: Build the provider-specific request payload\n const payload = this.buildRequestPayload(options, descriptor, spec, preparedMessages);\n\n // Step 3: Execute the stream request using the provider's SDK\n const rawStream = await this.executeStreamRequest(payload);\n\n // Step 4: Transform the provider-specific stream into universal format\n yield* this.wrapStream(rawStream);\n }\n\n /**\n * Prepare messages for the request.\n * Default implementation returns messages unchanged.\n * Override this to implement provider-specific message transformations\n * (e.g., Gemini's consecutive message merging, Anthropic's system message extraction).\n *\n * @param messages - The input messages\n * @returns Prepared messages\n */\n protected prepareMessages(messages: LLMMessage[]): LLMMessage[] {\n return messages;\n }\n\n /**\n * Build the provider-specific request payload.\n * This method must be implemented by each concrete provider.\n *\n * @param options - The generation options\n * @param descriptor - The model descriptor\n * @param spec - Optional model specification with metadata\n * @param messages - The prepared messages\n * @returns Provider-specific payload ready for the API call\n */\n protected abstract buildRequestPayload(\n options: LLMGenerationOptions,\n descriptor: ModelDescriptor,\n spec: ModelSpec | undefined,\n messages: LLMMessage[],\n ): unknown;\n\n /**\n * Execute the stream request using the provider's SDK.\n * This method must be implemented by each concrete provider.\n *\n * @param payload - The provider-specific payload\n * @returns An async iterable of provider-specific chunks\n */\n protected abstract executeStreamRequest(payload: unknown): Promise<AsyncIterable<unknown>>;\n\n /**\n * Wrap the provider-specific stream into the universal LLMStream format.\n * This method must be implemented by each concrete provider.\n *\n * @param rawStream - The provider-specific stream\n * @returns Universal LLMStream\n */\n protected abstract wrapStream(rawStream: AsyncIterable<unknown>): LLMStream;\n}\n","/**\n * Provider-specific constants and default values.\n *\n * This file centralizes magic numbers and hardcoded defaults to improve\n * maintainability and documentation. Each constant includes a comment\n * explaining its purpose and rationale.\n */\n\n/**\n * Default maximum output tokens for Anthropic models.\n *\n * Rationale: Most Anthropic models (Claude 3 Opus, Sonnet, Haiku) support\n * at least 4096 output tokens. This is used as a fallback when:\n * - The user doesn't specify maxTokens explicitly\n * - The model spec doesn't define maxOutputTokens\n *\n * Note: Anthropic's API requires the max_tokens parameter, unlike OpenAI\n * which can infer it from the context window. This default ensures the API\n * call succeeds while allowing substantial output.\n *\n * Reference: https://docs.anthropic.com/en/docs/about-claude/models\n */\nexport const ANTHROPIC_DEFAULT_MAX_OUTPUT_TOKENS = 4096;\n\n/**\n * Character-to-token ratio for fallback token estimation.\n *\n * Rationale: When native token counting APIs fail, we estimate tokens using\n * a rough heuristic of 4 characters per token. This is based on empirical\n * observations across multiple LLM providers:\n * - OpenAI's GPT models average ~4 chars/token for English text\n * - Anthropic's Claude models have similar characteristics\n * - Gemini models also approximate this ratio\n *\n * This is intentionally conservative to avoid underestimating token usage.\n * While not perfectly accurate, it provides a reasonable fallback when\n * precise tokenization is unavailable.\n *\n * Reference: https://help.openai.com/en/articles/4936856-what-are-tokens-and-how-to-count-them\n */\nexport const FALLBACK_CHARS_PER_TOKEN = 4;\n\n/**\n * OpenAI message structure overhead in tokens.\n *\n * Rationale: OpenAI's chat completion format adds tokens for message\n * boundaries and structure. Each message follows the pattern:\n * <im_start>{role/name}\\n{content}<im_end>\\n\n *\n * This overhead accounts for:\n * - <im_start> token\n * - Role/name field tokens\n * - Newline and separator tokens\n * - <im_end> token\n *\n * The value of 4 tokens per message is based on OpenAI's official\n * tokenization examples and testing.\n *\n * Reference: https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb\n */\nexport const OPENAI_MESSAGE_OVERHEAD_TOKENS = 4;\n\n/**\n * OpenAI reply priming overhead in tokens.\n *\n * Rationale: Every OpenAI assistant reply is primed with the tokens:\n * <im_start>assistant\\n\n *\n * This adds 2 tokens to the total input token count before the actual\n * response generation begins. This is part of OpenAI's message formatting\n * and must be accounted for in accurate token counting.\n *\n * Reference: https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb\n */\nexport const OPENAI_REPLY_PRIMING_TOKENS = 2;\n\n/**\n * OpenAI name field overhead in tokens.\n *\n * Rationale: When a message includes a \"name\" field (for identifying the\n * speaker in multi-party conversations), OpenAI's format adds 1 extra\n * token beyond the name's actual token count.\n *\n * This accounts for the separator between the role and name fields.\n *\n * Reference: https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb\n */\nexport const OPENAI_NAME_FIELD_OVERHEAD_TOKENS = 1;\n","/**\n * Common utility functions shared across provider implementations\n */\n\n/**\n * Safely read an environment variable\n * @param key - The environment variable key to read\n * @returns The value if found and valid, undefined otherwise\n */\nexport function readEnvVar(key: string): string | undefined {\n if (typeof process === \"undefined\" || typeof process.env === \"undefined\") {\n return undefined;\n }\n const value = process.env[key];\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * Check if a value is a non-empty string\n * @param value - The value to check\n * @returns true if the value is a non-empty string, false otherwise\n */\nexport function isNonEmpty(value: string | undefined): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\n/**\n * Generic factory function for creating provider instances from environment variables\n * @param envVarName - Name of the environment variable containing the API key\n * @param ClientClass - Constructor for the SDK client\n * @param ProviderClass - Constructor for the provider adapter\n * @param clientOptions - Optional additional options to pass to the client constructor\n * @returns Provider instance or null if API key is not set\n */\nexport function createProviderFromEnv<TClient, TProvider>(\n envVarName: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ClientClass: new (config: any) => TClient,\n ProviderClass: new (client: TClient) => TProvider,\n clientOptions?: Record<string, unknown>,\n): TProvider | null {\n const apiKey = readEnvVar(envVarName);\n if (!isNonEmpty(apiKey)) {\n return null;\n }\n\n // Create client with API key and optional config\n const client = new ClientClass({ apiKey: apiKey.trim(), ...clientOptions });\n\n return new ProviderClass(client);\n}\n","import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n MessageCreateParamsStreaming,\n MessageStreamEvent,\n} from \"@anthropic-ai/sdk/resources/messages\";\nimport type { LLMMessage } from \"../core/messages.js\";\nimport type { ModelSpec } from \"../core/model-catalog.js\";\nimport type { LLMGenerationOptions, LLMStream, ModelDescriptor } from \"../core/options.js\";\nimport { ANTHROPIC_MODELS } from \"./anthropic-models.js\";\nimport { BaseProviderAdapter } from \"./base-provider.js\";\nimport { ANTHROPIC_DEFAULT_MAX_OUTPUT_TOKENS, FALLBACK_CHARS_PER_TOKEN } from \"./constants.js\";\nimport { createProviderFromEnv } from \"./utils.js\";\n\nexport class AnthropicMessagesProvider extends BaseProviderAdapter {\n readonly providerId = \"anthropic\" as const;\n\n supports(descriptor: ModelDescriptor): boolean {\n return descriptor.provider === this.providerId;\n }\n\n getModelSpecs() {\n return ANTHROPIC_MODELS;\n }\n\n protected buildRequestPayload(\n options: LLMGenerationOptions,\n descriptor: ModelDescriptor,\n spec: ModelSpec | undefined,\n messages: LLMMessage[],\n ): MessageCreateParamsStreaming {\n const systemMessages = messages.filter((message) => message.role === \"system\");\n\n // System message as array of text blocks with cache_control on last block\n // This enables Anthropic's prompt caching for the system prompt\n const system =\n systemMessages.length > 0\n ? systemMessages.map((m, index) => ({\n type: \"text\" as const,\n text: m.content,\n // Add cache_control to the LAST system message block\n ...(index === systemMessages.length - 1\n ? { cache_control: { type: \"ephemeral\" as const } }\n : {}),\n }))\n : undefined;\n\n const nonSystemMessages = messages.filter(\n (message): message is LLMMessage & { role: \"user\" | \"assistant\" } =>\n message.role !== \"system\",\n );\n\n // Find index of last user message for cache breakpoint\n const lastUserIndex = nonSystemMessages.reduce(\n (lastIdx, msg, idx) => (msg.role === \"user\" ? idx : lastIdx),\n -1,\n );\n\n // Build conversation with cache_control on the last user message\n // This caches the conversation history prefix for multi-turn efficiency\n const conversation = nonSystemMessages.map((message, index) => ({\n role: message.role,\n content: [\n {\n type: \"text\" as const,\n text: message.content,\n // Add cache_control to the LAST user message\n ...(message.role === \"user\" && index === lastUserIndex\n ? { cache_control: { type: \"ephemeral\" as const } }\n : {}),\n },\n ],\n }));\n\n // Anthropic requires max_tokens, so use a smart default if not specified\n // Use model's max from the passed spec, or fall back to the default constant\n const defaultMaxTokens = spec?.maxOutputTokens ?? ANTHROPIC_DEFAULT_MAX_OUTPUT_TOKENS;\n\n const payload: MessageCreateParamsStreaming = {\n model: descriptor.name,\n system,\n messages: conversation,\n max_tokens: options.maxTokens ?? defaultMaxTokens,\n temperature: options.temperature,\n top_p: options.topP,\n stop_sequences: options.stopSequences,\n stream: true,\n ...options.extra,\n };\n\n return payload;\n }\n\n protected async executeStreamRequest(\n payload: MessageCreateParamsStreaming,\n ): Promise<AsyncIterable<MessageStreamEvent>> {\n const client = this.client as Anthropic;\n const stream = await client.messages.create(payload);\n return stream as unknown as AsyncIterable<MessageStreamEvent>;\n }\n\n protected async *wrapStream(iterable: AsyncIterable<unknown>): LLMStream {\n const stream = iterable as AsyncIterable<MessageStreamEvent>;\n let inputTokens = 0;\n let cachedInputTokens = 0;\n let cacheCreationInputTokens = 0;\n\n for await (const event of stream) {\n // Track and yield input tokens from message_start event\n // Anthropic returns cache_read_input_tokens and cache_creation_input_tokens\n if (event.type === \"message_start\") {\n const usage = event.message.usage as {\n input_tokens: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n // Total input tokens includes uncached + cached reads + cache writes\n cachedInputTokens = usage.cache_read_input_tokens ?? 0;\n cacheCreationInputTokens = usage.cache_creation_input_tokens ?? 0;\n inputTokens = usage.input_tokens + cachedInputTokens + cacheCreationInputTokens;\n // Yield early so hooks can access input tokens before text streams\n yield {\n text: \"\",\n usage: {\n inputTokens,\n outputTokens: 0,\n totalTokens: inputTokens,\n cachedInputTokens,\n cacheCreationInputTokens,\n },\n rawEvent: event,\n };\n continue;\n }\n\n if (event.type === \"content_block_delta\" && event.delta.type === \"text_delta\") {\n yield { text: event.delta.text ?? \"\", rawEvent: event };\n continue;\n }\n\n if (event.type === \"message_delta\") {\n const usage = event.usage\n ? {\n inputTokens,\n outputTokens: event.usage.output_tokens,\n totalTokens: inputTokens + event.usage.output_tokens,\n cachedInputTokens,\n cacheCreationInputTokens,\n }\n : undefined;\n\n if (event.delta.stop_reason || usage) {\n yield {\n text: \"\",\n finishReason: event.delta.stop_reason ?? undefined,\n usage,\n rawEvent: event,\n };\n }\n continue;\n }\n\n if (event.type === \"message_stop\") {\n yield { text: \"\", finishReason: \"stop\", rawEvent: event };\n }\n }\n }\n\n /**\n * Count tokens in messages using Anthropic's native token counting API.\n *\n * This method provides accurate token estimation for Anthropic models by:\n * - Using the native messages.countTokens() API\n * - Properly handling system messages and conversation structure\n * - Transforming messages to Anthropic's expected format\n *\n * @param messages - The messages to count tokens for\n * @param descriptor - Model descriptor containing the model name\n * @param _spec - Optional model specification (currently unused)\n * @returns Promise resolving to the estimated input token count\n *\n * @throws Never throws - falls back to character-based estimation (4 chars/token) on error\n *\n * @example\n * ```typescript\n * const count = await provider.countTokens(\n * [{ role: \"user\", content: \"Hello!\" }],\n * { provider: \"anthropic\", name: \"claude-3-5-sonnet-20241022\" }\n * );\n * ```\n */\n async countTokens(\n messages: LLMMessage[],\n descriptor: ModelDescriptor,\n _spec?: ModelSpec,\n ): Promise<number> {\n const client = this.client as Anthropic;\n\n // Extract system messages and conversation messages\n const systemMessages = messages.filter((message) => message.role === \"system\");\n const system =\n systemMessages.length > 0 ? systemMessages.map((m) => m.content).join(\"\\n\\n\") : undefined;\n\n const conversation = messages\n .filter(\n (message): message is LLMMessage & { role: \"user\" | \"assistant\" } =>\n message.role !== \"system\",\n )\n .map((message) => ({\n role: message.role,\n content: [\n {\n type: \"text\" as const,\n text: message.content,\n },\n ],\n }));\n\n try {\n // Use the native token counting API\n const response = await client.messages.countTokens({\n model: descriptor.name,\n messages: conversation,\n ...(system ? { system } : {}),\n });\n\n return response.input_tokens;\n } catch (error) {\n // Log the error for debugging\n console.warn(\n `Token counting failed for ${descriptor.name}, using fallback estimation:`,\n error,\n );\n // Fallback to rough estimation if API fails\n const totalChars = messages.reduce((sum, msg) => sum + (msg.content?.length ?? 0), 0);\n return Math.ceil(totalChars / FALLBACK_CHARS_PER_TOKEN);\n }\n }\n}\n\nexport function createAnthropicProviderFromEnv(): AnthropicMessagesProvider | null {\n return createProviderFromEnv(\"ANTHROPIC_API_KEY\", Anthropic, AnthropicMessagesProvider);\n}\n","/**\n * Google Gemini Model Specifications\n *\n * Model data for Google Gemini models including 3.0, 2.5 and 2.0 series\n * with their specifications, pricing (Standard Paid tier), and capabilities.\n *\n * Pricing source: https://ai.google.dev/gemini-api/docs/pricing\n * Last updated: 2025-11-29\n */\n\nimport type { ModelSpec } from \"../core/model-catalog.js\";\n\nexport const GEMINI_MODELS: ModelSpec[] = [\n // Gemini 3 Pro (Preview)\n {\n provider: \"gemini\",\n modelId: \"gemini-3-pro-preview\",\n displayName: \"Gemini 3 Pro (Preview)\",\n contextWindow: 1_048_576,\n maxOutputTokens: 65_536,\n pricing: {\n input: 2.0, // $2.00 for prompts <= 200k, $4.00 for > 200k (using lower tier)\n output: 12.0, // $12.00 for prompts <= 200k, $18.00 for > 200k\n cachedInput: 0.2, // $0.20 for prompts <= 200k\n },\n knowledgeCutoff: \"2025-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n structuredOutputs: true,\n },\n metadata: {\n family: \"Gemini 3\",\n releaseDate: \"2025-11-18\",\n notes:\n \"Best model for multimodal understanding, agentic and vibe-coding. Deep Think mode available.\",\n },\n },\n\n // Gemini 2.5 Pro\n {\n provider: \"gemini\",\n modelId: \"gemini-2.5-pro\",\n displayName: \"Gemini 2.5 Pro\",\n contextWindow: 1_048_576,\n maxOutputTokens: 65_536,\n pricing: {\n input: 1.25, // $1.25 for prompts <= 200k, $2.50 for > 200k\n output: 10.0, // $10.00 for prompts <= 200k, $15.00 for > 200k\n cachedInput: 0.125, // $0.125 for prompts <= 200k\n },\n knowledgeCutoff: \"2025-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n structuredOutputs: true,\n },\n metadata: {\n family: \"Gemini 2.5\",\n releaseDate: \"2025-06\",\n notes: \"State-of-the-art multipurpose model. Excels at coding and complex reasoning.\",\n },\n },\n\n // Gemini 2.5 Flash\n {\n provider: \"gemini\",\n modelId: \"gemini-2.5-flash\",\n displayName: \"Gemini 2.5 Flash\",\n contextWindow: 1_048_576,\n maxOutputTokens: 65_536,\n pricing: {\n input: 0.3, // $0.30 for text/image/video, $1.00 for audio\n output: 2.5,\n cachedInput: 0.03, // $0.03 for text/image/video\n },\n knowledgeCutoff: \"2025-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n structuredOutputs: true,\n },\n metadata: {\n family: \"Gemini 2.5\",\n releaseDate: \"2025-06\",\n notes: \"First hybrid reasoning model with 1M context and thinking budgets.\",\n },\n },\n\n // Gemini 2.5 Flash-Lite\n {\n provider: \"gemini\",\n modelId: \"gemini-2.5-flash-lite\",\n displayName: \"Gemini 2.5 Flash-Lite\",\n contextWindow: 1_048_576,\n maxOutputTokens: 65_536,\n pricing: {\n input: 0.1, // $0.10 for text/image/video, $0.30 for audio\n output: 0.4,\n cachedInput: 0.01, // $0.01 for text/image/video\n },\n knowledgeCutoff: \"2025-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n structuredOutputs: true,\n },\n metadata: {\n family: \"Gemini 2.5\",\n releaseDate: \"2025-06\",\n notes: \"Smallest and most cost effective model, built for at scale usage.\",\n },\n },\n\n // Gemini 2.0 Flash\n {\n provider: \"gemini\",\n modelId: \"gemini-2.0-flash\",\n displayName: \"Gemini 2.0 Flash\",\n contextWindow: 1_048_576,\n maxOutputTokens: 8_192,\n pricing: {\n input: 0.1, // $0.10 for text/image/video, $0.70 for audio\n output: 0.4,\n cachedInput: 0.025, // $0.025 for text/image/video\n },\n knowledgeCutoff: \"2024-08\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n structuredOutputs: true,\n },\n metadata: {\n family: \"Gemini 2.0\",\n notes: \"Balanced multimodal model with 1M context, built for the era of Agents.\",\n },\n },\n\n // Gemini 2.0 Flash-Lite\n {\n provider: \"gemini\",\n modelId: \"gemini-2.0-flash-lite\",\n displayName: \"Gemini 2.0 Flash-Lite\",\n contextWindow: 1_048_576,\n maxOutputTokens: 8_192,\n pricing: {\n input: 0.075,\n output: 0.3,\n // No context caching available for 2.0-flash-lite\n },\n knowledgeCutoff: \"2024-08\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n structuredOutputs: true,\n },\n metadata: {\n family: \"Gemini 2.0\",\n notes: \"Smallest and most cost effective 2.0 model for at scale usage.\",\n },\n },\n];\n","import { FunctionCallingConfigMode, GoogleGenAI } from \"@google/genai\";\nimport type { LLMMessage } from \"../core/messages.js\";\nimport type { ModelSpec } from \"../core/model-catalog.js\";\nimport type { LLMGenerationOptions, LLMStream, ModelDescriptor } from \"../core/options.js\";\nimport { BaseProviderAdapter } from \"./base-provider.js\";\nimport { FALLBACK_CHARS_PER_TOKEN } from \"./constants.js\";\nimport { GEMINI_MODELS } from \"./gemini-models.js\";\nimport { createProviderFromEnv } from \"./utils.js\";\n\ntype GeminiContent = {\n role: string;\n parts: Array<{ text: string }>;\n};\n\ntype GeminiChunk = {\n text?: () => string;\n candidates?: Array<{\n content?: {\n parts?: Array<{ text?: string }>;\n };\n finishReason?: string;\n }>;\n usageMetadata?: {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n totalTokenCount?: number;\n cachedContentTokenCount?: number;\n };\n};\n\nconst GEMINI_ROLE_MAP: Record<LLMMessage[\"role\"], \"user\" | \"model\"> = {\n system: \"user\",\n user: \"user\",\n assistant: \"model\",\n};\n\nexport class GeminiGenerativeProvider extends BaseProviderAdapter {\n readonly providerId = \"gemini\" as const;\n\n supports(descriptor: ModelDescriptor): boolean {\n return descriptor.provider === this.providerId;\n }\n\n getModelSpecs() {\n return GEMINI_MODELS;\n }\n\n protected buildRequestPayload(\n options: LLMGenerationOptions,\n descriptor: ModelDescriptor,\n _spec: ModelSpec | undefined,\n messages: LLMMessage[],\n ): {\n model: string;\n contents: Array<{ role: string; parts: Array<{ text: string }> }>;\n config: Record<string, unknown>;\n } {\n // Convert messages to Gemini format (system messages become user+model exchanges)\n const contents = this.convertMessagesToContents(messages);\n const generationConfig = this.buildGenerationConfig(options);\n\n // Build the config object for the new SDK\n const config: Record<string, unknown> = {\n // Note: systemInstruction removed - it doesn't work with countTokens()\n // System messages are now included in contents as user+model exchanges\n ...(generationConfig ? { ...generationConfig } : {}),\n // Explicitly disable function calling to prevent UNEXPECTED_TOOL_CALL errors\n toolConfig: {\n functionCallingConfig: {\n mode: FunctionCallingConfigMode.NONE,\n },\n },\n ...options.extra,\n };\n\n return {\n model: descriptor.name,\n contents: this.convertContentsForNewSDK(contents),\n config,\n };\n }\n\n protected async executeStreamRequest(payload: {\n model: string;\n contents: Array<{ role: string; parts: Array<{ text: string }> }>;\n config: Record<string, unknown>;\n }): Promise<AsyncIterable<GeminiChunk>> {\n const client = this.client as GoogleGenAI;\n const streamResponse = await client.models.generateContentStream(payload);\n return streamResponse as unknown as AsyncIterable<GeminiChunk>;\n }\n\n /**\n * Convert LLM messages to Gemini contents format.\n *\n * For Gemini, we convert system messages to user+model exchanges instead of\n * using systemInstruction, because:\n * 1. systemInstruction doesn't work with countTokens() API\n * 2. This approach gives perfect token counting accuracy (0% error)\n * 3. The model receives and follows system instructions identically\n *\n * System message: \"You are a helpful assistant\"\n * Becomes:\n * - User: \"You are a helpful assistant\"\n * - Model: \"Understood.\"\n */\n private convertMessagesToContents(messages: LLMMessage[]): GeminiContent[] {\n const expandedMessages: LLMMessage[] = [];\n\n for (const message of messages) {\n if (message.role === \"system\") {\n // Convert system message to user+model exchange\n expandedMessages.push({\n role: \"user\",\n content: message.content,\n });\n expandedMessages.push({\n role: \"assistant\",\n content: \"Understood.\",\n });\n } else {\n expandedMessages.push(message);\n }\n }\n\n return this.mergeConsecutiveMessages(expandedMessages);\n }\n\n private mergeConsecutiveMessages(messages: LLMMessage[]): GeminiContent[] {\n if (messages.length === 0) {\n return [];\n }\n\n const result: GeminiContent[] = [];\n let currentGroup: GeminiContent | null = null;\n\n for (const message of messages) {\n const geminiRole = GEMINI_ROLE_MAP[message.role];\n\n if (currentGroup && currentGroup.role === geminiRole) {\n // Merge into current group\n currentGroup.parts.push({ text: message.content });\n } else {\n // Start new group\n if (currentGroup) {\n result.push(currentGroup);\n }\n currentGroup = {\n role: geminiRole,\n parts: [{ text: message.content }],\n };\n }\n }\n\n // Push the last group\n if (currentGroup) {\n result.push(currentGroup);\n }\n\n return result;\n }\n\n private convertContentsForNewSDK(\n contents: GeminiContent[],\n ): Array<{ role: string; parts: Array<{ text: string }> }> {\n // The new SDK expects a simpler format for contents\n return contents.map((content) => ({\n role: content.role,\n parts: content.parts.map((part) => ({ text: part.text })),\n }));\n }\n\n private buildGenerationConfig(options: LLMGenerationOptions) {\n const config: Record<string, unknown> = {};\n\n // Only set maxOutputTokens if explicitly provided\n // Otherwise let Gemini use \"as much as fits\" in the context window\n if (typeof options.maxTokens === \"number\") {\n config.maxOutputTokens = options.maxTokens;\n }\n\n if (typeof options.temperature === \"number\") {\n config.temperature = options.temperature;\n }\n if (typeof options.topP === \"number\") {\n config.topP = options.topP;\n }\n if (options.stopSequences?.length) {\n config.stopSequences = options.stopSequences;\n }\n\n return Object.keys(config).length > 0 ? config : null;\n }\n\n protected async *wrapStream(iterable: AsyncIterable<unknown>): LLMStream {\n const stream = iterable as AsyncIterable<GeminiChunk>;\n for await (const chunk of stream) {\n const text = this.extractText(chunk);\n if (text) {\n yield { text, rawEvent: chunk };\n }\n\n const finishReason = this.extractFinishReason(chunk);\n const usage = this.extractUsage(chunk);\n\n if (finishReason || usage) {\n yield { text: \"\", finishReason, usage, rawEvent: chunk };\n }\n }\n }\n\n private extractText(chunk: GeminiChunk): string {\n if (!chunk?.candidates) {\n return \"\";\n }\n\n return chunk.candidates\n .flatMap((candidate) => candidate.content?.parts ?? [])\n .map((part) => part.text ?? \"\")\n .join(\"\");\n }\n\n private extractFinishReason(chunk: GeminiChunk): string | null {\n const candidate = chunk?.candidates?.find((item) => item.finishReason);\n return candidate?.finishReason ?? null;\n }\n\n private extractUsage(\n chunk: GeminiChunk,\n ):\n | { inputTokens: number; outputTokens: number; totalTokens: number; cachedInputTokens?: number }\n | undefined {\n const usageMetadata = chunk?.usageMetadata;\n if (!usageMetadata) {\n return undefined;\n }\n\n return {\n inputTokens: usageMetadata.promptTokenCount ?? 0,\n outputTokens: usageMetadata.candidatesTokenCount ?? 0,\n totalTokens: usageMetadata.totalTokenCount ?? 0,\n // Gemini returns cached token count in cachedContentTokenCount\n cachedInputTokens: usageMetadata.cachedContentTokenCount ?? 0,\n };\n }\n\n /**\n * Count tokens in messages using Gemini's native token counting API.\n *\n * This method provides accurate token estimation for Gemini models by:\n * - Using the SDK's countTokens() method\n * - Converting system messages to user+model exchanges (same as in generation)\n * - This gives perfect token counting accuracy (0% error vs actual usage)\n *\n * @param messages - The messages to count tokens for\n * @param descriptor - Model descriptor containing the model name\n * @param _spec - Optional model specification (currently unused)\n * @returns Promise resolving to the estimated input token count\n *\n * @throws Never throws - falls back to character-based estimation (4 chars/token) on error\n *\n * @example\n * ```typescript\n * const count = await provider.countTokens(\n * [{ role: \"user\", content: \"Hello!\" }],\n * { provider: \"gemini\", name: \"gemini-1.5-pro\" }\n * );\n * ```\n */\n async countTokens(\n messages: LLMMessage[],\n descriptor: ModelDescriptor,\n _spec?: ModelSpec,\n ): Promise<number> {\n const client = this.client as GoogleGenAI;\n\n // Convert messages to Gemini format (same as buildRequestPayload)\n const contents = this.convertMessagesToContents(messages);\n\n try {\n // Use Gemini's count_tokens method\n const response = await client.models.countTokens({\n model: descriptor.name,\n contents: this.convertContentsForNewSDK(contents),\n // Note: systemInstruction not used - it's not supported by countTokens()\n // and would cause a 2100% token counting error\n });\n return response.totalTokens ?? 0;\n } catch (error) {\n // Log the error for debugging\n console.warn(\n `Token counting failed for ${descriptor.name}, using fallback estimation:`,\n error,\n );\n // Fallback to rough estimation if API fails\n const totalChars = messages.reduce((sum, msg) => sum + (msg.content?.length ?? 0), 0);\n return Math.ceil(totalChars / FALLBACK_CHARS_PER_TOKEN);\n }\n }\n}\n\nexport function createGeminiProviderFromEnv(): GeminiGenerativeProvider | null {\n return createProviderFromEnv(\"GEMINI_API_KEY\", GoogleGenAI, GeminiGenerativeProvider);\n}\n","/**\n * OpenAI Model Specifications\n *\n * Model data for OpenAI models including GPT-5, GPT-4.1, GPT-4o, and o-series\n * with their specifications, pricing (Standard tier), and capabilities.\n *\n * Pricing source: https://openai.com/api/pricing (Standard tier)\n * Last updated: 2025-11-29\n */\n\nimport type { ModelSpec } from \"../core/model-catalog.js\";\n\nexport const OPENAI_MODELS: ModelSpec[] = [\n // GPT-5 Family\n {\n provider: \"openai\",\n modelId: \"gpt-5.1\",\n displayName: \"GPT-5.1\",\n contextWindow: 128_000,\n maxOutputTokens: 32_768,\n pricing: {\n input: 1.25,\n output: 10.0,\n cachedInput: 0.125,\n },\n knowledgeCutoff: \"2024-09-30\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n structuredOutputs: true,\n fineTuning: true,\n },\n metadata: {\n family: \"GPT-5\",\n releaseDate: \"2025-11-12\",\n notes: \"Latest GPT-5 with improved instruction following. 2-3x faster than GPT-5.\",\n supportsTemperature: false,\n },\n },\n {\n provider: \"openai\",\n modelId: \"gpt-5\",\n displayName: \"GPT-5\",\n contextWindow: 272_000,\n maxOutputTokens: 128_000,\n pricing: {\n input: 1.25,\n output: 10.0,\n cachedInput: 0.125,\n },\n knowledgeCutoff: \"2024-09-30\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n structuredOutputs: true,\n fineTuning: true,\n },\n metadata: {\n family: \"GPT-5\",\n releaseDate: \"2025-08-07\",\n notes: \"Best model for coding and agentic tasks. Adaptive reasoning with 90% caching discount.\",\n supportsTemperature: false,\n },\n },\n {\n provider: \"openai\",\n modelId: \"gpt-5-mini\",\n displayName: \"GPT-5 Mini\",\n contextWindow: 272_000,\n maxOutputTokens: 32_768,\n pricing: {\n input: 0.25,\n output: 2.0,\n cachedInput: 0.025,\n },\n knowledgeCutoff: \"2024-06-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n structuredOutputs: true,\n fineTuning: true,\n },\n metadata: {\n family: \"GPT-5\",\n notes: \"Fast and cost-efficient with adaptive reasoning\",\n supportsTemperature: false,\n },\n },\n {\n provider: \"openai\",\n modelId: \"gpt-5-nano\",\n displayName: \"GPT-5 Nano\",\n contextWindow: 272_000,\n maxOutputTokens: 32_768,\n pricing: {\n input: 0.05,\n output: 0.4,\n cachedInput: 0.005,\n },\n knowledgeCutoff: \"2024-05-31\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n structuredOutputs: true,\n fineTuning: true,\n },\n metadata: {\n family: \"GPT-5\",\n notes: \"Fastest, most cost-efficient version for well-defined tasks\",\n supportsTemperature: false,\n },\n },\n {\n provider: \"openai\",\n modelId: \"gpt-5-pro\",\n displayName: \"GPT-5 Pro\",\n contextWindow: 272_000,\n maxOutputTokens: 128_000,\n pricing: {\n input: 15.0,\n output: 120.0,\n // No cached input pricing for gpt-5-pro\n },\n knowledgeCutoff: \"2024-09-30\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n structuredOutputs: true,\n },\n metadata: {\n family: \"GPT-5\",\n notes: \"Premium tier with enhanced capabilities. Does not support prompt caching.\",\n supportsTemperature: false,\n },\n },\n\n // GPT-4.1 Family\n {\n provider: \"openai\",\n modelId: \"gpt-4.1\",\n displayName: \"GPT-4.1\",\n contextWindow: 128_000,\n maxOutputTokens: 32_768,\n pricing: {\n input: 2.0,\n output: 8.0,\n cachedInput: 0.5,\n },\n knowledgeCutoff: \"2024-04-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n structuredOutputs: true,\n fineTuning: true,\n },\n metadata: {\n family: \"GPT-4.1\",\n notes: \"Improved GPT-4 with better instruction following\",\n },\n },\n {\n provider: \"openai\",\n modelId: \"gpt-4.1-mini\",\n displayName: \"GPT-4.1 Mini\",\n contextWindow: 128_000,\n maxOutputTokens: 32_768,\n pricing: {\n input: 0.4,\n output: 1.6,\n cachedInput: 0.1,\n },\n knowledgeCutoff: \"2024-04-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n structuredOutputs: true,\n fineTuning: true,\n },\n metadata: {\n family: \"GPT-4.1\",\n notes: \"Cost-efficient GPT-4.1 variant\",\n },\n },\n {\n provider: \"openai\",\n modelId: \"gpt-4.1-nano\",\n displayName: \"GPT-4.1 Nano\",\n contextWindow: 128_000,\n maxOutputTokens: 32_768,\n pricing: {\n input: 0.1,\n output: 0.4,\n cachedInput: 0.025,\n },\n knowledgeCutoff: \"2024-04-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n structuredOutputs: true,\n fineTuning: true,\n },\n metadata: {\n family: \"GPT-4.1\",\n notes: \"Fastest GPT-4.1 variant for simple tasks\",\n },\n },\n\n // GPT-4o Family\n {\n provider: \"openai\",\n modelId: \"gpt-4o\",\n displayName: \"GPT-4o\",\n contextWindow: 128_000,\n maxOutputTokens: 16_384,\n pricing: {\n input: 2.5,\n output: 10.0,\n cachedInput: 1.25,\n },\n knowledgeCutoff: \"2024-04-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n structuredOutputs: true,\n fineTuning: true,\n },\n metadata: {\n family: \"GPT-4o\",\n notes: \"Multimodal model optimized for speed\",\n },\n },\n {\n provider: \"openai\",\n modelId: \"gpt-4o-mini\",\n displayName: \"GPT-4o Mini\",\n contextWindow: 128_000,\n maxOutputTokens: 16_384,\n pricing: {\n input: 0.15,\n output: 0.6,\n cachedInput: 0.075,\n },\n knowledgeCutoff: \"2024-04-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n structuredOutputs: true,\n fineTuning: true,\n },\n metadata: {\n family: \"GPT-4o\",\n notes: \"Fast and affordable multimodal model\",\n },\n },\n\n // o-series (Reasoning models)\n {\n provider: \"openai\",\n modelId: \"o1\",\n displayName: \"o1\",\n contextWindow: 200_000,\n maxOutputTokens: 100_000,\n pricing: {\n input: 15.0,\n output: 60.0,\n cachedInput: 7.5,\n },\n knowledgeCutoff: \"2024-12-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n structuredOutputs: true,\n },\n metadata: {\n family: \"o-series\",\n notes: \"Advanced reasoning model with chain-of-thought\",\n supportsTemperature: false,\n },\n },\n {\n provider: \"openai\",\n modelId: \"o3\",\n displayName: \"o3\",\n contextWindow: 200_000,\n maxOutputTokens: 100_000,\n pricing: {\n input: 2.0,\n output: 8.0,\n cachedInput: 0.5,\n },\n knowledgeCutoff: \"2025-01-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n structuredOutputs: true,\n },\n metadata: {\n family: \"o-series\",\n notes: \"Next-gen reasoning model, more efficient than o1\",\n supportsTemperature: false,\n },\n },\n {\n provider: \"openai\",\n modelId: \"o4-mini\",\n displayName: \"o4 Mini\",\n contextWindow: 200_000,\n maxOutputTokens: 100_000,\n pricing: {\n input: 1.1,\n output: 4.4,\n cachedInput: 0.275,\n },\n knowledgeCutoff: \"2025-04-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n structuredOutputs: true,\n fineTuning: true,\n },\n metadata: {\n family: \"o-series\",\n notes: \"Cost-efficient reasoning model\",\n supportsTemperature: false,\n },\n },\n {\n provider: \"openai\",\n modelId: \"o3-mini\",\n displayName: \"o3 Mini\",\n contextWindow: 200_000,\n maxOutputTokens: 100_000,\n pricing: {\n input: 1.1,\n output: 4.4,\n cachedInput: 0.55,\n },\n knowledgeCutoff: \"2025-01-01\",\n features: {\n streaming: true,\n functionCalling: true,\n vision: true,\n reasoning: true,\n structuredOutputs: true,\n },\n metadata: {\n family: \"o-series\",\n notes: \"Compact reasoning model for cost-sensitive applications\",\n supportsTemperature: false,\n },\n },\n];\n","import OpenAI from \"openai\";\nimport type { ChatCompletionChunk } from \"openai/resources/chat/completions\";\nimport { encoding_for_model, type TiktokenModel } from \"tiktoken\";\nimport type { LLMMessage } from \"../core/messages.js\";\nimport type { ModelSpec } from \"../core/model-catalog.js\";\nimport type { LLMGenerationOptions, LLMStream, ModelDescriptor } from \"../core/options.js\";\nimport { BaseProviderAdapter } from \"./base-provider.js\";\nimport {\n FALLBACK_CHARS_PER_TOKEN,\n OPENAI_MESSAGE_OVERHEAD_TOKENS,\n OPENAI_NAME_FIELD_OVERHEAD_TOKENS,\n OPENAI_REPLY_PRIMING_TOKENS,\n} from \"./constants.js\";\nimport { OPENAI_MODELS } from \"./openai-models.js\";\nimport { createProviderFromEnv } from \"./utils.js\";\n\nconst ROLE_MAP: Record<LLMMessage[\"role\"], \"system\" | \"user\" | \"assistant\"> = {\n system: \"system\",\n user: \"user\",\n assistant: \"assistant\",\n};\n\n// Note: Temperature support is now determined from the ModelSpec passed to stream()\n// instead of being hardcoded at module level\n\nfunction sanitizeExtra(\n extra: Record<string, unknown> | undefined,\n allowTemperature: boolean,\n): Record<string, unknown> | undefined {\n if (!extra) {\n return undefined;\n }\n\n if (allowTemperature || !Object.hasOwn(extra, \"temperature\")) {\n return extra;\n }\n\n return Object.fromEntries(Object.entries(extra).filter(([key]) => key !== \"temperature\"));\n}\n\nexport class OpenAIChatProvider extends BaseProviderAdapter {\n readonly providerId = \"openai\" as const;\n\n supports(descriptor: ModelDescriptor): boolean {\n return descriptor.provider === this.providerId;\n }\n\n getModelSpecs() {\n return OPENAI_MODELS;\n }\n\n protected buildRequestPayload(\n options: LLMGenerationOptions,\n descriptor: ModelDescriptor,\n spec: ModelSpec | undefined,\n messages: LLMMessage[],\n ): Parameters<OpenAI[\"chat\"][\"completions\"][\"create\"]>[0] {\n const { maxTokens, temperature, topP, stopSequences, extra } = options;\n\n // Use spec metadata to determine temperature support, defaulting to true if spec is unavailable\n const supportsTemperature = spec?.metadata?.supportsTemperature !== false;\n const shouldIncludeTemperature = typeof temperature === \"number\" && supportsTemperature;\n const sanitizedExtra = sanitizeExtra(extra, shouldIncludeTemperature);\n\n return {\n model: descriptor.name,\n messages: messages.map((message) => ({\n role: ROLE_MAP[message.role],\n content: message.content,\n name: message.name,\n })),\n // Only set max_completion_tokens if explicitly provided\n // Otherwise let the API use \"as much as fits\" in the context window\n ...(maxTokens !== undefined ? { max_completion_tokens: maxTokens } : {}),\n top_p: topP,\n stop: stopSequences,\n stream: true,\n stream_options: { include_usage: true },\n ...(sanitizedExtra ?? {}),\n ...(shouldIncludeTemperature ? { temperature } : {}),\n };\n }\n\n protected async executeStreamRequest(\n payload: Parameters<OpenAI[\"chat\"][\"completions\"][\"create\"]>[0],\n ): Promise<AsyncIterable<ChatCompletionChunk>> {\n const client = this.client as OpenAI;\n const stream = await client.chat.completions.create(payload);\n return stream as unknown as AsyncIterable<ChatCompletionChunk>;\n }\n\n protected async *wrapStream(iterable: AsyncIterable<unknown>): LLMStream {\n const stream = iterable as AsyncIterable<ChatCompletionChunk>;\n for await (const chunk of stream) {\n const text = chunk.choices.map((choice) => choice.delta?.content ?? \"\").join(\"\");\n if (text) {\n yield { text, rawEvent: chunk };\n }\n\n const finishReason = chunk.choices.find((choice) => choice.finish_reason)?.finish_reason;\n\n // Extract token usage if available (typically in the final chunk)\n // OpenAI returns cached token count in prompt_tokens_details.cached_tokens\n const usage = chunk.usage\n ? {\n inputTokens: chunk.usage.prompt_tokens,\n outputTokens: chunk.usage.completion_tokens,\n totalTokens: chunk.usage.total_tokens,\n cachedInputTokens:\n (chunk.usage as { prompt_tokens_details?: { cached_tokens?: number } })\n .prompt_tokens_details?.cached_tokens ?? 0,\n }\n : undefined;\n\n if (finishReason || usage) {\n yield { text: \"\", finishReason, usage, rawEvent: chunk };\n }\n }\n }\n\n /**\n * Count tokens in messages using OpenAI's tiktoken library.\n *\n * This method provides accurate token estimation for OpenAI models by:\n * - Using the model-specific tokenizer encoding\n * - Accounting for message formatting overhead\n * - Falling back to gpt-4o encoding for unknown models\n *\n * @param messages - The messages to count tokens for\n * @param descriptor - Model descriptor containing the model name\n * @param _spec - Optional model specification (currently unused)\n * @returns Promise resolving to the estimated input token count\n *\n * @throws Never throws - falls back to character-based estimation (4 chars/token) on error\n *\n * @example\n * ```typescript\n * const count = await provider.countTokens(\n * [{ role: \"user\", content: \"Hello!\" }],\n * { provider: \"openai\", name: \"gpt-4\" }\n * );\n * ```\n */\n async countTokens(\n messages: LLMMessage[],\n descriptor: ModelDescriptor,\n _spec?: ModelSpec,\n ): Promise<number> {\n try {\n // Map model names to tiktoken models\n // For models not directly supported, use a reasonable default\n const modelName = descriptor.name as TiktokenModel;\n let encoding;\n\n try {\n encoding = encoding_for_model(modelName);\n } catch {\n // If the specific model isn't supported, fall back to gpt-4o which uses cl100k_base\n encoding = encoding_for_model(\"gpt-4o\");\n }\n\n try {\n let tokenCount = 0;\n\n // Count tokens per message with proper formatting\n // OpenAI's format adds tokens for message boundaries and roles\n // Token overhead based on OpenAI's message formatting\n // See: https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb\n for (const message of messages) {\n // Every message follows <im_start>{role/name}\\n{content}<im_end>\\n\n tokenCount += OPENAI_MESSAGE_OVERHEAD_TOKENS;\n\n const roleText = ROLE_MAP[message.role];\n tokenCount += encoding.encode(roleText).length;\n tokenCount += encoding.encode(message.content ?? \"\").length;\n\n if (message.name) {\n tokenCount += encoding.encode(message.name).length;\n tokenCount += OPENAI_NAME_FIELD_OVERHEAD_TOKENS;\n }\n }\n\n tokenCount += OPENAI_REPLY_PRIMING_TOKENS;\n\n return tokenCount;\n } finally {\n // Always free the encoding to prevent memory leaks\n encoding.free();\n }\n } catch (error) {\n // Log the error for debugging\n console.warn(\n `Token counting failed for ${descriptor.name}, using fallback estimation:`,\n error,\n );\n // If tiktoken fails, provide a rough estimate\n const totalChars = messages.reduce((sum, msg) => sum + (msg.content?.length ?? 0), 0);\n return Math.ceil(totalChars / FALLBACK_CHARS_PER_TOKEN);\n }\n }\n}\n\nexport function createOpenAIProviderFromEnv(): OpenAIChatProvider | null {\n return createProviderFromEnv(\"OPENAI_API_KEY\", OpenAI, OpenAIChatProvider);\n}\n","import { createAnthropicProviderFromEnv } from \"./anthropic.js\";\nimport { createGeminiProviderFromEnv } from \"./gemini.js\";\nimport { createOpenAIProviderFromEnv } from \"./openai.js\";\nimport type { ProviderAdapter } from \"./provider.js\";\n\nexport type ProviderDiscoverer = () => ProviderAdapter | null | undefined;\n\nconst DISCOVERERS: ProviderDiscoverer[] = [\n createOpenAIProviderFromEnv,\n createAnthropicProviderFromEnv,\n createGeminiProviderFromEnv,\n];\n\nexport function discoverProviderAdapters(): ProviderAdapter[] {\n const adapters: ProviderAdapter[] = [];\n\n for (const discover of DISCOVERERS) {\n const adapter = discover();\n if (adapter) {\n adapters.push(adapter);\n }\n }\n\n return adapters;\n}\n","/**\n * Model Registry\n *\n * Centralized registry for querying LLM model specifications,\n * validating configurations, and estimating costs.\n *\n * Model data is provided by ProviderAdapter implementations and\n * automatically populated when providers are registered.\n */\n\nimport type { ProviderAdapter } from \"../providers/provider.js\";\nimport type { CostEstimate, ModelLimits, ModelSpec } from \"./model-catalog.js\";\n\nexport class ModelRegistry {\n private modelSpecs: ModelSpec[] = [];\n private providerMap = new Map<string, ModelSpec[]>();\n\n /**\n * Register a provider and collect its model specifications\n */\n registerProvider(provider: ProviderAdapter): void {\n const specs = provider.getModelSpecs?.() ?? [];\n\n if (specs.length > 0) {\n this.modelSpecs.push(...specs);\n this.providerMap.set(provider.providerId, specs);\n }\n }\n\n /**\n * Register a custom model specification at runtime\n *\n * Use this to add models that aren't in the built-in catalog, such as:\n * - Fine-tuned models with custom pricing\n * - New models not yet supported by llmist\n * - Custom deployments with different configurations\n *\n * @param spec - Complete model specification\n * @throws {Error} If spec is missing required fields\n *\n * @example\n * ```ts\n * client.modelRegistry.registerModel({\n * provider: \"openai\",\n * modelId: \"ft:gpt-4o-2024-08-06:my-org:custom:abc123\",\n * displayName: \"My Fine-tuned GPT-4o\",\n * contextWindow: 128_000,\n * maxOutputTokens: 16_384,\n * pricing: { input: 7.5, output: 30.0 },\n * knowledgeCutoff: \"2024-08\",\n * features: { streaming: true, functionCalling: true, vision: true }\n * });\n * ```\n */\n registerModel(spec: ModelSpec): void {\n // Validate required fields\n if (!spec.modelId || !spec.provider) {\n throw new Error(\"ModelSpec must have modelId and provider\");\n }\n\n // Check for duplicates\n const existing = this.getModelSpec(spec.modelId);\n if (existing) {\n console.warn(\n `[llmist] Overwriting existing model spec for \"${spec.modelId}\". ` +\n `Previous: ${existing.displayName}, New: ${spec.displayName}`,\n );\n // Remove old spec from arrays\n const index = this.modelSpecs.findIndex((m) => m.modelId === spec.modelId);\n if (index !== -1) {\n this.modelSpecs.splice(index, 1);\n }\n // Remove from provider map\n const providerSpecs = this.providerMap.get(spec.provider);\n if (providerSpecs) {\n const providerIndex = providerSpecs.findIndex((m) => m.modelId === spec.modelId);\n if (providerIndex !== -1) {\n providerSpecs.splice(providerIndex, 1);\n }\n }\n }\n\n // Add to registry\n this.modelSpecs.push(spec);\n\n // Update provider map\n const providerSpecs = this.providerMap.get(spec.provider) ?? [];\n providerSpecs.push(spec);\n this.providerMap.set(spec.provider, providerSpecs);\n }\n\n /**\n * Register multiple custom model specifications at once\n *\n * @param specs - Array of complete model specifications\n *\n * @example\n * ```ts\n * client.modelRegistry.registerModels([\n * { provider: \"openai\", modelId: \"gpt-5\", ... },\n * { provider: \"openai\", modelId: \"gpt-5-mini\", ... }\n * ]);\n * ```\n */\n registerModels(specs: ModelSpec[]): void {\n for (const spec of specs) {\n this.registerModel(spec);\n }\n }\n\n /**\n * Get model specification by model ID\n * @param modelId - Full model identifier (e.g., 'gpt-5', 'claude-sonnet-4-5-20250929')\n * @returns ModelSpec if found, undefined otherwise\n */\n getModelSpec(modelId: string): ModelSpec | undefined {\n return this.modelSpecs.find((model) => model.modelId === modelId);\n }\n\n /**\n * List all models, optionally filtered by provider\n * @param providerId - Optional provider ID to filter by (e.g., 'openai', 'anthropic')\n * @returns Array of ModelSpec objects\n */\n listModels(providerId?: string): ModelSpec[] {\n if (!providerId) {\n return [...this.modelSpecs];\n }\n\n return this.providerMap.get(providerId) ?? [];\n }\n\n /**\n * Get context window and output limits for a model\n * @param modelId - Full model identifier\n * @returns ModelLimits if model found, undefined otherwise\n */\n getModelLimits(modelId: string): ModelLimits | undefined {\n const spec = this.getModelSpec(modelId);\n if (!spec) return undefined;\n\n return {\n contextWindow: spec.contextWindow,\n maxOutputTokens: spec.maxOutputTokens,\n };\n }\n\n /**\n * Estimate API cost for a given model and token usage\n * @param modelId - Full model identifier\n * @param inputTokens - Number of input tokens (total, including cached and cache creation)\n * @param outputTokens - Number of output tokens\n * @param cachedInputTokens - Number of cached input tokens (subset of inputTokens)\n * @param cacheCreationInputTokens - Number of cache creation tokens (subset of inputTokens, Anthropic only)\n * @returns CostEstimate if model found, undefined otherwise\n */\n estimateCost(\n modelId: string,\n inputTokens: number,\n outputTokens: number,\n cachedInputTokens = 0,\n cacheCreationInputTokens = 0,\n ): CostEstimate | undefined {\n const spec = this.getModelSpec(modelId);\n if (!spec) return undefined;\n\n // Pricing is per 1M tokens, so convert to actual cost\n // Cached tokens are charged at a lower rate (or same rate if no cached pricing)\n // Cache creation tokens are charged at a higher rate (Anthropic: 1.25x input)\n const cachedRate = spec.pricing.cachedInput ?? spec.pricing.input;\n const cacheWriteRate = spec.pricing.cacheWriteInput ?? spec.pricing.input;\n const uncachedInputTokens = inputTokens - cachedInputTokens - cacheCreationInputTokens;\n\n const uncachedInputCost = (uncachedInputTokens / 1_000_000) * spec.pricing.input;\n const cachedInputCost = (cachedInputTokens / 1_000_000) * cachedRate;\n const cacheCreationCost = (cacheCreationInputTokens / 1_000_000) * cacheWriteRate;\n const inputCost = uncachedInputCost + cachedInputCost + cacheCreationCost;\n const outputCost = (outputTokens / 1_000_000) * spec.pricing.output;\n const totalCost = inputCost + outputCost;\n\n return {\n inputCost,\n cachedInputCost,\n cacheCreationCost,\n outputCost,\n totalCost,\n currency: \"USD\",\n };\n }\n\n /**\n * Validate that requested token count fits within model limits\n * @param modelId - Full model identifier\n * @param requestedTokens - Total tokens requested (input + output)\n * @returns true if valid, false if model not found or exceeds limits\n */\n validateModelConfig(modelId: string, requestedTokens: number): boolean {\n const limits = this.getModelLimits(modelId);\n if (!limits) return false;\n\n return requestedTokens <= limits.contextWindow;\n }\n\n /**\n * Check if a model supports a specific feature\n * @param modelId - Full model identifier\n * @param feature - Feature to check ('streaming', 'functionCalling', 'vision', etc.)\n * @returns true if model supports feature, false otherwise\n */\n supportsFeature(modelId: string, feature: keyof ModelSpec[\"features\"]): boolean {\n const spec = this.getModelSpec(modelId);\n if (!spec) return false;\n\n return spec.features[feature] === true;\n }\n\n /**\n * Get all models that support a specific feature\n * @param feature - Feature to filter by\n * @param providerId - Optional provider ID to filter by\n * @returns Array of ModelSpec objects that support the feature\n */\n getModelsByFeature(feature: keyof ModelSpec[\"features\"], providerId?: string): ModelSpec[] {\n const models = this.listModels(providerId);\n return models.filter((model) => model.features[feature] === true);\n }\n\n /**\n * Get the most cost-effective model for a given provider and token budget\n * @param inputTokens - Expected input tokens\n * @param outputTokens - Expected output tokens\n * @param providerId - Optional provider ID to filter by\n * @returns ModelSpec with lowest total cost, or undefined if no models found\n */\n getCheapestModel(\n inputTokens: number,\n outputTokens: number,\n providerId?: string,\n ): ModelSpec | undefined {\n const models = this.listModels(providerId);\n if (models.length === 0) return undefined;\n\n let cheapest: { model: ModelSpec; cost: number } | undefined;\n\n for (const model of models) {\n const estimate = this.estimateCost(model.modelId, inputTokens, outputTokens);\n if (!estimate) continue;\n\n if (!cheapest || estimate.totalCost < cheapest.cost) {\n cheapest = { model, cost: estimate.totalCost };\n }\n }\n\n return cheapest?.model;\n }\n}\n","import type { LLMMessage } from \"./messages.js\";\n\nexport interface LLMGenerationOptions {\n model: string;\n messages: LLMMessage[];\n maxTokens?: number;\n temperature?: number;\n topP?: number;\n stopSequences?: string[];\n responseFormat?: \"text\";\n metadata?: Record<string, unknown>;\n extra?: Record<string, unknown>;\n}\n\nexport interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n /** Number of input tokens served from cache (subset of inputTokens) */\n cachedInputTokens?: number;\n /** Number of input tokens written to cache (subset of inputTokens, Anthropic only) */\n cacheCreationInputTokens?: number;\n}\n\nexport interface LLMStreamChunk {\n text: string;\n /**\n * Indicates that the provider has finished producing output and includes the reason if available.\n */\n finishReason?: string | null;\n /**\n * Token usage information, typically available in the final chunk when the stream completes.\n */\n usage?: TokenUsage;\n /**\n * Provider specific payload emitted at the same time as the text chunk. This is useful for debugging and tests.\n */\n rawEvent?: unknown;\n}\n\nexport interface LLMStream extends AsyncIterable<LLMStreamChunk> {}\n\nexport type ProviderIdentifier = string;\n\nexport interface ModelDescriptor {\n provider: string;\n name: string;\n}\n\nexport class ModelIdentifierParser {\n constructor(private readonly defaultProvider: string = \"openai\") {}\n\n parse(identifier: string): ModelDescriptor {\n const trimmed = identifier.trim();\n if (!trimmed) {\n throw new Error(\"Model identifier cannot be empty\");\n }\n\n const [maybeProvider, ...rest] = trimmed.split(\":\");\n if (rest.length === 0) {\n return { provider: this.defaultProvider, name: maybeProvider };\n }\n\n const provider = maybeProvider;\n const name = rest.join(\":\");\n if (!name) {\n throw new Error(\"Model name cannot be empty\");\n }\n\n return { provider, name };\n }\n}\n","/**\n * Quick execution methods for simple use cases.\n *\n * These methods provide convenient shortcuts for common operations\n * without requiring full agent setup.\n *\n * @example\n * ```typescript\n * // Quick completion\n * const answer = await llmist.complete(\"What is 2+2?\");\n *\n * // Quick streaming\n * for await (const chunk of llmist.stream(\"Tell me a story\")) {\n * process.stdout.write(chunk);\n * }\n * ```\n */\n\nimport type { LLMist } from \"./client.js\";\nimport { LLMMessageBuilder } from \"./messages.js\";\nimport { resolveModel } from \"./model-shortcuts.js\";\n\n/**\n * Options for quick execution methods.\n */\nexport interface QuickOptions {\n /** Model to use (supports aliases like \"gpt4\", \"sonnet\", \"flash\") */\n model?: string;\n\n /** Temperature (0-1) */\n temperature?: number;\n\n /** System prompt */\n systemPrompt?: string;\n\n /** Max tokens to generate */\n maxTokens?: number;\n}\n\n/**\n * Quick completion - returns final text response.\n *\n * @param client - LLMist client instance\n * @param prompt - User prompt\n * @param options - Optional configuration\n * @returns Complete text response\n *\n * @example\n * ```typescript\n * const client = new LLMist();\n * const answer = await complete(client, \"What is 2+2?\");\n * console.log(answer); // \"4\" or \"2+2 equals 4\"\n * ```\n */\nexport async function complete(\n client: LLMist,\n prompt: string,\n options: QuickOptions = {},\n): Promise<string> {\n const model = resolveModel(options.model ?? \"gpt-5-nano\");\n\n const builder = new LLMMessageBuilder();\n if (options.systemPrompt) {\n builder.addSystem(options.systemPrompt);\n }\n builder.addUser(prompt);\n\n let fullResponse = \"\";\n for await (const chunk of client.stream({\n model,\n messages: builder.build(),\n temperature: options.temperature,\n maxTokens: options.maxTokens,\n })) {\n fullResponse += chunk.text;\n }\n\n return fullResponse.trim();\n}\n\n/**\n * Quick streaming - returns async generator of text chunks.\n *\n * @param client - LLMist client instance\n * @param prompt - User prompt\n * @param options - Optional configuration\n * @returns Async generator yielding text chunks\n *\n * @example\n * ```typescript\n * const client = new LLMist();\n *\n * for await (const chunk of stream(client, \"Tell me a story\")) {\n * process.stdout.write(chunk);\n * }\n * ```\n */\nexport async function* stream(\n client: LLMist,\n prompt: string,\n options: QuickOptions = {},\n): AsyncGenerator<string> {\n const model = resolveModel(options.model ?? \"gpt-5-nano\");\n\n const builder = new LLMMessageBuilder();\n if (options.systemPrompt) {\n builder.addSystem(options.systemPrompt);\n }\n builder.addUser(prompt);\n\n for await (const chunk of client.stream({\n model,\n messages: builder.build(),\n temperature: options.temperature,\n maxTokens: options.maxTokens,\n })) {\n yield chunk.text;\n }\n}\n","/**\n * Internal key for Agent instantiation.\n * This Symbol is used to ensure only AgentBuilder can create Agent instances.\n *\n * @internal\n */\nexport const AGENT_INTERNAL_KEY = Symbol(\"AGENT_INTERNAL_KEY\");\n\n/**\n * Type guard to check if the key is the correct internal key\n * @internal\n */\nexport function isValidAgentKey(key: unknown): key is typeof AGENT_INTERNAL_KEY {\n return key === AGENT_INTERNAL_KEY;\n}\n","/**\n * Agent: Lean orchestrator using the clean hooks architecture.\n *\n * The Agent delegates ALL stream processing and hook coordination to StreamProcessor,\n * making it a simple loop orchestrator with clear responsibilities.\n */\n\nimport type { ILogObj, Logger } from \"tslog\";\nimport type { LLMist } from \"../core/client.js\";\nimport {\n CHARS_PER_TOKEN,\n DEFAULT_GADGET_OUTPUT_LIMIT,\n DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT,\n FALLBACK_CONTEXT_WINDOW,\n} from \"../core/constants.js\";\nimport { LLMMessageBuilder } from \"../core/messages.js\";\nimport { resolveModel } from \"../core/model-shortcuts.js\";\nimport type { LLMGenerationOptions } from \"../core/options.js\";\nimport type { PromptConfig } from \"../core/prompt-config.js\";\nimport type { GadgetRegistry } from \"../gadgets/registry.js\";\nimport type { StreamEvent, TextOnlyHandler } from \"../gadgets/types.js\";\nimport { createGadgetOutputViewer } from \"../gadgets/output-viewer.js\";\nimport { createLogger } from \"../logging/logger.js\";\nimport { GadgetOutputStore } from \"./gadget-output-store.js\";\nimport type { GadgetResultInterceptorContext } from \"./hooks.js\";\nimport { type AGENT_INTERNAL_KEY, isValidAgentKey } from \"./agent-internal-key.js\";\nimport { ConversationManager } from \"./conversation-manager.js\";\nimport { type EventHandlers, runWithHandlers } from \"./event-handlers.js\";\nimport {\n validateAfterLLMCallAction,\n validateAfterLLMErrorAction,\n validateBeforeLLMCallAction,\n} from \"./hook-validators.js\";\nimport type {\n AfterLLMCallAction,\n AfterLLMCallControllerContext,\n AfterLLMErrorAction,\n AgentHooks,\n BeforeLLMCallAction,\n LLMCallControllerContext,\n LLMErrorControllerContext,\n ObserveLLMCallContext,\n ObserveLLMCompleteContext,\n ObserveLLMErrorContext,\n} from \"./hooks.js\";\nimport { StreamProcessor } from \"./stream-processor.js\";\n\n/**\n * Configuration options for the Agent.\n */\nexport interface AgentOptions {\n /** The LLM client */\n client: LLMist;\n\n /** The model ID */\n model: string;\n\n /** System prompt */\n systemPrompt?: string;\n\n /** Initial user prompt (optional if using build()) */\n userPrompt?: string;\n\n /** Maximum iterations */\n maxIterations?: number;\n\n /** Temperature */\n temperature?: number;\n\n /** Gadget registry */\n registry: GadgetRegistry;\n\n /** Logger */\n logger?: Logger<ILogObj>;\n\n /** Clean hooks system */\n hooks?: AgentHooks;\n\n /** Callback for human input */\n onHumanInputRequired?: (question: string) => Promise<string>;\n\n /** Custom gadget start prefix */\n gadgetStartPrefix?: string;\n\n /** Custom gadget end prefix */\n gadgetEndPrefix?: string;\n\n /** Custom gadget argument prefix for block format parameters */\n gadgetArgPrefix?: string;\n\n /** Initial messages */\n initialMessages?: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>;\n\n /** Text-only handler */\n textOnlyHandler?: TextOnlyHandler;\n\n /**\n * Handler for text content that appears alongside gadget calls.\n * When set, text accompanying gadgets will be wrapped as a synthetic gadget call.\n */\n textWithGadgetsHandler?: {\n /** Name of the gadget to use for wrapping text */\n gadgetName: string;\n /** Maps text content to gadget parameters */\n parameterMapping: (text: string) => Record<string, unknown>;\n /** Maps text content to the result string (optional, defaults to text) */\n resultMapping?: (text: string) => string;\n };\n\n /** Stop on gadget error */\n stopOnGadgetError?: boolean;\n\n /** Custom error continuation logic */\n shouldContinueAfterError?: (context: {\n error: string;\n gadgetName: string;\n errorType: \"parse\" | \"validation\" | \"execution\";\n parameters?: Record<string, unknown>;\n }) => boolean | Promise<boolean>;\n\n /** Default gadget timeout */\n defaultGadgetTimeoutMs?: number;\n\n /** Custom prompt configuration for gadget system prompts */\n promptConfig?: PromptConfig;\n\n /** Enable gadget output limiting (default: true) */\n gadgetOutputLimit?: boolean;\n\n /** Max gadget output as % of model context window (default: 15) */\n gadgetOutputLimitPercent?: number;\n}\n\n/**\n * Agent: Lean orchestrator that delegates to StreamProcessor.\n *\n * Responsibilities:\n * - Run the main agent loop\n * - Call LLM API\n * - Delegate stream processing to StreamProcessor\n * - Coordinate conversation management\n * - Execute top-level lifecycle controllers\n *\n * NOT responsible for:\n * - Stream parsing (StreamProcessor)\n * - Hook coordination (StreamProcessor)\n * - Gadget execution (StreamProcessor -> GadgetExecutor)\n */\nexport class Agent {\n private readonly client: LLMist;\n private readonly model: string;\n private readonly maxIterations: number;\n private readonly temperature?: number;\n private readonly logger: Logger<ILogObj>;\n private readonly hooks: AgentHooks;\n private readonly conversation: ConversationManager;\n private readonly registry: GadgetRegistry;\n private readonly gadgetStartPrefix?: string;\n private readonly gadgetEndPrefix?: string;\n private readonly gadgetArgPrefix?: string;\n private readonly onHumanInputRequired?: (question: string) => Promise<string>;\n private readonly textOnlyHandler: TextOnlyHandler;\n private readonly textWithGadgetsHandler?: {\n gadgetName: string;\n parameterMapping: (text: string) => Record<string, unknown>;\n resultMapping?: (text: string) => string;\n };\n private readonly stopOnGadgetError: boolean;\n private readonly shouldContinueAfterError?: (context: {\n error: string;\n gadgetName: string;\n errorType: \"parse\" | \"validation\" | \"execution\";\n parameters?: Record<string, unknown>;\n }) => boolean | Promise<boolean>;\n private readonly defaultGadgetTimeoutMs?: number;\n private readonly defaultMaxTokens?: number;\n private userPromptProvided: boolean;\n\n // Gadget output limiting\n private readonly outputStore: GadgetOutputStore;\n private readonly outputLimitEnabled: boolean;\n private readonly outputLimitCharLimit: number;\n\n /**\n * Creates a new Agent instance.\n * @internal This constructor is private. Use LLMist.createAgent() or AgentBuilder instead.\n */\n constructor(key: typeof AGENT_INTERNAL_KEY, options: AgentOptions) {\n if (!isValidAgentKey(key)) {\n throw new Error(\n \"Agent cannot be instantiated directly. Use LLMist.createAgent() or new AgentBuilder() instead.\",\n );\n }\n\n this.client = options.client;\n this.model = resolveModel(options.model);\n this.maxIterations = options.maxIterations ?? 10;\n this.temperature = options.temperature;\n this.logger = options.logger ?? createLogger({ name: \"llmist:agent\" });\n this.registry = options.registry;\n this.gadgetStartPrefix = options.gadgetStartPrefix;\n this.gadgetEndPrefix = options.gadgetEndPrefix;\n this.gadgetArgPrefix = options.gadgetArgPrefix;\n this.onHumanInputRequired = options.onHumanInputRequired;\n this.textOnlyHandler = options.textOnlyHandler ?? \"terminate\";\n this.textWithGadgetsHandler = options.textWithGadgetsHandler;\n this.stopOnGadgetError = options.stopOnGadgetError ?? true;\n this.shouldContinueAfterError = options.shouldContinueAfterError;\n this.defaultGadgetTimeoutMs = options.defaultGadgetTimeoutMs;\n this.defaultMaxTokens = this.resolveMaxTokensFromCatalog(options.model);\n\n // Initialize gadget output limiting\n this.outputLimitEnabled = options.gadgetOutputLimit ?? DEFAULT_GADGET_OUTPUT_LIMIT;\n this.outputStore = new GadgetOutputStore();\n\n // Calculate character limit from model context window\n const limitPercent = options.gadgetOutputLimitPercent ?? DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT;\n const limits = this.client.modelRegistry.getModelLimits(this.model);\n const contextWindow = limits?.contextWindow ?? FALLBACK_CONTEXT_WINDOW;\n this.outputLimitCharLimit = Math.floor(contextWindow * (limitPercent / 100) * CHARS_PER_TOKEN);\n\n // Auto-register GadgetOutputViewer when limiting is enabled\n if (this.outputLimitEnabled) {\n this.registry.register(\"GadgetOutputViewer\", createGadgetOutputViewer(this.outputStore));\n }\n\n // Merge output limiter interceptor into hooks\n this.hooks = this.mergeOutputLimiterHook(options.hooks);\n\n // Build conversation\n const baseBuilder = new LLMMessageBuilder(options.promptConfig);\n if (options.systemPrompt) {\n baseBuilder.addSystem(options.systemPrompt);\n }\n\n baseBuilder.addGadgets(this.registry.getAll(), {\n startPrefix: options.gadgetStartPrefix,\n endPrefix: options.gadgetEndPrefix,\n argPrefix: options.gadgetArgPrefix,\n });\n const baseMessages = baseBuilder.build();\n\n const initialMessages = (options.initialMessages ?? []).map((message) => ({\n role: message.role,\n content: message.content,\n }));\n\n this.conversation = new ConversationManager(baseMessages, initialMessages, {\n startPrefix: options.gadgetStartPrefix,\n endPrefix: options.gadgetEndPrefix,\n argPrefix: options.gadgetArgPrefix,\n });\n this.userPromptProvided = !!options.userPrompt;\n if (options.userPrompt) {\n this.conversation.addUserMessage(options.userPrompt);\n }\n }\n\n /**\n * Get the gadget registry for this agent.\n *\n * Useful for inspecting registered gadgets in tests or advanced use cases.\n *\n * @returns The GadgetRegistry instance\n *\n * @example\n * ```typescript\n * const agent = new AgentBuilder()\n * .withModel(\"sonnet\")\n * .withGadgets(Calculator, Weather)\n * .build();\n *\n * // Inspect registered gadgets\n * console.log(agent.getRegistry().getNames()); // ['Calculator', 'Weather']\n * ```\n */\n getRegistry(): GadgetRegistry {\n return this.registry;\n }\n\n /**\n * Run the agent loop.\n * Clean, simple orchestration - all complexity is in StreamProcessor.\n *\n * @throws {Error} If no user prompt was provided (when using build() without ask())\n */\n async *run(): AsyncGenerator<StreamEvent> {\n if (!this.userPromptProvided) {\n throw new Error(\n \"No user prompt provided. Use .ask(prompt) instead of .build(), or call agent.run() after providing a prompt.\",\n );\n }\n\n let currentIteration = 0;\n\n this.logger.info(\"Starting agent loop\", {\n model: this.model,\n maxIterations: this.maxIterations,\n });\n\n while (currentIteration < this.maxIterations) {\n this.logger.debug(\"Starting iteration\", { iteration: currentIteration });\n\n try {\n // Prepare LLM call options\n let llmOptions: LLMGenerationOptions = {\n model: this.model,\n messages: this.conversation.getMessages(),\n temperature: this.temperature,\n maxTokens: this.defaultMaxTokens,\n };\n\n // Observer: LLM call start\n await this.safeObserve(async () => {\n if (this.hooks.observers?.onLLMCallStart) {\n const context: ObserveLLMCallContext = {\n iteration: currentIteration,\n options: llmOptions,\n logger: this.logger,\n };\n await this.hooks.observers.onLLMCallStart(context);\n }\n });\n\n // Controller: Before LLM call\n if (this.hooks.controllers?.beforeLLMCall) {\n const context: LLMCallControllerContext = {\n iteration: currentIteration,\n options: llmOptions,\n logger: this.logger,\n };\n const action: BeforeLLMCallAction = await this.hooks.controllers.beforeLLMCall(context);\n\n // Validate the action\n validateBeforeLLMCallAction(action);\n\n if (action.action === \"skip\") {\n this.logger.info(\"Controller skipped LLM call, using synthetic response\");\n // Add synthetic response to conversation\n this.conversation.addAssistantMessage(action.syntheticResponse);\n // Yield as text event\n yield { type: \"text\", content: action.syntheticResponse };\n break;\n } else if (action.action === \"proceed\" && action.modifiedOptions) {\n llmOptions = { ...llmOptions, ...action.modifiedOptions };\n }\n }\n\n // Call LLM\n this.logger.info(\"Calling LLM\", { model: this.model });\n this.logger.silly(\"LLM request details\", {\n model: llmOptions.model,\n temperature: llmOptions.temperature,\n maxTokens: llmOptions.maxTokens,\n messageCount: llmOptions.messages.length,\n messages: llmOptions.messages,\n });\n const stream = this.client.stream(llmOptions);\n\n // Process stream - ALL complexity delegated to StreamProcessor\n const processor = new StreamProcessor({\n iteration: currentIteration,\n registry: this.registry,\n gadgetStartPrefix: this.gadgetStartPrefix,\n gadgetEndPrefix: this.gadgetEndPrefix,\n gadgetArgPrefix: this.gadgetArgPrefix,\n hooks: this.hooks,\n logger: this.logger.getSubLogger({ name: \"stream-processor\" }),\n onHumanInputRequired: this.onHumanInputRequired,\n stopOnGadgetError: this.stopOnGadgetError,\n shouldContinueAfterError: this.shouldContinueAfterError,\n defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,\n });\n\n const result = await processor.process(stream);\n\n // Yield all outputs to user\n for (const output of result.outputs) {\n yield output;\n }\n\n this.logger.info(\"LLM response completed\", {\n finishReason: result.finishReason,\n usage: result.usage,\n didExecuteGadgets: result.didExecuteGadgets,\n });\n this.logger.silly(\"LLM response details\", {\n rawResponse: result.rawResponse,\n });\n\n // Observer: LLM call complete\n await this.safeObserve(async () => {\n if (this.hooks.observers?.onLLMCallComplete) {\n const context: ObserveLLMCompleteContext = {\n iteration: currentIteration,\n options: llmOptions,\n finishReason: result.finishReason,\n usage: result.usage,\n rawResponse: result.rawResponse,\n finalMessage: result.finalMessage,\n logger: this.logger,\n };\n await this.hooks.observers.onLLMCallComplete(context);\n }\n });\n\n // Controller: After LLM call\n let finalMessage = result.finalMessage;\n if (this.hooks.controllers?.afterLLMCall) {\n const context: AfterLLMCallControllerContext = {\n iteration: currentIteration,\n options: llmOptions,\n finishReason: result.finishReason,\n usage: result.usage,\n finalMessage: result.finalMessage,\n logger: this.logger,\n };\n const action: AfterLLMCallAction = await this.hooks.controllers.afterLLMCall(context);\n\n // Validate the action\n validateAfterLLMCallAction(action);\n\n if (action.action === \"modify_and_continue\" || action.action === \"append_and_modify\") {\n finalMessage = action.modifiedMessage;\n }\n\n if (action.action === \"append_messages\" || action.action === \"append_and_modify\") {\n for (const msg of action.messages) {\n if (msg.role === \"user\") {\n this.conversation.addUserMessage(msg.content);\n } else if (msg.role === \"assistant\") {\n this.conversation.addAssistantMessage(msg.content);\n } else if (msg.role === \"system\") {\n // System messages can't be added mid-conversation, treat as user\n this.conversation.addUserMessage(`[System] ${msg.content}`);\n }\n }\n }\n }\n\n // Add gadget results to conversation (if any were executed)\n if (result.didExecuteGadgets) {\n // If configured, wrap accompanying text as a synthetic gadget call (before actual gadgets)\n if (this.textWithGadgetsHandler) {\n const textContent = result.outputs\n .filter((output): output is { type: \"text\"; content: string } => output.type === \"text\")\n .map((output) => output.content)\n .join(\"\");\n\n if (textContent.trim()) {\n const { gadgetName, parameterMapping, resultMapping } = this.textWithGadgetsHandler;\n this.conversation.addGadgetCall(\n gadgetName,\n parameterMapping(textContent),\n resultMapping ? resultMapping(textContent) : textContent,\n );\n }\n }\n\n // Extract and add all gadget results to conversation\n for (const output of result.outputs) {\n if (output.type === \"gadget_result\") {\n const gadgetResult = output.result;\n this.conversation.addGadgetCall(\n gadgetResult.gadgetName,\n gadgetResult.parameters,\n gadgetResult.error ?? gadgetResult.result ?? \"\",\n );\n }\n }\n } else {\n // No gadgets executed - wrap text as synthetic TellUser result\n // This keeps conversation history consistent (gadget-oriented) and\n // helps LLMs stay in the \"gadget invocation\" mindset\n if (finalMessage.trim()) {\n this.conversation.addGadgetCall(\n \"TellUser\",\n { message: finalMessage, done: false, type: \"info\" },\n `ℹ️ ${finalMessage}`,\n );\n }\n // Empty responses: don't add anything, just check if we should continue\n\n // Handle text-only responses\n const shouldBreak = await this.handleTextOnlyResponse(finalMessage);\n if (shouldBreak) {\n break;\n }\n }\n\n // Check if loop should break\n if (result.shouldBreakLoop) {\n this.logger.info(\"Loop terminated by gadget or processor\");\n break;\n }\n } catch (error) {\n // Handle LLM error\n const errorHandled = await this.handleLLMError(error as Error, currentIteration);\n\n // Observer: LLM error\n await this.safeObserve(async () => {\n if (this.hooks.observers?.onLLMCallError) {\n const context: ObserveLLMErrorContext = {\n iteration: currentIteration,\n options: {\n model: this.model,\n messages: this.conversation.getMessages(),\n temperature: this.temperature,\n maxTokens: this.defaultMaxTokens,\n },\n error: error as Error,\n recovered: errorHandled,\n logger: this.logger,\n };\n await this.hooks.observers.onLLMCallError(context);\n }\n });\n\n if (!errorHandled) {\n throw error;\n }\n }\n\n currentIteration++;\n }\n\n this.logger.info(\"Agent loop completed\", {\n totalIterations: currentIteration,\n reason: currentIteration >= this.maxIterations ? \"max_iterations\" : \"natural_completion\",\n });\n }\n\n /**\n * Handle LLM error through controller.\n */\n private async handleLLMError(error: Error, iteration: number): Promise<boolean> {\n this.logger.error(\"LLM call failed\", { error: error.message });\n\n if (this.hooks.controllers?.afterLLMError) {\n const context: LLMErrorControllerContext = {\n iteration,\n options: {\n model: this.model,\n messages: this.conversation.getMessages(),\n temperature: this.temperature,\n maxTokens: this.defaultMaxTokens,\n },\n error,\n logger: this.logger,\n };\n const action: AfterLLMErrorAction = await this.hooks.controllers.afterLLMError(context);\n\n // Validate the action\n validateAfterLLMErrorAction(action);\n\n if (action.action === \"recover\") {\n this.logger.info(\"Controller recovered from LLM error\");\n this.conversation.addAssistantMessage(action.fallbackResponse);\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Handle text-only response (no gadgets called).\n */\n private async handleTextOnlyResponse(_text: string): Promise<boolean> {\n const handler = this.textOnlyHandler;\n\n if (typeof handler === \"string\") {\n switch (handler) {\n case \"terminate\":\n this.logger.info(\"No gadgets called, ending loop\");\n return true;\n case \"acknowledge\":\n this.logger.info(\"No gadgets called, continuing loop\");\n return false;\n case \"wait_for_input\":\n this.logger.info(\"No gadgets called, waiting for input\");\n return true;\n default:\n this.logger.warn(`Unknown text-only strategy: ${handler}, defaulting to terminate`);\n return true;\n }\n }\n\n // For gadget and custom handlers, they would need to be implemented\n // This is simplified for now\n return true;\n }\n\n /**\n * Safely execute an observer, catching and logging any errors.\n */\n private async safeObserve(fn: () => void | Promise<void>): Promise<void> {\n try {\n await fn();\n } catch (error) {\n this.logger.error(\"Observer threw error (ignoring)\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Resolve max tokens from model catalog.\n */\n private resolveMaxTokensFromCatalog(modelId: string): number | undefined {\n const limits = this.client.modelRegistry.getModelLimits(modelId);\n if (limits?.maxOutputTokens !== undefined) {\n return limits.maxOutputTokens;\n }\n\n const separatorIndex = modelId.indexOf(\":\");\n if (separatorIndex === -1) {\n return undefined;\n }\n\n const unprefixedModelId = modelId.slice(separatorIndex + 1).trim();\n if (!unprefixedModelId) {\n return undefined;\n }\n\n return this.client.modelRegistry.getModelLimits(unprefixedModelId)?.maxOutputTokens;\n }\n\n /**\n * Merge the output limiter interceptor into user-provided hooks.\n * The limiter runs first, then chains to any user interceptor.\n */\n private mergeOutputLimiterHook(userHooks?: AgentHooks): AgentHooks {\n if (!this.outputLimitEnabled) {\n return userHooks ?? {};\n }\n\n const limiterInterceptor = (\n result: string,\n ctx: GadgetResultInterceptorContext,\n ): string => {\n // Skip limiting for GadgetOutputViewer itself to avoid recursion\n if (ctx.gadgetName === \"GadgetOutputViewer\") {\n return result;\n }\n\n if (result.length > this.outputLimitCharLimit) {\n const id = this.outputStore.store(ctx.gadgetName, result);\n const lines = result.split(\"\\n\").length;\n const bytes = new TextEncoder().encode(result).length;\n\n this.logger.info(\"Gadget output exceeded limit, stored for browsing\", {\n gadgetName: ctx.gadgetName,\n outputId: id,\n bytes,\n lines,\n charLimit: this.outputLimitCharLimit,\n });\n\n return (\n `[Gadget \"${ctx.gadgetName}\" returned too much data: ` +\n `${bytes.toLocaleString()} bytes, ${lines.toLocaleString()} lines. ` +\n `Use GadgetOutputViewer with id \"${id}\" to read it]`\n );\n }\n\n return result;\n };\n\n // Chain with any user-provided interceptor (limiter runs first)\n const userInterceptor = userHooks?.interceptors?.interceptGadgetResult;\n const chainedInterceptor = userInterceptor\n ? (result: string, ctx: GadgetResultInterceptorContext) =>\n userInterceptor(limiterInterceptor(result, ctx), ctx)\n : limiterInterceptor;\n\n return {\n ...userHooks,\n interceptors: {\n ...userHooks?.interceptors,\n interceptGadgetResult: chainedInterceptor,\n },\n };\n }\n\n /**\n * Run agent with named event handlers (syntactic sugar).\n *\n * Instead of verbose if/else chains, use named handlers for cleaner code.\n *\n * @param handlers - Named event handlers\n *\n * @example\n * ```typescript\n * await agent.runWith({\n * onText: (text) => console.log(\"LLM:\", text),\n * onGadgetResult: (result) => console.log(\"Result:\", result.result),\n * onGadgetCall: (call) => console.log(\"Calling:\", call.gadgetName),\n * });\n * ```\n */\n async runWith(handlers: EventHandlers): Promise<void> {\n return runWithHandlers(this.run(), handlers);\n }\n}\n","/**\n * Fluent builder for creating agents with delightful DX.\n *\n * @example\n * ```typescript\n * const agent = await LLMist.createAgent()\n * .withModel(\"sonnet\")\n * .withSystem(\"You are a helpful assistant\")\n * .withGadgets(Calculator, Weather)\n * .withMaxIterations(10)\n * .ask(\"What's the weather in Paris?\");\n *\n * for await (const event of agent.run()) {\n * // process events\n * }\n * ```\n */\n\nimport type { ILogObj, Logger } from \"tslog\";\nimport type { LLMist } from \"../core/client.js\";\nimport { GADGET_ARG_PREFIX, GADGET_END_PREFIX, GADGET_START_PREFIX } from \"../core/constants.js\";\nimport { resolveModel } from \"../core/model-shortcuts.js\";\nimport type { PromptConfig } from \"../core/prompt-config.js\";\nimport type { GadgetOrClass } from \"../gadgets/registry.js\";\nimport { GadgetRegistry } from \"../gadgets/registry.js\";\nimport type { TextOnlyHandler } from \"../gadgets/types.js\";\nimport { Agent, type AgentOptions } from \"./agent.js\";\nimport { AGENT_INTERNAL_KEY } from \"./agent-internal-key.js\";\nimport { collectText, type EventHandlers } from \"./event-handlers.js\";\nimport type { AgentHooks } from \"./hooks.js\";\n\n/**\n * Message for conversation history.\n */\nexport type HistoryMessage = { user: string } | { assistant: string } | { system: string };\n\n/**\n * Fluent builder for creating agents.\n *\n * Provides a chainable API for configuring and creating agents,\n * making the code more expressive and easier to read.\n */\nexport class AgentBuilder {\n private client?: LLMist;\n private model?: string;\n private systemPrompt?: string;\n private temperature?: number;\n private maxIterations?: number;\n private logger?: Logger<ILogObj>;\n private hooks?: AgentHooks;\n private promptConfig?: PromptConfig;\n private gadgets: GadgetOrClass[] = [];\n private initialMessages: Array<{\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n }> = [];\n private onHumanInputRequired?: (question: string) => Promise<string>;\n private gadgetStartPrefix?: string;\n private gadgetEndPrefix?: string;\n private gadgetArgPrefix?: string;\n private textOnlyHandler?: TextOnlyHandler;\n private textWithGadgetsHandler?: {\n gadgetName: string;\n parameterMapping: (text: string) => Record<string, unknown>;\n resultMapping?: (text: string) => string;\n };\n private stopOnGadgetError?: boolean;\n private shouldContinueAfterError?: (context: {\n error: string;\n gadgetName: string;\n errorType: \"parse\" | \"validation\" | \"execution\";\n parameters?: Record<string, unknown>;\n }) => boolean | Promise<boolean>;\n private defaultGadgetTimeoutMs?: number;\n private gadgetOutputLimit?: boolean;\n private gadgetOutputLimitPercent?: number;\n\n constructor(client?: LLMist) {\n this.client = client;\n }\n\n /**\n * Set the model to use.\n * Supports aliases like \"gpt4\", \"sonnet\", \"flash\".\n *\n * @param model - Model name or alias\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .withModel(\"sonnet\") // Alias\n * .withModel(\"gpt-5-nano\") // Auto-detects provider\n * .withModel(\"openai:gpt-5\") // Explicit provider\n * ```\n */\n withModel(model: string): this {\n this.model = resolveModel(model);\n return this;\n }\n\n /**\n * Set the system prompt.\n *\n * @param prompt - System prompt\n * @returns This builder for chaining\n */\n withSystem(prompt: string): this {\n this.systemPrompt = prompt;\n return this;\n }\n\n /**\n * Set the temperature (0-1).\n *\n * @param temperature - Temperature value\n * @returns This builder for chaining\n */\n withTemperature(temperature: number): this {\n this.temperature = temperature;\n return this;\n }\n\n /**\n * Set maximum iterations.\n *\n * @param max - Maximum number of iterations\n * @returns This builder for chaining\n */\n withMaxIterations(max: number): this {\n this.maxIterations = max;\n return this;\n }\n\n /**\n * Set logger instance.\n *\n * @param logger - Logger instance\n * @returns This builder for chaining\n */\n withLogger(logger: Logger<ILogObj>): this {\n this.logger = logger;\n return this;\n }\n\n /**\n * Add hooks for agent lifecycle events.\n *\n * @param hooks - Agent hooks configuration\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * import { HookPresets } from 'llmist/hooks';\n *\n * .withHooks(HookPresets.logging())\n * .withHooks(HookPresets.merge(\n * HookPresets.logging(),\n * HookPresets.timing()\n * ))\n * ```\n */\n withHooks(hooks: AgentHooks): this {\n this.hooks = hooks;\n return this;\n }\n\n /**\n * Configure custom prompts for gadget system messages.\n *\n * @param config - Prompt configuration object\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .withPromptConfig({\n * mainInstruction: \"Use the gadget markers below:\",\n * rules: [\"Always use markers\", \"Never use function calling\"]\n * })\n * ```\n */\n withPromptConfig(config: PromptConfig): this {\n this.promptConfig = config;\n return this;\n }\n\n /**\n * Add gadgets (classes or instances).\n * Can be called multiple times to add more gadgets.\n *\n * @param gadgets - Gadget classes or instances\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .withGadgets(Calculator, Weather, Email)\n * .withGadgets(new Calculator(), new Weather())\n * .withGadgets(createGadget({ ... }))\n * ```\n */\n withGadgets(...gadgets: GadgetOrClass[]): this {\n this.gadgets.push(...gadgets);\n return this;\n }\n\n /**\n * Add conversation history messages.\n * Useful for continuing previous conversations.\n *\n * @param messages - Array of history messages\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .withHistory([\n * { user: \"Hello\" },\n * { assistant: \"Hi there!\" },\n * { user: \"How are you?\" },\n * { assistant: \"I'm doing well, thanks!\" }\n * ])\n * ```\n */\n withHistory(messages: HistoryMessage[]): this {\n for (const msg of messages) {\n if (\"user\" in msg) {\n this.initialMessages.push({ role: \"user\", content: msg.user });\n } else if (\"assistant\" in msg) {\n this.initialMessages.push({ role: \"assistant\", content: msg.assistant });\n } else if (\"system\" in msg) {\n this.initialMessages.push({ role: \"system\", content: msg.system });\n }\n }\n return this;\n }\n\n /**\n * Add a single message to the conversation history.\n *\n * @param message - Single history message\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .addMessage({ user: \"Hello\" })\n * .addMessage({ assistant: \"Hi there!\" })\n * ```\n */\n addMessage(message: HistoryMessage): this {\n return this.withHistory([message]);\n }\n\n /**\n * Set the human input handler for interactive conversations.\n *\n * @param handler - Function to handle human input requests\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .onHumanInput(async (question) => {\n * return await promptUser(question);\n * })\n * ```\n */\n onHumanInput(handler: (question: string) => Promise<string>): this {\n this.onHumanInputRequired = handler;\n return this;\n }\n\n /**\n * Set custom gadget marker prefix.\n *\n * @param prefix - Custom start prefix for gadget markers\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .withGadgetStartPrefix(\"<<GADGET_START>>\")\n * ```\n */\n withGadgetStartPrefix(prefix: string): this {\n this.gadgetStartPrefix = prefix;\n return this;\n }\n\n /**\n * Set custom gadget marker suffix.\n *\n * @param suffix - Custom end suffix for gadget markers\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .withGadgetEndPrefix(\"<<GADGET_END>>\")\n * ```\n */\n withGadgetEndPrefix(suffix: string): this {\n this.gadgetEndPrefix = suffix;\n return this;\n }\n\n /**\n * Set custom argument prefix for block format parameters.\n *\n * @param prefix - Custom prefix for argument markers (default: \"!!!ARG:\")\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .withGadgetArgPrefix(\"<<ARG>>\")\n * ```\n */\n withGadgetArgPrefix(prefix: string): this {\n this.gadgetArgPrefix = prefix;\n return this;\n }\n\n /**\n * Set the text-only handler strategy.\n *\n * Controls what happens when the LLM returns text without calling any gadgets:\n * - \"terminate\": End the agent loop (default)\n * - \"acknowledge\": Continue the loop for another iteration\n * - \"wait_for_input\": Wait for human input\n * - Custom handler: Provide a function for dynamic behavior\n *\n * @param handler - Text-only handler strategy or custom handler\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * // Simple strategy\n * .withTextOnlyHandler(\"acknowledge\")\n *\n * // Custom handler\n * .withTextOnlyHandler({\n * type: \"custom\",\n * handler: async (context) => {\n * if (context.text.includes(\"?\")) {\n * return { action: \"wait_for_input\", question: context.text };\n * }\n * return { action: \"continue\" };\n * }\n * })\n * ```\n */\n withTextOnlyHandler(handler: TextOnlyHandler): this {\n this.textOnlyHandler = handler;\n return this;\n }\n\n /**\n * Set the handler for text content that appears alongside gadget calls.\n *\n * When set, text accompanying gadget responses will be wrapped as a\n * synthetic gadget call before the actual gadget results in the\n * conversation history.\n *\n * @param handler - Configuration for wrapping text\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * // Wrap text as TellUser gadget\n * .withTextWithGadgetsHandler({\n * gadgetName: \"TellUser\",\n * parameterMapping: (text) => ({ message: text, done: false, type: \"info\" }),\n * resultMapping: (text) => `ℹ️ ${text}`,\n * })\n * ```\n */\n withTextWithGadgetsHandler(handler: {\n gadgetName: string;\n parameterMapping: (text: string) => Record<string, unknown>;\n resultMapping?: (text: string) => string;\n }): this {\n this.textWithGadgetsHandler = handler;\n return this;\n }\n\n /**\n * Set whether to stop gadget execution on first error.\n *\n * When true (default), if a gadget fails:\n * - Subsequent gadgets in the same response are skipped\n * - LLM stream is cancelled to save costs\n * - Agent loop continues with error in context\n *\n * When false:\n * - All gadgets in the response still execute\n * - LLM stream continues to completion\n *\n * @param stop - Whether to stop on gadget error\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .withStopOnGadgetError(false)\n * ```\n */\n withStopOnGadgetError(stop: boolean): this {\n this.stopOnGadgetError = stop;\n return this;\n }\n\n /**\n * Set custom error handling logic.\n *\n * Provides fine-grained control over whether to continue after different types of errors.\n * Overrides `stopOnGadgetError` when provided.\n *\n * **Note:** This builder method configures the underlying `shouldContinueAfterError` option\n * in `AgentOptions`. The method is named `withErrorHandler` for better developer experience,\n * but maps to the `shouldContinueAfterError` property internally.\n *\n * @param handler - Function that decides whether to continue after an error.\n * Return `true` to continue execution, `false` to stop.\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .withErrorHandler((context) => {\n * // Stop on parse errors, continue on validation/execution errors\n * if (context.errorType === \"parse\") {\n * return false;\n * }\n * if (context.error.includes(\"CRITICAL\")) {\n * return false;\n * }\n * return true;\n * })\n * ```\n */\n withErrorHandler(\n handler: (context: {\n error: string;\n gadgetName: string;\n errorType: \"parse\" | \"validation\" | \"execution\";\n parameters?: Record<string, unknown>;\n }) => boolean | Promise<boolean>,\n ): this {\n this.shouldContinueAfterError = handler;\n return this;\n }\n\n /**\n * Set default timeout for gadget execution.\n *\n * @param timeoutMs - Timeout in milliseconds (must be non-negative)\n * @returns This builder for chaining\n * @throws {Error} If timeout is negative\n *\n * @example\n * ```typescript\n * .withDefaultGadgetTimeout(5000) // 5 second timeout\n * ```\n */\n withDefaultGadgetTimeout(timeoutMs: number): this {\n if (timeoutMs < 0) {\n throw new Error(\"Timeout must be a non-negative number\");\n }\n this.defaultGadgetTimeoutMs = timeoutMs;\n return this;\n }\n\n /**\n * Enable or disable gadget output limiting.\n *\n * When enabled, gadget outputs exceeding the configured limit are stored\n * and can be browsed using the GadgetOutputViewer gadget.\n *\n * @param enabled - Whether to enable output limiting (default: true)\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .withGadgetOutputLimit(false) // Disable output limiting\n * ```\n */\n withGadgetOutputLimit(enabled: boolean): this {\n this.gadgetOutputLimit = enabled;\n return this;\n }\n\n /**\n * Set the maximum gadget output as a percentage of the model's context window.\n *\n * Outputs exceeding this limit are stored for later browsing with GadgetOutputViewer.\n *\n * @param percent - Percentage of context window (1-100, default: 15)\n * @returns This builder for chaining\n * @throws {Error} If percent is not between 1 and 100\n *\n * @example\n * ```typescript\n * .withGadgetOutputLimitPercent(25) // 25% of context window\n * ```\n */\n withGadgetOutputLimitPercent(percent: number): this {\n if (percent < 1 || percent > 100) {\n throw new Error(\"Output limit percent must be between 1 and 100\");\n }\n this.gadgetOutputLimitPercent = percent;\n return this;\n }\n\n /**\n * Add a synthetic gadget call to the conversation history.\n *\n * This is useful for in-context learning - showing the LLM what \"past self\"\n * did correctly so it mimics the pattern. The call is formatted with proper\n * markers and parameter format.\n *\n * @param gadgetName - Name of the gadget\n * @param parameters - Parameters passed to the gadget\n * @param result - Result returned by the gadget\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .withSyntheticGadgetCall(\n * 'TellUser',\n * {\n * message: '👋 Hello!\\n\\nHere\\'s what I can do:\\n- Analyze code\\n- Run commands',\n * done: false,\n * type: 'info'\n * },\n * 'ℹ️ 👋 Hello!\\n\\nHere\\'s what I can do:\\n- Analyze code\\n- Run commands'\n * )\n * ```\n */\n withSyntheticGadgetCall(\n gadgetName: string,\n parameters: Record<string, unknown>,\n result: string,\n ): this {\n const startPrefix = this.gadgetStartPrefix ?? GADGET_START_PREFIX;\n const endPrefix = this.gadgetEndPrefix ?? GADGET_END_PREFIX;\n\n const paramStr = this.formatBlockParameters(parameters, \"\");\n\n // Assistant message with gadget call\n this.initialMessages.push({\n role: \"assistant\",\n content: `${startPrefix}${gadgetName}\\n${paramStr}\\n${endPrefix}`,\n });\n\n // User message with result\n this.initialMessages.push({\n role: \"user\",\n content: `Result: ${result}`,\n });\n\n return this;\n }\n\n /**\n * Format parameters as block format with JSON Pointer paths.\n */\n private formatBlockParameters(params: Record<string, unknown>, prefix: string): string {\n const lines: string[] = [];\n const argPrefix = this.gadgetArgPrefix ?? GADGET_ARG_PREFIX;\n\n for (const [key, value] of Object.entries(params)) {\n const fullPath = prefix ? `${prefix}/${key}` : key;\n\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n const itemPath = `${fullPath}/${index}`;\n if (typeof item === \"object\" && item !== null) {\n lines.push(this.formatBlockParameters(item as Record<string, unknown>, itemPath));\n } else {\n lines.push(`${argPrefix}${itemPath}`);\n lines.push(String(item));\n }\n });\n } else if (typeof value === \"object\" && value !== null) {\n lines.push(this.formatBlockParameters(value as Record<string, unknown>, fullPath));\n } else {\n lines.push(`${argPrefix}${fullPath}`);\n lines.push(String(value));\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Build and create the agent with the given user prompt.\n * Returns the Agent instance ready to run.\n *\n * @param userPrompt - User's question or request\n * @returns Configured Agent instance\n *\n * @example\n * ```typescript\n * const agent = await LLMist.createAgent()\n * .withModel(\"sonnet\")\n * .withGadgets(Calculator)\n * .ask(\"What is 2+2?\");\n *\n * for await (const event of agent.run()) {\n * // handle events\n * }\n * ```\n */\n ask(userPrompt: string): Agent {\n // Lazy import to avoid circular dependency\n if (!this.client) {\n const { LLMist: LLMistClass } =\n require(\"../core/client.js\") as typeof import(\"../core/client.js\");\n this.client = new LLMistClass();\n }\n const registry = GadgetRegistry.from(this.gadgets);\n\n const options: AgentOptions = {\n client: this.client,\n model: this.model ?? \"openai:gpt-5-nano\",\n systemPrompt: this.systemPrompt,\n userPrompt,\n registry,\n maxIterations: this.maxIterations,\n temperature: this.temperature,\n logger: this.logger,\n hooks: this.hooks,\n promptConfig: this.promptConfig,\n initialMessages: this.initialMessages,\n onHumanInputRequired: this.onHumanInputRequired,\n gadgetStartPrefix: this.gadgetStartPrefix,\n gadgetEndPrefix: this.gadgetEndPrefix,\n gadgetArgPrefix: this.gadgetArgPrefix,\n textOnlyHandler: this.textOnlyHandler,\n textWithGadgetsHandler: this.textWithGadgetsHandler,\n stopOnGadgetError: this.stopOnGadgetError,\n shouldContinueAfterError: this.shouldContinueAfterError,\n defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,\n gadgetOutputLimit: this.gadgetOutputLimit,\n gadgetOutputLimitPercent: this.gadgetOutputLimitPercent,\n };\n\n return new Agent(AGENT_INTERNAL_KEY, options);\n }\n\n /**\n * Build, run, and collect only the text response.\n * Convenient for simple queries where you just want the final answer.\n *\n * @param userPrompt - User's question or request\n * @returns Promise resolving to the complete text response\n *\n * @example\n * ```typescript\n * const answer = await LLMist.createAgent()\n * .withModel(\"gpt4-mini\")\n * .withGadgets(Calculator)\n * .askAndCollect(\"What is 42 * 7?\");\n *\n * console.log(answer); // \"294\"\n * ```\n */\n async askAndCollect(userPrompt: string): Promise<string> {\n const agent = this.ask(userPrompt);\n return collectText(agent.run());\n }\n\n /**\n * Build and run with event handlers.\n * Combines agent creation and event handling in one call.\n *\n * @param userPrompt - User's question or request\n * @param handlers - Event handlers\n *\n * @example\n * ```typescript\n * await LLMist.createAgent()\n * .withModel(\"sonnet\")\n * .withGadgets(Calculator)\n * .askWith(\"What is 2+2?\", {\n * onText: (text) => console.log(\"LLM:\", text),\n * onGadgetResult: (result) => console.log(\"Result:\", result.result),\n * });\n * ```\n */\n async askWith(userPrompt: string, handlers: EventHandlers): Promise<void> {\n const agent = this.ask(userPrompt);\n await agent.runWith(handlers);\n }\n\n /**\n * Build the agent without a user prompt.\n *\n * Returns an Agent instance that can be inspected (e.g., check registered gadgets)\n * but cannot be run without first calling .ask(prompt).\n *\n * This is useful for:\n * - Testing: Inspect the registry, configuration, etc.\n * - Advanced use cases: Build agent configuration separately from execution\n *\n * @returns Configured Agent instance (without user prompt)\n *\n * @example\n * ```typescript\n * // Build agent for inspection\n * const agent = new AgentBuilder()\n * .withModel(\"sonnet\")\n * .withGadgets(Calculator, Weather)\n * .build();\n *\n * // Inspect registered gadgets\n * console.log(agent.getRegistry().getNames()); // ['Calculator', 'Weather']\n *\n * // Note: Calling agent.run() will throw an error\n * // Use .ask(prompt) instead if you want to run the agent\n * ```\n */\n build(): Agent {\n // Lazy import to avoid circular dependency\n if (!this.client) {\n const { LLMist: LLMistClass } =\n require(\"../core/client.js\") as typeof import(\"../core/client.js\");\n this.client = new LLMistClass();\n }\n const registry = GadgetRegistry.from(this.gadgets);\n\n const options: AgentOptions = {\n client: this.client,\n model: this.model ?? \"openai:gpt-5-nano\",\n systemPrompt: this.systemPrompt,\n // No userPrompt - agent.run() will throw if called directly\n registry,\n maxIterations: this.maxIterations,\n temperature: this.temperature,\n logger: this.logger,\n hooks: this.hooks,\n promptConfig: this.promptConfig,\n initialMessages: this.initialMessages,\n onHumanInputRequired: this.onHumanInputRequired,\n gadgetStartPrefix: this.gadgetStartPrefix,\n gadgetEndPrefix: this.gadgetEndPrefix,\n gadgetArgPrefix: this.gadgetArgPrefix,\n textOnlyHandler: this.textOnlyHandler,\n textWithGadgetsHandler: this.textWithGadgetsHandler,\n stopOnGadgetError: this.stopOnGadgetError,\n shouldContinueAfterError: this.shouldContinueAfterError,\n defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,\n gadgetOutputLimit: this.gadgetOutputLimit,\n gadgetOutputLimitPercent: this.gadgetOutputLimitPercent,\n };\n\n return new Agent(AGENT_INTERNAL_KEY, options);\n }\n}\n","import { AgentBuilder } from \"../agent/builder.js\";\nimport { discoverProviderAdapters } from \"../providers/discovery.js\";\nimport type { ProviderAdapter } from \"../providers/provider.js\";\nimport type { LLMMessage } from \"./messages.js\";\nimport type { ModelSpec } from \"./model-catalog.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport type { LLMGenerationOptions, LLMStream, ModelDescriptor } from \"./options.js\";\nimport { ModelIdentifierParser } from \"./options.js\";\nimport {\n complete as completeHelper,\n type QuickOptions,\n stream as streamHelper,\n} from \"./quick-methods.js\";\n\nexport interface LLMistOptions {\n /**\n * Provider adapters to register manually.\n */\n adapters?: ProviderAdapter[];\n /**\n * Default provider prefix applied when a model identifier omits it.\n */\n defaultProvider?: string;\n /**\n * Automatically discover built-in providers based on environment configuration.\n * Enabled by default.\n */\n autoDiscoverProviders?: boolean;\n /**\n * Custom model specifications to register at initialization.\n * Use this to define models not in the built-in catalog, such as:\n * - Fine-tuned models with custom pricing\n * - New models not yet supported by llmist\n * - Custom deployments with different configurations\n *\n * @example\n * ```ts\n * new LLMist({\n * customModels: [{\n * provider: \"openai\",\n * modelId: \"ft:gpt-4o-2024-08-06:my-org:custom:abc123\",\n * displayName: \"My Fine-tuned GPT-4o\",\n * contextWindow: 128_000,\n * maxOutputTokens: 16_384,\n * pricing: { input: 7.5, output: 30.0 },\n * knowledgeCutoff: \"2024-08\",\n * features: { streaming: true, functionCalling: true, vision: true }\n * }]\n * });\n * ```\n */\n customModels?: ModelSpec[];\n}\n\nexport class LLMist {\n private readonly parser: ModelIdentifierParser;\n readonly modelRegistry: ModelRegistry;\n private readonly adapters: ProviderAdapter[];\n\n constructor();\n constructor(adapters: ProviderAdapter[]);\n constructor(adapters: ProviderAdapter[], defaultProvider: string);\n constructor(options: LLMistOptions);\n constructor(...args: [] | [ProviderAdapter[]] | [ProviderAdapter[], string] | [LLMistOptions]) {\n let adapters: ProviderAdapter[] = [];\n let defaultProvider: string | undefined;\n let autoDiscoverProviders = true;\n let customModels: ModelSpec[] = [];\n\n if (args.length === 0) {\n // Use defaults\n } else if (Array.isArray(args[0])) {\n adapters = args[0];\n if (args.length > 1) {\n defaultProvider = args[1];\n }\n } else if (typeof args[0] === \"object\" && args[0] !== null) {\n const options = args[0];\n adapters = options.adapters ?? [];\n defaultProvider = options.defaultProvider;\n customModels = options.customModels ?? [];\n if (typeof options.autoDiscoverProviders === \"boolean\") {\n autoDiscoverProviders = options.autoDiscoverProviders;\n }\n }\n\n const discoveredAdapters = autoDiscoverProviders ? discoverProviderAdapters() : [];\n const combinedAdapters: ProviderAdapter[] = [...adapters];\n for (const adapter of discoveredAdapters) {\n if (!combinedAdapters.some((existing) => existing.providerId === adapter.providerId)) {\n combinedAdapters.push(adapter);\n }\n }\n\n if (combinedAdapters.length === 0) {\n throw new Error(\n \"No LLM providers available. Provide adapters explicitly or set provider API keys in the environment.\",\n );\n }\n\n const resolvedDefaultProvider = defaultProvider ?? combinedAdapters[0]?.providerId ?? \"openai\";\n\n // Sort by priority (descending: higher priority first)\n // Use stable sort to preserve order for equal priorities\n this.adapters = [...combinedAdapters].sort((a, b) => {\n const priorityA = a.priority ?? 0;\n const priorityB = b.priority ?? 0;\n return priorityB - priorityA;\n });\n this.parser = new ModelIdentifierParser(resolvedDefaultProvider);\n this.modelRegistry = new ModelRegistry();\n\n // Register all providers with the model registry\n for (const adapter of this.adapters) {\n this.modelRegistry.registerProvider(adapter);\n }\n\n // Register custom models if provided\n if (customModels.length > 0) {\n this.modelRegistry.registerModels(customModels);\n }\n }\n\n stream(options: LLMGenerationOptions): LLMStream {\n const descriptor = this.parser.parse(options.model);\n const spec = this.modelRegistry.getModelSpec(descriptor.name);\n const adapter = this.resolveAdapter(descriptor);\n return adapter.stream(options, descriptor, spec);\n }\n\n /**\n * Count tokens in messages for a given model.\n *\n * Uses provider-specific token counting methods for accurate estimation:\n * - OpenAI: tiktoken library with model-specific encodings\n * - Anthropic: Native messages.countTokens() API\n * - Gemini: SDK's countTokens() method\n *\n * Falls back to character-based estimation (4 chars/token) if the provider\n * doesn't support native token counting or if counting fails.\n *\n * This is useful for:\n * - Pre-request cost estimation\n * - Context window management\n * - Request batching optimization\n *\n * @param model - Model identifier (e.g., \"openai:gpt-4\", \"anthropic:claude-3-5-sonnet-20241022\")\n * @param messages - Array of messages to count tokens for\n * @returns Promise resolving to the estimated input token count\n *\n * @example\n * ```typescript\n * const client = new LLMist();\n * const messages = [\n * { role: 'system', content: 'You are a helpful assistant.' },\n * { role: 'user', content: 'Hello!' }\n * ];\n *\n * const tokenCount = await client.countTokens('openai:gpt-4', messages);\n * console.log(`Estimated tokens: ${tokenCount}`);\n * ```\n */\n async countTokens(model: string, messages: LLMMessage[]): Promise<number> {\n const descriptor = this.parser.parse(model);\n const spec = this.modelRegistry.getModelSpec(descriptor.name);\n const adapter = this.resolveAdapter(descriptor);\n\n // Check if the provider supports token counting\n if (adapter.countTokens) {\n return adapter.countTokens(messages, descriptor, spec);\n }\n\n // Fallback: rough character-based estimation (4 chars per token)\n const totalChars = messages.reduce((sum, msg) => sum + (msg.content?.length ?? 0), 0);\n return Math.ceil(totalChars / 4);\n }\n\n private resolveAdapter(descriptor: ModelDescriptor): ProviderAdapter {\n const adapter = this.adapters.find((item) => item.supports(descriptor));\n if (!adapter) {\n throw new Error(`No adapter registered for provider ${descriptor.provider}`);\n }\n\n return adapter;\n }\n\n /**\n * Quick completion - returns final text response.\n * Convenient for simple queries without needing agent setup.\n *\n * @param prompt - User prompt\n * @param options - Optional configuration\n * @returns Complete text response\n *\n * @example\n * ```typescript\n * const answer = await LLMist.complete(\"What is 2+2?\");\n * console.log(answer); // \"4\" or \"2+2 equals 4\"\n *\n * const answer = await LLMist.complete(\"Tell me a joke\", {\n * model: \"sonnet\",\n * temperature: 0.9\n * });\n * ```\n */\n static async complete(prompt: string, options?: QuickOptions): Promise<string> {\n const client = new LLMist();\n return completeHelper(client, prompt, options);\n }\n\n /**\n * Quick streaming - returns async generator of text chunks.\n * Convenient for streaming responses without needing agent setup.\n *\n * @param prompt - User prompt\n * @param options - Optional configuration\n * @returns Async generator yielding text chunks\n *\n * @example\n * ```typescript\n * for await (const chunk of LLMist.stream(\"Tell me a story\")) {\n * process.stdout.write(chunk);\n * }\n *\n * // With options\n * for await (const chunk of LLMist.stream(\"Generate code\", {\n * model: \"gpt4\",\n * systemPrompt: \"You are a coding assistant\"\n * })) {\n * process.stdout.write(chunk);\n * }\n * ```\n */\n static stream(prompt: string, options?: QuickOptions): AsyncGenerator<string> {\n const client = new LLMist();\n return streamHelper(client, prompt, options);\n }\n\n /**\n * Instance method: Quick completion using this client instance.\n *\n * @param prompt - User prompt\n * @param options - Optional configuration\n * @returns Complete text response\n */\n async complete(prompt: string, options?: QuickOptions): Promise<string> {\n return completeHelper(this, prompt, options);\n }\n\n /**\n * Instance method: Quick streaming using this client instance.\n *\n * @param prompt - User prompt\n * @param options - Optional configuration\n * @returns Async generator yielding text chunks\n */\n streamText(prompt: string, options?: QuickOptions): AsyncGenerator<string> {\n return streamHelper(this, prompt, options);\n }\n\n /**\n * Create a fluent agent builder.\n * Provides a chainable API for configuring and creating agents.\n *\n * @returns AgentBuilder instance for chaining\n *\n * @example\n * ```typescript\n * const agent = LLMist.createAgent()\n * .withModel(\"sonnet\")\n * .withSystem(\"You are a helpful assistant\")\n * .withGadgets(Calculator, Weather)\n * .ask(\"What's the weather in Paris?\");\n *\n * for await (const event of agent.run()) {\n * // handle events\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Quick one-liner for simple queries\n * const answer = await LLMist.createAgent()\n * .withModel(\"gpt4-mini\")\n * .askAndCollect(\"What is 2+2?\");\n * ```\n */\n static createAgent(): AgentBuilder {\n return new AgentBuilder();\n }\n\n /**\n * Create agent builder with this client instance.\n * Useful when you want to reuse a configured client.\n *\n * @returns AgentBuilder instance using this client\n *\n * @example\n * ```typescript\n * const client = new LLMist({ ... });\n *\n * const agent = client.createAgent()\n * .withModel(\"sonnet\")\n * .ask(\"Hello\");\n * ```\n */\n createAgent(): AgentBuilder {\n return new AgentBuilder(this);\n }\n}\n"],"mappings":"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","names":["z","z","pointer","stream","init_constants","init_constants","stream","init_constants","stream","init_constants","stream","providerSpecs","stream"]}