Skip to content

zidane/tools/prompts

Every native tool's model-facing description as plain strings, free of runtime dependencies.

import { … } from 'zidane/tools/prompts'src/tools/prompts.ts

Use toolPrompts to read a built-in tool's default description, change it and pass it to toolDescriptions in createAgent(). The entry has no runtime dependencies, so a config file can import it without loading tool code. Tools with runtime-dependent text expose named fragments, so String#replace edits the exact text the model sees. See Tools.

TypeScript
import { createAgent } from 'zidane'
import { basic } from 'zidane/presets'
import { anthropic } from 'zidane/providers/anthropic'
import { toolPrompts } from 'zidane/tools/prompts'

const agent = createAgent({
  ...basic,
  provider: anthropic(),
  toolDescriptions: { read_file: `${toolPrompts.read_file} Read a file before you edit it.` },
})

await agent.run({ prompt: 'Fix the typo in README.md.' })

Constants#

toolPromptsConstant#

Every native tool's LLM-facing description, in one place.

This module is the source of truth: each tool file imports its spec.description from here rather than inlining it. It has no runtime dependencies (pure strings and tiny template functions) so hosts can import it from a config file — zidane/tools/prompts — read the defaults, and feed adjusted text into AgentOptions.toolDescriptions:

Text
import { toolPrompts } from 'zidane/tools/prompts'

createAgent({
  toolDescriptions: {
    read_file: toolPrompts.read_file.replace('Claude Code', 'the editor'),
    shell: cur => cur.replace(toolPrompts.shell.core, myShellIntro),
  },
})

Scope is the top-level spec.description — the surface toolDescriptions overrides. Parameter descriptions live with their schemas in the tool files.

Static tools are plain strings. Tools whose description depends on runtime configuration expose named fragments the factory joins conditionally; the fragments are the exact bytes the model receives, so String#replace against them is a precise edit.

TypeScript
const toolPrompts: { readonly call_tool: (discovery: string) => string; readonly edit: 'Replace exact `old_string` with `new_string` in a file. Fails if `old_string` is not unique unless `replace_all: true`. Prefer over `write_file` for surgical changes: preserves the rest of the file. Tolerates `read_file` line-number prefixes (`<N>\\t…`, `<N>|…`, or `<N>→…`) in `old_string` / `new_string`; they are stripped before matching/writing, so you can paste a numbered chunk verbatim. Several `edit` / `multi_edit` / `write_file` calls and a verifying `shell` call (tests, typecheck) in one message run in order, in a single round-trip.'; readonly fetch_url: 'Fetch a public URL and return its body as plain text. HTML is reduced to text (scripts, styles, tags stripped; entities decoded). If a `web_search` tool is also available, use it first when you do not already know the exact URL. Only http(s) URLs are accepted; loopback, link-local, private, and cloud-metadata addresses are refused. Output is capped (default 200 KiB).'; readonly generate_image: string; readonly glob: 'Match files by glob pattern (supports **, *, ?). Relative to the execution context cwd; patterns may reach outside the workspace (e.g. "../shared/**/*.ts"). By default each row is `<path>\\t<size-bytes>\\t<mtime-iso>`; set `metadata: false` for a plain newline-separated list of paths. Always sorted.'; readonly grep: 'Search file contents by regex. Returns matching paths (default), match content, or per-file counts. One call covers several patterns (`patterns`), several roots (`paths`), context lines, literal (`fixed_strings`) or whole-word (`-w`) matching, skipping files (`glob: "!*.lock"`, several in `globs`), and dropping noise lines (`exclude`, a regex); `head_limit` caps output. A missing root among several is skipped with a note. Backed by ripgrep when available, with a portable shell-listing + regex fallback when `rg` is absent.'; readonly interaction: 'Request structured input from the user or external system.'; readonly list_files: 'List the immediate entries (files and subdirectories) at literal directory `path`. Returns a newline-separated list; subdirectories carry a trailing `/`; or `(empty directory)` when the directory exists but is empty. Non-recursive: use `glob` for pattern matching across nested directories.'; readonly model_search: string; readonly multi_edit: 'Apply a sequential list of edits to a file. Each edit operates on the result of the previous APPLIED edit. Prefer this over multiple `edit` calls when several non-overlapping changes are needed in the same file. Edits run best-effort: a per-step failure (`old_string` not found, ambiguous match without `replace_all`, identical strings) is reported in the result but does NOT block the remaining steps. The file is written iff at least one step applied. The result lists per-hunk outcomes (`applied` / `failed`) so the model can re-issue just the failures without resending the whole batch. Each step tolerates `read_file` line-number prefixes (`<N>\\t…`, `<N>|…`, or `<N>→…`) in `old_string` / `new_string`. Several `edit` / `multi_edit` / `write_file` calls and a verifying `shell` call (tests, typecheck) in one message run in order, in a single round-trip.'; readonly read_chat_turns: string; readonly read_file: 'Read a file by path. Text files return lines [offset..offset+limit). Default offset=1, limit=2000; a negative offset reads from the end (`-50` = last 50 lines). Pass `paths` to read several files, or several ranges of one file, in one call. Each line is prefixed with its 1-indexed line number followed by a tab (e.g. `42\\tconst foo = bar`); the prefix is metadata, not part of the file. Mirrors Claude Code\'s `cat -n`-style compact output for token efficiency. A trailing footer explains how to read the rest when truncated. Images (png/jpg/gif/webp) and PDFs return structured attachments for capable models; other binary files return a short marker rather than mojibake.'; readonly read_parent_session: string; readonly record_artifact: string; readonly shell: { readonly background: string; readonly core: string; readonly preferDedicated: 'When a dedicated tool fits, prefer it over shell:'; readonly reminder: 'Re-running `ls`/`cat` on the same path is not useful: the prior result is still current unless you wrote to that path since.'; readonly swapHints: readonly [{ readonly canonical: 'read_file'; readonly instead: 'cat/head/tail/sed -n'; readonly label: 'Read files' }, { readonly canonical: 'glob'; readonly instead: 'find/ls'; readonly label: 'File search' }, { readonly canonical: 'grep'; readonly instead: 'grep/rg'; readonly label: 'Content search' }, { readonly canonical: 'list_files'; readonly instead: 'ls'; readonly label: 'Directory listings' }, { readonly canonical: 'edit'; readonly instead: 'sed/awk/python scripts'; readonly label: 'Edit files' }, { readonly canonical: 'write_file'; readonly instead: 'echo>/heredoc'; readonly label: 'Write files' }] }; readonly shell_kill: string; readonly skills_read: string; readonly skills_run_script: string; readonly skills_use: string; readonly spawn: { readonly core: 'Spawn a sub-agent for a self-contained task that benefits from isolation (separate context window, separate retries): for example, a deep research dive or a long codegen pass on a specific file. The sub-agent inherits your tool set (including `spawn` itself, depth-capped) and your system prompt unless overridden, runs independently, and returns its final response. Do NOT spawn for sequential steps you could do yourself.'; readonly modelTiering: ' Children can run on a DIFFERENT model via the `model` field: cost-tier your delegation: mechanical, parallelizable, or high-volume search work belongs on cheaper/faster models, while synthesis and judgment stay on your own model.'; readonly resume: ' A stopped or failed sub-agent can be CONTINUED instead of restarted: pass `resume` with its child label (e.g. "child-2") and put the continuation instruction in `task`; the child picks up with its prior conversation intact.' }; readonly tool_search: { readonly callable: 'Returned tools become callable for the rest of this run.'; readonly callableVia: (dispatcher: string) => string; readonly core: string }; readonly wait_task: string; readonly web_search: { readonly core: string; readonly recency: string }; readonly write_file: 'Write `content` to `path`, creating any missing parent directories. Overwrites existing files in full; prefer `edit` / `multi_edit` for surgical changes when you only want to alter part of a file. Returns one of: `Created <path> (N bytes)` (file did not exist), `Updated <path> (N bytes)` (content differed), or `No change needed: <path> already at target state (N bytes)`, so the model can detect no-ops without a separate `read_file`. Several `edit` / `multi_edit` / `write_file` calls and a verifying `shell` call (tests, typecheck) in one message run in order, in a single round-trip.' }

src/tools/prompts.ts:30

Types#

ToolPromptsType#

Shape of toolPrompts.

TypeScript
type ToolPrompts = typeof toolPrompts

src/tools/prompts.ts:188