Commit Graph

1879 Commits

Author SHA1 Message Date
Teknium 53db597201 simplify(compat): hermes_state — drop 81 re-exports + 3 registry aliases + 3 shims, repoint 45 callers + 60 test files
hermes_state.py: delete every '# noqa: F401 (re-exported...)' import block (hermes_state_common/errors/guard/
readpool/sessions/fts/dbfile/wal/repair/registry + agent.context_compressor _DB_PERSISTED_MARKER_KEY); keep
only the names hermes_state.py itself uses, without noqa.
hermes_state_registry.py: drop get_shared_session_db/release_shared_session_db/close_shared_session_dbs
aliases; every caller (gateway/, tools/, tui_gateway/, cron/, mcp_serve, run_agent, tests) now imports
acquire/release/close_all/release_or_close from hermes_state_registry.
hermes_state_titles.py: drop set_auto_title_if_empty shim (title_generator keeps its getattr fallback).
Re-remove shim-only names restored by 34abf954bd: latest_user_message_row_id (tests call
latest_message_row_id(key, role='user'); role-targeting assertions kept) and get_session_activity (tests
build the snapshot via agent.session_activity.build_activity_snapshot over db.get_session(sid)).
hermes_state_wal._log_once resolves its dedupe sets as module globals instead of via hermes_state;
hermes_state_repair helpers call module globals directly (tests patch hermes_state_repair.<name>).
Frozen updater surface untouched (update_cmd_maint imports only SessionDB from hermes_state).
2026-09-03 13:46:50 -07:00
Teknium a9b0dd6742 simplify(compat): cron scheduler — drop 82 re-exports, repoint 8 callers + 33 test files
cron/scheduler.py no longer re-exports the split modules (scheduler_delivery /
_script / _prompt / _preflight); it imports only the 19 names it calls itself
(bottom-of-file, E402 kept for the import cycle). Dropped the shim-only
`import shutil` and the F401 note on windows_hide_flags (still used by
scheduler.py). Split modules now call same-module helpers directly, reach
sibling split modules via late-bound module refs (_delivery/_script/_preflight)
next to _sched, and import windows_hide_flags themselves; origin-resident names
(load_config, Path, _SCRIPT_TIMEOUT, heartbeat_run_claim, ...) still go through
_sched. Callers/tests import + patch the defining module.
2026-09-03 13:38:36 -07:00
Teknium 491e53ef3c simplify(compat): tool_search/skills_sync_client — drop 22 re-exports, repoint 5 callers + 5 test files; drop stale re-export prose in web_tools_truncate/file_operations_lint 2026-09-03 13:33:47 -07:00
Teknium fcbe4acbef simplify(compat): tools/mcp_tool — repoint 20 non-test callers to the defining mcp_tool_* siblings 2026-09-03 13:29:35 -07:00
Teknium 2a95791992 simplify(compat): run_agent/model_tools/toolsets/acp/providers — drop 42 re-exports/aliases, repoint 15 callers + 99 test files
run_agent.py: delete the `# noqa: F401` re-export block (agent.process_bootstrap
OpenAI/_SafeWriter/_get_proxy_*, model_tools get_tool_definitions/
handle_function_call/check_toolset_requirements, FailoverReason,
_qwen_portal_headers/_routermint_headers, session_persistence names,
estimate_request_tokens_rough, ContextCompressor + friends, jittered_backoff,
prompt_builder names, message_sanitization names, tool_dispatch_helpers
names) — 41 names run_agent never used itself — and the `_STREAM_DIAG_HEADERS`
back-compat class alias (no in-tree reader). run_agent now imports only what
it uses (get_toolset_for_tool, is_local_endpoint, coalesce/uniquify tool-call
ids, cleanup_vm/get_active_env from terminal_tool_lifecycle).

agent/*: `_ra().X` late-binds that only reached a re-export now import the
defining module directly (agent_runtime_helpers -> process_bootstrap.OpenAI,
model_tools.handle_function_call, session_persistence._safe_session_filename_component;
agent_init -> model_tools.get_tool_definitions/check_toolset_requirements,
_lazy_headers("agent.client_lifecycle", ...) for qwen/routermint;
system_prompt -> agent.prompt_builder / model_tools directly, dropping its
own _ra() shim and the `_r` parameter threading). `_ra()` stays for
run_agent-resident names (logger, AIAgent, _hermes_home, _set_interrupt, ...).

toolsets.py: remove resolve_multiple_toolsets (shim-only, restored by
34abf954bd); tests/test_toolsets.py pins the same union behavior via
resolve_toolset over each name.

providers/__init__.py: drop the OMIT_TEMPERATURE re-export (no callers via the
package); ProviderProfile stays because __init__ uses it for annotations —
2 tests repointed to providers.base.

agent/iteration_budget.py: drop the "run_agent re-exports the class"
docstring pointer; 4 tests import IterationBudget from its home.

model_tools.py (arg_coercion names), agent/tool_executor.py, and
hermes_cli/cli_session_mixin.py repoints landed via a sibling commit on this
shared worktree.

Callers repointed: gateway/run.py, hermes_cli/cli_chat_turn_mixin.py,
hermes_cli/cli_tui_mixin.py, tui_gateway/session_workdir.py,
agent/transports/codex.py (one-line imports) + comment pointers in
tools/file_state.py, tools/schema_sanitizer.py, scripts/tool_search_livetest.py.
Tests: patch("run_agent.X") / monkeypatch.setattr(run_agent, "X") /
`from run_agent import X` -> defining module across 99 test files.
2026-09-03 13:28:22 -07:00
Teknium 00a3cfe5c9 simplify(compat): hermes_cli split-module docstrings — drop 're-exported there' compat pointers (9 files, comments only) 2026-09-03 13:08:40 -07:00
Teknium e83816a4d1 review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged)
For each issue anchor present in BASE 63279301bc non-test .py and absent on HEAD, the BASE comment/docstring block was re-attached at the HEAD location of the code it explained (matched by the distinctive code line / enclosing def). Sentences already covered by an existing HEAD comment were deduped; the issue number always survives. Insert-only: no code lines changed.
2026-09-03 09:44:26 -07:00
Teknium 0071ba9965 Merge origin/main (561b053f79) into simp/forwardport: forward-port 220 main commits into the simplified tree 2026-09-03 03:31:03 -07:00
Brooklyn Nicholson 83efdf5e5e [verified] fix(cron): close restart handoff races 2026-09-03 12:40:26 +05:30
Brooklyn Nicholson 29e5172487 [verified] fix(cron): harden gateway restart handoff 2026-09-03 12:40:26 +05:30
Brooklyn Nicholson 3373e97693 [verified] fix(cron): preserve active runs across gateway restart 2026-09-03 12:40:26 +05:30
kshitijk4poor 914d8a0bd6 fix(recovery): name the real state.db in the copy-pasteable recovery banners
The gateway broadcast and turn-failure explanation printed a literal
~/.hermes/state.db; now that the line is a command the operator is meant to
run as-is, interpolate _default_db_path() so profile / HERMES_HOME installs are
pointed at the store that actually failed. Also: split a comment that a merge
fused onto the logger line in session_lost_and_found.py, and fix an inverted
test docstring.
2026-09-03 11:28:21 +05:30
sal a15f96450b fix(recovery): make the printed salvage command satisfy the real CLI contract
Review blocker on e62940d: every state-db guidance site printed

  hermes sessions recover --source <db>

but cmd_sessions rejects that shape with exit 2 ("--output is required
unless --inspect-only is used") before any snapshot is taken — the user
follows the instruction during a corruption incident and gets nothing.

All five state-db sites now print the established two-stage operator
contract (the same shape `sessions repair` failure output and
docs/state-db-recovery.md already use):

  hermes sessions recover --source <db> --inspect-only
  hermes sessions recover --source <db> --output recovered-state.db

with the stop-the-gateway precondition stated for the gateway/turn
banners, and --inspect-only leading in the hermes_state refusal strings
(inspection before writing anything).

New TestEmittedCommandsSatisfyCliContract dispatches the exact emitted
flag shapes through the real cmd_sessions and asserts they pass the
contract gate (rc != 2) on a scratch DB, plus a premise test pinning
that the v1 no-flag shape is still rejected with rc 2 — so a guidance
string can never again pass a source-substring test while the command
it prints deterministically fails.

Noted for merge order: #101423 and #101168 also touch
hermes_cli/session_recovery.py. They are complementary recovery-integrity
work, not duplicates of this guidance/gate fix; whichever lands second
should rebase and rerun the lost_and_found + session-recovery suites.

(cherry picked from commit 34dc59a284509e76a0342c36d03a2a437aa8a3b9)
2026-09-03 11:28:21 +05:30
sal 5d9a2110ba fix(recovery): stop pointing sqlite3 .recover guidance at the live state.db
Refs #100368. The forensics thread established that a sqlite3 CLI with
the WAL-reset opener bug (fixed 3.51.3+ / backports 3.50.7 / 3.44.6;
Debian/Ubuntu system shells 3.45.1/3.46.1 are in the vulnerable band)
unlinks the live -wal/-shm pair when pointed at a live state.db whose
writer's DMS lock has been cancelled, splitting the store into two
concurrent generations whose acknowledged writes vanish while both
report integrity_check ok. Hermes' own corruption banners instructed
exactly that command.

- gateway corruption broadcast, run_agent corrupt-cause explanation,
  hermes_state repair-budget and forensic-backup refusals, and the
  kanban manual-recovery hint now route operators to
  `hermes sessions recover --source <db>` (which snapshots the damaged
  bundle before any shell touches it) and warn against a raw sqlite3
  shell on the live file
- find_sqlite3_cli() now refuses a WAL-reset-vulnerable shell for the
  page-level salvage lane even on the snapshot, reusing the canonical
  gate from hermes_cli.sqlite_runtime so the embedded runtime and the
  salvage shell can never disagree
- find_sqlite3_cli_refusal() records why a shell was refused so the
  lost_and_found lane can tell the operator exactly what to install
  instead of a generic "not found"
- regression tests cover the version gate (vulnerable/fixed matrix, the
  mirror check), every refusal reason, and each guidance site

Test plan:
- scripts/run_tests.sh tests/hermes_cli/test_sqlite3_cli_salvage_gate.py
  tests/test_state_db_repair_loop_cap.py
  tests/run_agent/test_corruption_recovery_guidance.py
  tests/hermes_cli/test_session_recovery_lost_and_found.py
  tests/hermes_cli/test_session_recovery.py tests/test_sqlite_wal_reset_gate.py
  tests/hermes_cli/test_sqlite_runtime.py - 91 passed, 1 skipped locally

(cherry picked from commit e62940d1021e80e9b7d6423ced1cbdfe7dd0c37d)
2026-09-03 11:28:21 +05:30
kshitijk4poor 25caae02c0 refactor(gateway): derive the compacting noisy-status match from the templates
Replaces the hand-transcribed regex fragment with re.escape of COMPACTION_STATUS
and COMPACTION_HEARTBEAT_STATUS, matching the COMPACTION_DONE_STATUS precedent
two lines down, so wording drift cannot desync the chat-platform gate.
2026-09-03 11:27:55 +05:30
kshitijk4poor 548e0ec923 fix(compression): route the heartbeat through the shared compaction status contract
The contributor heartbeat called status_callback("compacting", <ad-hoc text>).
Every other compaction status uses the "lifecycle" key: the TUI gateway
re-tags lifecycle statuses to kind="compacting" via
is_compaction_progress_status, Telegram edits one bubble per status key, and
gateway/run.py's chat-platform filter only recognises the registered
templates — so the ad-hoc text leaked to Telegram/Discord on every tick with
compression.progress_notices off (verified: _prepare_gateway_status_message
passed it through). Register COMPACTION_HEARTBEAT_STATUS next to
COMPACTION_STATUS, emit it under "lifecycle", and cover the filter.
2026-09-03 11:27:55 +05:30
Teknium 13e502357b refactor(gateway): wave-2 compaction of run.py runtime/model/skill/status helpers 2026-09-02 20:26:42 -07:00
Teknium 126ade8e45 refactor(gateway): wave-2 compaction of run.py header helpers, GatewayRunner and startup/shutdown tail 2026-09-02 20:22:32 -07:00
Teknium 924845b16c refactor(gateway): wave-2 compaction of run.py media/env/profile helpers (fuzzed parity) 2026-09-02 20:15:43 -07:00
Teknium 435e8b9ae1 refactor(gateway): fold docstring closers in run.py (text parity via cleandoc) 2026-09-02 19:58:01 -07:00
Teknium 054d466ee5 refactor(gateway): fold shutdown signal handler probes into _best_effort (81-case parity) 2026-09-02 19:55:01 -07:00
Teknium abf46f2e42 refactor(gateway): AST-neutral closer folding in run.py 2026-09-02 19:49:42 -07:00
Teknium 3be336aee7 refactor(gateway): table-drive start_gateway signal handler install; drop getattr on always-present watchdog 2026-09-02 19:45:58 -07:00
Teknium bbc61dce26 refactor(gateway): compact run.py comments/docstrings (helpers between media tags and GatewayRunner); ruff SIM102 clean 2026-09-02 19:41:31 -07:00
Teknium 7befd2afd3 refactor(gateway): compact run.py docstrings/comments (module helpers + GatewayRunner), keep every WHY 2026-09-02 19:37:11 -07:00
Teknium f0d579cc0b refactor(gateway): extract cached-agent lookup from run_codex_hygiene_compaction 2026-09-02 19:11:29 -07:00
Teknium b64d0c7602 refactor(gateway): phase helpers for _resolve_gateway_model_context (differentially fuzzed, 3072 cases) 2026-09-02 19:08:44 -07:00
Teknium 9610173c22 refactor(gateway): compact GatewayRunner init phases (chained flag defaults, tightened WHY comments) 2026-09-02 19:04:59 -07:00
Teknium 1cf3c5d582 refactor(gateway): fold try/except-log startup steps into _best_effort; refuse() closure for --replace ownership 2026-09-02 19:00:37 -07:00
Teknium 7199cfc927 refactor(gateway): join implicit string concatenations in run.py 2026-09-02 18:49:35 -07:00
Teknium 13a9574a6c refactor(gateway): strip orphaned section headers from GatewayRunner; group mixin tunables 2026-09-02 18:39:04 -07:00
Teknium e5a71229c9 refactor(gateway): AST-neutral bracket packing in run.py 2026-09-02 18:33:17 -07:00
Teknium a49d85bc75 refactor(gateway): table-drive housekeeping chores; collapse --replace takeover flow 2026-09-02 18:30:12 -07:00
Teknium 2ac81da48e refactor(gateway): table-drive the run.py config->env bridge; share loader with per-turn max_turns re-bridge 2026-09-02 18:25:16 -07:00
Teknium a1f134730f refactor(gateway): dedupe run.py regex tables, runtime-kwargs builders, media-kind predicates 2026-09-02 18:21:37 -07:00
Teknium 4ad1c6c1be refactor(gateway): drop dead GatewayRunner._has_setup_skill (no production caller; tests only stub it) 2026-09-02 16:26:11 -07:00
Teknium 66366d3dab refactor(gateway): split GatewayRunner into 13 run_* mixins + TurnRunner module (run.py 31332 -> 6957)
AST-driven, body-identical move of 359 GatewayRunner methods into cohesive
mixin modules (gateway/run_{voice,adapters,topics,turn,shutdown,busy,
config_loaders,startup,watchers,notifications,inbound,goals,agent_cache}.py)
plus TurnRunner -> gateway/run_turn_runner.py. run.py-internal symbols are
imported lazily inside method bodies so patch('gateway.run.X') keeps
intercepting; neutral deps are top-level; logger name stays 'gateway.run'.
_UNSET moved to leaf gateway/run_common.py (def-time default-arg sentinel).
Whole-module inspect.getsource(gateway_run) AST-walker tests repointed to
the module that now holds the walked code.
2026-09-02 16:11:50 -07:00
Teknium b3759fa8d6 Merge branch 'simp/r2-gwrun-hmwa' into simp/r2-gwrun 2026-09-02 15:57:24 -07:00
Teknium 94af71400d Merge branch 'simp/r2-gwrun-rai' into simp/r2-gwrun 2026-09-02 15:57:23 -07:00
Teknium 6e4e1674e4 Merge branch 'simp/r2-gwrun-runsync' into simp/r2-gwrun 2026-09-02 15:57:22 -07:00
Teknium 0b3f9ae7b3 Merge branch 'simp/r2-gwrun-hm' into simp/r2-gwrun 2026-09-02 15:57:20 -07:00
Teknium 95801ab139 Merge branch 'simp/r2-gwrun-busyprep' into simp/r2-gwrun 2026-09-02 15:57:19 -07:00
Teknium 4e8daa54f9 Merge branch 'simp/r2-gwrun-startgw' into simp/r2-gwrun 2026-09-02 15:57:18 -07:00
Teknium 98a528a65a refactor(gateway): split _handle_message_with_agent into _hmwa_* helpers (2365 -> 242 LOC, max helper 249) 2026-09-02 15:50:25 -07:00
Teknium f92267f6f6 refactor(gateway): split TurnRunner.send_progress_messages into state carrier + 8 helpers (333 -> 168 LOC) 2026-09-02 15:49:24 -07:00
Teknium b3ad91bef0 refactor(gateway): split GatewayRunner._run_agent_inner into 24 helper methods (1638 -> 241 LOC) 2026-09-02 15:43:35 -07:00
Teknium a0556c7ef1 refactor(gateway): split TurnRunner.run_sync into 11 helper methods (1229 -> 211 LOC) 2026-09-02 15:42:16 -07:00
Teknium 99164fca16 refactor(gateway): split GatewayRunner._handle_message into _hm_* stage helpers
1361 -> 186 LOC orchestrator; 11 contiguous helpers (ingress/auth admit, estop gate,
update-prompt / clarify / slash-confirm replies, stale-agent eviction, running-session
fast-path, command resolve+hooks, canonical dispatch, quick+plugin commands, skill
slash rewrite). Bodies are verbatim; early returns become Optional / (handled, result)
tuples the orchestrator returns as-is. Largest function in the region: 195 LOC.
2026-09-02 15:40:08 -07:00
Teknium c4250a6660 refactor(gateway): split GatewayRunner.start/stop into phase helpers (878/622 -> 75/90 LOC) 2026-09-02 15:33:05 -07:00
Teknium e3bda94407 refactor(gateway): split _handle_active_session_busy_message and _prepare_inbound_message_text into helpers 2026-09-02 15:32:53 -07:00