Skip to content

feat(events): add SESSION_START and SESSION_END lifecycle events#47

Merged
galuszkm merged 2 commits into
mainfrom
feat/mg/session-events
May 24, 2026
Merged

feat(events): add SESSION_START and SESSION_END lifecycle events#47
galuszkm merged 2 commits into
mainfrom
feat/mg/session-events

Conversation

@galuszkm
Copy link
Copy Markdown
Member

Description

External consumers of the event stream had no reliable way to know the topology of a session before agent activity started, and no typed signal that a session had cleanly ended.

This PR adds two session-level lifecycle events that bracket every invocation, giving consumers a deterministic start and end marker with rich metadata attached.

  • SESSION_START — first event on the queue, emitted synchronously before any agent runs. Carries a SessionManifest in data.
  • SESSION_END — last typed event before the end-of-stream sentinel. Carries {"session_id": <str|null>} so consumers can finalise UI state deterministically without relying on the sentinel.
  • New strands_compose.manifest module with pure builder functions build_manifest() and build_session_manager_descriptor().
  • New SessionManifest Pydantic v2 models in types.py: AgentDescriptor, OrchestrationDescriptor, EntryDescriptor, ModelDescriptor, NodeRef, EdgeRef, SessionManagerDescriptor.
  • EventQueue.emit_session_start(manifest) — synchronous, guarded against double-emission.
  • EventQueue.flush() resets both SESSION_START and SESSION_END guards in addition to draining the queue.
  • wire_event_queue() builds the manifest and emits SESSION_START before returning.
  • AnsiRenderer updated to handle SESSION_START and SESSION_END

Related Issues

N/A

Type of Change

  • New feature

YAML / API Impact

No YAML schema changes. All new Python API is additive:

  • New keyword-only parameters on make_event_queue() (entry_name, session_id) default to None — existing callers are unaffected.
  • wire_event_queue() behaviour is unchanged for single-turn use. Callers that reuse the queue across turns (e.g. multi-turn servers) must call flush() then emit_session_start() explicitly after each flush to re-emit SESSION_START per turn.
  • New public symbols: SessionManifest, AgentDescriptor, OrchestrationDescriptor, EntryDescriptor, ModelDescriptor, NodeRef, EdgeRef, FileProviderDescriptor, S3ProviderDescriptor, AgentCoreProviderDescriptor, CustomProviderDescriptor.

Fully backwards-compatible.

Testing

How have you tested the change?

  • I ran uv run just check (lint + type check)
  • I ran uv run just test for overall testing
  • I added or updated tests that prove my fix is effective or my feature works
  • I verified existing examples in examples/ still work

Checklist

  • I have read the CONTRIBUTING document
  • I have updated the documentation accordingly
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

galuszkm added 2 commits May 24, 2026 21:49
- Add SESSION_START event carries SessionManifest (topology, models, session managers)
- Add SESSION_END event carries effective session_id
- Add strands_compose.manifest
- Add SessionManifest Pydantic models in types.py
- wire_event_queue() builds manifest and emits SESSION_START
- Test suite update
- Docs update
- Implement _handle_session_start and _handle_session_end to show session lifecycle events in ANSI renderer
- Remove not required flush from example 12
@galuszkm galuszkm merged commit 96f96c5 into main May 24, 2026
8 checks passed
@galuszkm galuszkm deleted the feat/mg/session-events branch May 24, 2026 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant