feat(acp): adopt the cloud agent session lifecycle for resume and close and errors#536
Merged
Conversation
…, structured errors
The cloud agent (nori-handroll acp --type cloud) advertises
sessionCapabilities.{list,resume,close} with loadSession:false, but the
CLI never called session/resume or session/close, gated the agent-sourced
/resume picker on load_session (hiding every cloud session), and mapped
ACP errors by substring only.
- Project session_resume/session_close into AgentCapabilitiesView
- Reattach via session/resume when load is unsupported; never fall back
to session/new on a resume failure (it would claim a fresh cloud VM)
- /close: capability-gated release of the live session, new chat only on
success; session-switching commands blocked while the close is in flight
- Structured error mapping by JSON-RPC code (-32000 auth_required with
error.data.detail surfaced, -32002/-32010/-32012/-32014/-32015), code
wins over message heuristics; spawn/resume/close and prompt failures all
use it
- /resume picker gate is now session_list && (load_session || session_resume);
the cloud sentinel cwd "/" is hidden from picker rows
- Mock agent gains env-gated resume/close support and failure switches
🤖 Generated with Nori
🤖 Generated with [Nori](https://noriagentic.com)
Co-Authored-By: Nori <contact@tilework.tech>
…0204) New advisory published against crossbeam-epoch 0.9.18 (invalid pointer dereference in the fmt::Pointer/Display impls); lockfile-only patch bump per the advisory's recommended fix. cargo deny check advisories is green locally.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
🤖 Generated with Nori
session/resumesupport:AcpBackend::resume_sessiongains a third branch — when the agent advertisessessionCapabilities.resumebut notsession/load(the nori-cloud contract), reattach viasession/resumewith no silentsession/newfallback (on a cloud agent that would claim a brand-new VM). Branch order:load_session(replay) >session_resume(live reattach) > client-side transcript replay. The shared MCP-registration block was deduped into one helper across the four branches./closecommand: capability-gated onsessionCapabilities.close; releases the live session oversession/closeand starts a fresh chat only on success. While the close is in flight, session-switching commands (/new,/resume,/agent, …) are blocked so the deferredNewSessioncan't clobber a conversation the user switched to; failures surface viaAppEvent::SessionCloseFailedwith the enhanced message and unblock the widget.categorize_acp_error_chainwalks the anyhow chain for the structuredacp::Error, maps by JSON-RPC code (-32000auth_required,-32002session-not-found,-32010unreachable (retryable),-32012not-resumable,-32014no-active-session,-32015already-active), code wins over substring heuristics, and surfaceserror.data.detail(e.g. the deployment's exact login hint) — used by spawn/resume/close and prompt-failure paths.session_list && (load_session || session_resume)— cloud sessions actually appear (PR feat(acp): source /resume picker from agent session/list #518's feature was gated off for the one agent that needed it). The cloud sentinel cwd/is hidden from row descriptions and search.AgentCapabilitiesViewgains serde-defaultedsession_resume/session_close; mock-acp-agent gains env-gated resume/close handlers + failure switches for tests.This is the client half of
nori-cloud-cli-followup.md(agent/router half landed in nori-sessions PR #1045). Capability-gated throughout — agents that don't advertise the new capabilities behave exactly as before.Decisions to review / known follow-ups
/close= swap, not just release: on success we start a new chat, which (for cloud) immediately claims a fresh VM — consistent with existing/newsemantics, but "release and idle" isn't expressible today. Flagging the UX question./closeshows in the slash popup for all agents (gated with an explanation on invoke); wiring it into thedisabled_builtin_commandsgreying mechanism (like/goal) is a clean follow-up.data.detailas raw JSON via{err:#}rather than the curated treatment; cosmetic inconsistency.CloseSessioncommand arm is covered indirectly (connection tests below, widget tests above, harness close-failure test throughclose_active_session).Test Plan
/clslash-popup snapshotcargo test(full workspace) green;cargo test -p tui-pty-e2egreen;just fmt+just fixclean/resumeshows agent-sourced sessions under the cloud contract → select reattaches viasession/resume→/closeprints "Session closed (released)." and starts a fresh chatnori-handroll acp --type cloud+ broker (needs Sessions auth; verified against the mock contract only)Share Nori with your team: https://www.npmjs.com/package/nori-skillsets