Class ComposableToolBuilder

Builds composite ITool instances by chaining existing tool invocations.

Each invocation is described by a ComposableStep that maps values from a shared pipeline context into the step tool's arguments via a lightweight reference expression syntax:

Expression Resolves to
"$input.foo" args.foo from the composite tool's own input
"$input" the whole input object
"$prev.bar" bar from the previous step's output
"$prev" the previous step's full output
"$steps[0].output.data" output.data from the first step's output
"$steps[0]" the first step's full output
anything else used as a literal value without transformation

Reference expressions nested inside plain objects are resolved recursively, so { query: "$input.topic", limit: 10 } becomes { query: "actual-topic", limit: 10 }.

Safe by construction — all tool invocations are delegated to the executeTool callback supplied at construction time. The builder never holds a reference to any tool registry.

Example

const builder = new ComposableToolBuilder(async (toolName, args, ctx) => {
const tool = registry.get(toolName);
return tool.execute(args, ctx);
});

const spec: ComposableToolSpec = {
mode: 'compose',
steps: [
{ name: 'search', tool: 'web_search', inputMapping: { query: '$input.topic' } },
{ name: 'summarise', tool: 'summarise_text', inputMapping: { text: '$prev.snippet' } },
],
};

const tool = builder.build('research', 'Search then summarise a topic', schema, spec);
const result = await tool.execute({ topic: 'quantum computing' }, ctx);

Constructors

Methods

Properties

Constructors

  • Parameters

    • executeTool: ((toolName, args, context) => Promise<ToolExecutionResult<any>>)

      Callback invoked for each pipeline step. Receives the target tool name, the resolved argument object, and the outer execution context forwarded from the composite tool's own execute call. Must return a ToolExecutionResult; a success: false result aborts the remainder of the pipeline.

    • Optional options: {
          strictMode?: boolean;
      }

      Optional builder configuration.

      • Optional strictMode?: boolean

        When true, unresolved reference expressions throw an error instead of falling through as literal strings.

    Returns ComposableToolBuilder

Methods

  • Build an ITool-compatible object from a ComposableToolSpec.

    The returned tool can be registered directly with any tool orchestrator that accepts ITool. Its execute method runs the step pipeline sequentially, threading outputs through the reference resolution system.

    Parameters

    • name: string

      Machine-readable tool name exposed to the LLM (e.g. "research_topic").

    • description: string

      Natural language description of what the composite tool does.

    • inputSchema: JSONSchemaObject

      JSON Schema describing the arguments the composite tool accepts.

    • spec: ComposableToolSpec

      The composable pipeline specification to execute.

    Returns ITool<any, any>

    A fully-formed ITool instance whose execute method runs the pipeline.

    Example

    const tool = builder.build(
    'fetch_and_summarise',
    'Fetch a URL then return a one-paragraph summary.',
    { type: 'object', properties: { url: { type: 'string' } }, required: ['url'] },
    spec,
    );
  • Validate a ComposableToolSpec before building.

    Performs structural checks only — it does not verify that the referenced tool names are actually registered in any registry. Use this method to give early, actionable feedback before attempting to build a tool.

    Checks performed:

    1. spec.steps must be a non-empty array.
    2. Every step must have a non-empty tool string.

    Parameters

    Returns {
        valid: boolean;
        errors?: string[];
    }

    { valid: true } when the spec passes all checks, or { valid: false, errors: string[] } with one message per failing check.

    • valid: boolean
    • Optional errors?: string[]

    Example

    const result = builder.validate(spec);
    if (!result.valid) {
    console.error('Invalid spec:', result.errors);
    }

Properties

strictMode: boolean

When true, unresolved $-prefixed reference expressions throw instead of silently passing through as literal strings. Useful for development and testing to catch typos in inputMapping expressions early.