sessions: vault discovery tools, shared stdin, ctrl-key fixes
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.
This commit is contained in:
@@ -53,6 +53,7 @@ The `shell_sessions` table records every shell id with its parent chain
|
||||
|---|---|
|
||||
| `SCHEMA`, `SCHEMA_INDEXES`, `ensure_schema`, `migrate_profiles`, `rebuild_with_profile`, `table_pk_columns`, `ensure_column`, `setup_fts` | `Schema` |
|
||||
| `Store.*` (history, events, search, secrets, tags, graph, records, chunks, audit, schedules, files, bots, settings, mcp, dir defaults) | `Store` same method names |
|
||||
| `Store.list_sessions` | `Store::list_sessions` (bot, sid, path, mtime, message count, turn goal; newest first) |
|
||||
| `fts_escape`, `fts_match*`, `fts_rank` | `Fts` |
|
||||
| `normalize_tag(s)`, `singular_noun`, `tag_variants`, `parse_node_id` | `TagRules` |
|
||||
| `PROFILE_RE`, `BOT_RE`, `SECRET_RE`, `MCP_SERVER_RE` | `Patterns` |
|
||||
@@ -65,7 +66,7 @@ The `shell_sessions` table records every shell id with its parent chain
|
||||
| `get_or_create_settings`, `get_all_settings`, `upsert_settings` | `Store` |
|
||||
| `export_settings_to_env`, `boot_settings`, `Config.apply_store_settings` | `BootSettings::ExportToEnv`, `BootSettings::Boot`, `Config::ApplyStoreSettings` |
|
||||
| `Config`, `parse_backends`, `split_models`, `known_model_ids` | `Config::Build`/`FromEnv`, `ParseBackends`, `SplitModels`, `KnownModelIds` |
|
||||
| `DEFAULT_SYSTEM` and the other prompt texts, `orientation_block`, `capability_block` | `Prompts` (generated byte for byte from tai.py) |
|
||||
| `DEFAULT_SYSTEM` and the other prompt texts, `orientation_block`, `capability_block`, `sessions_block` | `Prompts` (generated byte for byte from tai.py) |
|
||||
| `ShellSession` | `session::ShellContext` |
|
||||
| `Agent.switch_profile`, `switch_bot`, `apply_system`, `reset_history`, `update_system`, `checkpoint`, `close_turn`, `mark_turn_open` | `session::Conversation` |
|
||||
| `apply_dir_defaults` | `session::DirDefaults::apply` |
|
||||
@@ -86,6 +87,12 @@ is the python "seal disabled" path.
|
||||
- `ShellSession` is named `ShellContext` because `detz::shell::ShellSession` is the command runner.
|
||||
- A bare `/` at the prompt prints "unknown command, try /help" (tai.py raises IndexError).
|
||||
- Without readline there is no line editing, arrow-key history or tab completion; `LineInput` is a plain line reader.
|
||||
- One `LineInput` owns fd 0: the REPL prompt, `ask_user`, approvals, shell_ask and secret reads all go through
|
||||
`LineInput::shared()`, because two buffered readers on one fd steal each other's bytes and poison each other's
|
||||
EOF state (the 0 ms phantom-empty answers). EOF is one-shot (a tty recovers, a closed pipe EOFs again) and the
|
||||
SIGINT flag counts arrivals so two rapid Ctrl-C are both observed.
|
||||
- Ctrl keys at the REPL prompt: Ctrl-C clears the line and re-prompts, a second Ctrl-C within 2 s exits 0;
|
||||
Ctrl-D exits 0; Ctrl-Z keeps the default SIGTSTP suspend (no handler installed).
|
||||
- `PlexerController::ask` takes the timeout as `Json` so an int stays an int on the wire like in python; a `double` overload exists.
|
||||
- Unbounded python bigints in JSON become doubles.
|
||||
|
||||
@@ -115,6 +122,7 @@ Run from `taicpp/`: `make -f tests/foundation.mk test` (needs only g++, sqlite3,
|
||||
|---|---|
|
||||
| `tests/foundation_parity.py` + `foundation_probe` | one scenario replayed through tai.py and the C++ store: results, every table, the FTS index, the schema DDL and every profile file identical (timestamps and random ids masked). Pure functions (JSON, tags, settings rules, prompts, chunking, shell context against a fake /proc, flow validator and driver, Glow pieces), DebugLog sinks, REPL slash commands, native plexer against a scripted backend, tmux against a private server, and vault portability (each implementation reads the vault the other wrote) |
|
||||
| `tests/repl_persist.py` + `repl_probe` | the history bug: the REPL started repeatedly under a long-lived shell per pane resumes the same session file, another pane stays separate (also in real tmux panes), Ctrl-C mid-turn, an uncaught exception reaching the debug log, a pinned `TAI_SESSION` is shared, an interrupted turn is resumed by `--continue`; every assertion reads the vault |
|
||||
| `tests/repl_keys.py` | Ctrl keys over a real pty against `build/detz`, no model: single Ctrl-C re-prompts, Ctrl-C aborts `/secret set` and the next prompt still reads, double Ctrl-C exits 0, Ctrl-D exits 0, Ctrl-Z suspends and SIGCONT resumes (via a session-keeping middle process, else the kernel discards SIGTSTP), session file saved |
|
||||
| `tests/tmux_ask.py` | tmux `ask` (menu, text popup, message, cancel, timeout) with a real client attached through a pty, both implementations, same replies |
|
||||
| `tests/foundation_test.cpp` | hash vectors, UTF-8 helpers, seal-enabled store paths with a stand-in seal, boot settings, dir defaults, turn files, plexer detection, line input |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user