Skip to content
titah

Capabilities

Delegation

`@claude`, `@opencode`, and how to add a third agent with one config block and no code.

Type @<agent> at the start of a prompt:

@claude please review the changes in src/core/agent.ts
@opencode how many .ts files are in this repo?

Always triggered by you

Delegation is explicitly triggered by you. Titah’s model never decides on its own to call another agent.

The reason is cost: one turn could call Claude Code repeatedly and blow up the bill without anyone noticing. A mention is a decision you made; an autonomous call is one you did not.

What happens

Working directoryThe same as your session. The external agent sees the code you are working on
What enters contextOnly the final answer. The full transcript goes to tool-output/ and is referenced by path — injecting it whole would blow out the context window within two or three delegations
ContinuityThe external session id is mapped to yours, so the second @claude resumes the same conversation
CostShown separately in the footer (ext 1.2k/45 ≈$0.093). Summing it with Titah’s own tokens would make the number a lie
The $ figurePassed through from the external agent (Claude Code’s total_cost_usd). It is an API-price equivalent, not a bill — on a subscription, what you spend is rate-limit quota
CredentialsIts own. Titah never forwards its provider keys into the subprocess
Write accessRead-only by default. External agents answer; if a change is needed, Titah applies it through its own permission model

An agent whose CLI is not installed is still listed as unavailable rather than silently hidden. Check with titah doctor.

The mechanism

Subprocess plus JSON streaming, uniform across both targets:

claudeopencode
Commandclaude -p "<prompt>" --output-format stream-json --verboseopencode run "<msg>" --format json
Continuity--session-id <uuid> to create, --resume <uuid> to continue--session <id>
Other protocol—opencode acp (ACP) available

The internal adapter interface is deliberately shaped like ACP (prompt, sessionUpdate, requestPermission, cancel), so adding an ACP transport later means writing one new adapter rather than rebuilding the core.

!!! note “Two things that are easy to get wrong” Both were verified directly against the installed CLIs rather than guessed from documentation: Claude Code rejects --output-format stream-json without --verbose, and passing the same --session-id twice is not how you resume.

Adding a third agent

One config block, no code:

{
  "externalAgent": {
    "aider": {
      "command": "aider",
      "args": ["--message", "{prompt}", "--no-stream"],
      "format": "text",
      "timeout": 600000
    }
  }
}
KeyMeaning
commandThe executable, found on PATH
argsArgument template. {prompt} is substituted
formattext or json — how to read the output
timeoutMilliseconds. Default 600000 (10 minutes)
sessionModegenerate or discover — see below
enabledfalse removes it from /consensus and from the @ popup

sessionMode

Who owns the session id:

  • generate — Titah creates a UUID and hands it to the CLI. This is Claude Code’s way: --session-id <uuid> to create, --resume <uuid> to continue.
  • discover — the id is read from the first call’s output and sent back afterwards. This is opencode’s way.

Failure handling

FailureBehaviour
CLI not installedDetected via which at startup. Shown as unavailable, with the command that is missing — never hidden
Timeout10-minute default, configurable per adapter, with progress pulses so you can see the agent is alive. A silent timeout is the worst possible experience
Output does not match the schemaTolerant parsing plus a known-good minimum version. Raw stderr is saved to tool-output/ when parsing fails
Non-zero exitReported as a failed delegation with the exit code and the saved stderr path, not as an empty answer

Delegation from a sub-agent

An agent with delegate set routes its work through an external CLI instead of Titah’s own loop — the same engine, reached from task / /tim rather than a mention. It is mutually exclusive with model, and it is always treated as a writer for concurrency purposes.

See Sub-agents.

Asking everyone at once

/consensus fans one question out to every available agent in parallel. See Consensus mode.