Skip to content

Latest commit

 

History

History
141 lines (97 loc) · 10.1 KB

File metadata and controls

141 lines (97 loc) · 10.1 KB
description Headless dispatch patterns for parallel AI agent execution via OpenCode
mode subagent
tools
read write edit bash glob grep webfetch task
true
false
false
true
true
true
true
true

Headless Dispatch

Quick Reference

  • One-shot: opencode run "prompt" | Warm server: opencode run --attach http://localhost:4096 "prompt"
  • Server: opencode serve [--port 4096] | SDK: npm install @opencode-ai/sdk
  • Runners: runner-helper.sh [create|run|status|list|stop|destroy]~/.aidevops/.agent-workspace/runners/
  • Model override: opencode run -m openrouter/anthropic/claude-sonnet-4-6 "Task" | Auth: opencode auth login

Use for: parallel tasks, scheduled/cron AI work, CI/CD, chat-triggered dispatch (Matrix/Discord/Slack via OpenClaw), background tasks. Don't use for: interactive dev (use TUI), frequent human-in-the-loop, single quick questions. Diagnostics: When workers fail, stall, or loop: reference/worker-diagnostics.md.

Draft agents: Share domain instructions across workers via ~/.aidevops/agents/draft/. See tools/build-agent/build-agent.md. Remote dispatch: tools/containers/remote-dispatch.md (SSH/Tailscale with credential forwarding).

Never use bare opencode run for dispatch — skips lifecycle reinforcement, workers stop after PR creation (GH#5096). Always use headless-runtime-helper.sh run.

Security

  1. Network: --hostname 127.0.0.1 (default) | Set OPENCODE_SERVER_PASSWORD for network exposure
  2. Permissions: OPENCODE_PERMISSION env var for headless autonomy ('{"*":"allow"}' for CI/CD)
  3. Credentials: Never pass secrets in prompts — use environment variables. Delete sessions after use.
  4. Scoped tokens (t1412.2): Workers get minimal-permission GitHub tokens (contents:write, pull_requests:write, issues:write) scoped to target repo. Flow: worker-token-helper.sh create --repo owner/repo --ttl 3600GH_TOKEN env → worker executes → worker-token-helper.sh revoke. GitHub App installation tokens (repo-scoped, 1h TTL) or delegated tokens (configurable TTL). Disable: WORKER_SCOPED_TOKENS=false. Setup: https://github.com/settings/apps/new → Contents/PRs/Issues R&W → configure ~/.config/aidevops/github-app.json (600 perms).
  5. Worker sandbox (t1412.1): Fake HOME — only .gitconfig, GH_TOKEN, .aidevops/ symlink (read-only), MCP config, writable XDG dirs. No ~/.ssh/, gopass, credentials.sh, cloud/publish tokens, browser profiles. WORKER_SANDBOX_ENABLED=true (default). CLI: worker-sandbox-helper.sh create <task_id> → auto-clean on exit.
  6. Network tiering (t1412.3): 5-tier domain classification. Tier 5 (exfiltration) denied, Tier 4 (unknown) flagged. Config: configs/network-tiers.conf. See network-tier-helper.sh.

Dispatch Methods

opencode run "Review src/auth.ts for security issues"       # one-shot
opencode run -m anthropic/claude-sonnet-4-6 "Task"          # model override
opencode run --agent plan "Analyze the database schema"     # agent override
opencode run -f ./schema.sql "Generate types"               # file context
opencode run -c "Continue" | -s ses_abc123 "Add handling"   # resume session

Warm server: opencode serve --port 4096 once, then opencode run --attach http://localhost:4096 "Task" (avoids MCP cold boot).

SDK: import { createOpencode } from "@opencode-ai/sdk"createOpencode({ port: 4096 }). Connect: createOpencodeClient({ baseUrl: "http://localhost:4096" }).

HTTP API: tools/ai-assistants/opencode-server.md. Key: POST /sessionPOST /session/$ID/message. Async: POST .../prompt_async (204). SSE: GET /event. Fork: POST /session/$ID/fork. No-reply: noReply:true.

Parallel Execution (t1419)

Stagger manual launches by 30-60s to avoid thundering herd (RAM exhaustion, API rate limiting, MCP cold boot storms). Pulse supervisor handles staggering automatically (RAM_PER_WORKER_MB, RAM_RESERVE_MB, MAX_WORKERS_CAP).

HELPER="$(aidevops config get paths.agents_dir | sed "s|^~|$HOME|")/scripts/headless-runtime-helper.sh"
for issue in 42 43 44; do
  $HELPER run --role worker --session-key "issue-${issue}" --dir ~/Git/myproject \
    --title "Issue #${issue}" --prompt "/full-loop Implement issue #${issue}" &
  sleep 30
done

Monitoring: worker-watchdog.sh --status (active) | --install (launchd hung/idle detection with transcript-tail inspection). SDK: Promise.all for concurrent sessions, SSE via client.event.subscribe().

Runners and Custom Agents

Runners: Named, persistent agent instances at ~/.aidevops/.agent-workspace/runners/<name>/ with AGENTS.md, config.json, optional memory.db. CLI: runner-helper.sh create|run|status|list|destroy. Memory: memory-helper.sh store/recall --namespace "runner-name". Inter-runner: mail-helper.sh send --to/--from. Templates: tools/ai-assistants/runners/ (README).

Custom agents: Define via .opencode/agents/<name>.md or opencode.json with frontmatter controlling tools, permission, model, temperature. Example: restrict to read-only git commands with permission: { bash: { "git diff*": allow, "*": deny } }. Usage: opencode run --agent <name> "prompt".

Model Providers

opencode auth login for setup. Override: opencode run -m openrouter/anthropic/claude-sonnet-4-6 "Task".

OAuth-aware routing (t1163): SUPERVISOR_PREFER_OAUTH=true (default) routes Anthropic requests through Claude CLI if OAuth available (zero marginal cost). Non-Anthropic → opencode. Override: SUPERVISOR_CLI=opencode. Detection: ~/.claude/ credentials, cached 5 min. Budget: budget-tracker-helper.sh configure claude-oauth --billing-type subscription.

Worker Uncertainty Framework

Proceed autonomously (document in commit): inferable from context/conventions, only affects own task scope, multiple valid approaches (pick simplest), style ambiguity (follow conventions), equivalent patterns (match precedent), minor adjacent issues (note in PR body).

Exit BLOCKED: contradicts codebase, breaks public API, task done/obsolete, missing deps/credentials, architectural decisions affecting other tasks, create-vs-modify with data loss risk, multiple interpretations with very different outcomes. Example: BLOCKED: 'update the auth endpoint' but 3 exist (JWT, OAuth, API key). Need clarification.

Supervisor: Proceed → normal PR review. BLOCKED → clarifies/retries or creates prerequisite. Unclear error → diagnostic worker (-diag-N).

Subtask Lineage and Decomposition (t1408)

Lineage context (t1408): When dispatching subtasks (dot-notation IDs like t1408.3), include a lineage block to prevent scope drift. Include when task ID has a dot AND siblings may run in parallel. Workers: focus only on <-- THIS TASK, stub sibling deps, exit BLOCKED on hard dependencies.

TASK LINEAGE:
  0. [parent] Build a CRM (t1408)
    1. Contact management (t1408.1)
    2. Deal pipeline (t1408.2)  <-- THIS TASK
    3. Email integration (t1408.3)
LINEAGE RULES: Focus ONLY on "<-- THIS TASK". Stub sibling deps. Exit BLOCKED if hard dependency.

Assembly: PARENT_ID="${TASK_ID%.*}", grep TODO.md for siblings. task-decompose-helper.sh format-lineage does not yet support task-id lookup (t1408.1). Dispatch: append ${LINEAGE_BLOCK} to --prompt via headless-runtime-helper.sh run.

Decomposition (t1408.2): Tasks classified as atomic (dispatch directly) or composite (split into 2-5 subtasks with dependency edges). Interactive: show tree, ask Y/n/edit. Pulse: auto-proceed (depth limit: 3). Integration: /full-loop (Step 0.45), /pulse (Step 3), /new-task (Step 5.5), /mission. CLI: task-decompose-helper.sh classify|decompose|format-lineage|has-subtasks. Config: DECOMPOSE_MAX_DEPTH=3, DECOMPOSE_MODEL=haiku, DECOMPOSE_ENABLED=true. Principle: "When in doubt, atomic."

Batch strategies (t1408.4): batch-strategy-helper.sh next-batch --strategy depth-first|breadth-first --tasks "$JSON" --concurrency "$SLOTS". Depth-first (default): finish one branch before next. Breadth-first: one subtask per branch per batch. Hybrid: parallel analysis → sequential implementation.

Worker Efficiency Protocol

Injected via supervisor dispatch (~300-500 token overhead, 20-100x ROI):

  1. TodoWrite — 3-7 subtasks at start. Last: "Push and create PR". Survives compaction.
  2. Commit early — per subtask. After first: git push -u origin HEAD && gh pr create --draft.
  3. ShellCheck gate (t234) — Before push, if .sh changed: shellcheck -x -S warning.
  4. Parallel sub-work (MANDATORY) — Task tool for independent ops. Sequential for: same-file writes, dependent steps, git ops.
  5. Research offloading — Task sub-agents for 500+ line files. Checkpoint: session-checkpoint-helper.sh save per subtask.
  6. Fail fast — Verify assumptions before coding. Exit BLOCKED after one retry. Token min: read ranges, concise commits.

Parallel vs sequential: Independent read-only ops (reviews, audits, multi-module tests) → parallel. Dependent chains (fix→test, refactor→docs, plan→implement→verify) → sequential.

CI/CD Integration

- run: opencode run --format json "Review PR changes for security and quality" > review.md
  env: { ANTHROPIC_API_KEY: "${{ secrets.ANTHROPIC_API_KEY }}", OPENCODE_PERMISSION: '{"*":"allow"}' }

Related

tools/ai-assistants/opencode-server.md (server API) | tools/ai-assistants/overview.md (assistant comparison) | tools/ai-assistants/runners-README.md (templates) | scripts/runner-helper.sh | scripts/cron-dispatch.sh, scripts/cron-helper.sh (cron) | scripts/matrix-dispatch-helper.sh, services/communications/matrix-bot.md (Matrix) | scripts/commands/pulse.md (supervisor) | scripts/mail-helper.sh (mailbox) | scripts/worker-token-helper.sh (t1412.2) | scripts/network-tier-helper.sh, scripts/sandbox-exec-helper.sh (network+sandbox) | configs/network-tiers.conf | tools/security/prompt-injection-defender.md | reference/memory.md (memory system)