Skip to content

feat(events): give a session an event envelope carrying run lifecycle - #730

Closed
justintime4tea wants to merge 2 commits into
nightlyfrom
justingross/GH-578-1-run-events-carry-lifecycle-and-activity
Closed

justintime4tea wants to merge 2 commits into
nightlyfrom
justingross/GH-578-1-run-events-carry-lifecycle-and-activity

Conversation

@justintime4tea

@justintime4tea justintime4tea commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Implements #778, a sub-issue of #578. Two commits on nightly, now that #710 and #719 have merged.

AgentEvent says what an agent did and nothing about the run it belongs to, so every seam reconstructs a run's story from its transport. This gives the session an envelope that carries both, one ordered stream per session.

feat(events): give a session an event envelope carrying run lifecycle

aura_events::run adds SessionEvent: the session id, the run id when the event belongs to a run, a sequence number dense per session across its runs, a timestamp, and either an AgentEvent or a LifecycleEvent (started, observer attached and detached, claims exhausted, liveness decided, parked, finished, cancelled, failed). No producer emits it yet; #779 is the first.

The items #778 lists to settle before a producer exists:

  • Session-keyed. session_id is required, run_id optional, seq dense per session. ends_run() says whether an event ends its run; the stream goes on.
  • RunId is a UUID, v7 when minted with RunId::mint(). aura-events takes uuid for it (the CLI already depends on the same workspace crate).
  • Adjacent tagging on the payload, kind beside event, so no event field can collide with the envelope's tag. Lifecycle events stay internally tagged by type; the roundtrip test over every variant catches a field named after a tag. The module doc records that the family needs a self-describing format.
  • RunCancelReason moves here from aura::hooks (re-exported there), is #[non_exhaustive], and gains Unclaimed and Shutdown.
  • ObserverDetached carries a DetachCause (Released, Expired, Displaced).
  • Started carries the run's Liveness, read as cancel-at-once when an older payload omits it.

refactor(agents): name a run by its RunId

RunContext::id becomes the RunId, so the envelope's id and the task-local id are one value.

  • The chat, A2A, and Slack handlers mint a RunId and use its string form as the request id, so approvals, their sweep, MCP cancellation, and the A2A cancel map keep one value per run.
  • begin_run, AgentRuntimeConfig, and RigBuilder's build methods take a RunId; an agent built without one mints its own. The orchestration factory streams under the run id it was built for, as Agent already did.
  • Orchestration's RunId is a re-export of the shared type. Orchestration persistence still mints its own value for checkpoints and the park owner key; adopting the run's id there waits for [FEATURE]: A runtime that owns sessions and their runs #780, which owns resume.

Visible change: request ids are hyphenated UUIDs rather than req_<hex>, a2a_<task_id>, and slack_<channel>_<ts>. The A2A executor and Slack runner log the run id beside the task or message it serves, at debug.

Verification

Fixes: GH-778
Ref: GH-578

@greptile-apps

greptile-apps Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[High risk] Refactors run identification from strings to structured types.

No new blocking issue was identified, and the PR appears safe to merge on this review.

Summary

The PR adds a session event envelope and shared UUID run identifier, then threads that identifier through the chat, A2A, Slack, agent, and orchestration paths. Since the previous review, it has revised lifecycle comments and added a note about orchestration persistence retaining a separate identifier.

Reviews (4) · Last reviewed commit: "refactor(agents): name a run by its RunI..." · Reviewed by Greptile

Comment thread crates/aura-web-server/src/a2a/agent_executor.rs Outdated
Comment thread crates/aura/src/hooks.rs
@justintime4tea
justintime4tea force-pushed the justingross/GH-578-1-run-events-carry-lifecycle-and-activity branch from 69bfe5c to c2e2337 Compare October 7, 2026 19:22
@justintime4tea justintime4tea changed the title feat(events): give a run an event envelope carrying its lifecycle feat(events): give a session an event envelope carrying run lifecycle Oct 7, 2026
Comment thread crates/aura/src/orchestration/factory.rs
Comment thread crates/aura-events/src/run.rs Outdated
Comment thread crates/aura-events/src/run.rs Outdated
@justintime4tea
justintime4tea force-pushed the justingross/GH-578-1-run-events-carry-lifecycle-and-activity branch from ab55a86 to 921232c Compare October 7, 2026 21:00
AgentEvent says what an agent did and nothing about the run it belongs
to. Observers reconstruct the run's story from the transport — a stream
closing, an A2A status update, a [DONE] — and no two agree.

aura_events::run adds SessionEvent: the session id, the run id when the
event belongs to a run, a sequence number dense per session across its
runs, a timestamp, and either an AgentEvent or a LifecycleEvent
(started, observer attached and detached, claims exhausted, liveness
decided, parked, finished, cancelled, failed). One stream per session
means an agent's history loads as one stream, and a run boundary is a
position in it rather than a second stream.

The payload is adjacently tagged, kind beside event, so no field of an
event can collide with the envelope's tag. Lifecycle events stay
internally tagged by type, like AgentEventPayload; the roundtrip test
over every variant is what catches a field named after a tag. Internal
tagging and flatten need a self-describing format, which the module doc
records.

RunId is a UUID, v7 when minted, so it agrees with the orchestration
run id HITL parses and the park owner key; aura-events takes uuid for
it. SessionId and RunCancelReason move into aura-events, re-exported
from aura::config and aura::hooks. RunCancelReason is non_exhaustive
and gains Unclaimed and Shutdown, so a liveness or shutdown cancel is
not reported as External. ObserverDetached says why with a DetachCause,
and Started carries the run's Liveness, read as cancel-at-once when an
older payload omits it.

No producer emits it yet; this is the type and its tests.

Fixes: GH-778
Ref: GH-578
The envelope names a run by RunId, a UUID, while the task-local run
context named it by the HTTP request id string, so the two could never
be the same value.

RunContext::id is now a RunId. The chat, A2A, and Slack handlers mint
one before building the agent and use its string form as the request id,
so every request-keyed registry (HITL approvals and their sweep, MCP
cancellation, the A2A cancel map) keeps one value per run. begin_run,
AgentRuntimeConfig, and RigBuilder's build_agent,
build_streaming_agent_with_headers and build_streaming_agent_with_tools
take a RunId, and an agent built without one mints its own. The
orchestration factory streams under the run id it was built for, as
Agent already did. RunContext::has_id compares a request id string
against the run without allocating.

Request ids become hyphenated UUIDs rather than req_<hex>,
a2a_<task_id>, and slack_<channel>_<ts>; the A2A executor and the Slack
runner log each run id beside the task or message it serves, at debug,
so the two stay joinable.

The orchestration RunId becomes a re-export of aura_events::RunId, so
there is one run id type. Orchestration persistence still mints its own
value for checkpoints and the park owner key; adopting the run's id
there waits for the runtime, which owns resume.

Fixes: GH-778
Ref: GH-578
Ref: GH-780
@justintime4tea
justintime4tea force-pushed the justingross/GH-578-1-run-events-carry-lifecycle-and-activity branch from 921232c to e5ce350 Compare October 7, 2026 21:02
@justintime4tea
justintime4tea deleted the justingross/GH-578-1-run-events-carry-lifecycle-and-activity branch October 8, 2026 21:27
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 8, 2026
@justintime4tea

Copy link
Copy Markdown
Collaborator Author

Superseded by #794. Renaming this PR's branch to justingross/GH-778-run-events-carry-lifecycle-and-activity closed it; the commits are unchanged.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant