Files
tai/AGENTS.md
T
retoor 67d4806d82 v1.44.0: extensive debug logging behind --debug
- Rules first in logging.md: R1-R12 plus a 27-event registry, every
  site validated against the source before implementation.
- DebugLog: file/stdout/stderr sinks, sentence/json formats,
  wipe-on-first-write for roots, append for TAI_CHILD, per-row
  commit, prune to 20000 rows, never raises.
- Vault logs table with six indexes plus FTS triggers, sealed at
  rest, read back through Store.log_query.
- Hooks: turns, completions (backend, model, ms, tokens, texts),
  tool dispatch, approvals, vault mutations, scheduler, serve,
  CAP turns, telegram updates, uncaught exceptions.
- Secrets never logged: redact plus LOG_MASKED_ARGS.
- 13 new tests (1222 + 16 green).
2026-10-18 21:53:03 +02:00

7.9 KiB

AGENTS.md

Conventions

  • Use plain import and from statements in Python files.
  • Use the .py extension for Python source and test files.
  • tai.py is the entire product in one standalone stdlib-only file: CLI entry plus the stable import tai surface, grouped into classes (instance classes for stateful clusters, static utility classes for stateless groups). It must import nothing outside the standard library; a bare copy of the file has to import and run anywhere. Canonical patch targets are tai.<Class>.<name> (or the module attribute for module-level data).
  • There are two kinds of test, in two different places, on purpose — see "Testing" below for the full split. In short: unit tests are top-level test_*.py; integration tests are tests/<topic>.py (no test_ prefix) built on tai_test.py.
  • The in-tai.py TUI framework is documented in tui.md — read it before touching any Tui* code.
  • The grr terminal client (tai.py --tui, the Grr* classes) is specified in grrtui.md: read it before touching any Grr* code, and keep its screen, key and cap tables in step with the code (GrrSpecTests fails when they drift). It is a client of the grr server and shows what the server's /api/spec and /locales.json say; never copy a string, color or limit of the server into tai.py. tests/grr_tui.py drives the real binary against a real grr server (sibling ../grr, GRR_DIR to move it) and a real model.
  • The terminal multiplexer (Mplex* classes, tai.py --mplex, ~/.tai/mplex.toml) is specified in mplex.md: read it before touching any Mplex* code, and keep its option, command and key tables in step with the code (MplexSpecTests fails when they drift).
  • Interactive UI flows (plexer_show, PlexerFlow, PlexerController.ask, the show/result/cancel control commands) are specified in uiflow.md: read it before touching any flow code, and keep its contract and cap tables in step with the code (UiflowDocTests fails when they drift).
  • CAP protocol support (Cap* classes, --cap-manifest, --cap-speak, orchestrator drivers) is specified in cap.md: read it before touching any Cap* code, and keep its event, error and manifest tables in step with the code (CapDocTests fails when they drift).
  • MCP support (Mcp* classes, mcp_* tools, --serve-mcp) is specified in mcp.md: read it before touching any Mcp* code, and keep its wire, caps, and tool tables in step with the code (McpDocTests fails when they drift).
  • Skills (discover_skills, SKILL_BLUEPRINTS, BUNDLED_SKILLS, the skills install target) are specified in skills.md: read it before touching skill code or embedded skill text, and keep its bundled-skill and adaptation tables in step with the code (BundledSkillsTests fails when they drift).
  • Settings (SETTINGS_CATALOG, the settings table, get_or_create_settings/upsert_settings/get_all_settings, boot_settings) are specified in settings.md: read it before touching settings code, and keep its catalog table in step with the code (SettingsTests fails when they drift).
  • Debug logging (DebugLog, the module-global LOG, --debug/--debug-format, the logs table) is specified in logging.md: read it before touching logging code, and keep its rules, registry, and cap tables in step with the code (LoggingDocTests fails when they drift).

Testing

Unit tests: test_tai.py, test_seal.py, at the repository top level, named test_*.py, unittest-based, import tai.py as a module directly, no subprocess, fast. python3 test_tai.py / python3 test_seal.py, or a single test via python3 -m unittest test_tai.SomeClass.test_method.

Integration tests: tests/<topic>.py (e.g. tests/rag.py), deliberately not named test_*.py and not at the top level, so the two kinds are never confused. These drive the real tai.py binary as a subprocess (one-shot or REPL) and check actual CLI behavior, using tai_test.py (the framework, at the repository root) as the one and only base to build on — never a one-off subprocess/asyncio harness per file. They must exercise a real LLM call through the real binary — never a mocked model or a database write standing in for what the agent would have done; the resulting flakiness from a free, rotating backend is accepted, not engineered away. Full conventions, that rule's full rationale, the required isolation rule (always a throwaway TAI_HOME), and why verification must check vault state rather than scrape CLI rendering, are in tests/README.md — read it before adding a new one. Run with python3 tests/<topic>.py (--filter, --interactive, --timeout all supported).

Profiles and bots

  • A profile is a user-created identity (--profile NAME, /profile NAME); default is the fallback when none is given. Each profile owns a separate slice of every vault table; the only cross-profile knowledge is the identity list itself.
  • A bot is a role inside one profile. Every profile starts with main; more are added with create_bot. There are no built-in bots.

Key Features

  • Autonomous decision making
  • Multi-profile support
  • Background subagent orchestration
  • Secure vault storage
  • Container sandbox support
  • Progress tracking
  • Interactive REPL
  • Command-line interface

Usage Examples

  1. Start the main agent:

    ./tai.py
    
  2. Use a specific profile:

    ./tai.py --profile work
    
  3. Run a one-shot command:

    ./tai.py what is 2+3, use the shell
    
  4. Check agent status:

    ./tai.py --version
    
  5. Install the agent:

    ./tai.py --install
    

Development Guidelines

  • Write clear, concise code
  • Follow Python conventions
  • Test thoroughly
  • Use the agent for documentation
  • Keep code maintainable
  • Document decisions
  • Version control changes
  • Collaborate effectively

Command Output Rule

Every command an agent runs for the user (shell, ssh, sandbox box) must stream live to the user in both modes, in addition to being returned to the agent. It is a message, not a blocking spinner: a fixed-height window (REPL LiveStream, chat TUI live block) that keeps scrolling its last lines in place while the user keeps chatting. If the command stops on a prompt (sudo, ssh, y/n), it runs on a pty and asks the user through the same channel as ask_user (agent.prompter / REPL input); the answer is typed into the command, a decline sends end-of-file, and waiting for the user never counts against the timeout. Any new tool that runs a process must go through run_live with Tools.shell_stream and Tools.shell_ask, never a bare subprocess.run. Details: tui.md (chat scene).

Research Rule

All external research conducted for this project (web searches, reading documentation to settle a design question, competitive/prior-art analysis) is archived under research/, maintained under the auspices of the Molodetz Institute — Research & Retrieval Division. The full specification — folder layout, the three required document types (Source Dossier, Source Citation Card, Conclusion Document), required metadata, and the quality bar — lives in research/README.md; research/INDEX.md is the living registry and statistics page. Read research/README.md in full before writing into this archive.

The binding rule, in short: a research task is not done until it is written into research/. Every source actually consulted gets its own document (Tier 1 if read and synthesized, Tier 2 if only seen in a result listing — never skipped, never inflated past what's actually known), every decision the research produced gets its own Conclusion document in that subject's conclusions/ folder, and research/INDEX.md gets updated in the same pass. Check research/INDEX.md for an existing subject before opening a new one.