agentlane/ docs
On this page

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.