New sessions/session_export tools plus a sessions_block vault map in the system prompt (tai.py, ported to detz); recall/search carry a session footer instead of letting the model grep sealed bytes. write_file refuses new markdown at working/repo roots, and the blanket *.md gitignore is gone so docs stay visible. One LineInput owns fd 0 for every prompt (ask, approvals, shell_ask, secrets), ending phantom-empty answers; Ctrl-C re-prompts (double exits), Ctrl-D exits, Ctrl-Z suspends; mid-turn Ctrl-C announces itself and kills foreground shell children via RunInterrupted. Covered by SessionsTests, repl_keys.py pty checks, agent_diff sessions_block cases.
4.4 KiB
4.4 KiB
agent: Agent core, Tools, goal verifier, RAG stats, scheduler
Literal port of tai.py 1.44.2 (lines 9016-9335, 17071-20640, 40391-40460). Namespace detz::agent, sources in src/agent.
Layout
| File | tai.py origin |
|---|---|
data.cpp (generated) |
TOOL_SCHEMAS, TOOL_TAGS, CORE_TOOLS, LAZY_NAME_STOP, prompt texts. Regenerate: python3 -I src/agent/gen/gen_data.py > src/agent/data.cpp |
data_html.cpp (generated) |
html.entities.html5 for html.unescape |
agent.cpp/.h |
Agent, select_tools, tool_catalog, compact_messages, resume_turn, update_models_command, default_runner, mentions |
tools_*.cpp, tools.h |
Tools (63 handlers, dispatch, secrets, audit, box helpers) |
goal.cpp |
Denied, AgentsFull, Approval, GoalFailure, GoalVerdict, GoalVerifier |
rag.cpp |
RetrievalEval, RagStats |
registry.cpp |
spawn_agent, poll_agent, list_agents, clear_agents, running_agents |
scheduler.cpp |
note_schedule_result, watch_schedule, schedule_running, scheduler_tick, run_scheduler_loop/start_scheduler (class Scheduler) |
text.cpp |
truncate-family helpers, tags, chunk_lines, spill_*, tmux/history helpers, html.unescape, schedule helpers |
tui_control.cpp |
grr_control_path, grr_control_call (client only) |
zipfile.cpp |
zipfile.extractall (stored + deflate) for install_skill |
ports.h |
the narrow interfaces to everything this module does not own |
Ports (declared here, implemented elsewhere)
StorePort (mirrors Python Store method names), RuntimePort (worker store), ShellPort (run_live, LiveStream, LaneBoard, box), UiPort (Spinner, Glow, markdown, diff; optional, plain fallbacks exist), McpPort, SkillsPort, PlexerPort, TuiControlPort (optional, built-in client otherwise), OpsPort (install, release, sysinfo, speech), SchedulerDbPort. Unwired required ports raise PortNotWired, shown to the model as error: port not wired: X. Plexer unwired means "no session", exactly like no tmux.
Behaviour notes
- All string lengths and slices are code points (
detz::py,src/llm/py.h). - Integers beyond int64 clamp in
int()conversions (Python is unbounded); JSON keeps big ints verbatim. html.unescape,str.lower/upper(including final sigma) use tables generated from Python.
Verification (what was actually run)
tests/agent_diff.py: 7604 cases per seed (seeds 1-4 run, 0 mismatches). Includes the fulljson.dumps(TOOL_SCHEMAS)byte comparison,select_toolson 24 prompts plus fuzz,tool_catalog, all prompt texts, goal verdicts, CLI output parsers, history cleanup, tag helpers, html/url helpers, schedule helpers, candidate ordering ofChatClient,sessions_blockbyte comparison.tests/agent_e2e.py: 43 scripted conversations through the real Agent loop in both programs (messages, HTTP request bodies, store events, audit rows identical). Covers file tools, shell, secrets, schedules, bots/mentions, compaction, retries, 400 tool fallback, ask_user, approval deny, verify loop, remember, web_fetch/search, fork/poll, streaming quirks, deadline.tests/agent_sched.py:scheduler_tickagainst a real sqlite vault.- Build for these tests: compile
src/llm/*.cpp src/agent/*.cpp tests/agent_*.cppwith-lcurl -lpthread(see wiring doc).
Not verified / gaps (honest list)
- Tools needing FTS or other modules were only checked on argument validation paths:
search,record_search,graph_*,tags,recall,auditsearch,export_terminal_log. - Port-backed tools (MCP, skills install/create, plexer, install, release, sysinfo, speak, listen, sandbox
box_*paths, LaneBoard) are ported but no test drives a real implementation: the ports are fakes or unwired. RagStats/RetrievalEvalcompile and follow the Python line by line but have no differential test (needs a real vault).- Interactive tty paths (
ask_approvalconsole branch withDeniedguidance,shell_askgetpass) are unexercised. - urllib error strings are approximated from libcurl codes (
<urlopen error [Errno 111] Connection refused>etc.). - Muse session map/locking and CLI runners (
muse_run, grok, claude, codex, gemini, opencode) are ported; only their output parsers are differentially tested, the process runners were not run against the real CLIs. zipfile: bzip2/lzma members unsupported.str.lowerfinal-sigma uses derived property sets;reprprintable test is approximated for exotic code points.