Skip to content

feat: native background subagents (next_agent/agents_status) + auto-continue for transient provider errors - #40923

Open
mdsohail99 wants to merge 4 commits into
anomalyco:devfrom
mdsohail99:feat/native-agent-teams
Open

feat: native background subagents (next_agent/agents_status) + auto-continue for transient provider errors#40923
mdsohail99 wants to merge 4 commits into
anomalyco:devfrom
mdsohail99:feat/native-agent-teams

Conversation

@mdsohail99

Copy link
Copy Markdown

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Adds native background sub-agent orchestration to the core and makes transient provider errors self-recovering:

  1. Background subagentsTask(background=true) primitives plus next_agent (drain semantics) and agents_status (non-blocking snapshot) tools, enabling true parallel async fan-out of sub-agents from a single session.

  2. Auto-continue on transient provider errors — three error families that are not real failures get resumed automatically with a minimal "continue" prompt instead of failing the step:

    • DeepSeek thinking-mode quirk: reasoning_content must be passed back (400)
    • Model output JSON parse failures: AI_JSONParseError / JSON parsing failed
    • Provider overload: [503] The request queue is full

    The retry policy classifies these as retryable and the processor appends a {role:user, content:"continue"} message to the retried request so it is not byte-identical to the rejected one (a plain same-request retry fails identically). Retries are capped (2) so genuinely stuck sessions still surface their error.

  3. Agent-Teams orchestrator definition (.opencode/agent/orchestrator-agent-teams.md) — the async team-orchestration agent wired to the new native primitives.

How did you verify your code works?

  • bun test test/session/retry.test.ts — 69 pass / 0 fail (classifier positives/negatives, retryable() both APIError and UnknownError shapes, policy cap termination)
  • bun test test/session/processor-effect.test.ts — 16 pass / 0 fail (no regression, incl. upstream midstream server-error retry test)
  • bun run typecheck in packages/opencode — passes

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

…asoning_content, JSON parse)

DeepSeek thinking-mode quirk (400 invalid_request_error 'reasoning_content must be passed back')
and model output JSON-parse errors (AI_JSONParseError / JSON parsing failed) are transient:
a minimal 'continue' user prompt resumes the session and it completes normally.

- retry.ts: isAutoContinueError classifier (reasoning_content AND must-be-passed-back, or
  AI_JSONParseError / JSON parsing failed), classified before the isRetryable/5xx early-return
  so 400-class isRetryable:false errors still retry; AUTO_CONTINUE_MAX=2 cap
- processor.ts: on auto-continue retry, append {role:user, content:continue} to the retried
  request so it is not byte-identical to the rejected one (a plain retry fails identically)
- tests: classifier positives/negatives, retryable() both shapes, policy cap termination
…request queue is full'

- isAutoContinueError adds /request queue is full/i (distinctive token only,
  not 'streaming response failed' or bare 503, to avoid over-matching genuine
  Service Unavailable errors)
- retryable() classifies it before the isRetryable/5xx early-return; policy cap
  and processor continue-append reach it via the shared matcher (processor.ts
  unchanged — already consumes isAutoContinueError)
- tests: classifier positives/negatives incl. generic 503 negatives, retryable()
  as APIError statusCode 503 isRetryable:false, 5xx sanity guard
@mdsohail99

Copy link
Copy Markdown
Author

Note on .opencode/agent/orchestrator-agent-teams.md

Quick clarification on the two pieces in this PR, since they can look coupled:

  1. The core feature is self-contained. Task(background=true), next_agent, and agents_status are core-native tools registered in the global builtin tool list (packages/opencode/src/tool/registry.ts — alongside shell, read, task, etc.). They are available to every agent in any session, with no config file required. The next_agent/agents_status implementations (packages/opencode/src/tool/task-teams.ts) contain no agent-name gating — they operate on background jobs filtered by session ID. Tests for both the registry wiring and the tools are included.

  2. The Agent-Teams file is an optional persona. agents/orchestrator-agent-teams.md is just an agent definition (system prompt + permission.task allowlist) that makes a ready-made orchestrator agent available. It exists to demonstrate the workflow — it is not required for the primitives to function. Any developer or agent can use Task(background=true) + next_agent + agents_status directly.

So: the tools are the engine, the definition is a convenience wrapper. Happy to remove the .opencode/agent/ file from this PR if you'd prefer it kept out, or to split it into a follow-up.

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.

1 participant