ffwf-tau-coding-agent 0.9.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ffwf_tau_coding_agent-0.9.2/LICENSE +21 -0
- ffwf_tau_coding_agent-0.9.2/PKG-INFO +166 -0
- ffwf_tau_coding_agent-0.9.2/README.md +136 -0
- ffwf_tau_coding_agent-0.9.2/pyproject.toml +107 -0
- ffwf_tau_coding_agent-0.9.2/setup.cfg +4 -0
- ffwf_tau_coding_agent-0.9.2/src/ffwf_tau_coding_agent.egg-info/PKG-INFO +166 -0
- ffwf_tau_coding_agent-0.9.2/src/ffwf_tau_coding_agent.egg-info/SOURCES.txt +107 -0
- ffwf_tau_coding_agent-0.9.2/src/ffwf_tau_coding_agent.egg-info/dependency_links.txt +1 -0
- ffwf_tau_coding_agent-0.9.2/src/ffwf_tau_coding_agent.egg-info/entry_points.txt +3 -0
- ffwf_tau_coding_agent-0.9.2/src/ffwf_tau_coding_agent.egg-info/requires.txt +18 -0
- ffwf_tau_coding_agent-0.9.2/src/ffwf_tau_coding_agent.egg-info/top_level.txt +1 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/__init__.py +33 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/app.py +5014 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/backends.py +1825 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/chat_widgets.py +487 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/cli.py +710 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/config.py +115 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/devshot.py +119 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/headless.py +973 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/parley.tcss +797 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/rpc_mode.py +395 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/session_store.py +912 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/store_factory.py +265 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/tagline.py +66 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/tau_default_config.json +23 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/testing/__init__.py +38 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/testing/render.py +273 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/testing/sandbox.py +108 -0
- ffwf_tau_coding_agent-0.9.2/src/tau_coding_agent/testing/scenes.py +591 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_38_todo.py +225 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_41_bookmarks.py +169 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_42_session_autoname.py +164 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_50_review_swarm.py +385 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_51_delegate_fleet.py +448 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_52_red_team_memory.py +397 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_54_consequence_engine.py +461 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_agent_session_live_path.py +210 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_app_actions.py +514 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_app_command_dispatch.py +243 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_app_extension_commands.py +219 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_app_extension_loading.py +386 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_app_extension_mgmt.py +139 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_app_lifecycle_hooks.py +65 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_app_session_runtime.py +102 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_append_entry_reload.py +82 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_append_only_compaction_store.py +116 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_backend_reasoning.py +157 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_backend_telemetry_extra.py +133 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_backend_tool_filter.py +100 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_before_agent_start_durable.py +246 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_chat_placeholder.py +372 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_chat_rendering.py +916 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_chat_widgets.py +297 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_cli.py +977 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_cli_flag_inventory.py +162 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_config.py +140 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_context_surgeon.py +482 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_contract_file_catalog.py +39 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_contract_file_session.py +62 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_cost.py +185 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_ctx_fork_export.py +96 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_delegate.py +242 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_e5_integration_floor.py +344 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_e5_status_doc.py +123 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_ext_config_cli.py +147 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_ext_kit_gate.py +328 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_ext_kit_ledger.py +375 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_ext_kit_spawn.py +396 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_ext_kit_state.py +332 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_ext_kit_steer.py +551 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_ext_kit_stream.py +392 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_extension_dialogs.py +204 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_extension_form.py +189 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_extension_notify_and_veto.py +191 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_extension_panel.py +264 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_extension_shortcut.py +206 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_extension_status_bar.py +116 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_handoff.py +191 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_headless_command_output.py +193 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_headless_extension_records.py +142 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_headless_lifecycle.py +175 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_headless_resume.py +362 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_headless_submission_source.py +518 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_json_mode.py +262 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_live_procedures_doc.py +389 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_missing_api_key_raises.py +68 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_model_grammar_config.py +87 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_model_resolver_wiring.py +118 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_nested_collapsible_spike.py +86 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_no_host_addresses.py +64 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_packaging.py +299 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_palette_command_args.py +160 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_render_router.py +502 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_rollback_affordance.py +401 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_rpc_conformance.py +2334 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_rpc_line_limit.py +420 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_rpc_session_dir_isolation.py +478 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_session_dir_flag.py +287 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_session_store.py +399 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_session_tree_browser.py +304 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_store_factory.py +371 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_tree_detail_pane.py +360 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_tree_elide.py +448 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_tui_appearance.py +788 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_tui_multi_lane_render.py +653 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_tui_snapshots.py +174 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_tui_sole_persister.py +180 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_tui_submission_source.py +268 -0
- ffwf_tau_coding_agent-0.9.2/tests/test_ui_defaults_cli.py +99 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Fight Fire with Fire Robotics, LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ffwf-tau-coding-agent
|
|
3
|
+
Version: 0.9.2
|
|
4
|
+
Summary: τ-coding-agent: Interactive TUI (Textual) + CLI
|
|
5
|
+
Author: Fight Fire with Fire Robotics, LLC
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://ffwfrobotics.github.io/tau/
|
|
8
|
+
Project-URL: Documentation, https://ffwfrobotics.github.io/tau/
|
|
9
|
+
Project-URL: Repository, https://github.com/jmccardle/tau
|
|
10
|
+
Project-URL: Issues, https://github.com/jmccardle/tau/issues
|
|
11
|
+
Requires-Python: >=3.11
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: ffwf-tau-agent-core==0.9.2
|
|
15
|
+
Provides-Extra: tui
|
|
16
|
+
Requires-Dist: textual>=0.47; extra == "tui"
|
|
17
|
+
Requires-Dist: rich; extra == "tui"
|
|
18
|
+
Provides-Extra: jmfts
|
|
19
|
+
Requires-Dist: ffwf-tau-jmfts==0.9.2; extra == "jmfts"
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: ffwf-tau-coding-agent[jmfts,tui]==0.9.2; extra == "dev"
|
|
22
|
+
Requires-Dist: pytest; extra == "dev"
|
|
23
|
+
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
24
|
+
Requires-Dist: ruff; extra == "dev"
|
|
25
|
+
Requires-Dist: mypy==2.1.*; extra == "dev"
|
|
26
|
+
Requires-Dist: textual-dev; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-textual-snapshot; extra == "dev"
|
|
28
|
+
Requires-Dist: cairosvg; extra == "dev"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# ffwf-tau-coding-agent
|
|
32
|
+
|
|
33
|
+
The interface of **Tau**, a programmable coding agent harness: the `tau`
|
|
34
|
+
command, its Textual terminal UI, and the headless run paths behind `tau -p` and
|
|
35
|
+
`tau --mode rpc`.
|
|
36
|
+
|
|
37
|
+
Tau began as a Python port of the TypeScript project
|
|
38
|
+
[pi-mono](https://github.com/badlogic/pi-mono), which is still read as the
|
|
39
|
+
reference implementation when porting or debugging; it now diverges from pi
|
|
40
|
+
deliberately in several places.
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install ffwf-tau-coding-agent # headless: the CLI, `tau -p`, `--mode rpc`
|
|
46
|
+
pip install 'ffwf-tau-coding-agent[tui]' # add the interactive TUI
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Python 3.11 or newer. Pulls in `ffwf-tau-agent-core`, and through it
|
|
50
|
+
`ffwf-tau-llm`. Note the `ffwf-` prefix: `tau-llm` and `tau-ai` on PyPI are
|
|
51
|
+
unrelated projects.
|
|
52
|
+
|
|
53
|
+
| Extra | Adds | Needed for |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| `ffwf-tau-coding-agent[tui]` | `textual`, `rich` | the interactive TUI. `tau -p` runs a full turn without it |
|
|
56
|
+
| `ffwf-tau-coding-agent[jmfts]` | `ffwf-tau-jmfts` | `--store jmfts` session storage |
|
|
57
|
+
|
|
58
|
+
**The interface is an extra, not a base dependency.** A headless install is 15
|
|
59
|
+
packages and 13 MB; adding `[tui]` makes it 27 packages and 31 MB. Both extras
|
|
60
|
+
report their own absence — asking for the TUI or for `--store jmfts` without the
|
|
61
|
+
matching extra fails with the install command you need, not a traceback.
|
|
62
|
+
|
|
63
|
+
### Two names for one command
|
|
64
|
+
|
|
65
|
+
The install puts **both `tau` and `ffwf-tau`** on your PATH. They are the same
|
|
66
|
+
entry point, not a link: each is a wrapper pip owns and removes on uninstall.
|
|
67
|
+
|
|
68
|
+
Type `tau`. PyPI reserves distribution names but not command names, and at least
|
|
69
|
+
one unrelated project ships its own `tau`; in an environment holding both,
|
|
70
|
+
whichever installed last owns the name and neither pip nor uv says a word.
|
|
71
|
+
`ffwf-tau` cannot be taken, which makes it the right name inside scripts,
|
|
72
|
+
systemd units, and Dockerfiles. If `tau --version` does not report τ,
|
|
73
|
+
`ffwf-tau --version` will.
|
|
74
|
+
|
|
75
|
+
## Run
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
tau # interactive TUI
|
|
79
|
+
tau -p "list the files here" # headless: print a transcript, exit
|
|
80
|
+
tau -p --mode json "..." # headless: JSONL lifecycle events instead of text
|
|
81
|
+
tau --mode rpc # drive τ as a subprocess over stdio (JSON-RPC 2.0)
|
|
82
|
+
tau -e permission_gate.py # load an extension from a path
|
|
83
|
+
tau --help # the exact contract; treat this page as the stale one
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`tau -p` and `tau --mode rpc` both write and resume real sessions under
|
|
87
|
+
`~/.tau/sessions/`, so a headless run appears in the TUI's sidebar and can be
|
|
88
|
+
picked up interactively later. `--no-session` means nothing is persisted.
|
|
89
|
+
|
|
90
|
+
Flags worth knowing: `-m/--model`, `-t/--tools` and `-nt/--no-tools`,
|
|
91
|
+
`-e/--extension PATH`, `--thinking {off,minimal,low,medium,high,xhigh}`,
|
|
92
|
+
`-c/--continue`, `--session REF`, `--fork REF`, `--store {file,jmfts}`.
|
|
93
|
+
|
|
94
|
+
## Configure
|
|
95
|
+
|
|
96
|
+
On first run τ writes `~/.tau/config.json` from a default shipped inside the
|
|
97
|
+
package. It holds the `models` map that `--model` resolves names against, plus
|
|
98
|
+
per-extension config and the `session_store` block. A model entry names the
|
|
99
|
+
provider, the base URL, and the context window, so pointing τ at a local
|
|
100
|
+
OpenAI-compatible server (vLLM, llama.cpp, Ollama) is a config edit rather than
|
|
101
|
+
a code change.
|
|
102
|
+
|
|
103
|
+
## The TUI
|
|
104
|
+
|
|
105
|
+
Built on [Textual](https://textual.textualize.io/). Streamed text renders at
|
|
106
|
+
30 Hz; tool calls and their results appear as their own blocks.
|
|
107
|
+
|
|
108
|
+
| Key | Action |
|
|
109
|
+
|---|---|
|
|
110
|
+
| `Ctrl+Enter` | send the message |
|
|
111
|
+
| `Ctrl+B` | toggle the session sidebar |
|
|
112
|
+
| `Ctrl+N` | new chat |
|
|
113
|
+
| `Ctrl+G` | browse the conversation tree |
|
|
114
|
+
| `Ctrl+Z` | roll back the last turn |
|
|
115
|
+
| `Ctrl+R` / `Ctrl+T` | show or hide reasoning / tool blocks |
|
|
116
|
+
| `Ctrl+E` | extensions |
|
|
117
|
+
| `Ctrl+P` | command palette |
|
|
118
|
+
| `Escape` | cancel the current generation |
|
|
119
|
+
|
|
120
|
+
**The sidebar and the tree browser are two different things.** The sidebar picks
|
|
121
|
+
*which session to open* — a flat list grouped by date. `Ctrl+G` opens a browser
|
|
122
|
+
over the branch structure *inside the current conversation*, where you navigate
|
|
123
|
+
to an earlier node, summarise a branch, or elide a span. Typed commands cover
|
|
124
|
+
the rest: `/compact`, `/tree`, `/fork`, `/extensions`.
|
|
125
|
+
|
|
126
|
+
## Why it is a separate package
|
|
127
|
+
|
|
128
|
+
Everything here is presentation and process management. The agent lives in
|
|
129
|
+
`ffwf-tau-agent-core`, which has no Textual dependency and never imports this
|
|
130
|
+
package. `ffwf-tau-jmfts` is a peer rather than a dependency: `--store jmfts`
|
|
131
|
+
imports it lazily and fails at startup if it is absent, never falling back to
|
|
132
|
+
files without saying so.
|
|
133
|
+
|
|
134
|
+
If you want the agent rather than the interface, use the runtime directly:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
import asyncio
|
|
138
|
+
from tau_agent_core import create_agent_session
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
async def main():
|
|
142
|
+
session = create_agent_session(model="gpt-4o", tools=["read", "bash"])
|
|
143
|
+
print(await session.prompt("What is in this directory?"))
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
asyncio.run(main())
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Docs
|
|
150
|
+
|
|
151
|
+
- `docs/tau-coding-agent.md` — design notes for this package.
|
|
152
|
+
- `docs/CLI-PLAN.md` — the flag set and its status.
|
|
153
|
+
- `docs/REMOTE-CONTROL.md`, `docs/RPC-PROTOCOL.md` — `--mode rpc`.
|
|
154
|
+
- `docs/EXTENSIONS-WALKTHROUGH.md` — writing an extension to load with `-e`.
|
|
155
|
+
|
|
156
|
+
Repository: <https://github.com/jmccardle/tau>
|
|
157
|
+
|
|
158
|
+
## The rest of Tau
|
|
159
|
+
|
|
160
|
+
| Distribution | Imports as | What it is |
|
|
161
|
+
|---|---|---|
|
|
162
|
+
| `ffwf-tau-llm` | `tau_llm` | the provider and streaming layer |
|
|
163
|
+
| `ffwf-tau-agent-core` | `tau_agent_core` | the agent loop, tools, sessions, extensions |
|
|
164
|
+
| `ffwf-tau-jmfts` | `tau_jmfts` | a JMFTS-backed session store |
|
|
165
|
+
|
|
166
|
+
MIT © Fight Fire with Fire Robotics, LLC
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# ffwf-tau-coding-agent
|
|
2
|
+
|
|
3
|
+
The interface of **Tau**, a programmable coding agent harness: the `tau`
|
|
4
|
+
command, its Textual terminal UI, and the headless run paths behind `tau -p` and
|
|
5
|
+
`tau --mode rpc`.
|
|
6
|
+
|
|
7
|
+
Tau began as a Python port of the TypeScript project
|
|
8
|
+
[pi-mono](https://github.com/badlogic/pi-mono), which is still read as the
|
|
9
|
+
reference implementation when porting or debugging; it now diverges from pi
|
|
10
|
+
deliberately in several places.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install ffwf-tau-coding-agent # headless: the CLI, `tau -p`, `--mode rpc`
|
|
16
|
+
pip install 'ffwf-tau-coding-agent[tui]' # add the interactive TUI
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Python 3.11 or newer. Pulls in `ffwf-tau-agent-core`, and through it
|
|
20
|
+
`ffwf-tau-llm`. Note the `ffwf-` prefix: `tau-llm` and `tau-ai` on PyPI are
|
|
21
|
+
unrelated projects.
|
|
22
|
+
|
|
23
|
+
| Extra | Adds | Needed for |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| `ffwf-tau-coding-agent[tui]` | `textual`, `rich` | the interactive TUI. `tau -p` runs a full turn without it |
|
|
26
|
+
| `ffwf-tau-coding-agent[jmfts]` | `ffwf-tau-jmfts` | `--store jmfts` session storage |
|
|
27
|
+
|
|
28
|
+
**The interface is an extra, not a base dependency.** A headless install is 15
|
|
29
|
+
packages and 13 MB; adding `[tui]` makes it 27 packages and 31 MB. Both extras
|
|
30
|
+
report their own absence — asking for the TUI or for `--store jmfts` without the
|
|
31
|
+
matching extra fails with the install command you need, not a traceback.
|
|
32
|
+
|
|
33
|
+
### Two names for one command
|
|
34
|
+
|
|
35
|
+
The install puts **both `tau` and `ffwf-tau`** on your PATH. They are the same
|
|
36
|
+
entry point, not a link: each is a wrapper pip owns and removes on uninstall.
|
|
37
|
+
|
|
38
|
+
Type `tau`. PyPI reserves distribution names but not command names, and at least
|
|
39
|
+
one unrelated project ships its own `tau`; in an environment holding both,
|
|
40
|
+
whichever installed last owns the name and neither pip nor uv says a word.
|
|
41
|
+
`ffwf-tau` cannot be taken, which makes it the right name inside scripts,
|
|
42
|
+
systemd units, and Dockerfiles. If `tau --version` does not report τ,
|
|
43
|
+
`ffwf-tau --version` will.
|
|
44
|
+
|
|
45
|
+
## Run
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
tau # interactive TUI
|
|
49
|
+
tau -p "list the files here" # headless: print a transcript, exit
|
|
50
|
+
tau -p --mode json "..." # headless: JSONL lifecycle events instead of text
|
|
51
|
+
tau --mode rpc # drive τ as a subprocess over stdio (JSON-RPC 2.0)
|
|
52
|
+
tau -e permission_gate.py # load an extension from a path
|
|
53
|
+
tau --help # the exact contract; treat this page as the stale one
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`tau -p` and `tau --mode rpc` both write and resume real sessions under
|
|
57
|
+
`~/.tau/sessions/`, so a headless run appears in the TUI's sidebar and can be
|
|
58
|
+
picked up interactively later. `--no-session` means nothing is persisted.
|
|
59
|
+
|
|
60
|
+
Flags worth knowing: `-m/--model`, `-t/--tools` and `-nt/--no-tools`,
|
|
61
|
+
`-e/--extension PATH`, `--thinking {off,minimal,low,medium,high,xhigh}`,
|
|
62
|
+
`-c/--continue`, `--session REF`, `--fork REF`, `--store {file,jmfts}`.
|
|
63
|
+
|
|
64
|
+
## Configure
|
|
65
|
+
|
|
66
|
+
On first run τ writes `~/.tau/config.json` from a default shipped inside the
|
|
67
|
+
package. It holds the `models` map that `--model` resolves names against, plus
|
|
68
|
+
per-extension config and the `session_store` block. A model entry names the
|
|
69
|
+
provider, the base URL, and the context window, so pointing τ at a local
|
|
70
|
+
OpenAI-compatible server (vLLM, llama.cpp, Ollama) is a config edit rather than
|
|
71
|
+
a code change.
|
|
72
|
+
|
|
73
|
+
## The TUI
|
|
74
|
+
|
|
75
|
+
Built on [Textual](https://textual.textualize.io/). Streamed text renders at
|
|
76
|
+
30 Hz; tool calls and their results appear as their own blocks.
|
|
77
|
+
|
|
78
|
+
| Key | Action |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `Ctrl+Enter` | send the message |
|
|
81
|
+
| `Ctrl+B` | toggle the session sidebar |
|
|
82
|
+
| `Ctrl+N` | new chat |
|
|
83
|
+
| `Ctrl+G` | browse the conversation tree |
|
|
84
|
+
| `Ctrl+Z` | roll back the last turn |
|
|
85
|
+
| `Ctrl+R` / `Ctrl+T` | show or hide reasoning / tool blocks |
|
|
86
|
+
| `Ctrl+E` | extensions |
|
|
87
|
+
| `Ctrl+P` | command palette |
|
|
88
|
+
| `Escape` | cancel the current generation |
|
|
89
|
+
|
|
90
|
+
**The sidebar and the tree browser are two different things.** The sidebar picks
|
|
91
|
+
*which session to open* — a flat list grouped by date. `Ctrl+G` opens a browser
|
|
92
|
+
over the branch structure *inside the current conversation*, where you navigate
|
|
93
|
+
to an earlier node, summarise a branch, or elide a span. Typed commands cover
|
|
94
|
+
the rest: `/compact`, `/tree`, `/fork`, `/extensions`.
|
|
95
|
+
|
|
96
|
+
## Why it is a separate package
|
|
97
|
+
|
|
98
|
+
Everything here is presentation and process management. The agent lives in
|
|
99
|
+
`ffwf-tau-agent-core`, which has no Textual dependency and never imports this
|
|
100
|
+
package. `ffwf-tau-jmfts` is a peer rather than a dependency: `--store jmfts`
|
|
101
|
+
imports it lazily and fails at startup if it is absent, never falling back to
|
|
102
|
+
files without saying so.
|
|
103
|
+
|
|
104
|
+
If you want the agent rather than the interface, use the runtime directly:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
import asyncio
|
|
108
|
+
from tau_agent_core import create_agent_session
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
async def main():
|
|
112
|
+
session = create_agent_session(model="gpt-4o", tools=["read", "bash"])
|
|
113
|
+
print(await session.prompt("What is in this directory?"))
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
asyncio.run(main())
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Docs
|
|
120
|
+
|
|
121
|
+
- `docs/tau-coding-agent.md` — design notes for this package.
|
|
122
|
+
- `docs/CLI-PLAN.md` — the flag set and its status.
|
|
123
|
+
- `docs/REMOTE-CONTROL.md`, `docs/RPC-PROTOCOL.md` — `--mode rpc`.
|
|
124
|
+
- `docs/EXTENSIONS-WALKTHROUGH.md` — writing an extension to load with `-e`.
|
|
125
|
+
|
|
126
|
+
Repository: <https://github.com/jmccardle/tau>
|
|
127
|
+
|
|
128
|
+
## The rest of Tau
|
|
129
|
+
|
|
130
|
+
| Distribution | Imports as | What it is |
|
|
131
|
+
|---|---|---|
|
|
132
|
+
| `ffwf-tau-llm` | `tau_llm` | the provider and streaming layer |
|
|
133
|
+
| `ffwf-tau-agent-core` | `tau_agent_core` | the agent loop, tools, sessions, extensions |
|
|
134
|
+
| `ffwf-tau-jmfts` | `tau_jmfts` | a JMFTS-backed session store |
|
|
135
|
+
|
|
136
|
+
MIT © Fight Fire with Fire Robotics, LLC
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ffwf-tau-coding-agent"
|
|
3
|
+
# The version is not a literal here. Each distribution reads it from its own
|
|
4
|
+
# package's ``__version__``, so the wheel metadata and what the code reports can
|
|
5
|
+
# never disagree -- they are the same line. Bump that line to cut a release.
|
|
6
|
+
dynamic = ["version"]
|
|
7
|
+
description = "τ-coding-agent: Interactive TUI (Textual) + CLI"
|
|
8
|
+
requires-python = ">=3.11"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
# SPDX expression + the file itself (PEP 639), which is why build-system below
|
|
11
|
+
# needs setuptools >= 77.0.3: earlier versions ignore `license-files` and the
|
|
12
|
+
# wheel ships without the licence text. Each package carries its own copy of the
|
|
13
|
+
# repo-root LICENSE because a wheel is built from one package directory and
|
|
14
|
+
# cannot reach outside it.
|
|
15
|
+
license = "MIT"
|
|
16
|
+
license-files = ["LICENSE"]
|
|
17
|
+
authors = [{ name = "Fight Fire with Fire Robotics, LLC" }]
|
|
18
|
+
dependencies = [
|
|
19
|
+
"ffwf-tau-agent-core==0.9.2",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.optional-dependencies]
|
|
23
|
+
# The interface. `tau -p` (cli.py -> headless.py) never imports textual: the only
|
|
24
|
+
# entry into the Textual app is a lazy `from tau_coding_agent.app import Parley`
|
|
25
|
+
# inside cli._launch_tui, so a headless install runs a full turn -- extensions and
|
|
26
|
+
# all -- with neither library present. Measured: 15 packages / 13 MB without this
|
|
27
|
+
# extra, 27 packages / 31 MB with it.
|
|
28
|
+
#
|
|
29
|
+
# rich belongs here rather than in the base: its importers are app.py,
|
|
30
|
+
# chat_widgets.py and testing/render.py, and every one of them imports textual at
|
|
31
|
+
# module scope too. tau_coding_agent.testing is therefore TUI-side as a whole --
|
|
32
|
+
# testing/__init__.py re-exports render -- and needs this extra.
|
|
33
|
+
tui = [
|
|
34
|
+
"textual>=0.47",
|
|
35
|
+
"rich",
|
|
36
|
+
]
|
|
37
|
+
# The session store. tau-jmfts is a separate distribution and stays that way; this
|
|
38
|
+
# extra is only a convenience spelling for it. store_factory.py imports it lazily
|
|
39
|
+
# and converts a missing package into a StoreError that names this extra, so
|
|
40
|
+
# `--store jmfts` without it fails with an instruction rather than a traceback.
|
|
41
|
+
jmfts = ["ffwf-tau-jmfts==0.9.2"]
|
|
42
|
+
dev = [
|
|
43
|
+
"ffwf-tau-coding-agent[tui,jmfts]==0.9.2",
|
|
44
|
+
"pytest",
|
|
45
|
+
"pytest-asyncio",
|
|
46
|
+
"ruff",
|
|
47
|
+
# Pinned, unlike every other dev tool here. mypy has no "state your rule set"
|
|
48
|
+
# knob the way ruff does, so its findings move with its version: verified on
|
|
49
|
+
# this tree, 2.1.0 reports 0 errors and 2.3.1 reports 50 across 12 files.
|
|
50
|
+
# Those 50 look like real findings that a newer mypy got better at seeing --
|
|
51
|
+
# mostly no-any-return -- so they are scheduled, not suppressed: clearing
|
|
52
|
+
# them is its own pass, and until then the gate must mean the same thing in
|
|
53
|
+
# every clone. Raise this bound WITH that pass, never to make a hook go green.
|
|
54
|
+
"mypy==2.1.*",
|
|
55
|
+
# TUI visual inspection (see docs/textual-headless-testing.md):
|
|
56
|
+
# textual-dev -> `textual run --dev` live CSS editing, `textual console`
|
|
57
|
+
# pytest-textual-snapshot -> SVG visual-regression tests
|
|
58
|
+
# cairosvg -> rasterize an exported SVG so a human can look at it
|
|
59
|
+
"textual-dev",
|
|
60
|
+
"pytest-textual-snapshot",
|
|
61
|
+
"cairosvg",
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
# The PUBLIC repository only. This tree has a second, private git remote whose
|
|
65
|
+
# history is unfiltered; its hostname must never reach this file or a README,
|
|
66
|
+
# because both are uploaded verbatim (pyproject.toml ships inside the sdist).
|
|
67
|
+
# tests/test_packaging.py enforces that.
|
|
68
|
+
[project.urls]
|
|
69
|
+
Homepage = "https://ffwfrobotics.github.io/tau/"
|
|
70
|
+
Documentation = "https://ffwfrobotics.github.io/tau/"
|
|
71
|
+
Repository = "https://github.com/jmccardle/tau"
|
|
72
|
+
Issues = "https://github.com/jmccardle/tau/issues"
|
|
73
|
+
|
|
74
|
+
[build-system]
|
|
75
|
+
requires = ["setuptools>=77.0.3", "wheel"]
|
|
76
|
+
build-backend = "setuptools.build_meta"
|
|
77
|
+
|
|
78
|
+
[tool.setuptools.packages.find]
|
|
79
|
+
where = ["src"]
|
|
80
|
+
|
|
81
|
+
[tool.setuptools.dynamic]
|
|
82
|
+
version = { attr = "tau_coding_agent.__version__" }
|
|
83
|
+
|
|
84
|
+
# Non-.py files the installed package reads at runtime. Both are load-bearing:
|
|
85
|
+
# bootstrap_config() reads tau_default_config.json out of the installed package on
|
|
86
|
+
# first run (without it, `pip install tau-coding-agent` ships a τ that dies with
|
|
87
|
+
# FileNotFoundError before it can print a prompt), and Parley.CSS_PATH resolves
|
|
88
|
+
# parley.tcss next to app.py (without it, the TUI raises on startup with no
|
|
89
|
+
# stylesheet). Covered by tests/test_packaging.py.
|
|
90
|
+
[tool.setuptools.package-data]
|
|
91
|
+
tau_coding_agent = ["tau_default_config.json", "parley.tcss"]
|
|
92
|
+
|
|
93
|
+
# Two names for one entry point, not a symlink. A wheel cannot portably express a
|
|
94
|
+
# symlink, and pip generates each console script as an independent wrapper it owns
|
|
95
|
+
# in its RECORD -- so two entries uninstall as cleanly as one, on Windows too.
|
|
96
|
+
#
|
|
97
|
+
# `tau` is the name to type. It is also the name PyPI cannot reserve: console
|
|
98
|
+
# script names have no registry, and at least one active project (`tau-ai`, an
|
|
99
|
+
# unrelated pi-style harness) already ships its own `tau`. In an environment
|
|
100
|
+
# holding both, whichever installed last owns the name, silently.
|
|
101
|
+
#
|
|
102
|
+
# `ffwf-tau` is the name that cannot be taken. It is the fallback when `tau` is
|
|
103
|
+
# not ours, and the stable name for scripts, systemd units and Dockerfiles, where
|
|
104
|
+
# ergonomics do not matter and being the right program does.
|
|
105
|
+
[project.scripts]
|
|
106
|
+
tau = "tau_coding_agent.cli:main"
|
|
107
|
+
ffwf-tau = "tau_coding_agent.cli:main"
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ffwf-tau-coding-agent
|
|
3
|
+
Version: 0.9.2
|
|
4
|
+
Summary: τ-coding-agent: Interactive TUI (Textual) + CLI
|
|
5
|
+
Author: Fight Fire with Fire Robotics, LLC
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://ffwfrobotics.github.io/tau/
|
|
8
|
+
Project-URL: Documentation, https://ffwfrobotics.github.io/tau/
|
|
9
|
+
Project-URL: Repository, https://github.com/jmccardle/tau
|
|
10
|
+
Project-URL: Issues, https://github.com/jmccardle/tau/issues
|
|
11
|
+
Requires-Python: >=3.11
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: ffwf-tau-agent-core==0.9.2
|
|
15
|
+
Provides-Extra: tui
|
|
16
|
+
Requires-Dist: textual>=0.47; extra == "tui"
|
|
17
|
+
Requires-Dist: rich; extra == "tui"
|
|
18
|
+
Provides-Extra: jmfts
|
|
19
|
+
Requires-Dist: ffwf-tau-jmfts==0.9.2; extra == "jmfts"
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: ffwf-tau-coding-agent[jmfts,tui]==0.9.2; extra == "dev"
|
|
22
|
+
Requires-Dist: pytest; extra == "dev"
|
|
23
|
+
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
24
|
+
Requires-Dist: ruff; extra == "dev"
|
|
25
|
+
Requires-Dist: mypy==2.1.*; extra == "dev"
|
|
26
|
+
Requires-Dist: textual-dev; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-textual-snapshot; extra == "dev"
|
|
28
|
+
Requires-Dist: cairosvg; extra == "dev"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# ffwf-tau-coding-agent
|
|
32
|
+
|
|
33
|
+
The interface of **Tau**, a programmable coding agent harness: the `tau`
|
|
34
|
+
command, its Textual terminal UI, and the headless run paths behind `tau -p` and
|
|
35
|
+
`tau --mode rpc`.
|
|
36
|
+
|
|
37
|
+
Tau began as a Python port of the TypeScript project
|
|
38
|
+
[pi-mono](https://github.com/badlogic/pi-mono), which is still read as the
|
|
39
|
+
reference implementation when porting or debugging; it now diverges from pi
|
|
40
|
+
deliberately in several places.
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install ffwf-tau-coding-agent # headless: the CLI, `tau -p`, `--mode rpc`
|
|
46
|
+
pip install 'ffwf-tau-coding-agent[tui]' # add the interactive TUI
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Python 3.11 or newer. Pulls in `ffwf-tau-agent-core`, and through it
|
|
50
|
+
`ffwf-tau-llm`. Note the `ffwf-` prefix: `tau-llm` and `tau-ai` on PyPI are
|
|
51
|
+
unrelated projects.
|
|
52
|
+
|
|
53
|
+
| Extra | Adds | Needed for |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| `ffwf-tau-coding-agent[tui]` | `textual`, `rich` | the interactive TUI. `tau -p` runs a full turn without it |
|
|
56
|
+
| `ffwf-tau-coding-agent[jmfts]` | `ffwf-tau-jmfts` | `--store jmfts` session storage |
|
|
57
|
+
|
|
58
|
+
**The interface is an extra, not a base dependency.** A headless install is 15
|
|
59
|
+
packages and 13 MB; adding `[tui]` makes it 27 packages and 31 MB. Both extras
|
|
60
|
+
report their own absence — asking for the TUI or for `--store jmfts` without the
|
|
61
|
+
matching extra fails with the install command you need, not a traceback.
|
|
62
|
+
|
|
63
|
+
### Two names for one command
|
|
64
|
+
|
|
65
|
+
The install puts **both `tau` and `ffwf-tau`** on your PATH. They are the same
|
|
66
|
+
entry point, not a link: each is a wrapper pip owns and removes on uninstall.
|
|
67
|
+
|
|
68
|
+
Type `tau`. PyPI reserves distribution names but not command names, and at least
|
|
69
|
+
one unrelated project ships its own `tau`; in an environment holding both,
|
|
70
|
+
whichever installed last owns the name and neither pip nor uv says a word.
|
|
71
|
+
`ffwf-tau` cannot be taken, which makes it the right name inside scripts,
|
|
72
|
+
systemd units, and Dockerfiles. If `tau --version` does not report τ,
|
|
73
|
+
`ffwf-tau --version` will.
|
|
74
|
+
|
|
75
|
+
## Run
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
tau # interactive TUI
|
|
79
|
+
tau -p "list the files here" # headless: print a transcript, exit
|
|
80
|
+
tau -p --mode json "..." # headless: JSONL lifecycle events instead of text
|
|
81
|
+
tau --mode rpc # drive τ as a subprocess over stdio (JSON-RPC 2.0)
|
|
82
|
+
tau -e permission_gate.py # load an extension from a path
|
|
83
|
+
tau --help # the exact contract; treat this page as the stale one
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`tau -p` and `tau --mode rpc` both write and resume real sessions under
|
|
87
|
+
`~/.tau/sessions/`, so a headless run appears in the TUI's sidebar and can be
|
|
88
|
+
picked up interactively later. `--no-session` means nothing is persisted.
|
|
89
|
+
|
|
90
|
+
Flags worth knowing: `-m/--model`, `-t/--tools` and `-nt/--no-tools`,
|
|
91
|
+
`-e/--extension PATH`, `--thinking {off,minimal,low,medium,high,xhigh}`,
|
|
92
|
+
`-c/--continue`, `--session REF`, `--fork REF`, `--store {file,jmfts}`.
|
|
93
|
+
|
|
94
|
+
## Configure
|
|
95
|
+
|
|
96
|
+
On first run τ writes `~/.tau/config.json` from a default shipped inside the
|
|
97
|
+
package. It holds the `models` map that `--model` resolves names against, plus
|
|
98
|
+
per-extension config and the `session_store` block. A model entry names the
|
|
99
|
+
provider, the base URL, and the context window, so pointing τ at a local
|
|
100
|
+
OpenAI-compatible server (vLLM, llama.cpp, Ollama) is a config edit rather than
|
|
101
|
+
a code change.
|
|
102
|
+
|
|
103
|
+
## The TUI
|
|
104
|
+
|
|
105
|
+
Built on [Textual](https://textual.textualize.io/). Streamed text renders at
|
|
106
|
+
30 Hz; tool calls and their results appear as their own blocks.
|
|
107
|
+
|
|
108
|
+
| Key | Action |
|
|
109
|
+
|---|---|
|
|
110
|
+
| `Ctrl+Enter` | send the message |
|
|
111
|
+
| `Ctrl+B` | toggle the session sidebar |
|
|
112
|
+
| `Ctrl+N` | new chat |
|
|
113
|
+
| `Ctrl+G` | browse the conversation tree |
|
|
114
|
+
| `Ctrl+Z` | roll back the last turn |
|
|
115
|
+
| `Ctrl+R` / `Ctrl+T` | show or hide reasoning / tool blocks |
|
|
116
|
+
| `Ctrl+E` | extensions |
|
|
117
|
+
| `Ctrl+P` | command palette |
|
|
118
|
+
| `Escape` | cancel the current generation |
|
|
119
|
+
|
|
120
|
+
**The sidebar and the tree browser are two different things.** The sidebar picks
|
|
121
|
+
*which session to open* — a flat list grouped by date. `Ctrl+G` opens a browser
|
|
122
|
+
over the branch structure *inside the current conversation*, where you navigate
|
|
123
|
+
to an earlier node, summarise a branch, or elide a span. Typed commands cover
|
|
124
|
+
the rest: `/compact`, `/tree`, `/fork`, `/extensions`.
|
|
125
|
+
|
|
126
|
+
## Why it is a separate package
|
|
127
|
+
|
|
128
|
+
Everything here is presentation and process management. The agent lives in
|
|
129
|
+
`ffwf-tau-agent-core`, which has no Textual dependency and never imports this
|
|
130
|
+
package. `ffwf-tau-jmfts` is a peer rather than a dependency: `--store jmfts`
|
|
131
|
+
imports it lazily and fails at startup if it is absent, never falling back to
|
|
132
|
+
files without saying so.
|
|
133
|
+
|
|
134
|
+
If you want the agent rather than the interface, use the runtime directly:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
import asyncio
|
|
138
|
+
from tau_agent_core import create_agent_session
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
async def main():
|
|
142
|
+
session = create_agent_session(model="gpt-4o", tools=["read", "bash"])
|
|
143
|
+
print(await session.prompt("What is in this directory?"))
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
asyncio.run(main())
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Docs
|
|
150
|
+
|
|
151
|
+
- `docs/tau-coding-agent.md` — design notes for this package.
|
|
152
|
+
- `docs/CLI-PLAN.md` — the flag set and its status.
|
|
153
|
+
- `docs/REMOTE-CONTROL.md`, `docs/RPC-PROTOCOL.md` — `--mode rpc`.
|
|
154
|
+
- `docs/EXTENSIONS-WALKTHROUGH.md` — writing an extension to load with `-e`.
|
|
155
|
+
|
|
156
|
+
Repository: <https://github.com/jmccardle/tau>
|
|
157
|
+
|
|
158
|
+
## The rest of Tau
|
|
159
|
+
|
|
160
|
+
| Distribution | Imports as | What it is |
|
|
161
|
+
|---|---|---|
|
|
162
|
+
| `ffwf-tau-llm` | `tau_llm` | the provider and streaming layer |
|
|
163
|
+
| `ffwf-tau-agent-core` | `tau_agent_core` | the agent loop, tools, sessions, extensions |
|
|
164
|
+
| `ffwf-tau-jmfts` | `tau_jmfts` | a JMFTS-backed session store |
|
|
165
|
+
|
|
166
|
+
MIT © Fight Fire with Fire Robotics, LLC
|