Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
4f522be
[tau] Start on the coding agent demo
msullivan May 12, 2026
62c05af
[tau] Queue user input while a turn is streaming
msullivan May 12, 2026
7985b6d
[tau] Extract chat_loop into a standalone function
msullivan May 12, 2026
9d5feec
[tau] Don't yank scrolled-up readers down, and hide the scrollbar
msullivan May 12, 2026
2a842c3
[tau] Implement pi's seven tools with approval-gated mutations
msullivan May 12, 2026
b71b7ec
[tau] Approval prompt as a focusable widget above the composer
msullivan May 13, 2026
7b1fd02
[tau] Stop gating write and edit behind approval
msullivan May 13, 2026
2892859
[tau] Add TAU_ADVERTISE=1 flag to include co-author trailer in commit…
msullivan May 13, 2026
e98dd03
[tau] Add session history with persist/resume support
msullivan May 13, 2026
f954aca
[tau] Show cumulative token usage in footer bar
msullivan May 13, 2026
5db5b20
[tau] Show approximate context size in usage footer
msullivan May 13, 2026
8e17737
[tau] Enable gateway caching and improve usage display
msullivan May 13, 2026
a8e5968
[tau] Refactor chat_loop: extract _run_turn for single-turn logic
msullivan May 13, 2026
63081d8
[tau] Add ApprovalTracker with per-command and global auto-approve
msullivan May 13, 2026
f12eb93
[tau] Auto-approve file tools under cwd, prompt for external paths
msullivan May 13, 2026
f94cd93
[tau] Ring terminal bell on turn completion and approval prompts
msullivan May 13, 2026
bc616b4
[tau] Render assistant messages as markdown via Rich
msullivan May 13, 2026
3d9346d
[tau] ESC to interrupt running turn
msullivan May 13, 2026
253dbc6
[tau] Remove ctrl+d quit binding
msullivan May 13, 2026
72ac6c8
[tau] Consistent scroll-follow behavior for all event types
msullivan May 13, 2026
3650b20
[tau] Make bash tool a StreamingTextTool
msullivan May 13, 2026
65563e1
[tau] Unwrap ExceptionGroup errors for readable error bubbles
msullivan May 15, 2026
0d33a9f
[tau] Only send gateway providerOptions when using gateway provider
msullivan May 15, 2026
ed42745
[tau] Display thinking/reasoning blocks in dim italic bubbles
msullivan May 15, 2026
5051470
[tau] Enable adaptive thinking for Anthropic models via gateway
msullivan May 16, 2026
bc0c770
[tau] Fix crash when tool kwargs contain Pydantic models
msullivan May 16, 2026
3da4d22
[tau] Default auto_scroll=False for add_bubble
msullivan May 16, 2026
a094bbb
[tau] Move ApprovalTracker to agent-loop section of tau.py
msullivan May 16, 2026
2431939
[tau] Update uv.lock?
msullivan May 19, 2026
7e841c4
[tau] Move tau-agent to a proper Python package
msullivan May 19, 2026
b570542
[tau] Extract SessionManager from TauApp
msullivan May 19, 2026
5136332
[tau] Remove stale comment about ai library usage
msullivan May 19, 2026
09762a0
[tau] Move bubble management out of the agent loop into TauApp methods
msullivan May 20, 2026
a76795c
[tau] Use show_tool_result in session replay
msullivan May 20, 2026
ff6e6c9
[tau] Extract _replay_session from TauApp._restore_session
msullivan May 20, 2026
e541391
[tau] Use isinstance instead of hasattr for ToolResultPart check
msullivan May 20, 2026
ac4a87c
[tau] Consolidate approval decision handling into ApprovalTracker.rem…
msullivan May 20, 2026
e565615
[tau] Move hook resolution into ApprovalTracker.resolve
msullivan May 20, 2026
179e816
[tau] Introduce Hook dataclass to decouple UI from ai.messages.HookPart
msullivan May 20, 2026
0f565d4
[tau] Extract _resolve_hook helper for resolve + show_system
msullivan May 20, 2026
d05ff7e
[tau] Move prompt option logic from HookPrompt into ApprovalTracker
msullivan May 20, 2026
5630274
[tau] Fix _format_tool_result leading blank line
msullivan May 20, 2026
536c38e
[tau] Minor cleanups: _bell, on_text_area_changed, require_approval c…
msullivan May 20, 2026
3baa88b
[tau] Stream tool call outputs via PartialToolCallResult
msullivan May 20, 2026
feceda4
[tau] Set stdin=DEVNULL for bash subprocess
msullivan May 20, 2026
d7f88bb
[tau] Replay thinking blocks and tool calls on session restore
msullivan May 20, 2026
27f320e
[tau] Add AGENTS.md support
msullivan May 20, 2026
b150157
[tau] Add image support to the read tool
msullivan May 20, 2026
90d819b
[tau] Replace manual scroll management with Textual's anchor system
msullivan May 20, 2026
3cfca40
[tau] Support image reads
msullivan May 20, 2026
0a54dd8
[tau] Use ansi-dark theme for native terminal colors
msullivan May 20, 2026
14e5f54
[tau] Run formatting, make line length match the toplevel project
msullivan May 21, 2026
b2cf64a
[tau] Add multi-line input to composer
msullivan May 21, 2026
6d60bef
[tau] Add provider web search tool based on model backend
msullivan May 21, 2026
d24adfd
[tau] Mention web_search in system prompt when available
msullivan May 21, 2026
73eb5cb
[tau] Show builtin tool events in transcript
msullivan May 21, 2026
5050f3e
[tau] use raw model name in Co-authored-by trailer
msullivan May 22, 2026
615733d
[tau] ruff
msullivan May 22, 2026
3f9455d
[tau] fix mypy type errors
msullivan May 22, 2026
ea9289a
[tau] show tool results in a shaded block
msullivan May 22, 2026
343d297
[tau] render edit tool calls as pi-style diffs
msullivan May 23, 2026
863b19a
[tau] fix: reset bubble state at start of each chat turn
msullivan May 23, 2026
66e2da5
[tau] add AGENTS.md for coding agents
msullivan May 23, 2026
4852363
[tau] fix: handle legacy str results in _EditAggregator.to_model_input
msullivan May 23, 2026
5ca9f8f
[tau] default to claude-opus-4.8
msullivan May 28, 2026
4a0aa36
[tau] Only route to anthropic when using anthropic models
msullivan May 28, 2026
f89ec7d
[tau] only pin gateway routing for anthropic and openai
msullivan May 28, 2026
ed1fe38
[tau] Use adaptive thinking
msullivan May 28, 2026
49936ec
[tau] fix: return ContentOutput for image reads
msullivan May 28, 2026
a3ccfca
[tau] include anthropic and openai deps
msullivan May 29, 2026
001b72b
[tau] Tweak anthropic thinking settings
msullivan May 29, 2026
9881f4e
[tau] feat: render ContentOutput tool results as text
msullivan May 29, 2026
af816df
[tau] Use ai.InferenceRequestParams to configure model
msullivan May 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,4 @@ __marimo__/

.claude/
.codex
.tau/
6 changes: 6 additions & 0 deletions examples/.test_scripts/check-examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
["fastapi", "textual", "websockets"],
["."],
),
(
"tau-agent",
REPO / "examples" / "tau-agent",
["textual"],
["."],
),
(
"temporal-direct",
REPO / "examples" / "temporal-direct",
Expand Down
13 changes: 13 additions & 0 deletions examples/tau-agent/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Python
__pycache__/
*.py[cod]
*.egg-info/
.venv/
dist/

# Environment
.env
.env*.local

# Tau session history
.tau/
49 changes: 49 additions & 0 deletions examples/tau-agent/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# AGENTS.md — tau-agent

## Overview

`tau` is a single-process coding-agent TUI built on the `ai` library and
Textual. It gives the model seven filesystem/shell tools (read, write,
edit, bash, grep, find, ls) with an approval gate for mutating
operations.

## Project layout

```
tau/
app.py — Textual app, chat loop, approval flow
tools.py — tool definitions (mirrors pi's seven built-ins)
session.py — JSONL session persistence and resume
pyproject.toml — project metadata, dependencies, ruff/mypy config
```

## TODO list

There may be a task list in `.tau/TODO` — check it for current
priorities and open items.

## Running

```bash
uv sync # install deps
uv run tau # launch the TUI
```

## Linting & type-checking

```bash
uv run ruff check . # lint
uv run ruff format --check # format check
uv run mypy tau # type-check
```

## Conventions

- Python ≥ 3.12.
- Line length: 80 (`ruff` and project style).
- Lint rule set: E, F, I, UP, B, SIM (see `pyproject.toml`).
- No workspace jail — the approval gate is the safety mechanism.
- Approval-gated tools (`write`, `edit`, `bash`) require operator
confirmation; reads are auto-approved.
- Sessions persist as JSONL under `.tau/sessions/`.
- Commit messages for this subdirectory should be prefixed with `[tau]`.
41 changes: 41 additions & 0 deletions examples/tau-agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# tau-agent

`tau` is a coding-agent demo built on the `ai` library. Single
process, Textual TUI, streaming replies, pi-style tool surface:

- **`read`** — read files; offset/limit pagination with continuation hints
- **`write`** — create / overwrite a file
- **`edit`** — exact-match str_replace, multiple disjoint edits per call
- **`bash`** — run a shell command in cwd, output truncated to the last 50KB / 2000 lines *(requires approval)*
- **`grep`** — regex search (skips `.git`, `node_modules`, etc.)
- **`find`** — glob match
- **`ls`** — directory listing

Approval-gated tools fire a `ToolApproval` hook; the composer turns
into a `[y/n]` prompt mid-turn. Unrelated text typed during a
pending approval falls through to the message queue — the hook stays
pending until you give it a y or n.

No workspace jail. The approval gate is the safety mechanism;
everything else relies on you watching the prompts.

## Setup

```bash
uv sync
```

## Running

```bash
uv run tau
```

Type a message, hit enter. `ctrl+c` to quit.

## Environment

| Variable | Description | Default |
|----------|-------------|---------|
| `AI_GATEWAY_API_KEY` | Vercel AI Gateway API key | — |
| `TAU_MODEL` | Model id passed to `ai.ai_gateway(...)` | `anthropic/claude-sonnet-4.5` |
35 changes: 35 additions & 0 deletions examples/tau-agent/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[project]
name = "tau-agent"
version = "0.1.0"
description = "Tau — a coding-agent chat bot demo built with the ai library and Textual"
requires-python = ">=3.12"
dependencies = [
"ai[anthropic,openai]",
"textual>=3.0",
]

[project.scripts]
tau = "tau.app:main"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["tau"]

[tool.uv.sources]
ai = { path = "../..", editable = true }

[tool.ruff]
line-length = 80
target-version = "py312"

[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B", "SIM"]

[dependency-groups]
dev = [
"mypy~=2.1.0",
"ruff>=0.15.12",
]
1 change: 1 addition & 0 deletions examples/tau-agent/tau/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""tau — a coding-agent chat bot built on the `ai` library and Textual."""
5 changes: 5 additions & 0 deletions examples/tau-agent/tau/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Entry point for ``python -m tau``."""

from tau.app import main

main()
Loading
Loading