
Home | Docs for Humans | Policies for Teams | GitHub
AGENTS.talk Reference
Every line that AGENTS.talk can hold. For a guided tour, read Your AGENTS.talk. For rules across an organization, read Policies for Teams.
Top Lines
At the top of AGENTS.talk: what scripts and programs can reach, and how the session is recorded.
allow
allow env <NAME>, ... | allow changes to <path>, ... | allow fetch from '<host>' or <url pattern>, ... | allow secret <NAME> for fetch to '<host>' or <url pattern>, ... | allow secret <NAME> for run | allow secret <NAME> for subagents | use model '<id>' for subagents [with secret <NAME>] | use model '<id>' for judging [with secret <NAME>]
- Allow environment variables, changes to hidden files, fetch hosts and secrets. Only at the top of AGENTS.talk.
- 'allow env' lists the environment variables that run passes on.
- 'allow changes to' lists hidden files and folders (names that start with .) that scripts can change. A folder allows all of its files.
- 'allow fetch from' lists the hosts that fetch can reach with no question. '*.github.com' allows the hosts under github.com.
- A URL pattern allows less than a host: http://localhost:5173/ allows one port. The scheme and the port must be equal. *. in the host is one more part.
- In a URL pattern, a path that ends in / allows all paths below it. * is any text in one part of the path, and ** is any number of parts.
- 'allow secret ... for fetch to' lets scripts use a secret, and names the hosts that it can go to. The fetch question still comes.
- 'allow secret ... for run' gives the secret to a run or start in a tool, with 'using secret'.
- A name cannot be in both 'allow env' and 'allow secret'.
- 'use model' sets the model for subagents. pi lends its own model. Other harnesses need a key from 'allow secret ... for subagents'.
- 'use model ... for judging' sets the model of the judge, which reads untrusted inputs. With no line, the judge uses the subagent model.
Examples
allow env PATH, HOME
allow changes to @/.github/, @/.gitignore
allow fetch from http://localhost:5173/
allow secret GITHUB_TOKEN for fetch to https://api.github.com/repos/bigskysoftware/
limit
limit output keeping the first <n> lines | the last <n> lines | the first <n> and the last <n> lines | lines matching pattern /x/ [or <n> KB]
Choose the print output that the agent sees from one script, with the same forms as run ... keeping. Only at the top of AGENTS.talk, or in a policy. One line takes the place of the cut lines, and the previous output has all of them. AGENTS.talk cuts first, then the policy, then the host (1000 lines or 30 KB).
Examples
limit output keeping the first 200 and the last 200 lines
limit output keeping the last 400 lines or 20 KB
audit
the audit | audit as json (in AGENTS.talk) | keep audit for <n> days (in AGENTS.talk)
- The audit records every step that touches the world: reads, changes, run, git, fetch, ask and tool calls.
- 'the audit' is this session's records. Each record has time, script, kind, target, details and from.
- The host writes the records to .talk/audit/
.log. Scripts cannot change it. - With 'audit as json' in AGENTS.talk, the host writes JSON Lines.
- The host keeps 3 days of files, or the days in 'keep audit for 7 days' in AGENTS.talk.
Examples
for step in the audit
if step's kind is 'write'
print step's target
end
end
taint
taint on | taint off | taint required | taint asks before <push, secrets, commit, network runs, new hosts | nothing> | keep untrusted inputs up to <n> MB | let the judge approve clean inputs | judge untrusted inputs automatically | judge with prompt '<text>'
- Session taint. After text from fetch, an untrusted tool or a subagent, the session is untrusted until the human approves each input. Only at the top of AGENTS.talk.
- In a script, 'taint review' asks the human to approve inputs: see help untrusted.
- 'taint on' is the default. 'taint off' turns it off. 'taint required' keeps it on, also against 'npx clank-talk taint off'.
- 'taint asks before' lists what asks the human while inputs are not approved. The default is push and secrets (a fetch with a secret). 'network runs' is a run or start with network or with no sandbox. 'new hosts' is a fetch to a host not in 'allow fetch from'. 'nothing' asks nothing, and still keeps the inputs.
- 'keep untrusted inputs up to 5 MB' sets how much of each input .talk/untrusted/ keeps. The default is 1 MB.
- The judge is a model that reads an input and says clean, suspect or unsure. 'judge untrusted inputs automatically' runs it on each new input; else the human runs 'npx clank-talk taint judge'.
- 'let the judge approve clean inputs' lets a clean verdict approve the input. 'judge with prompt' replaces the judge's prompt. 'use model ... for judging' sets its model.
Examples
taint required
taint asks before push, secrets, commit
keep untrusted inputs up to 5 MB
use model 'claude-haiku-5-5' for judging with secret ANTHROPIC_API_KEY
allow secret ANTHROPIC_API_KEY for subagents
judge untrusted inputs automatically
Tools
What your agent can run.
tool
[untrusted] tool <name> [with <param>, ...] ... end
- Define a tool that the agent can call by name. Only in AGENTS.talk.
- The '#' comment lines just above the tool are its help.
- The tool gives back the result. A call is also a value, and then the result does not change: set tests to run_tests.
- If a tool brings in text from the network (curl, gh, npm view), mark it 'untrusted'. Then its result is untrusted.
Examples
# Runs one test class.
tool run_test with name
run 'mvn' with 'test', '-Dtest=' + name
end
# Shows a GitHub issue.
untrusted tool issue with id
run 'gh' with 'issue', 'view', id
end
run
run <program and args> | run <program> with <arg>, ... [using secret <NAME>, ...] [in a sandbox [with network, local network, writes to <path>, reads of <path>]] [within <duration>] [keeping the first <n> lines | the last <n> lines | the first <n> and the last <n> lines | lines matching pattern /x/]
- Run a program with no shell. Only in a tool. The result is { code, output }.
- Write the program in the tool: run 'npm' with name, not run name.
- Only the variables in 'allow env' go to the program.
- A file value is its path, such as './src/a.js'. A list gives one argument for each item.
- To give a tool a file, pass a path, such as @/test/app.test.js, not a string. A path outside the project is an error.
- In run 'npm test ${name}', each ${} is one whole argument, also with spaces in it.
- An argument that does not start with text written in the tool must not start with '-'. Put '--' before it if the program takes '--'.
- A program that PATH finds inside the project is an error. To run it, write its path, such as './node_modules/.bin/jest'.
- 'in a sandbox' runs the program in an OS sandbox. It can write only the project (not .git, .talk or hidden files). It can read only system folders, its install folder and tool caches. It has no network.
- 'with network' allows the network, and 'with local network' allows localhost only. 'writes to' and 'reads of' add paths.
- On an OS with no sandbox, a sandboxed run is an error, and nothing runs.
- 'using secret NPM_TOKEN' (or 'using secrets A, B') gives the program the secret as an environment variable. AGENTS.talk needs 'allow secret NPM_TOKEN for run'. The value shows as
in the output. - 'run
in a subagent with only ' gives the task to a model that can call only those tools. Its answer is untrusted. - 'keeping' cuts the output in the result to those lines, and 'or 20 KB' also limits the size. One line takes the place of the cut lines. The result's full has all of them.
Examples
tool test
run 'npm test' in a sandbox within 10 minutes keeping the last 200 lines
end
tool lint
run 'npx eslint .' in a sandbox keeping lines matching pattern /error/
end
tool install
run 'npm install' in a sandbox with network, writes to '~/.npm'
end
tool publish
run 'npm publish' using secret NPM_TOKEN
end
# Summarizes the most important open issues.
tool summarize_issues
run 'Summarize the most important open issues' in a subagent with only gh_issues
end
start
start <program> [with <arg>, ...] as <name> [using secret <NAME>, ...] [in a sandbox [with ...]] | start <prompt> as <name> in a subagent with only <tool>, ...
- Start a program in the background, such as a dev server, with no shell. Only in a tool.
- The program keeps running after the script. The host stops all of them when the session ends.
- Write the program in the tool, as in run. 'using secret' and 'in a sandbox' work as in run.
- 'process
' has name, status (running, exited, stopped), code and output. 'the processes' lists them. - 'start
as in a subagent with only ' runs a subagent in the background. Its answer is the output of the process.
Examples
tool site_server
start 'npm run serve-site' as 'site' in a sandbox
end
process
process <name> | the processes
A background process that a tool started: name, status (running, exited or stopped), code, and output (the last 64 KB). 'of' also works: the output of process 'site'. 'the processes' lists them, newest first.
Examples
print the output of process 'site'
if the status of process 'site' is 'running'
stop process 'site'
end
print the processes
import
import <path to a .talk file>
Load the tools from another .talk file. Only in AGENTS.talk and the files that it imports. ./ starts from the importing file, @/ from the project root.
Examples
import ./talk/git.talk
import @/talk/maven.talk
Hooks
Your rules, before and after each step.
before
before <step> ... end
- Run commands before a step. Only in AGENTS.talk.
- Steps: read, write, append, replace, put, remove, move, delete, change (any file change), undo, run, start, stop, git, fetch, or a tool name.
- 'the
' holds the step. For a tool, each parameter is a field by its name: the deploy's target. args and named hold all the arguments. - 'reject' stops the step.
- A hook cannot change the step. A hook cannot run a program, or call a tool that runs one.
Examples
before change
if the change's path ends with '.env'
reject 'Cannot change env files!'
end
end
after
after <step> ... end
Run commands after a step. Only in AGENTS.talk. 'the
Examples
after run
print 'ran ' + the run's program + ': ' + the result's code
end
reject
reject <message>
In a 'before' hook: stop the step. In a tool: stop the tool. The script gets an error with the message, at the command that it stopped. 'on error' can catch it.
Examples
before write
reject 'This project is read only'
end
tool deploy with target
if target is 'prod'
reject 'Only a human deploys to prod'
end
run 'fly' with 'deploy', '--app', 'shop-' + target in a sandbox with network
end
ask
ask <question> [with <choice> or <choice>] [within <duration>]
- Ask the human, and wait. Only the human answers, never you.
- The result is the text that the human types, or the choice that the human picks.
- The result is null if there is no way to ask, no answer in time (2 minutes, or the 'within' time), or the human declines. Treat null as no.
Examples
ask 'Which branch should I use?'
print it
ask 'Delete the old logs?' with 'yes' or 'no' within 5 minutes
if the result is 'yes'
print 'ok'
end
Hook Steps
In a hook, the <step> holds the step, such as the run's args. the session is untrusted is true after web text that the human did not approve. For run and start, sandbox is null, or { network, reads, writes }.
| Step | Fields |
|---|---|
read |
path, and text in an after hook |
write, append |
kind, path, text |
replace |
kind, path, old, new; for replace lines: from, to, text |
put |
kind, path, line, where, text |
remove |
kind, path, from, to |
move |
kind, path, to |
delete |
kind, path |
change |
any file change above, with its kind |
undo |
kind, path, text |
run |
program, args, sandbox, secrets |
start |
program, args, name, sandbox, secrets |
stop |
name |
git |
operation, args; files and message for commit; branch for switch, merge and rebase |
fetch |
url, method, secrets, and status in an after hook |
a tool name |
args, named |