preview(omnio): background-subagent stack integration (#63 + #67 + #68) — do not merge - #69
Closed
ppazosp wants to merge 10 commits into
Closed
preview(omnio): background-subagent stack integration (#63 + #67 + #68) — do not merge#69ppazosp wants to merge 10 commits into
ppazosp wants to merge 10 commits into
Conversation
…K as product turns - Thread the originating Omnio turn_id (POST /v1/runs) through session context -> delegation dispatch -> completion event (origin_turn_id), alongside each child's streamed subagent_id (subagent_ids). - gateway/wake.py: opt-in OMNIO_WAKE_HOOK redirect for non-push wakes, authenticated with OMNIO_INTERNAL_TOKEN; 409/429/5xx/connect retry with the existing ladder; permanent 4xx raises WakeHookPermanentError so the watcher consumes (drops) unwinnable wakes instead of requeueing forever; self-post fallback when the hook is unset or no turn id is bound. - Emit subagent.start synchronously at background dispatch (parent run is still live, so the event streams AND persists); suppress the child thread's duplicate emission. - Opt-in OMNIO_SUBAGENT_PROGRESS_HOOK: a 10s-cadence daemon monitor posts best-effort per-child progress (goal + current tool) for running delegations. All knobs default off: with the envs unset, behavior is unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This branch adds HERMES_ORIGIN_TURN_ID to gateway.session_context._VAR_MAP,
making it a per-turn bridged var, but never adds it to the snapshot exclusion
set — so it was captured into the shared session snapshot and re-sourced on
later turns, leaking one turn's origin id into the next.
Both exclusion sites are updated, not just the one the test asserts on:
* _SNAPSHOT_EXCLUDED_ENV_REGEX — the Python-side contract the unit test
checks against every name in _VAR_MAP.
* _export_dump_excluding_session_vars — the shell snippet that actually
unsets the vars before `export -p`. This is the one that prevents the
leak at runtime; fixing only the regex would turn the test green while
the variable still leaked.
The tiered-disclosure change (upstream 0986ac3) activates the tool_search bridge whenever ANY deferrable tool exists, so Omnia's six plugin tools all end up behind tool_search/tool_describe/tool_call. The agent's operating docs and skills name those tools directly, so a deferred one reads as unavailable and the model substitutes a weaker built-in — observed live: it wanted web_read, found it deferred, and used web_extract instead. Extend only the never-defer set tool_search consults, via a dedicated _OMNIO_ALWAYS_LOAD_TOOLS constant unioned into _core_tool_names(). _HERMES_CORE_TOOLS is left untouched because it doubles as the tools: payload for the hermes-cli/cron/telegram toolsets. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JwVLayGYn4ZdvF5oE6TYPA
A batch of N children had no per-child completion signal: the progress hook hardcoded status "running", and the only terminal signal was the delegation-level wake, which fires once ALL children finish. _run_single_child now marks its child terminal in its finally block, _batch_progress carries that flag as a fifth token element, and the progress reporter turns it into one POST with status "completed" and that child's subagent_id. A claim set on the record keeps it to exactly one tick per child across sweeps, and _finalize flushes before progress_fn is dropped so the last child — whose flip lands with the batch's own completion — is not missed. All of it stays best-effort: hook failures are logged and dropped, never raised into the delegation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JwVLayGYn4ZdvF5oE6TYPA
GET /api/sessions/{session_id}/delegations filters the process-wide
async-delegation registry by origin_session_id, exposing the registry's
live-status fields (children_activity, per-child finished) so an external
UI can rebuild what a session is still waiting on from the process that
owns the children.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NcRxDiCinRwLFJGDKvAJa3
/v1/runs accepts an optional delegation_sync_only flag, threaded into the session context as HERMES_DELEGATION_SYNC_ONLY (excluded from the session snapshot at both sites, like every _VAR_MAP name). When set, delegate_task forces synchronous execution unconditionally — defeating the wake-session re-enable rather than merely skipping it — so a headless caller (cron, trigger.dev run) that can never consume a background wake gets its result inside the turn. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NcRxDiCinRwLFJGDKvAJa3
The origin session id was only captured into the dispatch record on the
async_delivery_supported()=False self-post fallback; on the normal
api_server push path every delegation record carried an empty
origin_session_id, so GET /api/sessions/{id}/delegations could never
match a session's own live delegations and the Omnio conversation
snapshot read authoritative-empty for the whole run.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…hild-completion' into ppp/omnio-subagent-preview
The listing snapshot exposed only the combined batch goal, so every child in a conversation-events snapshot rendered the same title until its first per-child progress tick arrived. Stamp goals[idx] onto each sampled activity entry (token tuples are in dispatch order). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KU5yhnJcZzbi9kksVAKJad
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.
PREVIEW / INTEGRATION BRANCH — do not merge
Bundles the whole background-subagent hermes stack on top of current
main, as one branch tip a sprite can be reprovisioned from (OMNIO_E2E_HERMES_BRANCH=ppp/omnio-subagent-preview/DEV_HERMES_BRANCH) to preview the feature end-to-end with omnia PR NousResearch#4079's preview deployment.Contains, verbatim (no squash, original hashes):
ppp/omnio-subagent-wake— wake delivery viaOMNIO_WAKE_HOOKas product Turns +HERMES_ORIGIN_TURN_IDsnapshot-leak fixppp/omnio-tool-search-core-and-child-completion— per-child completion ticks,GET /api/sessions/{id}/delegations,delegation_sync_onlyforced-syncorigin/main(df32894d7, fetch_file re-land)Merge the real PRs in order (#68 → #63 → rebase #67
--ontomain → merge #67), then delete this branch. Sanity suites on the merged tip: tool_search 57 · async_delegation 50 · wake_delivery 17 · session_delegations 5 · delegate_apiserver_background 14 — all green.Backward compatibility
Same verdicts as the constituent PRs (#63, #67, #68) — all backward compatible; hermes + proxy ship together per sprite via reprovision.
🤖 Generated with Claude Code