Skip to content

Latest commit

 

History

History
249 lines (166 loc) · 8.59 KB

File metadata and controls

249 lines (166 loc) · 8.59 KB

Tools Spec(defineTool / zod / DI / serialization / tool output cache)

This document is a specification for the definition, execution, and schema generation of Tool (function tool). We aim for the “minimum and correct form” when converting the Python version of @tool and Depends to TS.


1. Terminology

  • Tool: A function that the model can call with tool call. Input is JSON (constrained by schema)
  • Tool definition: "Tool list" (name/description/JSON Schema) to be passed to LLM
  • DI: A mechanism to resolve and inject dependencies (DB clients, etc.) when running the tool

2. Basic form of Tool (recommended)

2.1 defineTool

In TS, the “data + function” form is easier to handle than the decorator.

export type DefineToolOptions<TInput, TResult> = {
  name: string;
  description: string;
  input: ZodSchema<TInput>;
  execute: (input: TInput, ctx: ToolContext) => Promise<TResult> | TResult;
};

export type Tool = {
  name: string;
  description: string;
definition: ToolDefinition; // parameters are JSON Schema
  executeRaw: (rawArgsJson: string, ctx: ToolContext) => Promise<ToolResult>;
};

By moving executeRaw to the Tool side, the Agent side can

  • JSON parse
  • Validation
  • Exception → ToolMessage

can be treated as a “Tool common” implementation.

2.2 ToolContext (DI receptacle)

export type ToolContext = {
  signal?: AbortSignal;
  logger?: Logger;
  now?: () => Date;

  // dependency overrides / injection
  deps: Record<string, unknown>;
  resolve: <T>(key: DependencyKey<T>) => Promise<T>;
};

Tool extracts dependencies using ctx.resolve(...) (or you can directly reference ctx.deps).


3. JSON Schema generation (zod → JSON Schema)

3.1 Purpose

  • Enable LLM to produce “correct argument form”
  • Validate invalid arguments before tool execution (zod validate)

3.2 Requirements

  • Ability to generate JSON Schema from zod schema
  • Must be able to attach constraints equivalent to additionalProperties: false (If not, reject on the Tool side)
  • Built-in defineTool definitions use explicit non-strict function calling so Zod optional/defaulted fields remain optional and model-visible schemas stay compact.
  • Runtime Zod parsing remains authoritative and rejects invalid generated arguments before execution.
  • External/client tools may still request provider strict mode when their supplied schema is compatible (see providers spec for details).

*Use Zod v4's toJSONSchema (target: "draft-07" / io: "input").


4. DI (equivalent to Depends) specifications

Properties that the Python version of Depends satisfies:

  • Dependencies can be resolved with either sync/async
  • Can be overridden (replaced)

In TS, it is easy to understand that the “dependency resolution key” is explicitly specified and handled.

4.1 DependencyKey

export type DependencyKey<T> = {
  id: string;
  create: () => T | Promise<T>;
};

export type DependencyOverrides = Map<string, () => unknown | Promise<unknown>>;

4.2 Resolve rules

  • If overrides has the same id, use it
  • If not, call create()
  • Values may be cached for the duration of a single tool call (“per-run” caching if necessary)

CLI is often used to replace file operation root'' and work directory'' with DI.


5. Tool result expression and serialization

5.1 ToolResult (internal representation)

export type ToolResult =
  | { type: 'text'; text: string }
  | { type: 'parts'; parts: ContentPart[] }
  | { type: 'json'; value: unknown };

5.2 ToolMessage conversion rules

  • textToolMessage.content is string
  • json → JSON.stringify (for stability)
  • partsToolMessage.content are parts

5.3 Exception

Tool exceptions are converted to ToolMessage(is_error=true, content="Error executing tool: ...").


6. Tool output cache

While tool output is "kept in context as much as possible", if the total size limit is exceeded, Trim from old output and leave reference ID. See dev-docs/specs/context-management.md for details.

ToolMessage may be given output_ref (reference ID).

Multimodal parts must remain structured in the live ToolMessage through tool-output cache processing. The current text-only cache store may persist a placeholder projection for lookup, but it must not replace the image/document parts before the next model call.

TODO:

  • Implementation of tool_output_cache / tool_output_cache_grep supports streaming in case of large output.
  • Extend the cache store to save and retrieve typed content parts, not only their text projection.

7. Positioning of “standard tools”

7.1 done

  • done is recommended as a “termination tool”
  • Not required (normally ends with response without tool call)

7.2 planning(todos)

Planning (write_todos, etc.) is not required for core, but is provided as a standard CLI tool.

With this design:

  • Library usage can be kept to a minimum
  • Using CLI can reduce the volatility of plans

Current runtime todo tooling:

  • todo_read: shows execution order, summary counts, and next actionable task.
  • todo_new: start/restart the plan with a new full list.
  • todo_append: append discovered tasks while keeping current items.
  • todo_patch: partially update/remove items by stable id; omitted patch fields keep their current values.
  • todo_clear: clear the entire todo list for the current session.
  • Todo item fields include id, content, status, priority(1-5), optional notes, optional activeForm.
  • Runtime validates that in_progress items are at most one so agents can process tasks one-by-one.
  • Todo state is persisted in session snapshot metadata (SessionState.meta.codelia_todos) and restored when resuming with run.start.session_id.

7.3 tool_output_cache

Standard tool to get the contents from the reference ID of the tool output cache.

  • name: tool_output_cache
  • input: { ref_id: string, offset?: number, limit?: number }
  • output: text with line numbers (similar to read)
  • default behavior: clip/truncate preview output and include continuation hints

7.4 tool_output_cache_grep

A standard tool that searches against the reference ID of the tool output cache.

  • name: tool_output_cache_grep
  • input: { ref_id: string, pattern: string, regex?: boolean, before?: number, after?: number, max_matches?: number }
  • output: text with line numbers (similar to grep)

7.5 tool_output_cache_line

A standard tool that reads one cached physical line by character window.

  • name: tool_output_cache_line
  • input: { ref_id: string, line_number: number, char_offset?: number, char_limit?: number }
  • output: text with segment metadata and continuation hint

7.6 search

Standard fallback tool for web search when provider-native search is not used.

  • name: search
  • input: { query: string, max_results?: number, backend?: "ddg" | "brave", allowed_domains?: string[] }
  • output: JSON summary of search candidates (title/url/snippet/source)

7.7 apply_patch

Structured multi-file edit tool for codex-style patch text.

  • name: apply_patch
  • input: { patch: string, dry_run?: boolean }
  • patch payload: codex-style *** Begin Patch / *** End Patch envelope with Add File / Delete File / Update File sections
  • update chunk rule: @@ chunk headers may omit unified-diff line numbers; context-only chunks are allowed, but each Update File section must contain at least one + or - change unless it is a move-only update
  • output: JSON summary including summary, file_count, files, and bounded diff preview (diff_cache_id when full diff is cached)
  • note: current codelia implementation keeps this as a normal JSON function tool carrying patch text, not a transport-level freeform tool

7.8 webfetch

Standard tool to fetch and normalize a specific URL after search/native search picks a candidate.

  • name: webfetch
  • input: { url: string, output_format?: "markdown" | "text" | "html", timeout_ms?: number, max_bytes?: number }
  • output: JSON summary including status, content_type, title, normalized content, and truncation metadata
  • note: intentionally treated as external access for permission policy, so it is not in the default system allowlist

7.9 view_image

Read-only local image inspection tool.

  • name: view_image
  • input: { file_path: string, detail?: "auto" | "low" | "high", max_bytes?: number }
  • output: multimodal content parts (text + image_url)
  • supported file types: png / jpeg / webp / gif
  • note: uses the same sandbox path semantics as other local file tools

8. Edit tool (enhanced behavior)

The edit tool semantics are defined in dev-docs/specs/edit-tool.md.