@funkai/agents 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.generated/req.txt +1 -0
- package/.turbo/turbo-build.log +21 -0
- package/.turbo/turbo-test$colon$coverage.log +109 -0
- package/.turbo/turbo-test.log +141 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/CHANGELOG.md +16 -0
- package/ISSUES.md +540 -0
- package/LICENSE +21 -0
- package/README.md +128 -0
- package/banner.svg +97 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/core/agents/base/agent.ts.html +1705 -0
- package/coverage/lcov-report/core/agents/base/index.html +146 -0
- package/coverage/lcov-report/core/agents/base/output.ts.html +256 -0
- package/coverage/lcov-report/core/agents/base/utils.ts.html +694 -0
- package/coverage/lcov-report/core/agents/flow/engine.ts.html +928 -0
- package/coverage/lcov-report/core/agents/flow/flow-agent.ts.html +1462 -0
- package/coverage/lcov-report/core/agents/flow/index.html +146 -0
- package/coverage/lcov-report/core/agents/flow/messages.ts.html +508 -0
- package/coverage/lcov-report/core/agents/flow/steps/factory.ts.html +1975 -0
- package/coverage/lcov-report/core/agents/flow/steps/index.html +116 -0
- package/coverage/lcov-report/core/index.html +131 -0
- package/coverage/lcov-report/core/logger.ts.html +541 -0
- package/coverage/lcov-report/core/models/providers/index.html +116 -0
- package/coverage/lcov-report/core/models/providers/openai.ts.html +337 -0
- package/coverage/lcov-report/core/provider/index.html +131 -0
- package/coverage/lcov-report/core/provider/provider.ts.html +346 -0
- package/coverage/lcov-report/core/provider/usage.ts.html +376 -0
- package/coverage/lcov-report/core/tool.ts.html +577 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +221 -0
- package/coverage/lcov-report/lib/hooks.ts.html +262 -0
- package/coverage/lcov-report/lib/index.html +161 -0
- package/coverage/lcov-report/lib/middleware.ts.html +274 -0
- package/coverage/lcov-report/lib/runnable.ts.html +151 -0
- package/coverage/lcov-report/lib/trace.ts.html +520 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/utils/attempt.ts.html +199 -0
- package/coverage/lcov-report/utils/error.ts.html +421 -0
- package/coverage/lcov-report/utils/index.html +176 -0
- package/coverage/lcov-report/utils/resolve.ts.html +208 -0
- package/coverage/lcov-report/utils/result.ts.html +538 -0
- package/coverage/lcov-report/utils/zod.ts.html +178 -0
- package/coverage/lcov.info +1566 -0
- package/dist/index.d.mts +2883 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2312 -0
- package/dist/index.mjs.map +1 -0
- package/docs/core/agent.md +231 -0
- package/docs/core/hooks.md +95 -0
- package/docs/core/overview.md +87 -0
- package/docs/core/step.md +279 -0
- package/docs/core/tools.md +98 -0
- package/docs/core/workflow.md +235 -0
- package/docs/guides/create-agent.md +224 -0
- package/docs/guides/create-tool.md +137 -0
- package/docs/guides/create-workflow.md +374 -0
- package/docs/overview.md +244 -0
- package/docs/provider/models.md +55 -0
- package/docs/provider/overview.md +106 -0
- package/docs/provider/usage.md +100 -0
- package/docs/research/experimental-context.md +167 -0
- package/docs/research/gap-analysis.md +86 -0
- package/docs/research/prepare-step-and-active-tools.md +138 -0
- package/docs/research/sub-agent-model.md +249 -0
- package/docs/troubleshooting.md +60 -0
- package/logo.svg +17 -0
- package/models.config.json +18 -0
- package/package.json +60 -0
- package/scripts/generate-models.ts +324 -0
- package/src/core/agents/base/agent.test.ts +1522 -0
- package/src/core/agents/base/agent.ts +547 -0
- package/src/core/agents/base/output.test.ts +93 -0
- package/src/core/agents/base/output.ts +57 -0
- package/src/core/agents/base/types.test-d.ts +69 -0
- package/src/core/agents/base/types.ts +503 -0
- package/src/core/agents/base/utils.test.ts +397 -0
- package/src/core/agents/base/utils.ts +197 -0
- package/src/core/agents/flow/engine.test.ts +452 -0
- package/src/core/agents/flow/engine.ts +281 -0
- package/src/core/agents/flow/flow-agent.test.ts +1027 -0
- package/src/core/agents/flow/flow-agent.ts +473 -0
- package/src/core/agents/flow/messages.test.ts +198 -0
- package/src/core/agents/flow/messages.ts +141 -0
- package/src/core/agents/flow/steps/agent.test.ts +280 -0
- package/src/core/agents/flow/steps/agent.ts +87 -0
- package/src/core/agents/flow/steps/all.test.ts +300 -0
- package/src/core/agents/flow/steps/all.ts +73 -0
- package/src/core/agents/flow/steps/builder.ts +124 -0
- package/src/core/agents/flow/steps/each.test.ts +257 -0
- package/src/core/agents/flow/steps/each.ts +61 -0
- package/src/core/agents/flow/steps/factory.test-d.ts +50 -0
- package/src/core/agents/flow/steps/factory.test.ts +1025 -0
- package/src/core/agents/flow/steps/factory.ts +645 -0
- package/src/core/agents/flow/steps/map.test.ts +273 -0
- package/src/core/agents/flow/steps/map.ts +75 -0
- package/src/core/agents/flow/steps/race.test.ts +290 -0
- package/src/core/agents/flow/steps/race.ts +59 -0
- package/src/core/agents/flow/steps/reduce.test.ts +310 -0
- package/src/core/agents/flow/steps/reduce.ts +73 -0
- package/src/core/agents/flow/steps/result.ts +27 -0
- package/src/core/agents/flow/steps/step.test.ts +402 -0
- package/src/core/agents/flow/steps/step.ts +51 -0
- package/src/core/agents/flow/steps/while.test.ts +283 -0
- package/src/core/agents/flow/steps/while.ts +75 -0
- package/src/core/agents/flow/types.ts +348 -0
- package/src/core/logger.test.ts +163 -0
- package/src/core/logger.ts +152 -0
- package/src/core/models/index.test.ts +137 -0
- package/src/core/models/index.ts +152 -0
- package/src/core/models/providers/openai.ts +84 -0
- package/src/core/provider/provider.test.ts +128 -0
- package/src/core/provider/provider.ts +99 -0
- package/src/core/provider/types.ts +98 -0
- package/src/core/provider/usage.test.ts +304 -0
- package/src/core/provider/usage.ts +97 -0
- package/src/core/tool.test.ts +65 -0
- package/src/core/tool.ts +164 -0
- package/src/core/types.ts +66 -0
- package/src/index.ts +95 -0
- package/src/lib/context.test.ts +86 -0
- package/src/lib/context.ts +49 -0
- package/src/lib/hooks.test.ts +102 -0
- package/src/lib/hooks.ts +59 -0
- package/src/lib/middleware.test.ts +122 -0
- package/src/lib/middleware.ts +63 -0
- package/src/lib/runnable.test.ts +41 -0
- package/src/lib/runnable.ts +22 -0
- package/src/lib/trace.test.ts +291 -0
- package/src/lib/trace.ts +145 -0
- package/src/models/index.ts +123 -0
- package/src/models/providers/index.ts +15 -0
- package/src/models/providers/openai.ts +84 -0
- package/src/testing/context.ts +32 -0
- package/src/testing/index.ts +2 -0
- package/src/testing/logger.ts +19 -0
- package/src/utils/attempt.test.ts +127 -0
- package/src/utils/attempt.ts +38 -0
- package/src/utils/error.test.ts +179 -0
- package/src/utils/error.ts +112 -0
- package/src/utils/resolve.test.ts +38 -0
- package/src/utils/resolve.ts +41 -0
- package/src/utils/result.test.ts +79 -0
- package/src/utils/result.ts +151 -0
- package/src/utils/zod.test.ts +69 -0
- package/src/utils/zod.ts +31 -0
- package/tsconfig.json +25 -0
- package/tsdown.config.ts +15 -0
- package/vitest.config.ts +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["aiTool","baseCreateOpenRouter","tool"],"sources":["../src/core/tool.ts","../src/utils/zod.ts","../src/core/agents/base/output.ts","../src/core/provider/provider.ts","../src/lib/runnable.ts","../src/core/agents/base/utils.ts","../src/core/logger.ts","../src/lib/hooks.ts","../src/lib/middleware.ts","../src/utils/error.ts","../src/core/agents/base/agent.ts","../src/core/agents/flow/messages.ts","../src/core/agents/flow/steps/factory.ts","../src/core/provider/usage.ts","../src/lib/trace.ts","../src/core/agents/flow/flow-agent.ts","../src/core/agents/flow/engine.ts","../src/core/models/providers/openai.ts","../src/core/models/index.ts","../src/utils/result.ts"],"sourcesContent":["import { tool as aiTool, zodSchema } from \"ai\";\nimport { isFunction, isNil } from \"es-toolkit\";\nimport { has, isObject } from \"es-toolkit/compat\";\nimport { P, match } from \"ts-pattern\";\nimport type { ZodType } from \"zod\";\n\n/**\n * Configuration for creating a tool.\n *\n * @typeParam TInput - Input type, inferred from the `inputSchema` Zod schema.\n * @typeParam TOutput - Output type, inferred from the `execute` return.\n */\nexport interface ToolConfig<TInput, TOutput> {\n /**\n * Human-readable description of what the tool does.\n *\n * Shown to the model alongside the tool name. A good description\n * helps the model decide when and how to call the tool.\n */\n description: string;\n\n /**\n * Display title for the tool.\n *\n * Optional human-readable title shown in UIs and logs.\n */\n title?: string;\n\n /**\n * Zod schema for validating and typing tool input.\n *\n * The schema is serialized to JSON Schema and sent to the model.\n * Input from the model is validated against it before `execute`\n * is called.\n */\n inputSchema: ZodType<TInput>;\n\n /**\n * Zod schema for validating tool output.\n *\n * When provided, the return value of `execute` is validated\n * against this schema before being sent back to the model.\n */\n outputSchema?: ZodType<TOutput>;\n\n /**\n * Example inputs to guide the model.\n *\n * Helps the model understand expected input structure. Natively\n * supported by Anthropic; for other providers, use\n * `addToolInputExamplesMiddleware` to inject examples into the\n * tool description.\n */\n inputExamples?: Array<{ input: TInput }>;\n\n /**\n * Execute the tool with validated input.\n *\n * Called by the framework after the model requests a tool call and\n * the input passes schema validation.\n *\n * @param input - The validated tool input.\n * @returns The tool output returned to the model.\n */\n execute: (input: TInput) => Promise<TOutput>;\n}\n\n/**\n * A tool instance — the return type of `tool()` / `ai.tool()`.\n *\n * Defaults use `any` so `Record<string, Tool>` accepts concrete\n * typed tools without contravariance issues (same pattern as\n * {@link SubAgents}).\n *\n * @typeParam TInput - Tool input type.\n * @typeParam TOutput - Tool output type.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Tool<TInput = any, TOutput = any> = ReturnType<typeof aiTool<TInput, TOutput>>;\n\n/**\n * Create a tool for AI agent function calling.\n *\n * Wraps the AI SDK's `tool()` helper. The `inputSchema` (and optional\n * `outputSchema`) are wrapped via `zodSchema()` so the AI SDK can\n * convert them to JSON Schema and validate model I/O at runtime.\n *\n * @see https://ai-sdk.dev/docs/reference/ai-sdk-core/tool\n *\n * @example\n * ```typescript\n * const fetchPage = tool({\n * description: 'Fetch the contents of a web page by URL',\n * inputSchema: z.object({\n * url: z.url(),\n * }),\n * execute: async ({ url }) => {\n * const res = await fetch(url)\n * return {\n * url,\n * status: res.status,\n * body: await res.text(),\n * }\n * },\n * })\n * ```\n */\nexport function tool<TInput, TOutput>(config: ToolConfig<TInput, TOutput>): Tool<TInput, TOutput> {\n const resolvedOutputSchema = resolveOutputSchema(config.outputSchema);\n const result = {\n description: config.description,\n title: config.title,\n inputSchema: zodSchema(config.inputSchema),\n outputSchema: resolvedOutputSchema,\n inputExamples: config.inputExamples,\n execute: async (data: TInput) => config.execute(data),\n };\n assertTool<TInput, TOutput>(result);\n return aiTool(result);\n}\n\n/**\n * Resolve an optional Zod output schema into a zodSchema-wrapped value.\n *\n * @private\n */\nfunction resolveOutputSchema<TOutput>(\n schema: ZodType<TOutput> | undefined,\n): ReturnType<typeof zodSchema> | undefined {\n return match(schema)\n .with(P.nullish, () => undefined)\n .otherwise((value) => zodSchema(value));\n}\n\n/**\n * Runtime assertion that narrows `value` to `Tool<TInput, TOutput>`.\n *\n * Validates structural shape at runtime — `inputSchema` is present and\n * `execute` is a function. Generic type parameters (`TInput`, `TOutput`)\n * are erased at runtime, so only the structural shape can be verified.\n *\n * This assertion exists because TypeScript cannot evaluate the AI SDK's\n * `NeverOptional<TOutput>` conditional type when `TOutput` is an\n * unresolved generic — a known limitation with higher-order conditional\n * types. Using `asserts` is TypeScript's endorsed narrowing mechanism\n * and provides a runtime safety net if the AI SDK's tool shape changes.\n *\n * @private\n */\n/* v8 ignore start -- defensive guard; tool() always constructs a valid object */\nfunction assertTool<TInput, TOutput>(value: unknown): asserts value is Tool<TInput, TOutput> {\n if (isNil(value) || !isObject(value)) {\n throw new TypeError(\"Expected tool to be an object\");\n }\n\n if (!has(value, \"inputSchema\")) {\n throw new TypeError(\"Tool is missing required property: inputSchema\");\n }\n\n if (!has(value, \"execute\") || !isFunction(value.execute)) {\n throw new TypeError(\"Tool is missing required property: execute\");\n }\n}\n/* v8 ignore stop */\n","import type { ZodType } from \"zod\";\nimport { z } from \"zod\";\n\ntype JSONSchema = z.core.JSONSchema.JSONSchema;\n\n/**\n * Convert a Zod schema to a JSON Schema object.\n */\nexport function toJsonSchema(schema: ZodType): JSONSchema {\n return z.toJSONSchema(schema);\n}\n\n/**\n * Check if a Zod schema produces a JSON Schema with `type: 'object'`.\n *\n * Uses JSON Schema output rather than `instanceof` to correctly handle\n * wrapped schemas (transforms, refinements, pipes).\n */\nexport function isZodObject(schema: ZodType): boolean {\n return toJsonSchema(schema).type === \"object\";\n}\n\n/**\n * Check if a Zod schema produces a JSON Schema with `type: 'array'`.\n *\n * Uses JSON Schema output rather than `instanceof` to correctly handle\n * wrapped schemas (transforms, refinements, pipes).\n */\nexport function isZodArray(schema: ZodType): boolean {\n return toJsonSchema(schema).type === \"array\";\n}\n","import { Output } from \"ai\";\nimport { match } from \"ts-pattern\";\nimport type { ZodType } from \"zod\";\n\nimport { isZodArray } from \"@/utils/zod.js\";\n\n/**\n * Base constraint for AI SDK output strategies.\n *\n * Reaches through the `Output` namespace to the underlying\n * `Output<OUTPUT, PARTIAL, ELEMENT>` interface. Use this as the\n * type for any field that accepts `Output.text()`, `Output.object()`, etc.\n */\nexport type OutputSpec = Output.Output<unknown, unknown>;\n\n/**\n * Accepted values for the `output` config field.\n *\n * Allows either:\n * - An AI SDK `Output` strategy (`Output.text()`, `Output.object()`, etc.)\n * - A raw Zod schema — automatically wrapped in `Output.object()` or\n * `Output.array()` depending on the schema type.\n */\nexport type OutputParam = OutputSpec | ZodType;\n\n/**\n * Resolve an `OutputParam` into an `OutputSpec`.\n *\n * If the value is already an `OutputSpec`, it is returned as-is.\n * If it is a raw Zod schema:\n * - `z.array(...)` → `Output.array({ element: innerSchema })`\n * - Anything else → `Output.object({ schema })`\n *\n * @internal\n */\nexport function resolveOutput(output: OutputParam): OutputSpec {\n // OutputSpec instances have `parseCompleteOutput` — Zod schemas don't\n return match(\"parseCompleteOutput\" in output)\n .with(true, () => output as OutputSpec)\n .otherwise(() => {\n const schema = output as ZodType;\n return match(isZodArray(schema))\n .with(true, () => {\n const def = (schema as unknown as Record<string, unknown>)._zod as\n | { def: { element?: ZodType } }\n | undefined;\n if (def != null && def.def.element != null) {\n return Output.array({ element: def.def.element });\n }\n throw new Error(\n \"Failed to extract element schema from Zod array. \" +\n \"Pass Output.array({ element: elementSchema }) explicitly.\",\n );\n })\n .otherwise(() => Output.object({ schema }));\n });\n}\n","import {\n createOpenRouter as baseCreateOpenRouter,\n type OpenRouterProvider,\n type OpenRouterProviderSettings,\n} from \"@openrouter/ai-sdk-provider\";\n\nimport type { ModelId } from \"@/core/models/index.js\";\nimport { type LanguageModel } from \"@/core/provider/types.js\";\n\n/**\n * Create an OpenRouter provider instance with automatic API key resolution.\n *\n * Falls back to the `OPENROUTER_API_KEY` environment variable when\n * no explicit `apiKey` is provided in the options.\n *\n * @param options - Provider settings forwarded to `@openrouter/ai-sdk-provider`.\n * @returns A configured {@link OpenRouterProvider} instance.\n *\n * @example\n * ```typescript\n * const openrouter = createOpenRouter({ apiKey: 'sk-...' })\n * const m = openrouter('openai/gpt-5.2-codex')\n * ```\n */\nexport function createOpenRouter(options?: OpenRouterProviderSettings): OpenRouterProvider {\n const apiKey = resolveApiKey(options);\n return baseCreateOpenRouter({\n ...options,\n apiKey,\n });\n}\n\nfunction resolveApiKey(options: OpenRouterProviderSettings | undefined): string {\n if (options != null && options.apiKey != null) {\n return options.apiKey;\n }\n return getOpenRouterApiKey();\n}\n\n/**\n * Create a cached OpenRouter model resolver.\n *\n * The returned function caches the underlying provider and invalidates\n * when the API key changes at runtime.\n *\n * @returns A function that resolves a model ID to a {@link LanguageModel}.\n *\n * @private\n */\nfunction createCachedOpenRouter(): (modelId: ModelId) => LanguageModel {\n const cache: { provider: OpenRouterProvider | undefined; apiKey: string | undefined } = {\n provider: undefined,\n apiKey: undefined,\n };\n return (modelId: ModelId): LanguageModel => {\n const apiKey = getOpenRouterApiKey();\n if (!cache.provider || cache.apiKey !== apiKey) {\n cache.provider = baseCreateOpenRouter({ apiKey });\n cache.apiKey = apiKey;\n }\n return cache.provider(modelId);\n };\n}\n\n/**\n * Shorthand for creating a single OpenRouter language model.\n *\n * Resolves the API key from the environment and returns a ready-to-use\n * {@link LanguageModel} that can be passed directly to AI SDK functions.\n *\n * The provider instance is cached at module scope and reused across\n * calls. If `OPENROUTER_API_KEY` changes at runtime, the cache is\n * invalidated and a new provider is created.\n *\n * @param modelId - An OpenRouter model identifier (e.g. `\"openai/gpt-5.2-codex\"`).\n * @returns A configured {@link LanguageModel} instance.\n *\n * @example\n * ```typescript\n * const m = openrouter('openai/gpt-5.2-codex')\n * ```\n */\nexport const openrouter: (modelId: ModelId) => LanguageModel = createCachedOpenRouter();\n\n/**\n * Read the OpenRouter API key from the environment.\n *\n * @throws {Error} If `OPENROUTER_API_KEY` is not set.\n */\nfunction getOpenRouterApiKey(): string {\n const apiKey = process.env.OPENROUTER_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"OPENROUTER_API_KEY environment variable is required. \" +\n \"Set it in your .env file or environment.\",\n );\n }\n return apiKey;\n}\n","import type { ZodType } from \"zod\";\n\n/**\n * Symbol key for internal runnable metadata.\n *\n * Stored on Agent and Workflow objects to enable composition:\n * `buildAITools()` reads this to wrap a Runnable as a delegatable\n * tool in parent agents.\n *\n * @internal\n */\nexport const RUNNABLE_META: unique symbol = Symbol.for(\"agent-sdk:runnable-meta\");\n\n/**\n * Metadata stored on Agent and Workflow objects via {@link RUNNABLE_META}.\n *\n * @internal\n */\nexport interface RunnableMeta {\n name: string;\n inputSchema?: ZodType;\n}\n","import type { LanguageModelUsage } from \"ai\";\nimport { tool } from \"ai\";\nimport { match, P } from \"ts-pattern\";\nimport type { ZodType } from \"zod\";\nimport { z } from \"zod\";\n\nimport type { Agent, Message } from \"@/core/agents/base/types.js\";\nimport { openrouter } from \"@/core/provider/provider.js\";\nimport type { LanguageModel, TokenUsage } from \"@/core/provider/types.js\";\nimport type { Tool } from \"@/core/tool.js\";\nimport type { Model } from \"@/core/types.js\";\nimport { RUNNABLE_META, type RunnableMeta } from \"@/lib/runnable.js\";\n\n/**\n * Resolve a display name for a sub-agent tool from its runnable\n * metadata, falling back to the provided name.\n *\n * @param meta - The runnable metadata, or undefined if not available.\n * @param fallback - The fallback name to use if metadata is missing.\n * @returns The resolved tool name.\n *\n * @private\n */\nfunction resolveToolName(meta: RunnableMeta | undefined, fallback: string): string {\n if (meta != null && meta.name != null) {\n return meta.name;\n }\n return fallback;\n}\n\n/**\n * Resolve a {@link Model} to an AI SDK `LanguageModel`.\n */\nexport function resolveModel(ref: Model): LanguageModel {\n if (typeof ref === \"string\") {\n return openrouter(ref);\n }\n return ref as LanguageModel;\n}\n\n/**\n * Merge `Tool` records and wrap subagent `Runnable` objects into AI SDK\n * tool format for `generateText` / `streamText`.\n *\n * Tools created via `tool()` are already AI SDK tools and are\n * passed through directly. Only subagents need wrapping.\n *\n * Parent tools are automatically forwarded to sub-agents so they\n * can access the same capabilities (e.g. sandbox filesystem tools)\n * without explicit injection at each call site.\n */\nexport function buildAITools(\n tools?: Record<string, Tool>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Agent generic params are contravariant; `unknown` breaks assignability\n agents?: Record<string, Agent<any, any, any, any>>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- ToolSet requires `any` values; `unknown` breaks assignability with AI SDK\n): Record<string, any> | undefined {\n const hasTools = tools != null && Object.keys(tools).length > 0;\n const hasAgents = agents != null && Object.keys(agents).length > 0;\n\n if (!hasTools && !hasAgents) {\n return undefined;\n }\n\n const agentTools = agents\n ? Object.fromEntries(\n Object.entries(agents).map(([name, runnable]) => {\n // eslint-disable-next-line security/detect-object-injection -- Symbol-keyed property access; symbols cannot be user-controlled\n const meta = (runnable as unknown as Record<symbol, unknown>)[RUNNABLE_META] as\n | RunnableMeta\n | undefined;\n const toolName = resolveToolName(meta, name);\n const agentToolName = `agent:${name}`;\n\n const agentTool =\n meta != null && meta.inputSchema != null\n ? tool({\n description: `Delegate to ${toolName}`,\n inputSchema: meta.inputSchema,\n execute: async (input, { abortSignal }) => {\n const r = await runnable.generate(input, { signal: abortSignal, tools });\n if (!r.ok) {\n throw new Error(r.error.message);\n }\n return r.output;\n },\n })\n : tool({\n description: `Delegate to ${toolName}`,\n inputSchema: z.object({ prompt: z.string().describe(\"The prompt to send\") }),\n execute: async (input: { prompt: string }, { abortSignal }) => {\n const r = await runnable.generate(input.prompt, { signal: abortSignal, tools });\n if (!r.ok) {\n throw new Error(r.error.message);\n }\n return r.output;\n },\n });\n\n return [agentToolName, agentTool];\n }),\n )\n : {};\n\n return { ...tools, ...agentTools };\n}\n\n/**\n * Resolve the system prompt from config or override.\n */\nexport function resolveSystem<TInput>(\n system: string | ((params: { input: TInput }) => string) | undefined,\n input: TInput,\n): string | undefined {\n if (system == null) {\n return undefined;\n }\n if (typeof system === \"function\") {\n return system({ input });\n }\n return system;\n}\n\n/**\n * Build the prompt/messages from input based on mode (typed vs simple).\n *\n * Returns a discriminated object: either `{ prompt }` or `{ messages }`,\n * never both — matching the AI SDK's `Prompt` union type.\n */\nexport function buildPrompt<TInput>(\n input: TInput,\n config: {\n input?: ZodType<TInput>;\n prompt?: (params: { input: TInput }) => string | Message[];\n },\n): { prompt: string } | { messages: Message[] } {\n const hasInput = Boolean(config.input);\n const hasPrompt = Boolean(config.prompt);\n\n return match({ hasInput, hasPrompt })\n .with({ hasInput: true, hasPrompt: false }, () => {\n throw new Error(\n \"Agent has `input` schema but no `prompt` function — both are required for typed mode\",\n );\n })\n .with({ hasInput: false, hasPrompt: true }, () => {\n throw new Error(\n \"Agent has `prompt` function but no `input` schema — both are required for typed mode\",\n );\n })\n .with({ hasInput: true, hasPrompt: true }, () => {\n // config.prompt is guaranteed non-null by the match\n const promptFn = config.prompt as NonNullable<typeof config.prompt>;\n const built = promptFn({ input });\n return match(typeof built === \"string\")\n .with(true, () => ({ prompt: built as string }))\n .otherwise(() => ({ messages: built as Message[] }));\n })\n .otherwise(() =>\n match(typeof input === \"string\")\n .with(true, () => ({ prompt: input as string }))\n .otherwise(() => ({ messages: input as Message[] })),\n );\n}\n\n/**\n * Convert AI SDK's `LanguageModelUsage` to our flat `TokenUsage`.\n *\n * Maps nested `inputTokenDetails` / `outputTokenDetails` to flat\n * fields, resolving `undefined` → `0`.\n *\n * @param usage - The AI SDK usage object (from `totalUsage`).\n * @returns A resolved {@link TokenUsage} with all fields as numbers.\n */\nexport function toTokenUsage(usage: LanguageModelUsage): TokenUsage {\n const inputDetails = match(usage.inputTokenDetails)\n .with(P.nonNullable, (d) => ({\n cacheReadTokens: d.cacheReadTokens ?? 0,\n cacheWriteTokens: d.cacheWriteTokens ?? 0,\n }))\n .otherwise(() => ({ cacheReadTokens: 0, cacheWriteTokens: 0 }));\n\n const outputDetails = match(usage.outputTokenDetails)\n .with(P.nonNullable, (d) => ({\n reasoningTokens: d.reasoningTokens ?? 0,\n }))\n .otherwise(() => ({ reasoningTokens: 0 }));\n\n return {\n inputTokens: usage.inputTokens ?? 0,\n outputTokens: usage.outputTokens ?? 0,\n totalTokens: usage.totalTokens ?? 0,\n cacheReadTokens: inputDetails.cacheReadTokens,\n cacheWriteTokens: inputDetails.cacheWriteTokens,\n reasoningTokens: outputDetails.reasoningTokens,\n };\n}\n","/**\n * Pino-compatible leveled logger with child logger support.\n *\n * Consumers inject a pino instance (or any compatible logger);\n * the SDK defines only the interface. Each method supports both\n * `(msg, meta?)` and `(meta, msg)` call signatures to match pino's API.\n *\n * Child loggers accumulate bindings from parents — the framework\n * uses `child()` at each scope boundary (workflow, step, agent)\n * so log output automatically includes execution context.\n */\nexport interface Logger {\n /**\n * Log a message at the DEBUG level.\n *\n * Use for verbose diagnostic output that is typically silenced\n * in production (e.g. intermediate state, resolved config).\n *\n * @param msg - Human-readable log message.\n * @param meta - Optional structured metadata merged into the log entry.\n */\n debug(msg: string, meta?: Record<string, unknown>): void;\n /**\n * Log a message at the DEBUG level (pino object-first overload).\n *\n * @param meta - Structured metadata merged into the log entry.\n * @param msg - Human-readable log message.\n */\n debug(meta: Record<string, unknown>, msg: string): void;\n\n /**\n * Log a message at the INFO level.\n *\n * Use for routine operational events worth recording — step\n * transitions, successful completions, and notable state changes.\n *\n * @param msg - Human-readable log message.\n * @param meta - Optional structured metadata merged into the log entry.\n */\n info(msg: string, meta?: Record<string, unknown>): void;\n /**\n * Log a message at the INFO level (pino object-first overload).\n *\n * @param meta - Structured metadata merged into the log entry.\n * @param msg - Human-readable log message.\n */\n info(meta: Record<string, unknown>, msg: string): void;\n\n /**\n * Log a message at the WARN level.\n *\n * Use for recoverable problems that do not halt execution but\n * may indicate degraded behavior (e.g. retries, fallback paths).\n *\n * @param msg - Human-readable log message.\n * @param meta - Optional structured metadata merged into the log entry.\n */\n warn(msg: string, meta?: Record<string, unknown>): void;\n /**\n * Log a message at the WARN level (pino object-first overload).\n *\n * @param meta - Structured metadata merged into the log entry.\n * @param msg - Human-readable log message.\n */\n warn(meta: Record<string, unknown>, msg: string): void;\n\n /**\n * Log a message at the ERROR level.\n *\n * Use for failures that prevent an operation from completing\n * successfully — unhandled exceptions, rejected promises, or\n * invariant violations.\n *\n * @param msg - Human-readable log message.\n * @param meta - Optional structured metadata merged into the log entry.\n */\n error(msg: string, meta?: Record<string, unknown>): void;\n /**\n * Log a message at the ERROR level (pino object-first overload).\n *\n * @param meta - Structured metadata merged into the log entry.\n * @param msg - Human-readable log message.\n */\n error(meta: Record<string, unknown>, msg: string): void;\n\n /**\n * Create a child logger that inherits all parent bindings.\n *\n * The returned logger automatically includes the merged bindings\n * in every log entry. The framework calls `child()` at each scope\n * boundary (workflow, step, agent) so downstream logs carry full\n * execution context without manual threading.\n *\n * @param bindings - Key-value pairs merged into every log entry\n * produced by the child (and its descendants).\n * @returns A new {@link Logger} with the accumulated bindings.\n */\n child(bindings: Record<string, unknown>): Logger;\n}\n\n/**\n * Create a minimal console-based logger satisfying the {@link Logger} interface.\n *\n * Supports `child()` by merging bindings into a prefix object.\n * Each log call prepends the accumulated bindings to the output.\n *\n * Used as the default when no pino-compatible logger is injected.\n */\nexport function createDefaultLogger(bindings?: Record<string, unknown>): Logger {\n const prefix = bindings ?? {};\n return {\n debug(first: string | Record<string, unknown>, second?: string | Record<string, unknown>) {\n writeLog(prefix, \"debug\", first, second);\n },\n info(first: string | Record<string, unknown>, second?: string | Record<string, unknown>) {\n writeLog(prefix, \"info\", first, second);\n },\n warn(first: string | Record<string, unknown>, second?: string | Record<string, unknown>) {\n writeLog(prefix, \"warn\", first, second);\n },\n error(first: string | Record<string, unknown>, second?: string | Record<string, unknown>) {\n writeLog(prefix, \"error\", first, second);\n },\n child(childBindings: Record<string, unknown>): Logger {\n return createDefaultLogger({ ...prefix, ...childBindings });\n },\n };\n}\n\n/**\n *\n * @param bindings\n * @param level\n * @param first\n * @param second\n * @private\n */\nfunction writeLog(\n bindings: Record<string, unknown>,\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n first: string | Record<string, unknown>,\n second?: string | Record<string, unknown>,\n): void {\n if (typeof first === \"string\") {\n const meta = second as Record<string, unknown> | undefined;\n // eslint-disable-next-line security/detect-object-injection -- Log level is a controlled string from the logger, not user input\n console[level]({ ...bindings, ...meta }, first);\n } else {\n // eslint-disable-next-line security/detect-object-injection -- Log level is a controlled string from the logger, not user input\n console[level]({ ...bindings, ...first }, second as string);\n }\n}\n","import { match } from \"ts-pattern\";\n\nimport type { Logger } from \"@/core/logger.js\";\n\nconst formatHookError = (err: unknown): string =>\n match(err)\n .when(\n (e): e is Error => e instanceof Error,\n (e) => e.message,\n )\n .otherwise((e) => String(e));\n\n/**\n * Wrap a nullable hook into a callback for `fireHooks`, avoiding\n * optional chaining, ternaries, and non-null assertions.\n *\n * @param hookFn - The hook callback, or undefined if not configured.\n * @param event - The event payload to pass to the hook.\n * @returns A thunk that calls the hook with the event, or undefined.\n *\n * @private\n */\nexport function wrapHook<T>(\n hookFn: ((event: T) => void | Promise<void>) | undefined,\n event: T,\n): (() => void | Promise<void>) | undefined {\n if (hookFn !== undefined) {\n return () => hookFn(event);\n }\n return undefined;\n}\n\n/**\n * Run hook callbacks sequentially, logging errors at warn level.\n *\n * Unlike `attemptEachAsync`, this function surfaces errors via the\n * logger so hook failures are visible in diagnostic output.\n *\n * @param log - Logger for warning about hook errors.\n * @param handlers - Callbacks to execute in order. `undefined` entries are skipped.\n */\nexport async function fireHooks(\n log: Logger,\n ...handlers: Array<(() => void | Promise<void>) | undefined>\n): Promise<void> {\n for (const h of handlers) {\n if (h != null) {\n try {\n // oxlint-disable-next-line no-await-in-loop - sequential by design\n await h();\n } catch (err) {\n const errorMessage = formatHookError(err);\n log.warn(\"hook error\", {\n error: errorMessage,\n });\n }\n }\n }\n}\n","import { wrapLanguageModel, type LanguageModelMiddleware } from \"ai\";\n\nimport { type LanguageModel } from \"@/core/provider/types.js\";\n\n/**\n * Options for {@link withModelMiddleware}.\n */\ninterface WrapModelOptions {\n /** The base language model to wrap. */\n model: LanguageModel;\n\n /**\n * Additional middleware to apply before defaults (outermost).\n * Middleware runs in array order — first entry wraps outermost.\n */\n middleware?: LanguageModelMiddleware[];\n\n /**\n * Whether to include the AI SDK devtools middleware.\n *\n * Defaults to `true` when `NODE_ENV === 'development'`.\n * Set to `false` to disable in development, or `true` to force-enable.\n */\n devtools?: boolean;\n}\n\n/**\n * Wrap a language model with middleware.\n *\n * In development (`NODE_ENV === 'development'`), the AI SDK devtools\n * middleware is appended automatically. Any additional middleware\n * provided in the options is applied first (outermost).\n *\n * @param options - The model and optional middleware configuration.\n * @returns A wrapped language model with middleware applied.\n */\nexport async function withModelMiddleware(options: WrapModelOptions): Promise<LanguageModel> {\n const useDevtools =\n options.devtools === true ||\n (options.devtools !== false && process.env.NODE_ENV === \"development\");\n\n const defaultMiddleware: LanguageModelMiddleware[] = [];\n if (useDevtools) {\n const { devToolsMiddleware } = await import(\"@ai-sdk/devtools\");\n defaultMiddleware.push(devToolsMiddleware());\n }\n\n const middleware: LanguageModelMiddleware[] = [];\n if (options.middleware) {\n middleware.push(...options.middleware, ...defaultMiddleware);\n } else {\n middleware.push(...defaultMiddleware);\n }\n\n if (middleware.length === 0) {\n return options.model;\n }\n\n return wrapLanguageModel({\n model: options.model,\n middleware,\n });\n}\n","import { attempt, isError, isMap, isNil, isPrimitive, isSet, isString } from \"es-toolkit\";\n\n/**\n * Coerces an unknown thrown value into a proper `Error` instance.\n *\n * Handles the common cases where libraries throw non-`Error` values\n * (e.g. plain API response bodies, arrays, Maps) that would otherwise\n * serialize as `[object Object]` in error messages.\n *\n * @param thrown - The caught value from a `catch` block.\n * @returns An `Error` with a meaningful `.message`. If `thrown` is\n * already an `Error`, it is returned as-is. The original value is\n * preserved as `.cause` for debugging.\n *\n * @example\n * ```typescript\n * try {\n * await riskyCall()\n * } catch (thrown) {\n * const error = toError(thrown)\n * console.error(error.message)\n * }\n * ```\n */\nexport function toError(thrown: unknown): Error {\n if (isError(thrown)) {\n return thrown;\n }\n if (isString(thrown)) {\n return new Error(thrown, { cause: thrown });\n }\n return new Error(safeStringify(thrown), { cause: thrown });\n}\n\n/**\n * Produce a human-readable string from any unknown value.\n *\n * Uses `JSON.stringify` for structured types (plain objects, arrays)\n * so the message contains actual content instead of `[object Object]`.\n * Maps and Sets are converted to their array representation first.\n * Falls back to `String()` for primitives or when serialization fails\n * (e.g. circular references).\n *\n * @param value - The value to stringify.\n * @returns A meaningful string representation.\n *\n * @example\n * ```typescript\n * safeStringify({ status: 400 }) // '{\"status\":400}'\n * safeStringify(new Map([['k', 'v']])) // '[[\"k\",\"v\"]]'\n * safeStringify(null) // 'null'\n * safeStringify(42) // '42'\n * ```\n */\nexport function safeStringify(value: unknown): string {\n if (isNil(value) || isPrimitive(value)) {\n return String(value);\n }\n return safeStringifyJSON(value) || String(value);\n}\n\n/**\n * Safely serializes a value to a JSON string without throwing.\n *\n * Converts types that `JSON.stringify` handles poorly (Maps, Sets)\n * into serializable equivalents before stringifying. Returns an empty\n * string when serialization fails (e.g. circular references).\n *\n * @param value - The value to serialize.\n * @returns The JSON string, or an empty string if serialization fails.\n *\n * @example\n * ```typescript\n * safeStringifyJSON({ status: 400 }) // '{\"status\":400}'\n * safeStringifyJSON(new Map([['k', 'v']])) // '[[\"k\",\"v\"]]'\n * safeStringifyJSON(circularObj) // ''\n * ```\n */\nexport function safeStringifyJSON(value: unknown): string {\n const serializable = toSerializable(value);\n const [error, json] = attempt(() => JSON.stringify(serializable) as string | undefined);\n if (!isNil(error) || isNil(json)) {\n return \"\";\n }\n return json;\n}\n\n// ---------------------------------------------------------------------------\n// private helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Convert types that `JSON.stringify` handles poorly into\n * serializable equivalents.\n *\n * - `Map` → array of `[key, value]` entries\n * - `Set` → array of values\n * - Everything else → passed through unchanged\n *\n * @private\n * @param value - The value to normalize.\n * @returns A JSON-friendly representation.\n */\nfunction toSerializable(value: unknown): unknown {\n if (isMap(value)) {\n return Array.from(value.entries());\n }\n if (isSet(value)) {\n return Array.from(value);\n }\n return value;\n}\n","import { generateText, streamText, stepCountIs } from \"ai\";\nimport type { AsyncIterableStream } from \"ai\";\n\nimport { resolveOutput } from \"@/core/agents/base/output.js\";\nimport type {\n Agent,\n AgentConfig,\n AgentOverrides,\n GenerateResult,\n Message,\n StreamPart,\n StreamResult,\n SubAgents,\n} from \"@/core/agents/base/types.js\";\nimport {\n resolveModel,\n buildAITools,\n resolveSystem,\n buildPrompt,\n toTokenUsage,\n} from \"@/core/agents/base/utils.js\";\nimport { createDefaultLogger } from \"@/core/logger.js\";\nimport type { Tool } from \"@/core/tool.js\";\nimport { fireHooks, wrapHook } from \"@/lib/hooks.js\";\nimport { withModelMiddleware } from \"@/lib/middleware.js\";\nimport { RUNNABLE_META, type RunnableMeta } from \"@/lib/runnable.js\";\nimport { toError } from \"@/utils/error.js\";\n\n/**\n * Safely read a property from `overrides`, which may be undefined.\n * Replaces `overrides?.prop` optional chaining.\n *\n * @private\n */\nfunction readOverride<\n TTools extends Record<string, Tool>,\n TSubAgents extends SubAgents,\n K extends keyof AgentOverrides<TTools, TSubAgents>,\n>(\n overrides: AgentOverrides<TTools, TSubAgents> | undefined,\n key: K,\n): AgentOverrides<TTools, TSubAgents>[K] | undefined {\n if (overrides !== undefined) {\n // eslint-disable-next-line security/detect-object-injection -- Key is a controlled function parameter, not user input\n return overrides[key];\n }\n return undefined;\n}\n\n/**\n * Safely compute the JSON-serialized length of a value.\n * Returns 0 if serialization fails (e.g. circular refs, BigInt).\n *\n * @private\n */\nfunction safeSerializedLength(value: unknown): number {\n try {\n const json = JSON.stringify(value);\n return typeof json === \"string\" ? json.length : 0;\n } catch {\n return 0;\n }\n}\n\n/**\n * Return the value if the predicate is true, otherwise undefined.\n * Replaces `predicate ? value : undefined` ternary.\n *\n * @private\n */\nfunction valueOrUndefined<T>(predicate: boolean, value: T): T | undefined {\n if (predicate) {\n return value;\n }\n return undefined;\n}\n\n/**\n * Resolve an optional output param. Returns `resolveOutput(param)` if\n * param is defined, otherwise undefined.\n *\n * @private\n */\nfunction resolveOptionalOutput(\n param: import(\"@/core/agents/base/output.js\").OutputParam | undefined,\n): import(\"@/core/agents/base/output.js\").OutputSpec | undefined {\n if (param !== undefined) {\n return resolveOutput(param);\n }\n return undefined;\n}\n\n/**\n * Safely extract a property from an object, returning `{}` if the\n * property does not exist. Replaces `'key' in obj ? obj[key] : {}` ternary.\n *\n * @private\n */\nfunction extractProperty(obj: Record<string, unknown>, key: string): unknown {\n if (key in obj) {\n // eslint-disable-next-line security/detect-object-injection -- Key is a controlled function parameter, not user input\n return obj[key];\n }\n return {};\n}\n\n/**\n * Extract token usage from a step's usage object, defaulting to 0\n * when usage is undefined. Replaces optional chaining on `step.usage`.\n *\n * @private\n */\nfunction extractUsage(\n usage: { inputTokens?: number; outputTokens?: number; totalTokens?: number } | undefined,\n): {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n} {\n if (usage !== undefined) {\n const inputTokens = usage.inputTokens ?? 0;\n const outputTokens = usage.outputTokens ?? 0;\n return {\n inputTokens,\n outputTokens,\n totalTokens: usage.totalTokens ?? inputTokens + outputTokens,\n };\n }\n return { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n}\n\n/**\n * Return `ifOutput` when `output` is defined, `ifText` otherwise.\n * Replaces `output ? aiResult.output : aiResult.text` ternary.\n *\n * @private\n */\nfunction pickByOutput<T>(output: unknown, ifOutput: T, ifText: T): T {\n if (output !== undefined) {\n return ifOutput;\n }\n return ifText;\n}\n\n/**\n * Create an agent with typed input, tools, subagents, and hooks.\n *\n * Agents run a tool loop (via the AI SDK's `generateText`) until a\n * stop condition is met. They support:\n * - **Typed input** via Zod schema + prompt template.\n * - **Simple mode** — pass a string or messages directly.\n * - **Tools** for function calling.\n * - **Subagents** auto-wrapped as delegatable tools.\n * - **Inline overrides** per call.\n * - **Hooks** for observability.\n * - **Result return type** that never throws.\n *\n * @typeParam TInput - Agent input type (default: `string | Message[]`).\n * @typeParam TOutput - Agent output type (default: `string`).\n * @typeParam TTools - Record of tools.\n * @typeParam TSubAgents - Record of subagents.\n * @param config - Agent configuration including name, model, schemas,\n * tools, subagents, hooks, and logger.\n * @returns An `Agent` instance with `.generate()`, `.stream()`, and `.fn()`.\n *\n * @example\n * ```typescript\n * // Simple mode — pass a string directly\n * const helper = agent({\n * name: 'helper',\n * model: 'openai/gpt-4.1',\n * system: 'You are a helpful assistant.',\n * })\n * await helper.generate('What is TypeScript?')\n *\n * // Typed mode — input schema + prompt template\n * const summarizer = agent({\n * name: 'summarizer',\n * input: z.object({ text: z.string() }),\n * model: 'openai/gpt-4.1',\n * prompt: ({ input }) => `Summarize:\\n\\n${input.text}`,\n * })\n * await summarizer.generate({ text: '...' })\n *\n * // Export as a plain function\n * export const summarize = summarizer.fn()\n * ```\n */\nexport function agent<\n TInput = string | Message[],\n TOutput = string,\n TTools extends Record<string, Tool> = {},\n TSubAgents extends SubAgents = {},\n>(\n config: AgentConfig<TInput, TOutput, TTools, TSubAgents>,\n): Agent<TInput, TOutput, TTools, TSubAgents> {\n const baseLogger = config.logger ?? createDefaultLogger();\n\n /**\n * Validate raw input against the config schema, if present.\n *\n * Returns a discriminated union: `{ ok: true, input }` on success,\n * `{ ok: false, error }` when validation fails.\n *\n * @private\n */\n function validateInput(\n rawInput: TInput,\n ): { ok: true; input: TInput } | { ok: false; error: { code: string; message: string } } {\n if (!config.input) {\n return { ok: true, input: rawInput };\n }\n const parsed = config.input.safeParse(rawInput);\n if (!parsed.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: `Input validation failed: ${parsed.error.message}`,\n },\n };\n }\n return { ok: true, input: parsed.data as TInput };\n }\n\n async function generate(\n rawInput: TInput,\n overrides?: AgentOverrides<TTools, TSubAgents>,\n ): Promise<import(\"@/utils/result.js\").Result<GenerateResult<TOutput>>> {\n const validated = validateInput(rawInput);\n if (!validated.ok) {\n return { ok: false, error: validated.error };\n }\n const input = validated.input;\n\n const overrideLogger = readOverride(overrides, \"logger\");\n const log = (overrideLogger ?? baseLogger).child({ agentId: config.name });\n const startedAt = Date.now();\n\n try {\n const overrideModel = readOverride(overrides, \"model\");\n const modelRef = overrideModel ?? config.model;\n const baseModel = resolveModel(modelRef);\n const model = await withModelMiddleware({ model: baseModel });\n\n const overrideTools = readOverride(overrides, \"tools\");\n const overrideAgents = readOverride(overrides, \"agents\");\n const mergedTools = { ...config.tools, ...overrideTools } as Record<string, Tool>;\n const mergedAgents = { ...config.agents, ...overrideAgents } as SubAgents;\n const hasTools = Object.keys(mergedTools).length > 0;\n const hasAgents = Object.keys(mergedAgents).length > 0;\n\n const aiTools = buildAITools(\n valueOrUndefined(hasTools, mergedTools),\n valueOrUndefined(hasAgents, mergedAgents),\n );\n\n const overrideSystem = readOverride(overrides, \"system\");\n const systemConfig = overrideSystem ?? config.system;\n const system = resolveSystem(systemConfig, input);\n\n const promptParams = buildPrompt(input, config);\n\n const overrideOutput = readOverride(overrides, \"output\");\n const outputParam = overrideOutput ?? config.output;\n const output = resolveOptionalOutput(outputParam);\n\n await fireHooks(\n log,\n wrapHook(config.onStart, { input }),\n wrapHook(readOverride(overrides, \"onStart\"), { input }),\n );\n\n log.debug(\"agent.generate start\", { name: config.name });\n\n const overrideMaxSteps = readOverride(overrides, \"maxSteps\");\n const maxSteps = overrideMaxSteps ?? config.maxSteps ?? 20;\n const overrideSignal = readOverride(overrides, \"signal\");\n const stepCounter = { value: 0 };\n const aiResult = await generateText({\n model,\n system,\n ...promptParams,\n tools: aiTools,\n output,\n stopWhen: stepCountIs(maxSteps),\n abortSignal: overrideSignal,\n onStepFinish: async (step) => {\n const stepId = `${config.name}:${stepCounter.value++}`;\n const toolCalls = (step.toolCalls ?? []).map((tc) => {\n const args = extractProperty(tc, \"args\");\n return { toolName: tc.toolName, argsTextLength: safeSerializedLength(args) };\n });\n const toolResults = (step.toolResults ?? []).map((tr) => {\n const result = extractProperty(tr, \"result\");\n return { toolName: tr.toolName, resultTextLength: safeSerializedLength(result) };\n });\n const usage = extractUsage(step.usage);\n const event = { stepId, toolCalls, toolResults, usage };\n await fireHooks(\n log,\n wrapHook(config.onStepFinish, event),\n wrapHook(readOverride(overrides, \"onStepFinish\"), event),\n );\n },\n });\n\n const duration = Date.now() - startedAt;\n\n const generateResult: GenerateResult<TOutput> = {\n output: pickByOutput(output, aiResult.output, aiResult.text) as TOutput,\n messages: aiResult.response.messages as Message[],\n usage: toTokenUsage(aiResult.totalUsage),\n finishReason: aiResult.finishReason,\n };\n\n await fireHooks(\n log,\n wrapHook(config.onFinish, { input, result: generateResult, duration }),\n wrapHook(readOverride(overrides, \"onFinish\"), {\n input,\n result: generateResult as GenerateResult,\n duration,\n }),\n );\n\n log.debug(\"agent.generate finish\", { name: config.name, duration });\n\n return { ok: true, ...generateResult };\n } catch (thrown) {\n const error = toError(thrown);\n const duration = Date.now() - startedAt;\n\n log.error(\"agent.generate error\", { name: config.name, error: error.message, duration });\n\n await fireHooks(\n log,\n wrapHook(config.onError, { input, error }),\n wrapHook(readOverride(overrides, \"onError\"), { input, error }),\n );\n\n return {\n ok: false,\n error: {\n code: \"AGENT_ERROR\",\n message: error.message,\n cause: error,\n },\n };\n }\n }\n\n async function stream(\n rawInput: TInput,\n overrides?: AgentOverrides<TTools, TSubAgents>,\n ): Promise<import(\"@/utils/result.js\").Result<StreamResult<TOutput>>> {\n const validated = validateInput(rawInput);\n if (!validated.ok) {\n return { ok: false, error: validated.error };\n }\n const input = validated.input;\n\n const overrideLogger = readOverride(overrides, \"logger\");\n const log = (overrideLogger ?? baseLogger).child({ agentId: config.name });\n const startedAt = Date.now();\n\n try {\n const overrideModel = readOverride(overrides, \"model\");\n const modelRef = overrideModel ?? config.model;\n const baseModel = resolveModel(modelRef);\n const model = await withModelMiddleware({ model: baseModel });\n\n const overrideTools = readOverride(overrides, \"tools\");\n const overrideAgents = readOverride(overrides, \"agents\");\n const mergedTools = { ...config.tools, ...overrideTools } as Record<string, Tool>;\n const mergedAgents = { ...config.agents, ...overrideAgents } as SubAgents;\n const hasTools = Object.keys(mergedTools).length > 0;\n const hasAgents = Object.keys(mergedAgents).length > 0;\n\n const aiTools = buildAITools(\n valueOrUndefined(hasTools, mergedTools),\n valueOrUndefined(hasAgents, mergedAgents),\n );\n\n const overrideSystem = readOverride(overrides, \"system\");\n const systemConfig = overrideSystem ?? config.system;\n const system = resolveSystem(systemConfig, input);\n\n const promptParams = buildPrompt(input, config);\n\n const overrideOutput = readOverride(overrides, \"output\");\n const outputParam = overrideOutput ?? config.output;\n const output = resolveOptionalOutput(outputParam);\n\n await fireHooks(\n log,\n wrapHook(config.onStart, { input }),\n wrapHook(readOverride(overrides, \"onStart\"), { input }),\n );\n\n log.debug(\"agent.stream start\", { name: config.name });\n\n const overrideMaxSteps = readOverride(overrides, \"maxSteps\");\n const maxSteps = overrideMaxSteps ?? config.maxSteps ?? 20;\n const overrideSignal = readOverride(overrides, \"signal\");\n const stepCounter = { value: 0 };\n const aiResult = streamText({\n model,\n system,\n ...promptParams,\n tools: aiTools,\n output,\n stopWhen: stepCountIs(maxSteps),\n abortSignal: overrideSignal,\n onStepFinish: async (step) => {\n const stepId = `${config.name}:${stepCounter.value++}`;\n const toolCalls = (step.toolCalls ?? []).map((tc) => {\n const args = extractProperty(tc, \"args\");\n return { toolName: tc.toolName, argsTextLength: safeSerializedLength(args) };\n });\n const toolResults = (step.toolResults ?? []).map((tr) => {\n const result = extractProperty(tr, \"result\");\n return { toolName: tr.toolName, resultTextLength: safeSerializedLength(result) };\n });\n const usage = extractUsage(step.usage);\n const event = { stepId, toolCalls, toolResults, usage };\n await fireHooks(\n log,\n wrapHook(config.onStepFinish, event),\n wrapHook(readOverride(overrides, \"onStepFinish\"), event),\n );\n },\n });\n\n const { readable, writable } = new TransformStream<StreamPart, StreamPart>();\n\n const done = (async () => {\n const writer = writable.getWriter();\n try {\n for await (const part of aiResult.fullStream) {\n await writer.write(part as StreamPart);\n }\n await writer.close();\n } catch (error) {\n await writer.abort(error).catch(() => {});\n throw error;\n }\n\n const finalOutput = pickByOutput(\n output,\n await aiResult.output,\n await aiResult.text,\n ) as TOutput;\n const response = await aiResult.response;\n const finalMessages = response.messages as Message[];\n const finalUsage = toTokenUsage(await aiResult.totalUsage);\n const finalFinishReason = await aiResult.finishReason;\n\n const duration = Date.now() - startedAt;\n\n const generateResult: GenerateResult<TOutput> = {\n output: finalOutput,\n messages: finalMessages,\n usage: finalUsage,\n finishReason: finalFinishReason,\n };\n await fireHooks(\n log,\n wrapHook(config.onFinish, { input, result: generateResult, duration }),\n wrapHook(readOverride(overrides, \"onFinish\"), {\n input,\n result: generateResult as GenerateResult,\n duration,\n }),\n );\n\n log.debug(\"agent.stream finish\", { name: config.name, duration });\n\n return {\n output: finalOutput,\n messages: finalMessages,\n usage: finalUsage,\n finishReason: finalFinishReason,\n };\n })();\n\n // Catch stream errors: fire onError hooks and prevent unhandled rejections\n done.catch(async (thrown) => {\n const error = toError(thrown);\n const duration = Date.now() - startedAt;\n\n log.error(\"agent.stream error\", { name: config.name, error: error.message, duration });\n\n await fireHooks(\n log,\n wrapHook(config.onError, { input, error }),\n wrapHook(readOverride(overrides, \"onError\"), { input, error }),\n );\n });\n\n const streamResult: StreamResult<TOutput> = {\n output: done.then((r) => r.output),\n messages: done.then((r) => r.messages),\n usage: done.then((r) => r.usage),\n finishReason: done.then((r) => r.finishReason),\n fullStream: readable as AsyncIterableStream<StreamPart>,\n };\n\n return { ok: true, ...streamResult };\n } catch (thrown) {\n const error = toError(thrown);\n const duration = Date.now() - startedAt;\n\n log.error(\"agent.stream error\", { name: config.name, error: error.message, duration });\n\n await fireHooks(\n log,\n wrapHook(config.onError, { input, error }),\n wrapHook(readOverride(overrides, \"onError\"), { input, error }),\n );\n\n return {\n ok: false,\n error: {\n code: \"AGENT_ERROR\",\n message: error.message,\n cause: error,\n },\n };\n }\n }\n\n // eslint-disable-next-line no-shadow -- Local variable is the return value constructed inside its own factory function\n const agent: Agent<TInput, TOutput, TTools, TSubAgents> = {\n generate,\n stream,\n fn: () => generate,\n };\n\n // eslint-disable-next-line security/detect-object-injection -- Symbol-keyed property access; symbols cannot be user-controlled\n (agent as unknown as Record<symbol, unknown>)[RUNNABLE_META] = {\n name: config.name,\n inputSchema: config.input,\n } satisfies RunnableMeta;\n\n return agent;\n}\n","import type { Message } from \"@/core/agents/base/types.js\";\nimport { safeStringify } from \"@/utils/error.js\";\n\n/**\n * Build the `toolCallId` for a step.\n *\n * Combines the step id with the global step index to produce a unique\n * identifier that correlates tool-call and tool-result messages.\n *\n * @param stepId - The step's user-provided id.\n * @param index - The step's global index within the flow.\n * @returns A unique tool call identifier.\n */\nexport function buildToolCallId(stepId: string, index: number): string {\n return `${stepId}-${index}`;\n}\n\n/**\n * Create an assistant message containing a synthetic tool-call part.\n *\n * Emitted when a `$` step starts execution. The `input` field captures\n * the step's input snapshot (or `{}` when no input is available).\n *\n * @param toolCallId - Unique tool call identifier.\n * @param toolName - The step id used as the tool name.\n * @param args - The step's input snapshot.\n * @returns A `Message` with role `assistant` and a `tool-call` content part.\n */\nexport function createToolCallMessage(\n toolCallId: string,\n toolName: string,\n args: unknown,\n): Message {\n return {\n role: \"assistant\",\n content: [\n {\n type: \"tool-call\",\n toolCallId,\n toolName,\n input: args ?? {},\n },\n ],\n };\n}\n\n/**\n * Create a tool message containing a synthetic tool-result part.\n *\n * Emitted when a `$` step finishes execution. The `result` field captures\n * the step's output. When `isError` is true, the result represents an\n * error message.\n *\n * @param toolCallId - Unique tool call identifier (must match the paired tool-call).\n * @param toolName - The step id used as the tool name.\n * @param result - The step's output snapshot.\n * @param isError - Whether this result represents an error.\n * @returns A `Message` with role `tool` and a `tool-result` content part.\n */\nexport function createToolResultMessage(\n toolCallId: string,\n toolName: string,\n result: unknown,\n isError?: boolean,\n): Message {\n // Synthetic tool-result for flow step tracking — not consumed by the AI SDK\n return {\n role: \"tool\",\n content: [\n {\n type: \"tool-result\",\n toolCallId,\n toolName,\n output: result ?? {},\n ...(isError ? { isError: true } : {}),\n },\n ],\n } as Message;\n}\n\n/**\n * Safely serialize a value to a string for message content.\n *\n * Returns the value as-is when it's already a string. Otherwise\n * delegates to {@link safeStringify} which handles circular refs,\n * Maps, Sets, bigints, and other non-JSON-serializable types.\n *\n * @param value - The value to serialize.\n * @returns A string representation of the value.\n */\nfunction serializeMessageContent(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n return safeStringify(value ?? null);\n}\n\n/**\n * Create a user message from flow agent input.\n *\n * This is the first message in the flow's message array, representing\n * the input passed to `flowAgent.generate()` or `flowAgent.stream()`.\n *\n * @param input - The flow agent input.\n * @returns A `Message` with role `user`.\n */\nexport function createUserMessage(input: unknown): Message {\n return { role: \"user\", content: serializeMessageContent(input) };\n}\n\n/**\n * Create a final assistant message from flow agent output.\n *\n * This is the last message in the flow's message array, representing\n * the validated output returned by the handler.\n *\n * @param output - The flow agent output.\n * @returns A `Message` with role `assistant`.\n */\nexport function createAssistantMessage(output: unknown): Message {\n return { role: \"assistant\", content: serializeMessageContent(output) };\n}\n\n/**\n * Collect text content from assistant messages in the message array.\n *\n * Used for flow agents without an output schema — the output is\n * the concatenated text from sub-agent responses. Only considers\n * messages with string content (tool-call messages have array content\n * and are skipped).\n *\n * @param messages - The flow's message array.\n * @returns The concatenated assistant text, trimmed.\n */\nexport function collectTextFromMessages(messages: readonly Message[]): string {\n return messages\n .filter((m) => m.role === \"assistant\" && typeof m.content === \"string\")\n .map((m) => m.content as string)\n .join(\"\\n\")\n .trim();\n}\n","import type { StreamPart } from \"@/core/agents/base/types.js\";\nimport {\n buildToolCallId,\n createToolCallMessage,\n createToolResultMessage,\n} from \"@/core/agents/flow/messages.js\";\nimport type { AgentStepConfig } from \"@/core/agents/flow/steps/agent.js\";\nimport type { AllConfig } from \"@/core/agents/flow/steps/all.js\";\nimport type { StepBuilder } from \"@/core/agents/flow/steps/builder.js\";\nimport type { EachConfig } from \"@/core/agents/flow/steps/each.js\";\nimport type { MapConfig } from \"@/core/agents/flow/steps/map.js\";\nimport type { RaceConfig } from \"@/core/agents/flow/steps/race.js\";\nimport type { ReduceConfig } from \"@/core/agents/flow/steps/reduce.js\";\nimport type { StepResult, StepError } from \"@/core/agents/flow/steps/result.js\";\nimport type { StepConfig } from \"@/core/agents/flow/steps/step.js\";\nimport type { WhileConfig } from \"@/core/agents/flow/steps/while.js\";\nimport type { StepInfo } from \"@/core/agents/flow/types.js\";\nimport type { Context } from \"@/lib/context.js\";\nimport { fireHooks } from \"@/lib/hooks.js\";\nimport type { TraceEntry, OperationType } from \"@/lib/trace.js\";\nimport { toError } from \"@/utils/error.js\";\n\n/**\n * Options for {@link createStepBuilder}.\n */\nexport interface StepBuilderOptions {\n /**\n * Internal execution context.\n *\n * Provides the abort signal, logger, and trace array.\n */\n ctx: Context;\n\n /**\n * Parent flow agent hooks forwarded to each step.\n *\n * These fire after the step's own hooks, giving the flow agent\n * visibility into every `$` call.\n */\n parentHooks?: {\n onStepStart?: (event: { step: StepInfo }) => void | Promise<void>;\n onStepFinish?: (event: {\n step: StepInfo;\n result: unknown;\n duration: number;\n }) => void | Promise<void>;\n };\n\n /**\n * Stream writer for emitting typed `StreamPart` events.\n *\n * When provided, step start/finish events are written as typed\n * AI SDK stream events. Used by `flowAgent.stream()` to pipe\n * step events through the readable stream.\n */\n writer?: WritableStreamDefaultWriter<StreamPart>;\n}\n\n/**\n * Mutable ref for globally unique step indices within a flow agent.\n */\ninterface IndexRef {\n current: number;\n}\n\n/**\n * Create a `StepBuilder` (`$`) instance.\n *\n * The returned builder is the `$` object passed into every flow agent\n * handler and step callback. It owns the full step lifecycle:\n * trace registration, hook firing, error wrapping,\n * and `StepResult<T>` construction.\n *\n * @param options - Factory configuration with context, optional parent\n * hooks, and optional stream writer.\n * @returns A `StepBuilder` instance.\n */\nexport function createStepBuilder(options: StepBuilderOptions): StepBuilder {\n const indexRef: IndexRef = { current: 0 };\n return createStepBuilderInternal(options, indexRef);\n}\n\n/**\n * Internal factory that accepts a shared index ref.\n *\n * Child builders (created for nested `$` in callbacks) share\n * the same ref so step indices are globally unique.\n */\nfunction createStepBuilderInternal(options: StepBuilderOptions, indexRef: IndexRef): StepBuilder {\n const { ctx, parentHooks, writer } = options;\n\n /**\n * Core step primitive — every other method delegates here.\n */\n async function step<T>(config: StepConfig<T>): Promise<StepResult<T>> {\n const onFinishHandler = buildOnFinishHandler<T>(config.onFinish);\n\n return executeStep<T>({\n id: config.id,\n type: \"step\",\n execute: config.execute,\n onStart: config.onStart,\n onFinish: onFinishHandler,\n onError: config.onError,\n });\n }\n\n /**\n * Shared lifecycle for all step types.\n */\n async function executeStep<T>(params: {\n id: string;\n type: OperationType;\n execute: (args: { $: StepBuilder }) => Promise<T>;\n input?: unknown;\n onStart?: (event: { id: string }) => void | Promise<void>;\n onFinish?: (event: { id: string; result: unknown; duration: number }) => void | Promise<void>;\n onError?: (event: { id: string; error: Error }) => void | Promise<void>;\n }): Promise<StepResult<T>> {\n const { id, type, execute, input, onStart, onFinish, onError } = params;\n\n const stepInfo: StepInfo = { id, index: indexRef.current++, type };\n const startedAt = Date.now();\n\n const childTrace: TraceEntry[] = [];\n const childCtx: Context = {\n signal: ctx.signal,\n log: ctx.log.child({ stepId: id }),\n trace: childTrace,\n messages: ctx.messages,\n };\n const child$ = createStepBuilderInternal({ ctx: childCtx, parentHooks, writer }, indexRef);\n\n // Build synthetic tool-call message and push to context\n const toolCallId = buildToolCallId(id, stepInfo.index);\n ctx.messages.push(createToolCallMessage(toolCallId, id, input));\n\n // Write tool-call event to stream if writer is available\n if (writer != null) {\n writer\n .write({\n type: \"tool-call\",\n toolCallId,\n toolName: id,\n input: input ?? {},\n } as StreamPart)\n /* v8 ignore start -- defensive; writer.write rarely rejects in practice */\n .catch((err) => {\n ctx.log.warn({ err, toolCallId }, \"failed to write tool-call event to stream\");\n });\n /* v8 ignore stop */\n }\n\n const onStartHook = buildHookCallback(onStart, (fn) => fn({ id }));\n const parentOnStepStartHook = buildParentHookCallback(parentHooks, \"onStepStart\", (fn) =>\n fn({ step: stepInfo }),\n );\n\n await fireHooks(ctx.log, onStartHook, parentOnStepStartHook);\n\n try {\n const value = await execute({ $: child$ });\n const finishedAt = Date.now();\n const duration = finishedAt - startedAt;\n\n const usage =\n value != null && typeof value === \"object\" && \"usage\" in value\n ? (value as { usage: import(\"@/core/provider/types.js\").TokenUsage }).usage\n : undefined;\n\n ctx.trace.push({\n id,\n type,\n input,\n startedAt,\n finishedAt,\n children: childTrace,\n output: value,\n ...(usage != null ? { usage } : {}),\n });\n\n // Push synthetic tool-result message\n ctx.messages.push(createToolResultMessage(toolCallId, id, value));\n\n // Write tool-result event to stream\n if (writer != null) {\n writer\n .write({\n type: \"tool-result\",\n toolCallId,\n toolName: id,\n input: input ?? {},\n output: value ?? null,\n } as StreamPart)\n /* v8 ignore start -- defensive; writer.write rarely rejects in practice */\n .catch((err) => {\n ctx.log.warn({ err, toolCallId }, \"failed to write tool-result event to stream\");\n });\n /* v8 ignore stop */\n }\n\n const onFinishHook = buildHookCallback(onFinish, (fn) =>\n fn({ id, result: value as T, duration }),\n );\n const parentOnStepFinishHook = buildParentHookCallback(parentHooks, \"onStepFinish\", (fn) =>\n fn({ step: stepInfo, result: value, duration }),\n );\n\n await fireHooks(ctx.log, onFinishHook, parentOnStepFinishHook);\n\n return { ok: true, value, step: stepInfo, duration } as StepResult<T>;\n } catch (thrown) {\n const error = toError(thrown);\n const finishedAt = Date.now();\n const duration = finishedAt - startedAt;\n\n ctx.trace.push({\n id,\n type,\n input,\n startedAt,\n finishedAt,\n children: childTrace,\n error,\n });\n\n const stepError: StepError = {\n code: \"STEP_ERROR\",\n message: error.message,\n cause: error,\n stepId: id,\n };\n\n // Push synthetic tool-result message for error\n ctx.messages.push(createToolResultMessage(toolCallId, id, { error: error.message }, true));\n\n // Write error tool-result event to stream\n if (writer != null) {\n writer\n .write({\n type: \"tool-result\",\n toolCallId,\n toolName: id,\n input: input ?? {},\n output: { error: error.message },\n } as StreamPart)\n /* v8 ignore start -- defensive; writer.write rarely rejects in practice */\n .catch((err) => {\n ctx.log.warn({ err, toolCallId }, \"failed to write error tool-result event to stream\");\n });\n /* v8 ignore stop */\n }\n\n const onErrorHook = buildHookCallback(onError, (fn) => fn({ id, error }));\n const parentOnStepFinishHook = buildParentHookCallback(parentHooks, \"onStepFinish\", (fn) =>\n fn({ step: stepInfo, result: undefined, duration }),\n );\n\n await fireHooks(ctx.log, onErrorHook, parentOnStepFinishHook);\n\n return { ok: false, error: stepError, step: stepInfo, duration } as StepResult<T>;\n }\n }\n\n async function agent<TInput>(\n config: AgentStepConfig<TInput>,\n ): Promise<StepResult<import(\"@/core/agents/base/types.js\").GenerateResult>> {\n const onFinishHandler = buildOnFinishHandlerWithCast<\n import(\"@/core/agents/base/types.js\").GenerateResult\n >(config.onFinish);\n\n return executeStep<import(\"@/core/agents/base/types.js\").GenerateResult>({\n id: config.id,\n type: \"agent\",\n input: config.input,\n execute: async () => {\n const agentConfig = {\n signal: ctx.signal,\n ...config.config,\n logger: ctx.log.child({ stepId: config.id }),\n };\n\n // When stream: true and a writer is available, use agent.stream()\n // to pipe events through the parent flow's stream\n if (config.stream && writer != null) {\n const streamResult = await config.agent.stream(config.input, agentConfig);\n if (!streamResult.ok) {\n throw streamResult.error.cause ?? new Error(streamResult.error.message);\n }\n // Safe after the `!streamResult.ok` guard above — the Result union\n // doesn't spread StreamResult props at the type level, so we cast.\n const full =\n streamResult as unknown as import(\"@/core/agents/base/types.js\").StreamResult & {\n ok: true;\n };\n\n // Forward text-delta events from sub-agent to parent stream\n for await (const part of full.fullStream) {\n if (part.type === \"text-delta\") {\n await writer.write(part);\n }\n }\n\n // Await the final results\n return {\n output: await full.output,\n messages: await full.messages,\n usage: await full.usage,\n finishReason: await full.finishReason,\n };\n }\n\n const result = await config.agent.generate(config.input, agentConfig);\n if (!result.ok) {\n throw result.error.cause ?? new Error(result.error.message);\n }\n // Runnable.generate() types only { output }, but Agent.generate()\n // returns full GenerateResult at runtime including messages, usage, finishReason.\n const full = result as unknown as import(\"@/core/agents/base/types.js\").GenerateResult & {\n ok: true;\n };\n return {\n output: full.output,\n messages: full.messages,\n usage: full.usage,\n finishReason: full.finishReason,\n };\n },\n onStart: config.onStart,\n onFinish: onFinishHandler,\n onError: config.onError,\n });\n }\n\n async function map<T, R>(config: MapConfig<T, R>): Promise<StepResult<R[]>> {\n const onFinishHandler = buildOnFinishHandlerWithCast<R[]>(config.onFinish);\n\n return executeStep<R[]>({\n id: config.id,\n type: \"map\",\n input: config.input,\n execute: async ({ $ }) => {\n const concurrency = config.concurrency;\n if (concurrency != null && concurrency !== Infinity) {\n return poolMap(config.input, concurrency, ctx.signal, (item, index) =>\n config.execute({ item, index, $ }),\n );\n }\n return Promise.all(config.input.map((item, index) => config.execute({ item, index, $ })));\n },\n onStart: config.onStart,\n onFinish: onFinishHandler,\n onError: config.onError,\n });\n }\n\n async function each<T>(config: EachConfig<T>): Promise<StepResult<void>> {\n const onFinishHandler = buildOnFinishHandlerVoid(config.onFinish);\n\n return executeStep<void>({\n id: config.id,\n type: \"each\",\n input: config.input,\n execute: async ({ $ }) => {\n for (const [i, item] of config.input.entries()) {\n if (ctx.signal.aborted) {\n throw new Error(\"Aborted\");\n }\n // oxlint-disable-next-line no-await-in-loop - sequential by design\n await config.execute({ item, index: i, $ });\n }\n },\n onStart: config.onStart,\n onFinish: onFinishHandler,\n onError: config.onError,\n });\n }\n\n async function reduce<T, R>(config: ReduceConfig<T, R>): Promise<StepResult<R>> {\n const onFinishHandler = buildOnFinishHandlerWithCast<R>(config.onFinish);\n\n return executeStep<R>({\n id: config.id,\n type: \"reduce\",\n input: config.input,\n execute: async ({ $ }) => {\n const result = await reduceSequential(\n config.input,\n config.initial,\n ctx.signal,\n (item, accumulator, index) => config.execute({ item, accumulator, index, $ }),\n );\n return result;\n },\n onStart: config.onStart,\n onFinish: onFinishHandler,\n onError: config.onError,\n });\n }\n\n async function whileStep<T>(config: WhileConfig<T>): Promise<StepResult<T | undefined>> {\n const onFinishHandler = buildOnFinishHandlerWithCast<T | undefined>(config.onFinish);\n\n return executeStep<T | undefined>({\n id: config.id,\n type: \"while\",\n execute: async ({ $ }) => {\n const result = await whileSequential(config.condition, ctx.signal, (index) =>\n config.execute({ index, $ }),\n );\n return result;\n },\n onStart: config.onStart,\n onFinish: onFinishHandler,\n onError: config.onError,\n });\n }\n\n async function all(config: AllConfig): Promise<StepResult<unknown[]>> {\n const onFinishHandler = buildOnFinishHandlerWithCast<unknown[]>(config.onFinish);\n\n return executeStep<unknown[]>({\n id: config.id,\n type: \"all\",\n execute: async ({ $ }) => {\n const ac = new AbortController();\n // Link to parent signal so cancellation propagates\n const onAbort = () => ac.abort();\n ctx.signal.addEventListener(\"abort\", onAbort, { once: true });\n try {\n return await Promise.all(config.entries.map((factory) => factory(ac.signal, $)));\n } catch (err) {\n ac.abort();\n throw err;\n } finally {\n ctx.signal.removeEventListener(\"abort\", onAbort);\n }\n },\n onStart: config.onStart,\n onFinish: onFinishHandler,\n onError: config.onError,\n });\n }\n\n async function race(config: RaceConfig): Promise<StepResult<unknown>> {\n const onFinishHandler = buildOnFinishHandlerRace(config.onFinish);\n\n return executeStep<unknown>({\n id: config.id,\n type: \"race\",\n execute: async ({ $ }) => {\n const ac = new AbortController();\n // Link to parent signal so cancellation propagates\n const onAbort = () => ac.abort();\n ctx.signal.addEventListener(\"abort\", onAbort, { once: true });\n try {\n return await Promise.race(config.entries.map((factory) => factory(ac.signal, $)));\n } finally {\n // Cancel losing entries (on success) or remaining entries (on error)\n ac.abort();\n ctx.signal.removeEventListener(\"abort\", onAbort);\n }\n },\n onStart: config.onStart,\n onFinish: onFinishHandler,\n onError: config.onError,\n });\n }\n\n return {\n step,\n agent,\n map,\n each,\n reduce,\n while: whileStep,\n all,\n race,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Helper: build hook callback without ternary or optional chaining\n// ---------------------------------------------------------------------------\nfunction buildHookCallback<F extends ((...args: never[]) => void | Promise<void>) | undefined>(\n handler: F,\n invoke: (fn: NonNullable<F>) => void | Promise<void>,\n): (() => void | Promise<void>) | undefined {\n if (handler != null) {\n return () => invoke(handler);\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Helper: build parent hook callback without ternary or optional chaining\n// ---------------------------------------------------------------------------\nfunction buildParentHookCallback<K extends \"onStepStart\" | \"onStepFinish\">(\n hooks: StepBuilderOptions[\"parentHooks\"],\n key: K,\n invoke: (\n fn: NonNullable<NonNullable<StepBuilderOptions[\"parentHooks\"]>[K]>,\n ) => void | Promise<void>,\n): (() => void | Promise<void>) | undefined {\n if (hooks == null) {\n return undefined;\n }\n // eslint-disable-next-line security/detect-object-injection -- Key is a controlled internal hook name, not user input\n const fn = hooks[key];\n if (fn == null) {\n return undefined;\n }\n return () => invoke(fn);\n}\n\n// ---------------------------------------------------------------------------\n// Helper: build onFinish handler (generic step) without ternary or !\n// ---------------------------------------------------------------------------\nfunction buildOnFinishHandler<T>(\n onFinish?: (event: { id: string; result: T; duration: number }) => void | Promise<void>,\n):\n | ((event: { id: string; result: unknown; duration: number }) => void | Promise<void>)\n | undefined {\n if (onFinish == null) {\n return undefined;\n }\n return (event) => onFinish({ id: event.id, result: event.result as T, duration: event.duration });\n}\n\n// ---------------------------------------------------------------------------\n// Helper: build onFinish handler with cast (for agent, map, reduce, while, all)\n// ---------------------------------------------------------------------------\nfunction buildOnFinishHandlerWithCast<T>(\n onFinish?: (event: { id: string; result: T; duration: number }) => void | Promise<void>,\n):\n | ((event: { id: string; result: unknown; duration: number }) => void | Promise<void>)\n | undefined {\n if (onFinish == null) {\n return undefined;\n }\n return (event) => onFinish({ id: event.id, result: event.result as T, duration: event.duration });\n}\n\n// ---------------------------------------------------------------------------\n// Helper: build onFinish handler for void-returning steps (each)\n// ---------------------------------------------------------------------------\nfunction buildOnFinishHandlerVoid(\n onFinish?: (event: { id: string; duration: number }) => void | Promise<void>,\n):\n | ((event: { id: string; result: unknown; duration: number }) => void | Promise<void>)\n | undefined {\n if (onFinish == null) {\n return undefined;\n }\n return (event) => onFinish({ id: event.id, duration: event.duration });\n}\n\n// ---------------------------------------------------------------------------\n// Helper: build onFinish handler for race (result is unknown, no cast needed)\n// ---------------------------------------------------------------------------\nfunction buildOnFinishHandlerRace(\n onFinish?: (event: { id: string; result: unknown; duration: number }) => void | Promise<void>,\n):\n | ((event: { id: string; result: unknown; duration: number }) => void | Promise<void>)\n | undefined {\n if (onFinish == null) {\n return undefined;\n }\n return (event) => onFinish({ id: event.id, result: event.result, duration: event.duration });\n}\n\n// ---------------------------------------------------------------------------\n// Helper: sequential reduce without let\n// ---------------------------------------------------------------------------\nasync function reduceSequential<T, R>(\n items: readonly T[],\n initial: R,\n signal: AbortSignal,\n fn: (item: T, accumulator: R, index: number) => Promise<R>,\n): Promise<R> {\n async function loop(accumulator: R, index: number): Promise<R> {\n if (index >= items.length) {\n return accumulator;\n }\n if (signal.aborted) {\n throw new Error(\"Aborted\");\n }\n // eslint-disable-next-line security/detect-object-injection -- Array index is a locally computed number, not user input\n const next = await fn(items[index] as T, accumulator, index);\n return loop(next, index + 1);\n }\n return loop(initial, 0);\n}\n\n// ---------------------------------------------------------------------------\n// Helper: sequential while without let\n// ---------------------------------------------------------------------------\nasync function whileSequential<T>(\n condition: (state: { value: T | undefined; index: number }) => boolean,\n signal: AbortSignal,\n fn: (index: number) => Promise<T>,\n): Promise<T | undefined> {\n async function loop(value: T | undefined, index: number): Promise<T | undefined> {\n if (!condition({ value, index })) {\n return value;\n }\n if (signal.aborted) {\n throw new Error(\"Aborted\");\n }\n const next = await fn(index);\n return loop(next, index + 1);\n }\n return loop(undefined, 0);\n}\n\n/**\n * Worker-pool map with bounded concurrency.\n *\n * Runs `fn` over `items` with at most `concurrency` concurrent\n * executions. Results are returned in input order.\n */\nasync function poolMap<T, R>(\n items: readonly T[],\n concurrency: number,\n signal: AbortSignal,\n fn: (item: T, index: number) => Promise<R>,\n): Promise<R[]> {\n const results = Array.from<R>({ length: items.length });\n const indexRef = { current: 0 };\n\n async function worker(): Promise<void> {\n while (indexRef.current < items.length) {\n if (signal.aborted) {\n throw new Error(\"Aborted\");\n }\n const i = indexRef.current++;\n // eslint-disable-next-line no-await-in-loop, security/detect-object-injection -- Sequential execution by design; array indices are locally computed numbers\n results[i] = await fn(items[i] as T, i);\n }\n }\n\n const workers = Array.from({ length: Math.min(concurrency, items.length) }, () => worker());\n await Promise.all(workers);\n return results;\n}\n","import { groupBy, sumBy } from \"es-toolkit\";\nimport { match, P } from \"ts-pattern\";\n\nimport type {\n TokenUsage,\n TokenUsageRecord,\n AgentTokenUsage,\n FlowAgentTokenUsage,\n} from \"@/core/provider/types.js\";\n\n/**\n * Aggregate token counts across multiple raw tracking records.\n *\n * Sums each field, treating `undefined` as `0`.\n */\nfunction aggregateTokens(usages: TokenUsageRecord[]): TokenUsage {\n return {\n inputTokens: sumBy(usages, (u) => u.inputTokens ?? 0),\n outputTokens: sumBy(usages, (u) => u.outputTokens ?? 0),\n totalTokens: sumBy(usages, (u) => u.totalTokens ?? 0),\n cacheReadTokens: sumBy(usages, (u) => u.cacheReadTokens ?? 0),\n cacheWriteTokens: sumBy(usages, (u) => u.cacheWriteTokens ?? 0),\n reasoningTokens: sumBy(usages, (u) => u.reasoningTokens ?? 0),\n };\n}\n\n/**\n * Compute final usage for a single agent call.\n *\n * Aggregates token counts from one or more raw tracking records.\n * Returns a flat object with tokens + agentId.\n *\n * @param agentId - The agent that produced these records.\n * @param records - Raw tracking records from the agent's execution.\n * @returns Flat {@link AgentTokenUsage} with resolved token counts.\n */\nexport function agentUsage(\n agentId: string,\n records: TokenUsageRecord | TokenUsageRecord[],\n): AgentTokenUsage {\n const arr = match(records)\n .when(Array.isArray, (r) => r)\n .otherwise((r) => [r]);\n const tokens = aggregateTokens(arr);\n\n return {\n agentId,\n ...tokens,\n };\n}\n\n/**\n * Compute final usage for a flow agent with multiple agent calls.\n *\n * Groups raw tracking records by `source.agentId`, computes per-agent\n * usage via {@link agentUsage}.\n *\n * @param records - Raw tracking records from all agents in the flow.\n * @returns {@link FlowAgentTokenUsage} with per-agent breakdown.\n */\nexport function flowAgentUsage(records: TokenUsageRecord[]): FlowAgentTokenUsage {\n const grouped = groupBy(records, (r) =>\n match(r.source)\n .with(P.nonNullable, (s) =>\n match(s.agentId)\n .with(P.string, (id) => id)\n .otherwise(() => \"unknown\"),\n )\n .otherwise(() => \"unknown\"),\n );\n\n const usages = Object.entries(grouped).map(([id, group]) => agentUsage(id, group));\n\n return {\n usages,\n };\n}\n\n/**\n * Sum multiple {@link TokenUsage} objects field-by-field.\n *\n * Pure function — returns a new object without mutating any input.\n * Returns zero-valued usage when given an empty array.\n *\n * @param usages - Array of usage objects to sum.\n * @returns A new `TokenUsage` with each field summed.\n */\nexport function sumTokenUsage(usages: TokenUsage[]): TokenUsage {\n return {\n inputTokens: sumBy(usages, (u) => u.inputTokens),\n outputTokens: sumBy(usages, (u) => u.outputTokens),\n totalTokens: sumBy(usages, (u) => u.totalTokens),\n cacheReadTokens: sumBy(usages, (u) => u.cacheReadTokens),\n cacheWriteTokens: sumBy(usages, (u) => u.cacheWriteTokens),\n reasoningTokens: sumBy(usages, (u) => u.reasoningTokens),\n };\n}\n","import { match, P } from \"ts-pattern\";\n\nimport type { TokenUsage } from \"@/core/provider/types.js\";\n\n/**\n * Known trace operation types.\n *\n * Each `$` method registers a specific operation type in the execution\n * trace. This discriminant allows consumers to filter or group trace\n * entries by kind.\n */\nexport type OperationType = \"step\" | \"agent\" | \"map\" | \"each\" | \"reduce\" | \"while\" | \"all\" | \"race\";\n\n/** @deprecated Use `OperationType` instead. */\nexport type TraceType = OperationType;\n\n/**\n * A single entry in the execution trace.\n *\n * Every tracked `$` operation produces a TraceEntry. Nested operations\n * (e.g. agent calls inside a map iteration) appear as children,\n * forming a tree that represents the full execution graph.\n *\n * @internal\n * Part of the internal execution context. Exposed on\n * `WorkflowResult.trace` for observability but not directly\n * constructed by user code.\n */\nexport interface TraceEntry {\n /**\n * Unique id of this operation.\n *\n * Corresponds to the `id` field from the `$` config that\n * produced this entry.\n */\n id: string;\n\n /**\n * What kind of operation produced this entry.\n *\n * Discriminant for filtering or grouping trace entries.\n */\n type: OperationType;\n\n /**\n * Input snapshot.\n *\n * Captured when the operation starts. May be `undefined` for\n * operations that have no meaningful input (e.g. `$.all`).\n */\n input?: unknown;\n\n /**\n * Output snapshot.\n *\n * Captured when the operation completes successfully. `undefined`\n * if the operation is still running or failed.\n */\n output?: unknown;\n\n /**\n * Start time in Unix milliseconds.\n *\n * Set when the operation begins execution.\n */\n startedAt: number;\n\n /**\n * End time in Unix milliseconds.\n *\n * Set when the operation completes (success or failure).\n * `undefined` while the operation is still running.\n */\n finishedAt?: number;\n\n /**\n * Error instance if the operation failed.\n *\n * `undefined` on success or while still running.\n */\n error?: Error;\n\n /**\n * Token usage from this operation.\n *\n * Populated for `agent` type entries that complete successfully.\n * `undefined` for non-agent steps or failed operations.\n */\n usage?: TokenUsage;\n\n /**\n * Nested trace entries for child operations.\n *\n * Present when this operation spawns sub-operations\n * (e.g. individual iterations inside `$.map`, or nested\n * `$.step` calls inside a step's `execute` callback).\n */\n children?: readonly TraceEntry[];\n}\n\n/**\n * Recursively collect all {@link TokenUsage} values from a trace tree.\n *\n * Walks every entry (including nested children) and returns a flat\n * array of usage objects. Entries without usage are skipped.\n *\n * @param trace - The trace array to collect from.\n * @returns Flat array of {@link TokenUsage} values found in the tree.\n */\nexport function collectUsages(trace: readonly TraceEntry[]): TokenUsage[] {\n return trace.flatMap((entry) => {\n const usages: TokenUsage[] = match(entry.usage)\n .with(P.nonNullable, (u) => [u])\n .otherwise(() => []);\n if (entry.children != null && entry.children.length > 0) {\n return [...usages, ...collectUsages(entry.children)];\n }\n return usages;\n });\n}\n\n/**\n * Recursively deep-clone and freeze a trace array.\n *\n * Returns a structurally identical tree that is `Object.freeze`d at\n * every level, preventing post-run mutation of the result trace.\n *\n * @internal\n */\nexport function snapshotTrace(trace: readonly TraceEntry[]): readonly TraceEntry[] {\n return Object.freeze(\n trace.map((entry) => {\n const children = match(entry.children)\n .with(P.nonNullable, (c) => snapshotTrace(c))\n .otherwise(() => undefined);\n const childSpread = match(children)\n .with(P.nonNullable, (c) => ({ children: c }))\n .otherwise(() => ({}));\n return Object.freeze({\n ...entry,\n ...childSpread,\n });\n }),\n );\n}\n","import type { AsyncIterableStream } from \"ai\";\n\nimport type { Message, StreamPart } from \"@/core/agents/base/types.js\";\nimport {\n collectTextFromMessages,\n createAssistantMessage,\n createUserMessage,\n} from \"@/core/agents/flow/messages.js\";\nimport type { StepBuilder } from \"@/core/agents/flow/steps/builder.js\";\nimport { createStepBuilder } from \"@/core/agents/flow/steps/factory.js\";\nimport type {\n FlowAgent,\n FlowAgentConfig,\n FlowAgentConfigWithOutput,\n FlowAgentConfigWithoutOutput,\n FlowAgentGenerateResult,\n FlowAgentHandler,\n FlowAgentOverrides,\n InternalFlowAgentOptions,\n} from \"@/core/agents/flow/types.js\";\nimport { createDefaultLogger } from \"@/core/logger.js\";\nimport type { Logger } from \"@/core/logger.js\";\nimport { sumTokenUsage } from \"@/core/provider/usage.js\";\nimport type { Context } from \"@/lib/context.js\";\nimport { fireHooks, wrapHook } from \"@/lib/hooks.js\";\nimport { RUNNABLE_META, type RunnableMeta } from \"@/lib/runnable.js\";\nimport type { TraceEntry } from \"@/lib/trace.js\";\nimport { collectUsages, snapshotTrace } from \"@/lib/trace.js\";\nimport { toError } from \"@/utils/error.js\";\nimport type { Result } from \"@/utils/result.js\";\n\n/**\n * Resolve the logger for a single flow agent execution.\n *\n * @private\n */\nfunction resolveFlowAgentLogger(\n base: Logger,\n flowAgentId: string,\n overrides?: FlowAgentOverrides,\n): Logger {\n const override = overrides && overrides.logger;\n return (override ?? base).child({ flowAgentId });\n}\n\n/**\n * Augment the step builder with custom steps from the engine.\n *\n * @private\n */\nfunction augmentStepBuilder(\n base: StepBuilder,\n ctx: Context,\n internal: InternalFlowAgentOptions | undefined,\n): StepBuilder {\n if (internal && internal.augment$) {\n return internal.augment$(base, ctx);\n }\n return base;\n}\n\n/**\n * Create a flow agent with typed input/output, tracked steps, and hooks.\n *\n * A flow agent is an agent whose behavior is defined by code, not by an LLM.\n * You write the orchestration logic — calling sub-agents, running steps,\n * using concurrency primitives — and the framework wraps it in the same\n * API surface as a regular `agent`.\n *\n * To consumers, a `FlowAgent` IS an `Agent`. Same `.generate()`, same\n * `.stream()`, same `.fn()`. Same `GenerateResult` return type. Same\n * `messages` array. The only difference is internal: an `agent` runs\n * an LLM tool loop, a `flowAgent` runs your handler function.\n *\n * Each `$` step is modeled as a synthetic tool call in the message history.\n *\n * @typeParam TInput - Input type, inferred from the `input` Zod schema.\n * @typeParam TOutput - Output type, inferred from the `output` Zod schema.\n * @param config - Flow agent configuration including name, schemas,\n * hooks, and logger.\n * @param handler - The flow agent handler function that receives\n * validated input and the `$` step builder.\n * @param _internal - Internal options used by the engine. Not public API.\n * @returns A `FlowAgent` instance with `.generate()`, `.stream()`,\n * and `.fn()`.\n *\n * @example\n * ```typescript\n * const pipeline = flowAgent({\n * name: 'doc-pipeline',\n * input: z.object({ repo: z.string() }),\n * output: z.object({ docs: z.array(z.string()) }),\n * }, async ({ input, $ }) => {\n * const files = await $.step({\n * id: 'scan-repo',\n * execute: () => scanRepo(input.repo),\n * })\n *\n * if (!files.ok) throw files.error\n *\n * const docs = await $.map({\n * id: 'generate-docs',\n * input: files.value,\n * execute: async ({ item, $ }) => {\n * const result = await $.agent({\n * id: 'write-doc',\n * agent: writerAgent,\n * input: item,\n * })\n * return result.ok ? result.value.output : ''\n * },\n * concurrency: 3,\n * })\n *\n * return { docs: docs.ok ? docs.value : [] }\n * })\n * ```\n */\n/**\n * Create a flow agent with structured output.\n *\n * @typeParam TInput - Input type, inferred from the `input` Zod schema.\n * @typeParam TOutput - Output type, inferred from the `output` Zod schema.\n */\nexport function flowAgent<TInput, TOutput>(\n config: FlowAgentConfigWithOutput<TInput, TOutput>,\n handler: FlowAgentHandler<TInput, TOutput>,\n _internal?: InternalFlowAgentOptions,\n): FlowAgent<TInput, TOutput>;\n\n/**\n * Create a flow agent without structured output.\n *\n * The handler returns `void` — sub-agent text is collected as the\n * `string` output. Ideal for orchestration-only flows where the\n * sub-agents produce the final text.\n *\n * @typeParam TInput - Input type, inferred from the `input` Zod schema.\n */\nexport function flowAgent<TInput>(\n config: FlowAgentConfigWithoutOutput<TInput>,\n handler: FlowAgentHandler<TInput, void>,\n _internal?: InternalFlowAgentOptions,\n): FlowAgent<TInput, string>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- implementation signature must accept both overloads\nexport function flowAgent<TInput, TOutput = any>(\n config: FlowAgentConfig<TInput, TOutput>,\n handler: FlowAgentHandler<TInput, TOutput> | FlowAgentHandler<TInput, void>,\n _internal?: InternalFlowAgentOptions,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- widened return to satisfy both overloads\n): FlowAgent<TInput, any> {\n const baseLogger = config.logger ?? createDefaultLogger();\n\n /**\n * Resolve the handler output into a final value, validating against\n * the output schema when present. Also pushes the assistant message.\n *\n * Returns `{ ok: true, value }` on success, or `{ ok: false, message }`\n * when output validation fails.\n *\n * @private\n */\n function resolveFlowOutput(\n output: unknown,\n messages: Message[],\n ): { ok: true; value: unknown } | { ok: false; message: string } {\n if (config.output !== undefined) {\n const outputParsed = config.output.safeParse(output);\n if (!outputParsed.success) {\n return { ok: false, message: `Output validation failed: ${outputParsed.error.message}` };\n }\n messages.push(createAssistantMessage(outputParsed.data));\n return { ok: true, value: outputParsed.data };\n }\n const text = collectTextFromMessages(messages);\n messages.push(createAssistantMessage(text));\n return { ok: true, value: text };\n }\n\n async function generate(\n input: TInput,\n overrides?: FlowAgentOverrides,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- widened to satisfy both overloads\n ): Promise<Result<FlowAgentGenerateResult<any>>> {\n const inputParsed = config.input.safeParse(input);\n if (!inputParsed.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: `Input validation failed: ${inputParsed.error.message}`,\n },\n };\n }\n const parsedInput = inputParsed.data as TInput;\n\n const startedAt = Date.now();\n const log = resolveFlowAgentLogger(baseLogger, config.name, overrides);\n\n const signal = (overrides && overrides.signal) || new AbortController().signal;\n const trace: TraceEntry[] = [];\n const messages: Message[] = [];\n const ctx: Context = { signal, log, trace, messages };\n\n const base$ = createStepBuilder({\n ctx,\n parentHooks: {\n onStepStart: config.onStepStart,\n onStepFinish: config.onStepFinish,\n },\n });\n\n const $ = augmentStepBuilder(base$, ctx, _internal);\n\n // Push user message\n messages.push(createUserMessage(parsedInput));\n\n await fireHooks(\n log,\n wrapHook(config.onStart, { input: parsedInput }),\n wrapHook(overrides && overrides.onStart, { input: parsedInput }),\n );\n\n log.debug(\"flowAgent.generate start\", { name: config.name });\n\n try {\n const output = await (handler as FlowAgentHandler<TInput, TOutput>)({\n input: parsedInput,\n $,\n log,\n });\n\n const outputResult = resolveFlowOutput(output, messages);\n if (!outputResult.ok) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: outputResult.message,\n },\n };\n }\n const resolvedOutput = outputResult.value;\n\n const duration = Date.now() - startedAt;\n\n const usage = sumTokenUsage(collectUsages(trace));\n const frozenTrace = snapshotTrace(trace);\n\n const result: FlowAgentGenerateResult<unknown> = {\n output: resolvedOutput,\n messages: [...messages],\n usage,\n finishReason: \"stop\",\n trace: frozenTrace,\n duration,\n };\n\n await fireHooks(\n log,\n wrapHook(\n config.onFinish as\n | ((event: {\n input: TInput;\n result: FlowAgentGenerateResult<unknown>;\n duration: number;\n }) => void | Promise<void>)\n | undefined,\n { input: parsedInput, result, duration },\n ),\n wrapHook(overrides && overrides.onFinish, {\n input: parsedInput,\n result: result as import(\"@/core/agents/base/types.js\").GenerateResult,\n duration,\n }),\n );\n\n log.debug(\"flowAgent.generate finish\", { name: config.name, duration });\n\n return { ok: true, ...result };\n } catch (thrown) {\n const error = toError(thrown);\n const duration = Date.now() - startedAt;\n\n log.error(\"flowAgent.generate error\", { name: config.name, error: error.message, duration });\n\n await fireHooks(\n log,\n wrapHook(config.onError, { input: parsedInput, error }),\n wrapHook(overrides && overrides.onError, { input: parsedInput, error }),\n );\n\n return {\n ok: false,\n error: {\n code: \"FLOW_AGENT_ERROR\",\n message: error.message,\n cause: error,\n },\n };\n }\n }\n\n async function stream(\n input: TInput,\n overrides?: FlowAgentOverrides,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- widened to satisfy both overloads\n ): Promise<Result<import(\"@/core/agents/base/types.js\").StreamResult<any>>> {\n const inputParsed = config.input.safeParse(input);\n if (!inputParsed.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: `Input validation failed: ${inputParsed.error.message}`,\n },\n };\n }\n const parsedInput = inputParsed.data as TInput;\n\n const startedAt = Date.now();\n const log = resolveFlowAgentLogger(baseLogger, config.name, overrides);\n\n const signal = (overrides && overrides.signal) || new AbortController().signal;\n const trace: TraceEntry[] = [];\n const messages: Message[] = [];\n const ctx: Context = { signal, log, trace, messages };\n\n const { readable, writable } = new TransformStream<StreamPart, StreamPart>();\n const writer = writable.getWriter();\n\n const base$ = createStepBuilder({\n ctx,\n parentHooks: {\n onStepStart: config.onStepStart,\n onStepFinish: config.onStepFinish,\n },\n writer,\n });\n\n const $ = augmentStepBuilder(base$, ctx, _internal);\n\n // Push user message\n messages.push(createUserMessage(parsedInput));\n\n await fireHooks(\n log,\n wrapHook(config.onStart, { input: parsedInput }),\n wrapHook(overrides && overrides.onStart, { input: parsedInput }),\n );\n\n log.debug(\"flowAgent.stream start\", { name: config.name });\n\n // Run handler in background, piping results through stream\n const done = (async () => {\n try {\n const output = await (handler as FlowAgentHandler<TInput, TOutput>)({\n input: parsedInput,\n $,\n log,\n });\n\n const outputResult = resolveFlowOutput(output, messages);\n if (!outputResult.ok) {\n throw new Error(outputResult.message);\n }\n const resolvedOutput = outputResult.value;\n\n const duration = Date.now() - startedAt;\n\n const usage = sumTokenUsage(collectUsages(trace));\n\n const result: FlowAgentGenerateResult<unknown> = {\n output: resolvedOutput,\n messages: [...messages],\n usage,\n finishReason: \"stop\",\n trace: snapshotTrace(trace),\n duration,\n };\n\n await fireHooks(\n log,\n wrapHook(\n config.onFinish as\n | ((event: {\n input: TInput;\n result: FlowAgentGenerateResult<unknown>;\n duration: number;\n }) => void | Promise<void>)\n | undefined,\n { input: parsedInput, result, duration },\n ),\n wrapHook(overrides && overrides.onFinish, {\n input: parsedInput,\n result: result as import(\"@/core/agents/base/types.js\").GenerateResult,\n duration,\n }),\n );\n\n log.debug(\"flowAgent.stream finish\", { name: config.name, duration });\n\n // Emit finish event and close the stream\n await writer.write({\n type: \"finish\",\n finishReason: \"stop\",\n rawFinishReason: undefined,\n totalUsage: {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n totalTokens: usage.totalTokens,\n },\n } as StreamPart);\n await writer.close();\n\n return result;\n } catch (thrown) {\n const error = toError(thrown);\n const duration = Date.now() - startedAt;\n\n log.error(\"flowAgent.stream error\", { name: config.name, error: error.message, duration });\n\n // Emit error event and close the stream\n /* v8 ignore start -- defensive; writer rarely rejects in practice */\n await writer.write({ type: \"error\", error } as StreamPart).catch((err) => {\n log.debug(\"failed to write error event to stream\", { err });\n });\n await writer.close().catch((err) => {\n log.debug(\"failed to close stream writer\", { err });\n });\n /* v8 ignore stop */\n\n await fireHooks(\n log,\n wrapHook(config.onError, { input: parsedInput, error }),\n wrapHook(overrides && overrides.onError, { input: parsedInput, error }),\n );\n\n throw error;\n }\n })();\n\n // Catch stream errors to prevent unhandled rejections\n done.catch(() => {});\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- widened to satisfy both overloads\n const streamResult: import(\"@/core/agents/base/types.js\").StreamResult<any> = {\n output: done.then((r) => r.output),\n messages: done.then((r) => r.messages),\n usage: done.then((r) => r.usage),\n finishReason: done.then((r) => r.finishReason),\n fullStream: readable as AsyncIterableStream<StreamPart>,\n };\n\n return { ok: true, ...streamResult };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- widened to satisfy both overloads\n const agent: FlowAgent<TInput, any> = {\n generate,\n stream,\n fn: () => generate,\n };\n\n // eslint-disable-next-line security/detect-object-injection -- Symbol-keyed property access; symbols cannot be user-controlled\n (agent as unknown as Record<symbol, unknown>)[RUNNABLE_META] = {\n name: config.name,\n inputSchema: config.input,\n } satisfies RunnableMeta;\n\n return agent;\n}\n","import { flowAgent } from \"@/core/agents/flow/flow-agent.js\";\nimport type { StepBuilder } from \"@/core/agents/flow/steps/builder.js\";\nimport type {\n FlowAgent,\n FlowAgentConfigWithOutput,\n FlowAgentHandler,\n} from \"@/core/agents/flow/types.js\";\nimport type { StepInfo } from \"@/core/agents/flow/types.js\";\nimport type { Logger } from \"@/core/logger.js\";\nimport { createDefaultLogger } from \"@/core/logger.js\";\nimport type { ExecutionContext } from \"@/lib/context.js\";\nimport { fireHooks } from \"@/lib/hooks.js\";\n\n/**\n * Factory function for a custom step type.\n *\n * Receives the internal context (for signal, logging) and the\n * user-provided config. Returns the step result.\n *\n * @typeParam TConfig - The config shape users pass to `$.myStep({ ... })`.\n * @typeParam TResult - The return type of the step.\n */\nexport type CustomStepFactory<TConfig, TResult> = (params: {\n /**\n * Execution context.\n */\n ctx: ExecutionContext;\n\n /**\n * The config object the user passed to the custom step.\n */\n config: TConfig;\n}) => Promise<TResult>;\n\n/**\n * Map of custom step names to their factory functions.\n *\n * Uses `config: never` as the base constraint so that any concrete\n * `CustomStepFactory<TConfig, TResult>` is assignable via function\n * parameter contravariance — `never extends TConfig` is always true.\n */\nexport type CustomStepDefinitions = Record<\n string,\n (params: { ctx: ExecutionContext; config: never }) => Promise<unknown>\n>;\n\n/**\n * Derive typed custom step methods from a definitions map.\n *\n * @typeParam T - The `CustomStepDefinitions` map.\n */\nexport type TypedCustomSteps<T extends CustomStepDefinitions> = {\n [K in keyof T]: T[K] extends CustomStepFactory<infer TConfig, infer TResult>\n ? (config: TConfig) => Promise<TResult>\n : never;\n};\n\n/**\n * Configuration for creating a custom flow engine.\n *\n * @typeParam TCustomSteps - The custom step definitions map.\n */\nexport interface FlowEngineConfig<TCustomSteps extends CustomStepDefinitions> {\n /**\n * Custom step types to add to `$`.\n */\n $?: TCustomSteps;\n\n /**\n * Default hook: fires when any flow agent starts.\n */\n onStart?: (event: { input: unknown }) => void | Promise<void>;\n\n /**\n * Default hook: fires when any flow agent finishes.\n */\n onFinish?: (event: { input: unknown; result: unknown; duration: number }) => void | Promise<void>;\n\n /**\n * Default hook: fires when any flow agent errors.\n */\n onError?: (event: { input: unknown; error: Error }) => void | Promise<void>;\n\n /**\n * Default hook: fires when any step starts.\n */\n onStepStart?: (event: { step: StepInfo }) => void | Promise<void>;\n\n /**\n * Default hook: fires when any step finishes.\n */\n onStepFinish?: (event: {\n step: StepInfo;\n result: unknown;\n duration: number;\n }) => void | Promise<void>;\n}\n\n/**\n * A `flowAgent` factory with custom steps merged into `$`.\n *\n * @typeParam TCustomSteps - The custom step definitions map.\n */\nexport type FlowFactory<TCustomSteps extends CustomStepDefinitions> = <TInput, TOutput>(\n config: FlowAgentConfigWithOutput<TInput, TOutput>,\n handler: (params: {\n input: TInput;\n $: StepBuilder & TypedCustomSteps<TCustomSteps>;\n log: Logger;\n }) => Promise<TOutput>,\n) => FlowAgent<TInput, TOutput>;\n\n/**\n * Wrap a hook callback so it can be passed to `fireHooks`.\n *\n * Generic over `TEvent` so the hook is called with the correct\n * event type without resorting to `any`.\n */\nfunction createHookCaller<TEvent>(\n hook: ((event: TEvent) => void | Promise<void>) | undefined,\n event: TEvent,\n): (() => void | Promise<void>) | undefined {\n if (hook) {\n return () => hook(event);\n }\n return undefined;\n}\n\n/**\n * Build a merged hook that runs engine and flow agent hooks sequentially.\n *\n * The `(event: never)` constraint is the widest function type under\n * strict mode — any single-argument function is assignable via\n * contravariance (`never extends T` for all `T`).\n */\nfunction buildMergedHook<THook extends (event: never) => void | Promise<void>>(\n log: Logger,\n engineHook: THook | undefined,\n flowHook: THook | undefined,\n): THook | undefined {\n if (!engineHook && !flowHook) {\n return undefined;\n }\n\n const merged = async (event: unknown): Promise<void> => {\n const engineFn = createHookCaller(\n engineHook as ((event: unknown) => void | Promise<void>) | undefined,\n event,\n );\n const flowFn = createHookCaller(\n flowHook as ((event: unknown) => void | Promise<void>) | undefined,\n event,\n );\n await fireHooks(log, engineFn, flowFn);\n };\n return merged as unknown as THook;\n}\n\n/**\n * Built-in StepBuilder method names that custom steps must not shadow.\n *\n * @private\n */\nconst RESERVED_STEP_NAMES: ReadonlySet<string> = new Set([\n \"step\",\n \"agent\",\n \"map\",\n \"each\",\n \"reduce\",\n \"while\",\n \"all\",\n \"race\",\n]);\n\n/**\n * Create a custom flow engine with additional step types\n * and/or default hooks.\n *\n * Returns a `flowAgent()`-like factory. Any custom steps defined\n * in `$` are merged into the handler's `$` parameter and fully typed.\n *\n * @typeParam TCustomSteps - The custom step definitions map.\n * @param config - Engine configuration including custom steps\n * and default hooks.\n * @returns A `FlowFactory` that creates flow agents with custom\n * `$` steps and engine-level default hooks.\n *\n * @example\n * ```typescript\n * const engine = createFlowEngine({\n * $: {\n * retry: async ({ ctx, config }) => {\n * let lastError: Error | undefined\n * for (let attempt = 0; attempt < config.attempts; attempt++) {\n * try {\n * return await config.execute({ attempt })\n * } catch (err) {\n * lastError = err as Error\n * }\n * }\n * throw lastError\n * },\n * },\n * onStart: ({ input }) => telemetry.trackStart(input),\n * })\n *\n * const myFlow = engine({\n * name: 'my-flow',\n * input: MyInput,\n * output: MyOutput,\n * }, async ({ input, $ }) => {\n * const data = await $.retry({\n * attempts: 3,\n * execute: async () => fetch('https://api.example.com/data'),\n * })\n * return data\n * })\n * ```\n */\nexport function createFlowEngine<\n TCustomSteps extends CustomStepDefinitions = Record<string, never>,\n>(engineConfig: FlowEngineConfig<TCustomSteps>): FlowFactory<TCustomSteps> {\n // Validate custom step names at engine creation time\n for (const name of Object.keys(engineConfig.$ ?? {})) {\n if (RESERVED_STEP_NAMES.has(name)) {\n throw new Error(`Custom step \"${name}\" conflicts with a built-in StepBuilder method`);\n }\n }\n\n return function engineCreateFlowAgent<TInput, TOutput>(\n flowConfig: FlowAgentConfigWithOutput<TInput, TOutput>,\n handler: (params: {\n input: TInput;\n $: StepBuilder & TypedCustomSteps<TCustomSteps>;\n log: Logger;\n }) => Promise<TOutput>,\n ): FlowAgent<TInput, TOutput> {\n const hookLog = (flowConfig.logger ?? createDefaultLogger()).child({ source: \"engine\" });\n\n const { onStart: engineOnStart } = engineConfig;\n const { onStart: flowOnStart } = flowConfig;\n const { onFinish: engineOnFinish } = engineConfig;\n const { onFinish: flowOnFinish } = flowConfig;\n const { onError: engineOnError } = engineConfig;\n const { onError: flowOnError } = flowConfig;\n const { onStepStart: engineOnStepStart } = engineConfig;\n const { onStepStart: flowOnStepStart } = flowConfig;\n const { onStepFinish: engineOnStepFinish } = engineConfig;\n const { onStepFinish: flowOnStepFinish } = flowConfig;\n\n const mergedConfig: FlowAgentConfigWithOutput<TInput, TOutput> = {\n ...flowConfig,\n onStart: buildMergedHook(hookLog, engineOnStart, flowOnStart),\n onFinish: buildMergedHook(hookLog, engineOnFinish, flowOnFinish),\n onError: buildMergedHook(hookLog, engineOnError, flowOnError),\n onStepStart: buildMergedHook(hookLog, engineOnStepStart, flowOnStepStart),\n onStepFinish: buildMergedHook(hookLog, engineOnStepFinish, flowOnStepFinish),\n };\n\n const wrappedHandler: FlowAgentHandler<TInput, TOutput> = async (params) => {\n return handler({\n input: params.input,\n $: params.$ as StepBuilder & TypedCustomSteps<TCustomSteps>,\n log: params.log,\n });\n };\n\n return flowAgent(mergedConfig, wrappedHandler, {\n augment$: ($, ctx) => {\n const customSteps: Record<string, (config: unknown) => Promise<unknown>> = {};\n\n for (const [name, factory] of Object.entries(engineConfig.$ ?? {})) {\n // eslint-disable-next-line security/detect-object-injection -- Key from Object.entries iteration, not user input\n customSteps[name] = (config: unknown) =>\n factory({ ctx: { signal: ctx.signal, log: ctx.log }, config: config as never });\n }\n return { ...$, ...customSteps } as StepBuilder;\n },\n });\n };\n}\n","// ──────────────────────────────────────────────────────────────\n// █████╗ ██████╗ ███████╗███╗ ██╗████████╗███████╗\n// ██╔══██╗██╔════╝ ██╔════╝████╗ ██║╚══██╔══╝██╔════╝\n// ███████║██║ ███╗█████╗ ██╔██╗ ██║ ██║ ███████╗\n// ██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║ ╚════██║\n// ██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║ ███████║\n// ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝\n//\n// AUTO-GENERATED — DO NOT EDIT\n// Update: pnpm --filter=@pkg/agent-sdk generate:models\n// ──────────────────────────────────────────────────────────────\n\nexport const OPENAI_MODELS = [\n {\n id: \"openai/gpt-5.2-codex\",\n category: \"coding\",\n pricing: { prompt: 0.00000175, completion: 0.000014, inputCacheRead: 1.75e-7, webSearch: 0.01 },\n },\n {\n id: \"openai/gpt-5.2\",\n category: \"chat\",\n pricing: { prompt: 0.00000175, completion: 0.000014, inputCacheRead: 1.75e-7, webSearch: 0.01 },\n },\n {\n id: \"openai/gpt-5.1\",\n category: \"chat\",\n pricing: { prompt: 0.00000125, completion: 0.00001, inputCacheRead: 1.25e-7, webSearch: 0.01 },\n },\n {\n id: \"openai/gpt-5\",\n category: \"chat\",\n pricing: { prompt: 0.00000125, completion: 0.00001, inputCacheRead: 1.25e-7, webSearch: 0.01 },\n },\n {\n id: \"openai/gpt-5-mini\",\n category: \"chat\",\n pricing: { prompt: 2.5e-7, completion: 0.000002, inputCacheRead: 2.5e-8, webSearch: 0.01 },\n },\n {\n id: \"openai/gpt-5-nano\",\n category: \"chat\",\n pricing: { prompt: 5e-8, completion: 4e-7, inputCacheRead: 5e-9, webSearch: 0.01 },\n },\n {\n id: \"openai/gpt-4.1\",\n category: \"chat\",\n pricing: { prompt: 0.000002, completion: 0.000008, inputCacheRead: 5e-7, webSearch: 0.01 },\n },\n {\n id: \"openai/gpt-4.1-mini\",\n category: \"chat\",\n pricing: { prompt: 4e-7, completion: 0.0000016, inputCacheRead: 1e-7, webSearch: 0.01 },\n },\n {\n id: \"openai/gpt-4.1-nano\",\n category: \"chat\",\n pricing: { prompt: 1e-7, completion: 4e-7, inputCacheRead: 2.5e-8, webSearch: 0.01 },\n },\n {\n id: \"openai/gpt-4o\",\n category: \"chat\",\n pricing: { prompt: 0.0000025, completion: 0.00001, inputCacheRead: 0.00000125 },\n },\n {\n id: \"openai/gpt-4o-mini\",\n category: \"chat\",\n pricing: { prompt: 1.5e-7, completion: 6e-7, inputCacheRead: 7.5e-8 },\n },\n {\n id: \"openai/o3\",\n category: \"reasoning\",\n pricing: { prompt: 0.000002, completion: 0.000008, inputCacheRead: 5e-7, webSearch: 0.01 },\n },\n {\n id: \"openai/o3-mini\",\n category: \"reasoning\",\n pricing: { prompt: 0.0000011, completion: 0.0000044, inputCacheRead: 5.5e-7 },\n },\n {\n id: \"openai/o4-mini\",\n category: \"reasoning\",\n pricing: { prompt: 0.0000011, completion: 0.0000044, inputCacheRead: 2.75e-7, webSearch: 0.01 },\n },\n] as const;\n","// ──────────────────────────────────────────────────────────────\n// █████╗ ██████╗ ███████╗███╗ ██╗████████╗███████╗\n// ██╔══██╗██╔════╝ ██╔════╝████╗ ██║╚══██╔══╝██╔════╝\n// ███████║██║ ███╗█████╗ ██╔██╗ ██║ ██║ ███████╗\n// ██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║ ╚════██║\n// ██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║ ███████║\n// ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝\n//\n// AUTO-GENERATED — DO NOT EDIT\n// Update: pnpm --filter=@pkg/agent-sdk generate:models\n// ──────────────────────────────────────────────────────────────\n\nimport { P, match } from \"ts-pattern\";\nimport type { LiteralUnion } from \"type-fest\";\n\nimport { OPENAI_MODELS } from \"@/core/models/providers/openai.js\";\n\nconst GENERATED_MODELS = [...OPENAI_MODELS] as const;\n\n/**\n * Supported OpenRouter model identifiers, derived from the generated {@link MODELS} array.\n */\nexport type OpenRouterLanguageModelId = (typeof GENERATED_MODELS)[number][\"id\"];\n\n/**\n * A model identifier that suggests known OpenRouter models but accepts any string.\n *\n * Provides autocomplete for cataloged models while allowing arbitrary\n * model IDs for new or custom models not yet in the catalog.\n */\nexport type ModelId = LiteralUnion<OpenRouterLanguageModelId, string>;\n\n/**\n * Model category for classification and filtering.\n */\nexport type ModelCategory = \"chat\" | \"coding\" | \"reasoning\";\n\n/**\n * Per-model pricing in USD per token.\n *\n * Field names match the OpenRouter API convention. All values are\n * per-token (or per-unit) rates as numbers. Optional fields are\n * omitted when the provider does not support them.\n */\nexport interface ModelPricing {\n /** Cost per input (prompt) token. */\n prompt: number;\n\n /** Cost per output (completion) token. */\n completion: number;\n\n /** Cost per cached input token (read). */\n inputCacheRead?: number;\n\n /** Cost per cached input token (write). */\n inputCacheWrite?: number;\n\n /** Cost per web search request. */\n webSearch?: number;\n\n /** Cost per internal reasoning token. */\n internalReasoning?: number;\n\n /** Cost per image input token. */\n image?: number;\n\n /** Cost per audio input second. */\n audio?: number;\n\n /** Cost per audio output second. */\n audioOutput?: number;\n}\n\n/**\n * Model definition with metadata and pricing.\n */\nexport interface ModelDefinition {\n /** OpenRouter model identifier (e.g. `\"openai/gpt-5.2-codex\"`). */\n id: string;\n\n /** Model category for classification. */\n category: ModelCategory;\n\n /** Token pricing rates. */\n pricing: ModelPricing;\n}\n\n/**\n * Supported OpenRouter models with pricing data.\n */\nexport const MODELS = GENERATED_MODELS satisfies readonly ModelDefinition[];\n\n/**\n * Look up a model definition by its identifier.\n *\n * @param id - The model identifier to look up.\n * @returns The matching model definition.\n * @throws {Error} If no model matches the given ID.\n *\n * @example\n * ```typescript\n * const m = model('openai/gpt-5.2-codex')\n * console.log(m.pricing.prompt) // 0.00000175\n * console.log(m.category) // 'coding'\n * ```\n */\nexport function model(id: ModelId): ModelDefinition {\n const found = MODELS.find((m) => m.id === id);\n if (!found) {\n throw new Error(`Unknown model: ${id}`);\n }\n return found;\n}\n\n/**\n * Look up a model definition by its identifier, returning `undefined` if not found.\n *\n * Unlike {@link model}, this does not throw for unknown IDs — useful when\n * the caller can gracefully handle missing pricing (e.g. non-OpenRouter models).\n *\n * @param id - The model identifier to look up.\n * @returns The matching model definition, or `undefined`.\n *\n * @example\n * ```typescript\n * const m = tryModel('anthropic/claude-sonnet-4-20250514')\n * if (m) {\n * console.log(m.pricing.prompt)\n * }\n * ```\n */\nexport function tryModel(id: ModelId): ModelDefinition | undefined {\n return MODELS.find((m) => m.id === id);\n}\n\n/**\n * Return supported model definitions, optionally filtered.\n *\n * @param filter - Optional predicate to filter models.\n * @returns A readonly array of matching model definitions.\n *\n * @example\n * ```typescript\n * const all = models()\n * const reasoning = models((m) => m.category === 'reasoning')\n * ```\n */\nexport function models(filter?: (m: ModelDefinition) => boolean): readonly ModelDefinition[] {\n return match(filter)\n .with(P.nullish, () => MODELS)\n .otherwise((fn) => MODELS.filter(fn));\n}\n","/**\n * Error information returned when an SDK operation fails.\n *\n * Every public method returns `Result<T>` instead of throwing.\n * When `ok` is `false`, the error details are available on this interface.\n */\nexport interface ResultError {\n /**\n * Machine-readable error code.\n *\n * Identifies the category of failure. Stable across versions —\n * safe to match against in application code.\n *\n * @example\n * ```typescript\n * switch (result.error.code) {\n * case 'VALIDATION_ERROR': // input schema failed\n * case 'ABORT_ERROR': // signal was aborted\n * case 'AGENT_ERROR': // agent execution failed\n * }\n * ```\n */\n code: string;\n\n /**\n * Human-readable error description.\n *\n * Suitable for logging but not for programmatic matching —\n * use `code` for that.\n */\n message: string;\n\n /**\n * Original thrown error, if any.\n *\n * Preserved so callers can inspect the root cause when the\n * SDK catches and wraps an exception.\n */\n cause?: Error;\n}\n\n/**\n * Discriminated union for SDK operation results.\n *\n * Success fields are **flat on the object** — no `.value` wrapper.\n * Callers pattern-match on `ok` instead of using try/catch.\n *\n * @typeParam T - The success payload shape. All fields from `T` are\n * spread directly onto the success branch alongside `ok: true`.\n *\n * @example\n * ```typescript\n * const result = await agent.generate({ topic: 'TypeScript' })\n *\n * if (!result.ok) {\n * // Error branch — only `ok` and `error` are present.\n * console.error(result.error.code, result.error.message)\n * return\n * }\n *\n * // Success branch — all fields from T are directly on result.\n * console.log(result.output)\n * console.log(result.duration)\n * console.log(result.trace)\n * ```\n */\nexport type Result<T> = (T & { ok: true }) | { ok: false; error: ResultError };\n\n// ---------------------------------------------------------------------------\n// Constructors\n// ---------------------------------------------------------------------------\n\n/**\n * Create a success `Result`.\n *\n * Spreads the payload flat onto the object alongside `ok: true`.\n *\n * @param value - The success payload.\n * @returns A success `Result<T>`.\n *\n * @example\n * ```typescript\n * return ok({ output: 'hello', messages: [] })\n * // → { ok: true, output: 'hello', messages: [] }\n * ```\n */\nexport function ok<T extends Record<string, unknown>>(value: T): T & { ok: true } {\n return { ...value, ok: true as const };\n}\n\n/**\n * Create a failure `Result`.\n *\n * @param code - Machine-readable error code.\n * @param message - Human-readable error description.\n * @param cause - Optional original thrown error.\n * @returns A failure `Result` for any `T`.\n *\n * @example\n * ```typescript\n * return err('VALIDATION_ERROR', 'Name is required')\n * return err('AGENT_ERROR', error.message, error)\n * ```\n */\nexport function err(\n code: string,\n message: string,\n cause?: Error,\n): { ok: false; error: ResultError } {\n return { ok: false as const, error: { code, message, cause } };\n}\n\n// ---------------------------------------------------------------------------\n// Type guards\n// ---------------------------------------------------------------------------\n\n/**\n * Narrow a `Result<T>` to its success branch.\n *\n * @param result - The result to check.\n * @returns `true` when `result.ok` is `true`.\n *\n * @example\n * ```typescript\n * const result = await agent.generate('hello')\n * if (isOk(result)) {\n * console.log(result.output)\n * }\n * ```\n */\nexport function isOk<T>(result: Result<T>): result is T & { ok: true } {\n return result.ok;\n}\n\n/**\n * Narrow a `Result<T>` to its failure branch.\n *\n * @param result - The result to check.\n * @returns `true` when `result.ok` is `false`.\n *\n * @example\n * ```typescript\n * const result = await agent.generate('hello')\n * if (isErr(result)) {\n * console.error(result.error.code, result.error.message)\n * }\n * ```\n */\nexport function isErr<T>(result: Result<T>): result is { ok: false; error: ResultError } {\n return !result.ok;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# agent()
|
|
2
|
+
|
|
3
|
+
`agent()` creates an `Agent` that wraps the AI SDK's tool loop (`generateText`/`streamText`) with typed input, subagents, hooks, and `Result` return types.
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
function agent<TInput, TOutput, TTools, TSubAgents>(
|
|
9
|
+
config: AgentConfig<TInput, TOutput, TTools, TSubAgents>,
|
|
10
|
+
): Agent<TInput, TOutput, TTools, TSubAgents>;
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## AgentConfig
|
|
14
|
+
|
|
15
|
+
| Field | Required | Type | Description |
|
|
16
|
+
| -------------- | -------- | --------------------------------------------------------------- | ----------------------------------------------------------- |
|
|
17
|
+
| `name` | Yes | `string` | Unique agent name (used in logs, traces, hooks) |
|
|
18
|
+
| `model` | Yes | `Model` (string ID or `LanguageModel`) | Model to use for generation |
|
|
19
|
+
| `input` | No | `ZodType<TInput>` | Zod schema for typed input (requires `prompt`) |
|
|
20
|
+
| `prompt` | No | `(params: { input: TInput }) => string \| Message[]` | Render typed input into the model prompt (requires `input`) |
|
|
21
|
+
| `system` | No | `string \| ((params: { input: TInput }) => string)` | System prompt (static or dynamic) |
|
|
22
|
+
| `tools` | No | `TTools` (Record of `Tool`) | Tools for function calling |
|
|
23
|
+
| `agents` | No | `TSubAgents` (Record of `Agent`) | Subagents, auto-wrapped as callable tools |
|
|
24
|
+
| `maxSteps` | No | `number` | Max tool-loop iterations (default: `20`) |
|
|
25
|
+
| `output` | No | `OutputParam` | Output type strategy (see below) |
|
|
26
|
+
| `logger` | No | `Logger` | Pino-compatible logger |
|
|
27
|
+
| `onStart` | No | `(event: { input }) => void \| Promise<void>` | Hook: fires when the agent starts |
|
|
28
|
+
| `onFinish` | No | `(event: { input, result, duration }) => void \| Promise<void>` | Hook: fires on success |
|
|
29
|
+
| `onError` | No | `(event: { input, error }) => void \| Promise<void>` | Hook: fires on error |
|
|
30
|
+
| `onStepFinish` | No | `(event: { stepId }) => void \| Promise<void>` | Hook: fires after each tool-loop step |
|
|
31
|
+
|
|
32
|
+
### Two Modes
|
|
33
|
+
|
|
34
|
+
| Config | `.generate()` first param | How prompt is built |
|
|
35
|
+
| ---------------------- | ------------------------- | ------------------------------ |
|
|
36
|
+
| `input` + `prompt` set | Typed `TInput` | `prompt({ input })` renders it |
|
|
37
|
+
| Both omitted | `string \| Message[]` | Passed directly to the model |
|
|
38
|
+
|
|
39
|
+
`input` and `prompt` are required together -- providing one without the other is a type error.
|
|
40
|
+
|
|
41
|
+
### Output
|
|
42
|
+
|
|
43
|
+
The `output` field accepts an AI SDK `Output` strategy or a raw Zod schema:
|
|
44
|
+
|
|
45
|
+
- `Output.text()` -- plain string (default when omitted)
|
|
46
|
+
- `Output.object({ schema })` -- validated structured object
|
|
47
|
+
- `Output.array({ element })` -- validated array
|
|
48
|
+
- `Output.choice({ options })` -- enum/classification
|
|
49
|
+
- `z.object({ ... })` -- auto-wrapped as `Output.object({ schema })`
|
|
50
|
+
- `z.array(z.object({ ... }))` -- auto-wrapped as `Output.array({ element })`
|
|
51
|
+
|
|
52
|
+
## Agent Interface
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
interface Agent<TInput, TOutput, TTools, TSubAgents> {
|
|
56
|
+
generate(
|
|
57
|
+
input: TInput,
|
|
58
|
+
config?: AgentOverrides<TTools, TSubAgents>,
|
|
59
|
+
): Promise<Result<GenerateResult<TOutput>>>;
|
|
60
|
+
stream(
|
|
61
|
+
input: TInput,
|
|
62
|
+
config?: AgentOverrides<TTools, TSubAgents>,
|
|
63
|
+
): Promise<Result<StreamResult<TOutput>>>;
|
|
64
|
+
fn(): (
|
|
65
|
+
input: TInput,
|
|
66
|
+
config?: AgentOverrides<TTools, TSubAgents>,
|
|
67
|
+
) => Promise<Result<GenerateResult<TOutput>>>;
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### generate()
|
|
72
|
+
|
|
73
|
+
Runs the agent to completion. Returns `Result<GenerateResult<TOutput>>`.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
interface GenerateResult<TOutput = string> {
|
|
77
|
+
output: TOutput; // the generation output
|
|
78
|
+
messages: Message[]; // full message history including tool calls
|
|
79
|
+
usage: TokenUsage; // aggregated token usage across all tool-loop steps
|
|
80
|
+
finishReason: string; // why the model stopped ('stop', 'length', 'tool-calls', etc.)
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
On success, `result.ok` is `true` and `output`/`messages` are flat on the result object. On failure, `result.ok` is `false` and `result.error` contains a `ResultError`.
|
|
85
|
+
|
|
86
|
+
### stream()
|
|
87
|
+
|
|
88
|
+
Runs the agent with streaming output. Returns `Result<StreamResult<TOutput>>`.
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
interface StreamResult<TOutput = string> {
|
|
92
|
+
output: Promise<TOutput>; // resolves after stream completes
|
|
93
|
+
messages: Promise<Message[]>; // resolves after stream completes
|
|
94
|
+
usage: Promise<TokenUsage>; // resolves after stream completes
|
|
95
|
+
finishReason: Promise<string>; // resolves after stream completes
|
|
96
|
+
stream: ReadableStream<string>; // live text deltas
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The `stream` is available immediately. Consume it for incremental output. Await `output` and `messages` after the stream ends.
|
|
101
|
+
|
|
102
|
+
### fn()
|
|
103
|
+
|
|
104
|
+
Returns a plain function with the same signature as `.generate()`. Use for clean single-function exports.
|
|
105
|
+
|
|
106
|
+
## AgentOverrides
|
|
107
|
+
|
|
108
|
+
Per-call overrides passed as the optional second parameter to `.generate()` or `.stream()`. Override fields replace the base config for that call only.
|
|
109
|
+
|
|
110
|
+
| Field | Type | Description |
|
|
111
|
+
| -------------- | --------------------------------------------- | ------------------------------- |
|
|
112
|
+
| `model` | `Model` | Override the model |
|
|
113
|
+
| `system` | `string \| ((params) => string)` | Override the system prompt |
|
|
114
|
+
| `tools` | `Partial<TTools> & Record<string, Tool>` | Merge with base tools |
|
|
115
|
+
| `agents` | `Partial<TSubAgents> & Record<string, Agent>` | Merge with base subagents |
|
|
116
|
+
| `maxSteps` | `number` | Override max tool-loop steps |
|
|
117
|
+
| `output` | `OutputParam` | Override the output strategy |
|
|
118
|
+
| `signal` | `AbortSignal` | Abort signal for cancellation |
|
|
119
|
+
| `logger` | `Logger` | Override the logger |
|
|
120
|
+
| `onStart` | hook | Per-call hook, fires after base |
|
|
121
|
+
| `onFinish` | hook | Per-call hook, fires after base |
|
|
122
|
+
| `onError` | hook | Per-call hook, fires after base |
|
|
123
|
+
| `onStepFinish` | hook | Per-call hook, fires after base |
|
|
124
|
+
|
|
125
|
+
Per-call hooks **merge** with base hooks -- base fires first, then call-level. Both are independently swallowed on error (via `attemptEachAsync`).
|
|
126
|
+
|
|
127
|
+
## Subagents
|
|
128
|
+
|
|
129
|
+
Agents declared in the `agents` field are automatically wrapped as tools that the parent agent can invoke through function calling. Abort signals propagate automatically from parent to child.
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
const researcher = agent({
|
|
133
|
+
name: "researcher",
|
|
134
|
+
model: "openai/gpt-4.1",
|
|
135
|
+
system: "You research topics thoroughly.",
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const writer = agent({
|
|
139
|
+
name: "writer",
|
|
140
|
+
model: "openai/gpt-4.1",
|
|
141
|
+
system: "You are a technical writer. Delegate research to the researcher agent.",
|
|
142
|
+
agents: { researcher },
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Examples
|
|
147
|
+
|
|
148
|
+
### Simple agent
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
const helper = agent({
|
|
152
|
+
name: "helper",
|
|
153
|
+
model: "openai/gpt-4.1",
|
|
154
|
+
system: "You are a helpful assistant.",
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const result = await helper.generate("What is TypeScript?");
|
|
158
|
+
if (result.ok) {
|
|
159
|
+
console.log(result.output); // string
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Typed agent
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
const summarizer = agent({
|
|
167
|
+
name: "summarizer",
|
|
168
|
+
model: "openai/gpt-4.1",
|
|
169
|
+
input: z.object({ text: z.string() }),
|
|
170
|
+
prompt: ({ input }) => `Summarize the following:\n\n${input.text}`,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const result = await summarizer.generate({ text: "Long article..." });
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Agent with tools
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
const search = tool({
|
|
180
|
+
description: "Search the web",
|
|
181
|
+
inputSchema: z.object({ query: z.string() }),
|
|
182
|
+
execute: async ({ query }) => webSearch(query),
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const assistant = agent({
|
|
186
|
+
name: "assistant",
|
|
187
|
+
model: "openai/gpt-4.1",
|
|
188
|
+
system: "You are a helpful assistant with web search.",
|
|
189
|
+
tools: { search },
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Agent with subagents
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
const analyst = agent({
|
|
197
|
+
name: "analyst",
|
|
198
|
+
model: "openai/gpt-4.1",
|
|
199
|
+
system: "You analyze data. Delegate searches to the searcher.",
|
|
200
|
+
agents: { searcher: searchAgent },
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Streaming
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
const result = await helper.stream("Tell me a story");
|
|
208
|
+
if (result.ok) {
|
|
209
|
+
for await (const chunk of result.stream) {
|
|
210
|
+
process.stdout.write(chunk);
|
|
211
|
+
}
|
|
212
|
+
const finalOutput = await result.output;
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Inline overrides
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
const result = await helper.generate("Explain quantum computing", {
|
|
220
|
+
model: "anthropic/claude-sonnet-4",
|
|
221
|
+
maxSteps: 5,
|
|
222
|
+
onFinish: ({ duration }) => console.log(`Took ${duration}ms`),
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## References
|
|
227
|
+
|
|
228
|
+
- [Core Overview](overview.md)
|
|
229
|
+
- [Hooks](hooks.md)
|
|
230
|
+
- [Tools](tools.md)
|
|
231
|
+
- [Guide: Create an Agent](../guides/create-agent.md)
|