> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tesslate.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agents

> The OpenSail agent runner is tesslate-agent, a 33-tool Python package that drives any LiteLLM-compatible model through a streaming iteration loop with progressive persistence and context compaction.

<img src="https://mintcdn.com/tesslate/VT6tbZolrCfpx26M/images/opensail-banner.png?fit=max&auto=format&n=VT6tbZolrCfpx26M&q=85&s=66579c47537b3464fb65b229cc9ab0fd" alt="Tesslate OpenSail" width="4712" height="1612" data-path="images/opensail-banner.png" />

## The agent runner

OpenSail ships one first-class agent runner: [**tesslate-agent**](https://github.com/TesslateAI/tesslate-agent). It is a Python package vendored in the monorepo at `packages/tesslate-agent/` and also published standalone. One class (`TesslateAgent`), 33 tools across 8 categories, LiteLLM for model access, and ATIF v1.4 trajectory recording.

There is no longer a `StreamAgent`, `IterativeAgent`, or `ReActAgent`. All four were replaced by this single runner.

<CardGroup cols={2}>
  <Card title="33 built-in tools" icon="wrench">
    File ops, shell, navigation, git, memory, web, planning, delegation.
  </Card>

  <Card title="Any LiteLLM model" icon="plug">
    OpenAI, Anthropic, DeepSeek, Qwen, Gemini, Mistral, xAI, Z.AI, local Ollama, any OpenAI-compatible endpoint.
  </Card>

  <Card title="Progressive persistence" icon="database">
    Every step streams to the database as it happens. Pods can die mid-run, you can resume later.
  </Card>

  <Card title="Context compaction" icon="compress">
    At 80 percent of the model window, the agent compacts older messages with a cheap model and keeps going.
  </Card>
</CardGroup>

## The agent loop

Everything happens inside `TesslateAgent.run(user_request, context)`. It is an async generator that yields events and never touches the filesystem directly. Every tool call goes through the `ToolRegistry`.

```
loop (iteration = 1..N):
  pre-flight compaction if tokens >= window * 0.80
  response = model.chat_with_tools(messages, tools)
  if response.content:          yield stream event
  if not response.tool_calls:   yield complete and return
  append assistant turn with tool_calls
  execute tool_calls in parallel (respecting approval policy)
  append tool results
```

The loop ends when the model emits a turn with no tool calls. There is no fixed iteration cap. Runs can be hours long thanks to compaction and progressive persistence.

<Info>
  Full protocol, tool schemas, edit modes, and quirks live in the agent repo: [DOCS.md on GitHub](https://github.com/TesslateAI/tesslate-agent/blob/main/docs/DOCS.md).
</Info>

## Tool catalog

33 tools across 8 categories. The registry is fixed; extensions happen through skills and MCP bridges, not new tool modules.

<Tabs>
  <Tab title="File operations (8)">
    `read_file`, `write_file`, `read_many_files`, `patch_file`, `multi_edit`, `apply_patch`, `view_image`, `file_undo`.

    Surgical edits use `patch_file` with fuzzy matching. Atomic multi-file changes use `multi_edit`. `apply_patch` takes unified diffs. `file_undo` rolls back the most recent edit.
  </Tab>

  <Tab title="Shell commands (8)">
    `bash_exec`, `shell_open`, `shell_close`, `shell_exec`, `write_stdin`, `list_background_processes`, `read_background_output`, `python_repl`.

    Shell sessions are persistent PTY sessions. Long-running processes (dev servers, watchers) go to background and the agent reads their output on demand.
  </Tab>

  <Tab title="Navigation (3)">
    `glob`, `grep`, `list_dir`. Fast code search without cat-ing entire files.
  </Tab>

  <Tab title="Git (4)">
    `git_log`, `git_blame`, `git_status`, `git_diff`. Read-only. Writes go through shell.
  </Tab>

  <Tab title="Memory (2)">
    `memory_read`, `memory_write`. Persistent key-value store scoped to the agent run.
  </Tab>

  <Tab title="Web (2)">
    `web_fetch`, `web_search`. Tavily, Brave, or DuckDuckGo backends configured at the platform level.
  </Tab>

  <Tab title="Planning (1)">
    `update_plan`. Structured plan that lives alongside the chat and gets updated as work progresses.
  </Tab>

  <Tab title="Delegation (5)">
    `task`, `wait_agent`, `send_message_to_agent`, `close_agent`, `list_agents`. Spawn subagents for focused subtasks and coordinate between them.
  </Tab>
</Tabs>

<Info>
  OpenSail extends this set with platform tools for project control, graph editing (`apply_setup_config`), and kanban (TSK-NNNN refs). The core 33 ship with every install.
</Info>

## Subagents and delegation

An agent can spawn subagents for focused subtasks. Each subagent gets its own system prompt, its own tool subset, and its own budget. The parent agent sees subagent output and decides what to do next.

Typical patterns:

* **Divide and conquer** Frontend agent and backend agent run in parallel inside the same workspace
* **Specialist lookup** Spawn a `doc-writer` subagent to generate changelog entries
* **Verification** Spawn a `reviewer` subagent to audit the main agent's diff before finalizing

Subagents use the `task`, `wait_agent`, `send_message_to_agent`, `close_agent`, and `list_agents` tools. They run in the same workspace, so file edits are visible to everyone.

## Skills and progressive disclosure

Skills are reusable capabilities (writing style, code review checklist, deployment playbook, research methodology). They attach to any agent.

Skills load progressively:

1. The lightweight **catalog** (name + description) is injected into the agent's context
2. The full **body** is pulled on demand only when the agent calls `load_skill`

This keeps the context window lean. An agent with 20 skills attached still only carries 20 short descriptions until it needs one.

Built-in skills like `project-architecture` use live marker tokens (`{{MARKER}}`) that get resolved at load time with the current config schema, service catalog, and URL patterns, so skill bodies never drift out of sync with the platform.

## MCP integration

The agent supports MCP (Model Context Protocol) natively. Installed MCP servers appear as native tools in the agent's registry. Tool schemas are cached in Redis (`MCP_TOOL_CACHE_TTL`, default 300 seconds) and refreshed on OAuth or server update.

The MCP bridge also surfaces:

* **Citations** returned by MCP tools render as `CitationCard` in chat
* **Re-auth prompts** trigger a yellow `ReauthBanner` linking to `/settings/connectors`
* **Structured outputs** per MCP spec 2025-06-18+

## Context compaction

When a session crosses 80 percent of the active model's context window, the agent compacts older messages with a cheap model (`compaction_summary_model`, usually a small, fast model). Compaction preserves tool outputs by reference and keeps the most recent turns verbatim. The agent continues without hitting a wall.

Multi-hour runs are normal. Compaction is automatic and costless from the user's perspective.

## Progressive persistence

Every agent step (`AgentStep`) streams to the database as it happens. The row goes in before the next tool call. If the pod dies, the browser closes, or the network hiccups, you can come back later and see the full trajectory.

Resuming picks up from the last persisted step. No re-execution, no duplicate tool calls.

## Edit modes and approval

Edit mode controls how much autonomy the agent has. Switch it any time from the chat input.

<Tabs>
  <Tab title="Ask (default)">
    Dangerous tools (writes, shell, git push) trigger an `ApprovalRequestCard` in chat. Three buttons: Allow Once, Allow All, Stop. Read-only tools run without prompting.
  </Tab>

  <Tab title="Allow">
    All tools run immediately. Use when you trust the agent fully.
  </Tab>

  <Tab title="Plan">
    Read-only. The agent gathers context and produces a structured plan instead of mutating anything. Activate with the mode button or `/plan`.
  </Tab>
</Tabs>

On desktop, permissions also flow through `.tesslate/permissions.json` per project. Each capability (shell, network, git push, file write, process spawn) has an `allow`, `deny`, or `ask` policy with optional always-allow persistence.

## Orchestration backends

`tesslate-agent` has a pluggable orchestration layer. `LocalOrchestrator` ships in the open-source repo. OpenSail registers Docker, Kubernetes, and desktop-local backends via `OrchestratorFactory.register(mode, cls)`, so the same agent code runs against subprocesses, containers, or pods without change.

## Running an agent

From the chat UI, pick an agent and type. From the external API, call `POST /api/external/agent/invoke` with your `tsk_` API key and subscribe to SSE events at `/api/external/agent/events/{task_id}`. From the CLI (inside the `tesslate-agent` repo), run `tesslate-agent run --task "..." --workdir . --output trajectory.json`.

<Info>
  Every execution produces an ATIF v1.4 trajectory recording (`trajectory.json`). Use it for replay, debugging, and benchmark analysis.
</Info>

## Related

<CardGroup cols={2}>
  <Card title="Full tool reference" icon="book" href="https://github.com/TesslateAI/tesslate-agent/blob/main/docs/DOCS.md">
    Every tool, every parameter, every quirk.
  </Card>

  <Card title="Chat interface" icon="comments" href="/guides/chat-interface">
    How agents stream to the chat panel.
  </Card>

  <Card title="Marketplace" icon="store" href="/guides/marketplace">
    Install specialized agents, skills, and MCP servers.
  </Card>

  <Card title="External agent API" icon="code" href="/guides/api-keys">
    Invoke agents from outside the UI with `tsk_` keys.
  </Card>
</CardGroup>
