{"version":3,"sources":["../src/compose-tool.ts"],"names":["composeTool","options","args","context","prior","state","i","step","subArgs","subCall","result"],"mappings":"aAgEO,SAASA,CAAAA,CACdC,EACuB,CACvB,GAAIA,EAAQ,KAAA,CAAM,MAAA,GAAW,CAAA,CAC3B,MAAM,IAAI,KAAA,CAAM,gBAAgBA,CAAAA,CAAQ,IAAI,CAAA,8BAAA,CAAgC,CAAA,CAG9E,OAAO,CACL,KAAMA,CAAAA,CAAQ,IAAA,CACd,WAAA,CAAaA,CAAAA,CAAQ,WAAA,CACrB,MAAA,CAAQA,EAAQ,MAAA,CAChB,oBAAA,CAAsBA,EAAQ,oBAAA,CAC9B,IAAA,CAAMA,EAAQ,IAAA,CACd,QAAA,CAAUA,CAAAA,CAAQ,QAAA,CAClB,MAAM,OAAA,CAAQC,EAAaC,CAAAA,CAAiD,CAC1E,IAAMC,CAAAA,CAAmB,EAAC,CACtBC,EAEJ,IAAA,IAASC,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAIL,CAAAA,CAAQ,KAAA,CAAM,OAAQK,CAAAA,EAAAA,CAAK,CAC7C,IAAMC,CAAAA,CAAON,CAAAA,CAAQ,MAAMK,CAAC,CAAA,CAC5B,GAAI,CAACC,CAAAA,CAAK,IAAA,CAAK,QACb,MAAM,IAAI,KAAA,CAAM,CAAA,aAAA,EAAgBN,CAAAA,CAAQ,IAAI,YAAYK,CAAC,CAAA,OAAA,EAAUC,CAAAA,CAAK,IAAA,CAAK,IAAI,CAAA,gBAAA,CAAkB,EAErG,IAAMC,CAAAA,CAAU,MAAMD,CAAAA,CAAK,OAAA,CAAQ,CAAE,KAAAL,CAAAA,CAAM,KAAA,CAAAG,CAAAA,CAAO,KAAA,CAAAD,CAAM,CAAC,EACzDH,CAAAA,CAAQ,MAAA,GAAS,CAAE,KAAA,CAAO,OAAA,CAAS,IAAA,CAAMK,EAAG,IAAA,CAAMC,CAAAA,CAAK,IAAA,CAAK,IAAA,CAAM,IAAA,CAAMC,CAAQ,CAAC,CAAA,CACjF,IAAMC,EAAU,CAAE,GAAGN,EAAQ,IAAA,CAAM,IAAA,CAAMI,CAAAA,CAAK,IAAA,CAAK,IAAA,CAAM,IAAA,CAAMC,CAAQ,CAAA,CACjEE,CAAAA,CAAS,MAAMH,CAAAA,CAAK,IAAA,CAAK,OAAA,CAAQC,EAAS,CAAE,QAAA,CAAUL,CAAAA,CAAQ,QAAA,CAAU,IAAA,CAAMM,CAAQ,CAAC,CAAA,CAM7F,GALAL,CAAAA,CAAM,IAAA,CAAKM,CAAM,CAAA,CACjBL,EAAQE,CAAAA,CAAK,SAAA,CACT,MAAMA,CAAAA,CAAK,SAAA,CAAUG,CAAAA,CAAQ,CAAE,IAAA,CAAAR,CAAAA,CAAM,KAAA,CAAAG,CAAAA,CAAO,KAAA,CAAAD,CAAM,CAAC,CAAA,CACnDM,CAAAA,CACJT,CAAAA,CAAQ,MAAA,GAAS,CAAE,KAAA,CAAO,MAAO,IAAA,CAAMK,CAAAA,CAAG,KAAMC,CAAAA,CAAK,IAAA,CAAK,KAAM,MAAA,CAAAG,CAAO,CAAC,CAAA,CACpEH,CAAAA,CAAK,QAAA,GAAWF,EAAO,CAAE,IAAA,CAAAH,CAAAA,CAAM,KAAA,CAAAE,CAAM,CAAC,EAAG,CAC3CH,CAAAA,CAAQ,MAAA,GAAS,CAAE,KAAA,CAAO,MAAA,CAAQ,KAAMK,CAAAA,CAAI,CAAA,CAAG,IAAA,CAAM,WAAY,CAAC,CAAA,CAClE,KACF,CACF,CAEA,OAAIL,CAAAA,CAAQ,QAAA,CAAiBA,CAAAA,CAAQ,SAAS,CAAE,IAAA,CAAAC,CAAAA,CAAM,KAAA,CAAAE,CAAAA,CAAO,KAAA,CAAAC,CAAM,CAAC,CAAA,CAC7DA,CACT,CACF,CACF","file":"compose-tool.cjs","sourcesContent":["import type { JSONSchema7 } from 'json-schema'\nimport type { ToolDefinition, ToolExecutionContext } from './types/tool'\n\n/**\n * One link in a composed tool: invoke `tool` with arguments derived\n * from the prior step's output (or the macro-call's original args),\n * optionally transform the result before feeding it into the next\n * link.\n */\nexport interface ComposeStep<TArgs extends Record<string, unknown> = Record<string, unknown>, TState = unknown> {\n  tool: ToolDefinition\n  /**\n   * Map the current pipeline state into the sub-tool's arguments.\n   * Receives the macro call's raw args and the accumulated state\n   * (the result of every prior step, in declaration order).\n   */\n  mapArgs: (input: { args: TArgs; state: TState; prior: unknown[] }) => Record<string, unknown> | Promise<Record<string, unknown>>\n  /**\n   * Transform the sub-tool's raw output before storing it in state.\n   * Default: pass the value through untouched.\n   */\n  mapResult?: (output: unknown, input: { args: TArgs; state: TState; prior: unknown[] }) => TState | Promise<TState>\n  /**\n   * Short-circuit the pipeline and return the current state when\n   * this returns true. The step's sub-tool is still executed; use\n   * `mapArgs` to skip if needed.\n   */\n  stopWhen?: (state: TState, input: { args: TArgs; prior: unknown[] }) => boolean\n}\n\nexport interface ComposeToolOptions<TArgs extends Record<string, unknown> = Record<string, unknown>> {\n  name: string\n  description?: string\n  schema?: JSONSchema7\n  requiresConfirmation?: boolean\n  tags?: string[]\n  category?: string\n  /** Execution steps. Run left-to-right; output becomes input of next. */\n  steps: ComposeStep<TArgs, unknown>[]\n  /**\n   * Final reducer — receives the last state + every intermediate\n   * output, returns the macro tool's result. Default: the last state.\n   */\n  finalize?: (input: { args: TArgs; prior: unknown[]; state: unknown }) => unknown | Promise<unknown>\n  /** Observability — fires before/after each step. */\n  onStep?: (event: {\n    phase: 'start' | 'end' | 'skip'\n    step: number\n    tool: string\n    args?: Record<string, unknown>\n    result?: unknown\n  }) => void\n}\n\n/**\n * Chain N tools into a single macro tool. The composed tool exposes\n * one schema to the model (`options.schema`) but under the hood runs\n * a fixed pipeline of sub-tools — a \"skill\" that always performs the\n * same multi-step recipe.\n *\n * Each step's `mapArgs` builds the next call from the running state;\n * `mapResult` transforms the output before it's stored. The final\n * step's state is returned unless a `finalize` reducer is given.\n */\nexport function composeTool<TArgs extends Record<string, unknown> = Record<string, unknown>>(\n  options: ComposeToolOptions<TArgs>,\n): ToolDefinition<TArgs> {\n  if (options.steps.length === 0) {\n    throw new Error(`composeTool(\"${options.name}\"): at least one step required`)\n  }\n\n  return {\n    name: options.name,\n    description: options.description,\n    schema: options.schema,\n    requiresConfirmation: options.requiresConfirmation,\n    tags: options.tags,\n    category: options.category,\n    async execute(args: TArgs, context: ToolExecutionContext): Promise<unknown> {\n      const prior: unknown[] = []\n      let state: unknown = undefined\n\n      for (let i = 0; i < options.steps.length; i++) {\n        const step = options.steps[i]!\n        if (!step.tool.execute) {\n          throw new Error(`composeTool(\"${options.name}\"): step ${i} tool \"${step.tool.name}\" has no execute`)\n        }\n        const subArgs = await step.mapArgs({ args, state, prior })\n        options.onStep?.({ phase: 'start', step: i, tool: step.tool.name, args: subArgs })\n        const subCall = { ...context.call, name: step.tool.name, args: subArgs }\n        const result = await step.tool.execute(subArgs, { messages: context.messages, call: subCall })\n        prior.push(result)\n        state = step.mapResult\n          ? await step.mapResult(result, { args, state, prior })\n          : result\n        options.onStep?.({ phase: 'end', step: i, tool: step.tool.name, result })\n        if (step.stopWhen?.(state, { args, prior })) {\n          options.onStep?.({ phase: 'skip', step: i + 1, tool: 'remaining' })\n          break\n        }\n      }\n\n      if (options.finalize) return options.finalize({ args, prior, state })\n      return state\n    },\n  }\n}\n"]}