feat: event-driven architecture + external triggers + Flow visualization#128
Merged
luokerenx4 merged 3 commits intomasterfrom Apr 17, 2026
Merged
feat: event-driven architecture + external triggers + Flow visualization#128luokerenx4 merged 3 commits intomasterfrom
luokerenx4 merged 3 commits intomasterfrom
Conversation
The tmp filename used process.pid alone, which is constant within a process. Concurrent save() calls (e.g. onTick and a UI-triggered add/update) collided on the same tmp file — one rename succeeded, the next found no file and threw ENOENT. Add a per-call randomUUID suffix so each save owns its own tmp path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce a POST /api/events/ingest endpoint that lets external systems push events into the EventLog. A new TriggerListener subscribes to 'trigger' events and routes them through the AgentCenter like CronListener does for cron.fire — same prompt-then-notify pipeline. Also adds a 'causedBy' field on EventLogEntry so emitted child events (cron.done, heartbeat.done, trigger.done, etc.) link back to the event that triggered them. Enables future causal tracing and graph visualization of the event flow. With this, Alice is no longer a closed loop — any external producer (webhook, API client, monitoring system) can pump an event and see Alice react. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Make `emits` declarations load-bearing: each Listener declares the event types it can emit, and the Registry wraps its handle() with a typed ListenerContext whose emit() is constrained to those types (compile-time via generics, runtime via a Set check). The emitter auto-populates causedBy with the parent event's seq — no more manual passing. Expose the resulting topology at GET /api/topology so the frontend can render Alice's async lifecycle as a graph. Add an "Flow" tab to the Automation page using @xyflow/react: event-type nodes on the left, listener nodes in the middle, emitted-type nodes on the right. Nodes pulse when events flow through via SSE. With this, users can see at a glance what Alice listens to, how she reacts, and what each reaction produces downstream. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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
Three commits that progressively open up Alice's event-driven lifecycle, culminating in a visual representation.
POST /api/events/ingest+TriggerListenerthat routes external events through the AI pipeline, plus acausedByfield on EventLogEntry for causal tracingemitstuples, Registry wrapshandle()with a typedListenerContextwhoseemit()is restricted (compile + runtime) to the declared set and auto-populatescausedBy.GET /api/topologyexposes the resulting graph. New Flow tab on/automationrenders it with@xyflow/reactand pulses nodes in real time via SSE.Test plan
npx tsc --noEmit— backend + UI cleanpnpm test— 1043/1043 pass (+14 new registry tests, +schema coverage for trigger.done / trigger.error)curl -X POST /api/events/ingest -d '{...}'→ 201, downstream trigger.done with causedBy/automation→ Flow tab renders full topology, nodes pulse when events flowcurl /api/topology→ expected shape (11 event types, 5 listeners with emits)🤖 Generated with Claude Code