Skip to main content

taut-summon

Summon extension for Taut: host an existing agent harness (Claude Code and friends) as an ordinary member of a taut workspace.

This package is intentionally separate from the core taut-chat distribution. The summon driver is the agent's terminal, not its runtime: it injects chat into the harness's own live session (its ears), and the agent speaks through the ordinary taut CLI selected by its continuity token (its mouth). The full contract lives in the core repository at docs/specs/04-summon.md.

Status

Functional. The CLI surface (taut-summon run|stop|status) and the installed root verbs (taut summon, taut dismiss), the foreground driver (bootstrap, chat injection, event pump, crash-resume, clean shutdown), the session ledger with a single-driver guard and PTY wired flag, the control plane (STOP/STATUS/PING) with a rate backstop, the default persona, and the provider adapters are implemented. One interactive PTY adapter hosts every named harness (claude, codex, coder, grok, qwen, kimi, opencode, pi); there is no provider-specific protocol adapter. The POSIX backend is implemented with a native pseudoterminal and the Windows backend with ConPTY. See the retired plan 2026-07-06-taut-summon-plan (source 0db6b82; see the ledger in docs/plans/README.md), the retired plan 2026-07-07-taut-summon-pty-harness-adapter-plan (source 587e6e3; see the ledger in docs/plans/README.md), and docs/implementation/05-taut-summon-architecture.md for the driver design. Command registration and rich-host composition are documented in docs/implementation/06-command-extensions.md.

Requirements

  • Python 3.11+
  • Core distribution taut-chat and extension taut-summon installed in the same environment
  • A SQL-sidecar backend (SQLite or Postgres) — summon state rides sidecar tables

Installation

The core distribution is taut-chat; it still installs the taut command and import package. The extension remains taut-summon. Once the first coordinated PyPI release is published:

pipx install taut-chat
pipx inject --include-apps taut-chat taut-summon

The tag gate reuses the exact wheel and sdist built by canonical Test. It stages them in a draft GitHub Release, publishes them through the taut-summon top-level PyPI Trusted Publisher, verifies filenames and SHA-256 digests, and only then publishes the GitHub Release as immutable.

Usage

taut summon claude              # summon a claude into #general
taut summon reviewer --provider claude dev
taut dismiss reviewer
taut-summon status

When the workspace is discoverable from the current directory, --db is not required. The quickstart above exercises the same discovery path for the driver, control loop, and recovered broker handles.

taut-summon --help lists the three verbs and their exit classes; each verb's own --help documents every positional and flag. Exit 0 is success, 1 is an invocation, adapter, storage, or unresponsive-driver error, and 2 means nothing is currently summoned. With no verb, help goes to stderr and exits 1.

Installing this package registers native taut summon and taut dismiss command adapters through Taut's command-extension interface. The root and standalone consoles use the same parser configuration and controller adapters; neither console invokes the other. taut-summon status remains the standalone control-plane listing and inspection command.

On first PTY use, summon first explains the handoff and waits for a blank Enter before it starts the provider. The provider screen is setup, not Taut chat: answer only trust, login, model, or equivalent prompts there. Detach with Ctrl-\ Ctrl-\. The same chord works after a provider enables Kitty CSI-u or xterm modifyOtherKeys; no terminal-specific configuration is required. After detach, keep the foreground Summon command running and use another terminal for Taut chat. Summon then starts its listener; the summoned ... line is the readiness marker. The member is marked wired and future summons run detached. EOF, cancellation, or any nonblank response at the acknowledgement exits before spawning the provider and leaves it unwired. Use taut summon --attach NAME to re-enter setup, or --detach for an explicit detached run. PTY output is never parsed as speech; the agent speaks by running taut say.

Summon command records, standalone status/errors, and Summon-owned non-interactive logs use core's public taut.escape_terminal_text policy. This reduces the chance that prompt-injected chat or provider text is relayed as a live terminal command sequence. It is a safe default, not a sandbox boundary. The explicit PTY attach is intentionally exempt and copies provider terminal bytes unchanged because those bytes are the attached terminal protocol. Provider-owned stderr inherited directly by an external adapter is also outside Taut-owned text rendering and may contain controls. Constrain or redirect that provider stream when its output is not trusted; mediating it would require a separately drained pipe rather than this text-display policy.

The PTY orientation is the first injected user turn, not a privileged system message. Chat continuation lines are indented to keep attribution visible, but chat remains untrusted user-role workspace input. Notification injection is at most once because inbox records are consumable pointers; the source chat is durable. The rate backstop limits posting volume and does not detect a low-rate semantic loop.

Trust boundary

Anyone who can write the configured Taut storage can feed user-role input and storage-backed control requests to the summoned harness. For SQLite this is the local file-access boundary. For shared Postgres, a remote database writer can therefore influence tools on the harness host. Restrict storage writers to principals authorized for that effect, or constrain the harness tools separately. Names, personas, message framing, driver evidence, and continuity tokens preserve attribution or lifecycle state; they are not authorization.

Control requests carry driver evidence as a stale-generation fence. That evidence prevents an old queued command from acting on a replacement driver; it does not authenticate the requester.

Testing

From the repository root:

uv run pytest extensions/taut_summon/tests

Local runs attempt the live PTY harness smoke matrix by default. Every enabled run prewires the temporary member as already acknowledged and onboarded; this models the human acknowledgement but does not synthesize provider login or credentials. When a provider binary is present, the lane proves real-provider reachability by requiring usable detached status and catch-up after a real chat injection. It supplies the orientation and the injected probe as at least two provider inputs, so it can consume real provider quota. The lane skips only when explicitly disabled or when a provider binary is absent. Any later readiness, status, terminal-query, or injection failure fails the test. CI skips the real-harness matrix unless TAUT_SUMMON_LIVE_HARNESS=1 is set. For a fast local loop, use:

TAUT_SUMMON_LIVE_HARNESS=0 uv run pytest extensions/taut_summon/tests

Complete any provider trust, login, or model setup before expecting its live smoke to pass. Strict mode has the same runtime checks as the default enabled lane, but also fails instead of skipping when a provider binary is absent. The external-provider lane does not require hosted CLIs to auto-execute shell commands; the local LLM lane below owns the deterministic sentinel-posting proof.

TAUT_SUMMON_LIVE_HARNESS_STRICT=1 uv run pytest extensions/taut_summon/tests/test_live_harness.py

The POSIX host-terminal scenario always runs a deterministic scripted provider through the root taut summon CLI. It covers first attach, legacy and Kitty detach input, direct termios restoration, out-of-band status/chat/dismiss, shell return, fresh attach after prior-driver release, and provider retirement. To add the same lifecycle smoke for one real provider, select it explicitly; the test never chooses the first binary on PATH:

TAUT_SUMMON_HOST_PTY_PROVIDER=codex uv run pytest extensions/taut_summon/tests/test_host_terminal_scenarios.py

Set TAUT_SUMMON_HOST_PTY_READY_TEXT for an unrecognized provider prompt and TAUT_SUMMON_HOST_PTY_SETUP_INPUT when that provider needs one prepared input. This lane consumes real provider input and credentials just like the live harness matrix.

The local LLM smoke runs locally by default when a loopback OpenAI-compatible endpoint lists the served model, and it runs in CI through the dedicated Ollama-backed workflow job. Defaults:

TAUT_SUMMON_LOCAL_LLM_ENDPOINT=http://127.0.0.1:11434/v1
TAUT_SUMMON_LOCAL_LLM_MODEL=taut-summon-local-model:latest

To run it locally with Ollama:

ollama pull qwen2.5:0.5b
cat > /tmp/TautSummonModelfile <<'EOF'
FROM qwen2.5:0.5b
PARAMETER num_ctx 2048
PARAMETER num_predict 64
PARAMETER temperature 0
EOF
ollama create taut-summon-local-model:latest -f /tmp/TautSummonModelfile
uv run pytest extensions/taut_summon/tests/test_live_local_llm.py

Use TAUT_SUMMON_LOCAL_LLM=0 to skip the local LLM smoke locally, or TAUT_SUMMON_LOCAL_LLM=1 to make missing endpoint/model setup fail instead of skip.

Release files for taut-summon 0.9.10

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for taut-summon 0.9.10
File Size Uploaded
taut_summon-0.9.10.tar.gz 92.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for taut-summon 0.9.10
File Interpreter ABI Platform
taut_summon-0.9.10-py3-none-any.whl Python 3 none any Details

Total release size: 204.6 kB

Release files / taut_summon-0.9.10.tar.gz

Download URL taut_summon-0.9.10.tar.gz
Size 92.8 kB
Tags Source
SHA-256 checksum
How to use checksums
185ab931a113db1b58dbdcbe2057236e17db87d43e35d4204ccb178e315cda33
BLAKE2b-256 checksum
How to use checksums
fcd56c852a8933ab2f8791efb2d4005cd690d8179029804236345765fa05e4ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / taut_summon-0.9.10-py3-none-any.whl

Download URL taut_summon-0.9.10-py3-none-any.whl
Size 111.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
917d154f81643440a41c1b4d76ca8d3280785c7c84328b29d9064014a2bf0bcc
BLAKE2b-256 checksum
How to use checksums
18fa10edab8cc10388231db26e8d77f0088c1b9aed28d602f10f0bee3b4de015
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.9.10 This release

2 release files

0.9.9

2 release files

0.9.8

2 release files

0.9.7

2 release files

0.9.6

2 release files

0.9.5

2 release files

0.9.4

2 release files

0.9.3

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.7

2 release files

0.8.6

2 release files

0.8.5

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.7

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page