Skip to content

fix: async agent delegation — config bug, pruning, observability, nor…#34

Merged
dgarson merged 3 commits intocodex/implement-async-sub-agent-communication-for-ttsfrom
claude/async-agent-delegation-5SWIg
Feb 21, 2026
Merged

fix: async agent delegation — config bug, pruning, observability, nor…#34
dgarson merged 3 commits intocodex/implement-async-sub-agent-communication-for-ttsfrom
claude/async-agent-delegation-5SWIg

Conversation

@dgarson
Copy link
Owner

@dgarson dgarson commented Feb 21, 2026

…malization, prompts

  • Fix maxPerCall config bug: broker was reading maxConcurrency for both limits; add dedicated maxPerCall field to VoiceCallSubagentConfigSchema
  • Replace O(n) pruning on every state transition with lazy threshold-based pruning (amortized via PRUNE_THRESHOLD=16)
  • Add BrokerMetrics type and metrics getter for observability: enqueued, completed, failed, expired, canceled, fallbacksSpoken, repairAttempts, repairSuccesses, totalExecutionMs
  • Improve JSON normalization pipeline: strip markdown fences, trailing commas, single-line comments; case-insensitive key matching; expanded alias sets; export extractFirstJsonObject, parseBoolean, parseNumber
  • Lighten repairPayload: thinkLevel=off, 4s timeout, truncate input to 1000 chars, pass context through to avoid redundant loadCoreAgentDeps
  • Clean up orphaned session store entries and temp files after job completion (finally block with fs.unlinkSync)
  • Move foreground envelope prompt to end of system prompt with structured RESPONSE FORMAT heading; wrap conversation history in XML tags
  • Add specialist-specific prompts (SPECIALIST_PROMPTS map) for research, scheduler, and policy roles
  • Expand test coverage: 55 tests across broker and normalization suites covering pruning, metrics, deadline clamping, JSON extraction edge cases, alias resolution, type coercion, and specialist prompts

https://claude.ai/code/session_01SYcKJe4ySZthJSCkKxzbFZ

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem:
  • Why it matters:
  • What changed:
  • What did NOT change (scope boundary):

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #
  • Related #

User-visible / Behavior Changes

List user-visible changes (including defaults/config).
If none, write None.

Security Impact (required)

  • New permissions/capabilities? (Yes/No)
  • Secrets/tokens handling changed? (Yes/No)
  • New/changed network calls? (Yes/No)
  • Command/tool execution surface changed? (Yes/No)
  • Data access scope changed? (Yes/No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS:
  • Runtime/container:
  • Model/provider:
  • Integration/channel (if any):
  • Relevant config (redacted):

Steps

Expected

Actual

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
  • Edge cases checked:
  • What you did not verify:

Compatibility / Migration

  • Backward compatible? (Yes/No)
  • Config/env changes? (Yes/No)
  • Migration needed? (Yes/No)
  • If yes, exact upgrade steps:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly:
  • Files/config to restore:
  • Known bad symptoms reviewers should watch for:

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk:
    • Mitigation:

…malization, prompts

- Fix maxPerCall config bug: broker was reading maxConcurrency for both
  limits; add dedicated maxPerCall field to VoiceCallSubagentConfigSchema
- Replace O(n) pruning on every state transition with lazy threshold-based
  pruning (amortized via PRUNE_THRESHOLD=16)
- Add BrokerMetrics type and metrics getter for observability: enqueued,
  completed, failed, expired, canceled, fallbacksSpoken, repairAttempts,
  repairSuccesses, totalExecutionMs
- Improve JSON normalization pipeline: strip markdown fences, trailing
  commas, single-line comments; case-insensitive key matching; expanded
  alias sets; export extractFirstJsonObject, parseBoolean, parseNumber
- Lighten repairPayload: thinkLevel=off, 4s timeout, truncate input to
  1000 chars, pass context through to avoid redundant loadCoreAgentDeps
- Clean up orphaned session store entries and temp files after job
  completion (finally block with fs.unlinkSync)
- Move foreground envelope prompt to end of system prompt with structured
  RESPONSE FORMAT heading; wrap conversation history in XML tags
- Add specialist-specific prompts (SPECIALIST_PROMPTS map) for research,
  scheduler, and policy roles
- Expand test coverage: 55 tests across broker and normalization suites
  covering pruning, metrics, deadline clamping, JSON extraction edge
  cases, alias resolution, type coercion, and specialist prompts

https://claude.ai/code/session_01SYcKJe4ySZthJSCkKxzbFZ
@dgarson dgarson marked this pull request as ready for review February 21, 2026 20:26
…onflict

- Wrap speakFallbackIfActive in try/catch inside the runJob catch block
  to prevent unhandled promise rejections when onSummaryReady is broken
- Check remaining time before applying Math.max(1000ms) clamp so jobs
  that have already expired hit the expiry branch instead of launching
  a 1s LLM call past their deadline
- Replace "use tools when helpful" with delegation guidance in the
  foreground voice prompt to avoid contradicting the JSON-only envelope
  instruction — tools belong in the specialist background lane

https://claude.ai/code/session_01SYcKJe4ySZthJSCkKxzbFZ
Replace naive regex-based stripTrailingCommas and stripJsonComments with
character-walking implementations that track whether we're inside a JSON
string literal, so commas and // sequences inside string values are never
corrupted.

Move session store cleanup into the finally block of runJob so entries are
removed on both success and failure paths.  Add reapOrphanedSessions()
method that sweeps stale voice-subagent:* keys older than a configurable
threshold, called at webhook server startup to catch entries orphaned by
crashes.

https://claude.ai/code/session_01SYcKJe4ySZthJSCkKxzbFZ
@dgarson dgarson merged commit b6a4660 into codex/implement-async-sub-agent-communication-for-tts Feb 21, 2026
2 of 9 checks passed
dgarson added a commit that referenced this pull request Feb 22, 2026
Feature flag management with per-environment and per-agent overrides.

Features:
- 10 seed flags: horizon_ui_enabled, voice_interface_enabled, adaptive_ux_level,
  max_concurrent_sessions, beta_model_access, debug_mode, agent_greeting_style,
  session_branching, token_budget_warning_threshold, multi_agent_orchestration
- Toggle switch per flag (role=switch, aria-checked)
- Type badges: Boolean / String / Number / Rollout % (violet)
- Expandable detail panel: rollout % slider, environment overrides, agent overrides, timestamps
- Filter tabs: All / Enabled / Disabled / Experimental
- Search (⌘F), stats strip
- 'Experimental' badge for beta flags
- Real flag keys that mirror actual OpenClaw capabilities
- Full a11y: role=switch, aria-checked, aria-expanded, aria-label, focus-visible
- Build: ✓ 0 TS errors, 1.42s, 13.48 kB / gzip 4.03 kB
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.

2 participants