Tools
The tools the agent works with in a session’s sandbox: reading, writing, and editing files, and
running shell commands. Their names and inputs are those of Claude Code’s and opencode’s tools,
so a model meets the tools it knows whichever agent runs it; searching goes through bash, with
grep and find.
File paths resolve against the session’s directory, and the tools refuse a path that names a place
outside it. That keeps the model’s work in its directory but confines nothing: a symbolic link in
the directory can lead outside it, and bash, which runs a shell in the directory, can reach
anything the sandbox can. bash kills a command that outruns its timeout. A tool that cannot do
what it was asked, such as an edit whose text is not in the file, answers the model with why,
so the model can try again, instead of failing the turn.
Since v0.1.0
Constants
Section titled “Constants”defaultCommandTimeout
Section titled “defaultCommandTimeout”How long a bash command runs before it is killed, unless the layer is given another.
Signature
declare const defaultCommandTimeout: Duration.DurationSince v0.1.0
defaultReadLimit
Section titled “defaultReadLimit”The most lines read returns unless asked for a limit.
Signature
declare const defaultReadLimit: 2000Since v0.1.0
maxOutputLength
Section titled “maxOutputLength”The most characters of a command’s output bash returns: the start and end, half each.
Signature
declare const maxOutputLength: 30000Since v0.1.0
Layers
Section titled “Layers”The tools’ handlers, working in workspace: its sandbox’s file system and processes, in its
directory.
Details
commandTimeout is how long a bash command runs before it is killed, defaultCommandTimeout
by default.
Example (Running a command in a session’s directory, as the model would)
import type { Agent } from "@amends-dev/harness"import { Tools } from "@amends-dev/harness-amends"import { Effect, Stream } from "effect"
declare const workspace: Agent.Workspace // the session's sandbox and directory
const program = Effect.gen(function* () { const toolkit = yield* Effect.provide(Tools.toolkit, Tools.layer(workspace)) const handled = yield* toolkit.handle("bash", { command: "ls" }) const [result] = yield* Stream.runCollect(handled) return result?.encodedResult})Signature
declare const layer: ( workspace: Agent.Workspace, options?: { readonly commandTimeout?: Duration.Duration | undefined }) => Layer< Tool.HandlersFor<{ readonly read: Tool.Tool< "read", { readonly parameters: Schema.Struct<{ readonly file_path: Schema.String readonly offset: Schema.optionalKey<Schema.Int> readonly limit: Schema.optionalKey<Schema.Int> }> readonly success: Schema.String readonly failure: Schema.String readonly failureMode: "return" }, never > readonly write: Tool.Tool< "write", { readonly parameters: Schema.Struct<{ readonly file_path: Schema.String; readonly content: Schema.String }> readonly success: Schema.String readonly failure: Schema.String readonly failureMode: "return" }, never > readonly edit: Tool.Tool< "edit", { readonly parameters: Schema.Struct<{ readonly file_path: Schema.String readonly old_string: Schema.String readonly new_string: Schema.String readonly replace_all: Schema.optionalKey<Schema.Boolean> }> readonly success: Schema.String readonly failure: Schema.String readonly failureMode: "return" }, never > readonly bash: Tool.Tool< "bash", { readonly parameters: Schema.Struct<{ readonly command: Schema.String }> readonly success: Schema.Struct<{ readonly exitCode: Schema.Int; readonly output: Schema.String }> readonly failure: Schema.String readonly failureMode: "return" }, never > }>, never, never>Since v0.1.0
Runs a shell command in the session’s directory, answering with its exit code and its output, stdout and stderr interleaved, of which long output keeps its start and end.
Details
A command that outruns the timeout is killed.
Signature
declare const Bash: Tool.Tool< "bash", { readonly parameters: Schema.Struct<{ readonly command: Schema.String }> readonly success: Schema.Struct<{ readonly exitCode: Schema.Int; readonly output: Schema.String }> readonly failure: Schema.String readonly failureMode: "return" }, never>Since v0.1.0
Replaces a text in a file in the session’s directory: the one place it appears, or every place
with replace_all, answering with why when the text is not there once.
Signature
declare const Edit: Tool.Tool< "edit", { readonly parameters: Schema.Struct<{ readonly file_path: Schema.String readonly old_string: Schema.String readonly new_string: Schema.String readonly replace_all: Schema.optionalKey<Schema.Boolean> }> readonly success: Schema.String readonly failure: Schema.String readonly failureMode: "return" }, never>Since v0.1.0
Reads a text file in the session’s directory, answering with its contents: all of it, or
limit lines from line offset, defaultReadLimit lines from the first by default, saying how
many lines follow.
Signature
declare const Read: Tool.Tool< "read", { readonly parameters: Schema.Struct<{ readonly file_path: Schema.String readonly offset: Schema.optionalKey<Schema.Int> readonly limit: Schema.optionalKey<Schema.Int> }> readonly success: Schema.String readonly failure: Schema.String readonly failureMode: "return" }, never>Since v0.1.0
Writes a text file in the session’s directory, replacing one that exists and creating the directories it needs.
Signature
declare const Write: Tool.Tool< "write", { readonly parameters: Schema.Struct<{ readonly file_path: Schema.String; readonly content: Schema.String }> readonly success: Schema.String readonly failure: Schema.String readonly failureMode: "return" }, never>Since v0.1.0
toolkit
Section titled “toolkit”The agent’s tools, as the toolkit a turn offers the model with the handlers layer gives them.
Signature
declare const toolkit: Toolkit.Toolkit<{ readonly read: Tool.Tool< "read", { readonly parameters: Schema.Struct<{ readonly file_path: Schema.String readonly offset: Schema.optionalKey<Schema.Int> readonly limit: Schema.optionalKey<Schema.Int> }> readonly success: Schema.String readonly failure: Schema.String readonly failureMode: "return" }, never > readonly write: Tool.Tool< "write", { readonly parameters: Schema.Struct<{ readonly file_path: Schema.String; readonly content: Schema.String }> readonly success: Schema.String readonly failure: Schema.String readonly failureMode: "return" }, never > readonly edit: Tool.Tool< "edit", { readonly parameters: Schema.Struct<{ readonly file_path: Schema.String readonly old_string: Schema.String readonly new_string: Schema.String readonly replace_all: Schema.optionalKey<Schema.Boolean> }> readonly success: Schema.String readonly failure: Schema.String readonly failureMode: "return" }, never > readonly bash: Tool.Tool< "bash", { readonly parameters: Schema.Struct<{ readonly command: Schema.String }> readonly success: Schema.Struct<{ readonly exitCode: Schema.Int; readonly output: Schema.String }> readonly failure: Schema.String readonly failureMode: "return" }, never >}>Since v0.1.0