Design
agentlane.harness.tools provides first-party harness tool definitions for
common local workspace actions. Each helper returns a HarnessToolDefinition,
which wraps an agentlane.models.ToolSpec plus optional prompt metadata for
HarnessToolsShim. Most definitions are executable agentlane.models.Tool
values. The agent definition is declarative and is executed by the harness
runner.
These tools are opinionated defaults for agent loops. They use stable argument
names, deterministic text results, visible truncation messages, .gitignore
handling where appropriate, and clear model-facing errors. That consistency
lets higher-level agents spend fewer turns rediscovering local shell behavior
and gives application code a predictable contract to test.
Use these tools with
DefaultAgent when you want the smallest local starting
point for a high-level agent. DefaultAgent owns the local runtime, runner, run
state, tool loop, and shim binding. HarnessToolsShim adds the tools and the
model guidance that tells the agent how to use them. As the application grows,
the same AgentDescriptor, Tools, shims, and native Tool values can move
down to the lower-level harness agent or runtime APIs.
Import Path
from agentlane.harness import INHERIT_TOOLS, OVERRIDE_TOOLS, RESTRICT_TOOLS
from agentlane.harness.tools import (
AllOfToolPermissionPolicy,
HarnessToolsShim,
PathScopeToolPermissionPolicy,
SideEffectApprovalToolPermissionPolicy,
ToolApprovalBroker,
ToolApprovalCallback,
ToolApprovalEvent,
ToolApprovalRecord,
ToolApprovalStatus,
ToolPermissionGrant,
ToolPermissionGrantPolicy,
ToolPermissionPolicy,
ToolOperation,
ToolPermissionDecision,
ToolPermissionRequest,
WorkspaceToolsShim,
WorkspaceToolPermissionPolicy,
agent_tool,
base_harness_tools,
bash_tool,
evaluate_tool_permission,
find_tool,
format_tool_permission_result,
grep_tool,
patch_tool,
plan_tool,
parse_tool_permission_grants,
read_tool,
workspace_tool_policy,
write_tool,
)
This block shows a representative subset. agentlane.harness.tools also
re-exports the path, output, and bash-executor primitives — ToolPathResolver,
GitignoreMatcher, ToolPermissionGrantPolicy, ToolPermissionOutcome, the
output-limit constants (TEXT_MAX_BYTES, TEXT_MAX_LINES, BASH_MAX_BYTES,
BASH_MAX_LINES, GREP_DEFAULT_LIMIT, GREP_MAX_LINE_LENGTH,
FIND_DEFAULT_LIMIT, LS_DEFAULT_LIMIT) plus TruncatedOutput and
truncate_output, and the bash-executor contract types (BashExecutor,
LocalBashExecutor, BashExecutionRequest, BashExecutionResult,
BashShellConfig, resolve_bash_shell). See bash for the
executor contracts.
Tool Definitions
Tool helpers return definitions, not raw model tools:
definition = write_tool(cwd=WORKSPACE)
tool = definition.tool
Use the definition when you want prompt snippets and guidelines to be rendered
by HarnessToolsShim. Use definition.tool when you need the underlying model
tool schema.
The current standard set is read, find, grep, patch, write,
write_plan, bash, and agent. The public base-tools set currently does not
include ls.
base_harness_tools() returns the standard set. By default each local tool
captures Path.cwd() at construction time and remains permissive. Filesystem
tools with local storage resolve relative paths through ToolPathResolver; see
Tool permissions for path boundaries and approval
behavior. Pass cwd=, permissions=, and optionally approval_callback=
when an agent should operate inside a specific workspace boundary:
workspace_tools = base_harness_tools(
cwd=WORKSPACE,
permissions=WorkspaceToolPermissionPolicy(WORKSPACE),
)
Pass reader= to read and find, writer= to write, and both to patch.
base_harness_tools() passes these capabilities to the selected file tools.
It can infer writes from a reader that implements WritableFileSystem.
Injected tools default to their storage root. Plain backends use relative
POSIX paths. Mounted backends accept rooted virtual paths and resolve relative
arguments from each tool’s captured cwd. In
base_harness_tools(), set storage_cwd for these tools and cwd for the
process workspace used by grep and bash. Process tools do not use storage
adapters. See File I/O interfaces.
Use include= or exclude= to derive a smaller set without manually
constructing each tool. Selectors are the model-visible names from the standard
set: read, find, grep, patch, write, write_plan, bash, and
agent. Returned tools keep standard order, even when include names are
listed in a different order:
search_tools = base_harness_tools(
cwd=WORKSPACE,
permissions=WorkspaceToolPermissionPolicy(WORKSPACE),
include=("grep", "read"),
)
no_shell_tools = base_harness_tools(
cwd=WORKSPACE,
permissions=WorkspaceToolPermissionPolicy(WORKSPACE),
exclude=("bash",),
)
Unknown selector names raise ValueError. Passing an overlapping name in both
include and exclude also raises ValueError.
You can also construct tools individually when an agent needs a custom tool set:
workspace_tools = (
read_tool(cwd=WORKSPACE),
find_tool(cwd=WORKSPACE),
grep_tool(cwd=WORKSPACE),
patch_tool(cwd=WORKSPACE),
write_tool(cwd=WORKSPACE),
plan_tool(),
bash_tool(cwd=WORKSPACE),
agent_tool(),
)
HarnessToolsShim
HarnessToolsShim merges tool schemas into each prepared turn and appends the
definitions’ prompt metadata to the first turn’s system instructions. Pass
prompt_guidelines= for guidance that belongs to the shim configuration rather
than to one tool definition, such as workspace-level path rules:
from agentlane.harness import AgentDescriptor
from agentlane.harness.tools import (
HarnessToolsShim,
agent_tool,
find_tool,
grep_tool,
patch_tool,
bash_tool,
read_tool,
write_tool,
)
from agentlane.models import Tools
descriptor = AgentDescriptor(
name="Workspace Agent",
model=model,
instructions="Use workspace tools before answering workspace questions.",
tools=Tools(
tools=[],
tool_call_limits={
"find": 1,
"grep": 1,
"patch": 1,
"read": 1,
"write": 1,
"bash": 1,
},
),
shims=(
HarnessToolsShim(
(
read_tool(cwd=WORKSPACE),
find_tool(cwd=WORKSPACE),
grep_tool(cwd=WORKSPACE),
patch_tool(cwd=WORKSPACE),
write_tool(cwd=WORKSPACE),
bash_tool(cwd=WORKSPACE),
agent_tool(),
),
prompt_guidelines=(
"Tool paths are relative to the workspace root.",
),
),
),
)
For quick prototypes that should use the process working directory, pass the standard set directly:
descriptor = AgentDescriptor(
name="Workspace Agent",
model=model,
instructions="Use workspace tools before answering workspace questions.",
shims=(HarnessToolsShim(base_harness_tools()),),
)
Output Limits
Text output is capped at shared deterministic limits. read output is capped
at 2000 lines or 51200 bytes, whichever limit is reached first. find output
is capped at 1000 matching paths or 51200 bytes, whichever limit is reached
first. grep output is capped at 100 matching entries or 51200 bytes,
whichever limit is reached first. patch success output is intentionally
minimal and does not need truncation. bash output is tail-truncated to the
most recent 2000 combined stdout/stderr lines or 51200 bytes.
Caller-provided limits are applied before the global caps. For large files, call
read repeatedly with offset and limit. For large search results, narrow
the find pattern or search path.
LS_DEFAULT_LIMIT is also exported, but it is reserved for a future ls tool
that is not yet part of the base set; there is no ls_tool() factory today.