Commit Graph

7 Commits

Author SHA1 Message Date
Frowtek 6dec4bfc88 fix(tui_gateway): install the parent profile's secret scope on session.branch
alongside every set_hermes_home_override() call site on the tui_gateway
path, and converted session.create, session.resume (both the _make_agent
and _init_session scopes), the lazy _build resume and the per-turn submit
handler. session.branch was missed.

The branch handler already binds the parent's HERMES_HOME and its
profile-scoped state.db — its own comment says it mirrors
session.create/resume — but builds the branched agent with no secret scope.
get_secret() then falls through to process os.environ, which in an
app-global/remote backend is the LAUNCH profile's environment: a session
branched off profile X authenticates with profile Y's credentials. That is
the same cross-profile resolution #67605 fixed for the sibling paths, and it
is silent (multiplexing is only activated by the messaging gateway, so the
fail-closed UnscopedSecretError path never fires here).

Install set_secret_scope(build_profile_secret_scope(parent_home)) for the
build and release it in the same finally block as the home override.

Salvage-note: code relocated from tui_gateway/server.py to tui_gateway/methods_session.py (session handlers moved after the PR was opened); test patch targets unchanged — HandlerRegistry rebinds handlers onto server.py globals
2026-08-02 10:01:16 -07:00
Shaun Prince d15b638a88 fix(compression): let explicit interrupts cancel safely
Makes interrupt-protected context compression cancellable by an explicit
user or lifecycle stop, without weakening protection against ordinary
incoming messages, voice interjections, or active-turn redirects.

Separates explicit hard cancellation from ordinary interrupt/redirect
state with a dedicated threading.Event; introduces
AuxiliaryExplicitCancellation as an attempt-local frozen-cause signal;
isolates the synchronous provider callback in a bounded daemon worker
during protected compression; atomically linearizes Codex timeout
cleanup against explicit cancellation; propagates hard cancellation
through child agents and explicit stop surfaces; serializes hard-cancel
admission against compression commit admission with
CompressionCommitFence; aborts before session rotation or late DB commit,
restores in-place transcript mutations and compressor state, and releases
the heartbeat and compression lease.

Based on #74449 by @suparious. Resolved merge conflicts in
agent/context_compressor.py (feasibility check + try/except) and
tui_gateway/methods_session.py.
2026-08-02 22:15:20 +05:30
fyzanshaik d50858584c fix(tui): preserve queued image ownership 2026-08-01 15:58:42 +05:30
Brooklyn Nicholson e41d2029b7 fix(sessions): keep kanban worker runs out of the session lists
Exclude the source from the desktop sidebar and project tree, the TUI
resume picker, session_search, and the CLI session listings.
2026-07-31 13:53:04 -05:00
Brooklyn Nicholson 5ecc35f9bb fix(tests): teach gateway-server fakes the include_row_ids kwarg
Slice 1 fell over on eight DB fakes with frozen get_messages_as_conversation
signatures — the new opt-in kwarg is part of the method's contract now, so
the fakes accept **_kwargs like the real SessionDB. Also opts the child-watch
resume projection into row ids: it feeds the same _history_to_messages as the
desktop resume, so reactions on a watched child session address rows the same
way.
2026-07-30 00:08:28 -05:00
Brooklyn Nicholson 7d92056c49 feat(gateway): iMessage-style message reactions — storage, RPC, agent tool, model context
Reactions live in the existing messages.display_metadata JSON column (no new
table), with iOS Tapback semantics enforced DB-side: one reaction per author
per message, re-tap retracts, different emoji replaces. The desktop catches up
to the reaction contract five platform adapters already ship.

- SessionDB: set/get_message_reaction, latest_message_row_id (role + offset +
  require_text so invisible tool-call-only rows are never targeted),
  take_unseen_reactions (announce-exactly-once), get_message_role
- message.react RPC: accepts row_id or newest_role for live messages that
  haven't learned their durable id yet
- react_to_message tool: desktop-gated (check_fn), defaults to the user's
  latest visible message, messages_back for retroactive reactions
- Model context rides run_message only (beside the speech-interrupted note):
  the persisted prompt stays clean, so no [The user reacted …] scaffolding in
  transcripts, and no cached prefix ever changes
- Resume projection forwards row_id + reactions; _row_id is stripped from
  outgoing API copies next to display_metadata
2026-07-30 00:08:28 -05:00
teknium1 f67ca220ab refactor(tui): split @method handlers into methods_* modules (mechanical move, registry set-equality verified) 2026-07-29 11:46:31 -07:00