Repository navigation
feat(explorer): show a run's Triggers tab, with the trigger-state route it reads - #27
Conversation
|
|
||
| pending = { | ||
| env_id: entry | ||
| for env_id, entry in list(captures.items())[:MAX_TRIGGER_ENVS] |
There was a problem hiding this comment.
Saved events vanish after 20 environments
For a run with more than 20 trigger-bearing environments, this route reads saved state for only the first 20. The writer saves the rest, but the Triggers tab never gets their events or state sources. Read the remaining saved state in bounded batches, or tell the viewer that the response is incomplete.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agent_env/explorer/routers/triggers.py
Line: 78
Comment:
**Saved events vanish after 20 environments**
For a run with more than 20 trigger-bearing environments, this route reads saved state for only the first 20. The writer saves the rest, but the Triggers tab never gets their events or state sources. Read the remaining saved state in bounded batches, or tell the viewer that the response is incomplete.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| pairs = [ | ||
| (env["env_id"], env["instance_id"]) | ||
| for env in deployed_envs | ||
| if isinstance(env, dict) and isinstance(env.get("env_id"), str) and isinstance(env.get("instance_id"), str) | ||
| ][:MAX_TRIGGER_ENVS] |
There was a problem hiding this comment.
Live events disappear after failed registration
If the environment-instance record write fails, deployment can still succeed with a working gateway. This lookup skips that environment because it has no instance_id. The Triggers tab then shows none of its live events and does not mark it unavailable. Account for working gateways without a saved instance record, without trusting a gateway URL supplied by a run request.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agent_env/explorer/routers/triggers.py
Line: 96-100
Comment:
**Live events disappear after failed registration**
If the environment-instance record write fails, deployment can still succeed with a working gateway. This lookup skips that environment because it has no `instance_id`. The Triggers tab then shows none of its live events and does not mark it unavailable. Account for working gateways without a saved instance record, without trusting a gateway URL supplied by a run request.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.b11d910 to
2c9d29a
Compare
5b734b2 to
35ad55f
Compare
…te it reads
The run viewer had the Triggers components (TriggersPanel, the event
timeline and its polling hook) but never mounted the tab, and the route the
timeline polls, GET /tasks/{task_id}/instances/{instance_id}/triggers,
did not exist in the explorer.
The tab now shows for any run that recorded trigger metadata, in the same
place as the hosted hub's: registrations, the final env-trigger state, the
event timeline on the gateway's virtual clock, and the per-turn record.
The route returns the run's trigger metadata plus each env's verbatim
/triggers/state: from the live gateway while the run is running, else from
the envelope prompt_agent saved through the object store. It keeps the
payload the UI parses. Instance and env-instance records are read through
the configured document store, the envelope through the configured object
store (a url that store does not own is refused), and gateway urls come from
the env-instance records rather than the run context's copy.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
35ad55f to
1148716
Compare
Builds on #25 (merged): the new route takes task and instance ids in the path through #25's
EntityIdand encoded-id routing. Rebased onto main after #24.The run viewer shipped the Triggers components (
TriggersPanel, the event timeline, theuseLiveTriggerspolling hook) but never mounted the tab. The route the timeline polls,GET /api/v1/tasks/{task_id}/instances/{instance_id}/triggers, didn't exist in the explorer. Both came over from Scale's hosted AgentEnvHub frontend, where the run viewer has a Triggers tab. This PR adds the route and mounts the tab.UI (
task-instance-viewer.tsx, +16): a Triggers tab after Server Config, the same position as the hosted viewer. It shows only when the run recorded trigger metadata (triggerRuntime, already computed fromcontext.metadata), and rendersTriggersPanel:Route (
explorer/routers/triggers.py, new; included inapp.py): the run's trigger metadata ledger, plus each env's verbatim/triggers/stateunderstate:running: read live from each env's gateway (/triggers/stateand/clock/state, concurrently, 2s timeout). An unreachable gateway reportsunavailablerather than looking like "no triggers".prompt_agentsaved at the end of the prompt step (context.metadata.env_trigger_state[env].object_url).state_metacarries the gateway clock the events'virtual_timeis measured on, andstate_sources/sourcesay where each env's state came from.The response payload is the hosted route's, key for key, which is what
useLiveTriggersandparse-trigger-*already parse.What differs from the hosted route
Filter/In).get_object_store_at(url)). A url that store doesn't own is refused and the env falls back to its metadata, and an envelope captured by another instance is skipped.prompt_agentalready writes the envelope through the configured store, so this works on the local filesystem store._SAFE_TASK_ID_RErejects/, so it would refuse bundle ids.running→cancellednormalization: the hosted route shares that rule with its list and detail endpoints. The explorer's other routes report an instance's status as stored, so this one does too. A run leftrunningby a killed process keeps polling its gone gateway, which readsunavailable.Testing
explorer_app_test.py:statefrom the object store,state_sources: artifact, and its clock instate_meta)MockTransport; the gateway comes from the env-instance record, not the context's url; the env with no gateway reportsunavailable)test_mcp_cli_buildertests that fail identically on main here: the generated CLI's interpreter has noclick, which is environmental.check_plugin_api.py: no break.typecheck,test:smokeandbuild:staticpass.agent-env up:artifact, with the virtual-clock line read fromstate_meta🤖 Generated with Claude Code
The PR is not ready to merge: task-runner navigation can target the wrong task, and saved trigger state still stops after 20 environments.
Fix with agent prompt
Summary
The run viewer now has a Triggers tab for runs with trigger data, backed by a new endpoint for the tab’s timeline. The endpoint combines the run’s trigger records with live gateway state or a saved capture, so the viewer can show trigger activity during and after a run.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart LR URL[Task-runner URL] --> ID[Task ID prop changes] ID --> Init[Initialization effect returns] Init --> Old[Runner keeps the old task]Reviews (3) · Last reviewed commit: "feat(explorer): show a run's Triggers ta..."