fix: prompt + query verbs (Ephemeral Sessions) #65
No reviewers
Labels
No labels
epic
in-review
ready-for-agent
ready-for-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
weiwen/evie!65
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "issue-58"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #58 (parent #55; builds on the #57 dispatch core). Adds the two pi-backed Verbs on top of the control plane, both served from throwaway Ephemeral Sessions so they never abort, block, or evict a
chat's live conversation Slot.
What changes
Ephemeral Session support (
src/session.rs)SessionManager::run_ephemeral(chat_id, message)— spawns a freshpiprocess for a single turn, returns theAgentResponse, and kills the process regardless of outcome. It never touches thesessionsmap: noget_or_create_slot, no abort registration, no eviction, so an in-flight live turn is neither interrupted nor polluted (the documented context-blindness tradeoff).spawn_ephemeral/run_ephemeral_turnhelpers. The turn holds its abort sender for the duration so the receiver stays pending and the read path always wins — ephemeral turns are never aborted.set_ephemeral_factory(test-only, behind#[cfg(test)]) injects aPiProcessfactory so ephemeral turns run againstPiProcess::fake_responderwithout a realpibinary; set before theArcisshared.
Control plane verbs (
src/control_plane.rs)ControlRequest::PromptandControlRequest::Queryvariants (taggedverb, snake_case), plus aresponsefield onControlResponsepopulated only byquery.Deliverertrait (async-trait) abstracts Telegram delivery:BotDelivererfor production, a recording double for tests.ControlPlane::newnow takesOption<Arc<SessionManager>>; the oldbot: Option<Bot>field is replaced bydeliverer: Option<Box<dyn Deliverer>>. Anew_with_deliverertest constructor injects the recorder.handle_prompt: resolves the chat, runs an ephemeral turn, delivers the response text to the resolved Telegram chat; rejectsapi-targets (no asynchronous delivery path for HTTP clients).handle_query: resolves the chat, runs an ephemeral turn, returns the response text to the caller and delivers nothing. Any resolved chat is accepted (api-included), since the ID only names thesession. Immediate-only — no Schedule/deferral wiring.
CLI (
src/main.rs)PromptandQueryclap subcommands with the same--chat → $EVIE_CHAT_ID → daemon-resolvedtargeting assend.send/prompt/querydispatch refactored into a sharedrun_cli_verbhelper: prints thequeryresponse text to stdout, printsokfor delivery verbs, exits non-zero on error.resolve_cli_chatextracts the shared client-side fallback. The daemon constructs
ControlPlanewith the liveSessionManager.Deps:
async-traitadded toCargo.toml/Cargo.lock.Tests (all at the dispatch-core seam via
PiProcess::fake_responder)run_ephemeral_returns_response/run_ephemeral_isolated_from_live_slot— the latter inserts a live slot with an active turn viainsert_slot_for_test, runs the ephemeral turn, and asserts the liveslot is still present, still
Arc::ptr_eqto the original, and its in-flight turn was not aborted.query_returns_ephemeral_response,prompt_delivers_ephemeral_response_to_chat(verifies exactly one delivery to the resolved chat with the ephemeral response text, andresponseabsent on theprompt reply),
prompt_rejects_api_chat_but_query_accepts_it, plus serde round-trips for the new variants andControlResponse::with_response.Full suite: 154 passed, 0 failed. Vocabulary and the Ephemeral-Session isolation contract follow CONTEXT.md and ADR 0006.
Closes #58