fix(tui): close notification lifecycle races - #4
Conversation
…lity docs The reset keywords have existed in both CLI and gateway handlers since June but were undocumented — users couldn't find how to cancel a personality overlay. Adds a 'Resetting to the default' section to the personality feature page and mentions the reset in the CLI guide, slash-command reference (both tables), and messaging command table.
|
Closed as an accidental fork-to-fork PR. The upstream replacement is NousResearch#77963. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a24828c984
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if session.get("_finalized"): | ||
| return _err(rid, 4001, "session not found") |
There was a problem hiding this comment.
Release leases before rejecting finalized submissions
When session.close finalizes immediately after _sess_nowait() but before this new guard, _ensure_active_session_slot() at line 114 can acquire and store a lease after _finalize_session() has already performed its only release. This return then leaves that lease in active_sessions.json; ActiveSessionLease has no destructor and the finalized session is no longer registered for later teardown, so repeated close/submit races permanently consume the configured session cap and eventually block new CLI, desktop, or gateway sessions. Check finalization before acquiring the slot and make the acquisition/finalization boundary atomic, or explicitly release the lease on this rejection path.
AGENTS.md reference: AGENTS.md:L54-L57
Useful? React with 👍 / 👎.
| | `/model [provider:model]` | Show or change the model. Supports provider switches (`/model zai:glm-5`), custom endpoints (`/model custom:model`), named custom providers (`/model custom:local:qwen`), auto-detect (`/model custom`), and user-defined aliases (`/model fav`, `/model grok` — see [Custom model aliases](#custom-model-aliases)). Use `--global` to persist the change to config.yaml. **Note:** `/model` can only switch between already-configured providers. To add a new provider or set up API keys, use `hermes model` from your terminal (outside the chat session). **Cost note:** a mid-session model switch resets the prompt cache (the cache key includes the model), so the next message re-reads the whole conversation at full input price. | | ||
| | `/codex-runtime [auto\|codex_app_server\|on\|off]` | Toggle the optional [Codex app-server runtime](../user-guide/features/codex-app-server-runtime). Persists to `model.openai_runtime` in config.yaml and evicts the cached agent so the next message picks up the new runtime. Effective on next session. | | ||
| | `/personality [name]` | Set a personality overlay for the session. | | ||
| | `/personality [name]` | Set a personality overlay for the session. `/personality none` (or `default` / `neutral`) clears it. | |
There was a problem hiding this comment.
Handle messaging resets before requiring presets
This new messaging documentation is false when agent.personalities is empty, which is the raw gateway-config default. In gateway/slash_commands.py, _handle_personality_command() returns gateway.personality.none_configured at line 2507 before reaching the none/default/neutral reset branch at line 2532, so a user who previously selected a built-in personality through the CLI cannot clear that saved agent.system_prompt from Telegram, Discord, or another messaging surface as documented. Process reset aliases before the empty-personalities guard, or restrict the documentation to surfaces where reset currently works.
Useful? React with 👍 / 👎.
Recreates the closed NousResearch#69035 change on the restored fork, rebased onto current
main, with the reviewer feedback folded in.The current main collector remains the single Kanban notification path; this does not reintroduce the duplicate poller. Session finalization now claims
_finalizedunderhistory_lock, and prompt submission, busy-queue acceptance, goal continuations, and post-turn notification drains all fail closed when finalization wins the race. Notification cursor claims still compose with the caller's delivery transaction.Original PR/review: NousResearch#69035
Verification:
pytest -q tests/test_tui_gateway_server.py(519 passed), including 40 finalization/prompt-submit race tests.