Skip to content

feat(plugins): extend public subagent lifecycle contract - #72630

Open
akivavh wants to merge 2 commits into
NousResearch:mainfrom
akivavh:feat/subagent-lifecycle-v2
Open

feat(plugins): extend public subagent lifecycle contract#72630
akivavh wants to merge 2 commits into
NousResearch:mainfrom
akivavh:feat/subagent-lifecycle-v2

Conversation

@akivavh

@akivavh akivavh commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • version the public plugin subagent lifecycle contract to v3
  • preserve opaque child identity, parent/tool-use identity, bounded lifecycle timestamps and active-task counts without persisting prompts or raw payloads
  • relay bounded subagent.progress milestones through the existing host surface
  • add generic durable origin notifications and terminal completion registration using Hermes' existing async-delivery queue
  • retain in-process terminal relaunch while explicitly treating process-restart loss as unknown, not recovered
  • accept currently registered plugin toolsets while preserving parent permission narrowing

Safety boundaries

  • no plugin-specific or vendor-specific core tool is added
  • plugins receive no live parent or child agent object
  • opaque context is cleared before terminal callback delivery
  • callback/rate-limit failures leave delivery retryable and cannot rewrite terminal state
  • origin acceptance controls final delivery acknowledgment; restored completions deduplicate
  • no process-restart execution takeover is claimed

Validation

  • python -m pytest -q tests/agent/test_subagent_lifecycle.py tests/tools/test_async_delegation.py — 66 passed
  • Ruff check and format-check on the changed Python/tests — passed
  • exact consumer composite against contract v3 — durable restore=1, terminal deduplicated, zero active supervisors/async residue, secret scan clean
  • merge-tree preflight against current origin/main — clean

The consumer connector and any provider/live acceptance remain outside this public host PR.

@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/plugins Plugin system and bundled plugins labels Jul 27, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related: #72501 merged the v1 lifecycle API; this PR extends that API to contract v2 with distinct process-local context, progress, and relaunch behavior.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for extending the lifecycle boundary while keeping child objects opaque and reusing the existing durable delivery rail.

Problems

  • tools/async_delegation.py:679-685 has a race for deterministic notification ids. Two concurrent publishers can both pass the lookup at :732-734; the loser then hits the durable uniqueness error and unconditionally removes _records[delegation_id] at :685, which may be the winner's record. The winner subsequently cannot finalize because _begin_finalization() requires that in-memory record (:969-972), leaving its durable row running without a completion event.
  • tests/agent/test_subagent_lifecycle.py:397-415 exercises duplicate publication sequentially, so it does not cover this interleaving.

Suggested changes

  • Make registration/reservation ownership-aware and atomic; only remove the exact record created by the failed attempt.
  • Add a barrier-based concurrent duplicate-publication regression test asserting one terminal row and one delivered event.

Current main remains at lifecycle contract v1 (agent/subagent_lifecycle.py:25), so the extension is not superseded. GitHub currently marks this branch dirty against main, so salvage also requires reconciling current production-file changes.

Automated hermes-sweeper review.

Comment thread tools/async_delegation.py
"external_producer": True,
}
with _records_lock:
_records[delegation_id] = record

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assignment is not ownership-safe against concurrent deterministic notification registration. Two callers can both pass the lookup in publish_external_notification; if the later durable INSERT raises IntegrityError, its cleanup at line 685 unconditionally removes this id and can delete the winning caller's in-memory record. Reserve atomically or only remove the exact record created by this attempt.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants