Skip to content

feat(providers): add opencode community provider#1462

Closed
alexsiri7 wants to merge 1 commit intocoleam00:devfrom
alexsiri7:feat/opencode-provider
Closed

feat(providers): add opencode community provider#1462
alexsiri7 wants to merge 1 commit intocoleam00:devfrom
alexsiri7:feat/opencode-provider

Conversation

@alexsiri7
Copy link
Copy Markdown
Contributor

@alexsiri7 alexsiri7 commented Apr 28, 2026

Summary

  • Adds OpencodeProvider — a community provider that wraps the opencode SDK to give Archon workflows access to any model configured in ~/.config/opencode/opencode.json (local Ollama models, Requesty, Anthropic, OpenAI, etc.)
  • Model format: <providerID>/<modelID> (e.g. ollama/qwen3:8b, requesty/google/gemini-3-flash-preview, anthropic/claude-sonnet-4-5)
  • Adds assistantText field to ResultChunk in types.ts so providers can surface the full accumulated text alongside the result event

Implementation notes

SSE event delivery fix — the root cause of the most interesting bug: opencode dispatches model-response events (message.part.delta, session.idle) through the process-CWD instance, not the session's cwd instance. Subscribing with directory: cwd scoped the SSE connection to the wrong instance. The fix is to subscribe without a directory filter and rely on the bridge's existing sessionID filter.

AsyncQueue pump — same pattern as the Pi provider: a background IIFE continuously reads from the SSE stream and pushes into a single-producer/single-consumer queue. This keeps the SSE response body alive (Bun closes idle bodies after ~99ms) and decouples the pump from the bridgeOpencodeEvents consumer.

Lazy server startupcreateOpencode() is dynamically imported on first sendQuery so the module can be loaded without spawning a child process when opencode is absent but unused.

Test plan

  • bun test packages/providers/src/community/opencode/ — 39 tests, all passing
  • bun test packages/providers/src/registry.test.ts — 35 tests, all passing
  • E2E smoke test via archon workflow run e2e-opencode-smoke — completes in ~3s with PASS: got response: '4'
  • TypeScript type check passes (tsc --noEmit)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added Opencode as a new community provider with model selection, session resumption, and structured output support
    • Support for configurable binary directory paths and token/cost tracking
  • Tests

    • Added comprehensive test coverage for Opencode provider integration
  • Chores

    • Extended community provider registry to include Opencode

Adds OpencodeProvider that wraps the opencode SDK to give Archon workflows
access to any model configured in ~/.config/opencode/opencode.json, including
local Ollama models and any provider opencode supports.

Key implementation details:
- Lazy server startup (deferred dynamic import avoids binary lookup at boot)
- Module-level singleton for the opencode server process (one process per parent)
- AsyncQueue-based SSE pump (same pattern as Pi provider) to keep the stream
  alive and buffer events without dropping any
- Subscribe without directory filter: opencode dispatches model events through
  the process-CWD instance, not the session's cwd instance; sessionID filtering
  in bridgeOpencodeEvents catches only the relevant session's events
- JSON schema structured output via prompt engineering (no SDK-level JSON mode)
- Session resume support via resumeSessionId

Model format: '<providerID>/<modelID>' (e.g. 'ollama/qwen3:8b',
'requesty/google/gemini-3-flash-preview', 'anthropic/claude-sonnet-4-5').

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ced06906-5963-4d43-91de-f336de8f6b09

📥 Commits

Reviewing files that changed from the base of the PR and between ff90111 and 591c741.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (14)
  • .archon/workflows/test-workflows/e2e-opencode-smoke.yaml
  • packages/providers/package.json
  • packages/providers/src/community/opencode/capabilities.ts
  • packages/providers/src/community/opencode/config.test.ts
  • packages/providers/src/community/opencode/config.ts
  • packages/providers/src/community/opencode/event-bridge.test.ts
  • packages/providers/src/community/opencode/event-bridge.ts
  • packages/providers/src/community/opencode/index.ts
  • packages/providers/src/community/opencode/provider.test.ts
  • packages/providers/src/community/opencode/provider.ts
  • packages/providers/src/community/opencode/registration.ts
  • packages/providers/src/registry.test.ts
  • packages/providers/src/registry.ts
  • packages/providers/src/types.ts

📝 Walkthrough

Walkthrough

This PR introduces a new OpenCode community provider for Archon, including provider implementation with async generator-based query execution, event bridging from OpenCode SSE streams to MessageChunk sequences, configuration parsing, capability definitions, and registration logic. An E2E smoke-test workflow and comprehensive test coverage are also included.

Changes

Cohort / File(s) Summary
OpenCode Provider Core
packages/providers/src/community/opencode/provider.ts, packages/providers/src/community/opencode/event-bridge.ts
Provider implements lazy-initialized SDK setup, session management (creation/resumption), model parsing, prompt augmentation for JSON schemas, and event stream handling. Event bridge converts OpenCode SSE events into MessageChunk sequences, handling text deltas, thinking updates, tool calls/results, token aggregation, structured output parsing, and error marking.
OpenCode Capabilities & Configuration
packages/providers/src/community/opencode/capabilities.ts, packages/providers/src/community/opencode/config.ts, packages/providers/src/community/opencode/registration.ts
Defines conservative capability matrix (sessionResume, structuredOutput enabled; MCPs/hooks/skills/agents/sandboxing disabled). Config utilities parse model strings (providerID/modelID) and extract valid config fields. Registration idempotently registers the provider with the Archon provider registry.
OpenCode Module Exports
packages/providers/src/community/opencode/index.ts
Re-exports public API surface: capabilities, config utilities, event bridging, provider class, and registration function.
OpenCode Tests
packages/providers/src/community/opencode/provider.test.ts, packages/providers/src/community/opencode/event-bridge.test.ts, packages/providers/src/community/opencode/config.test.ts
Comprehensive test coverage for provider query execution, event bridging (streaming, tool handling, error marking, structured output parsing), and configuration parsing with edge cases.
Provider Registry & Types Integration
packages/providers/src/registry.ts, packages/providers/src/registry.test.ts, packages/providers/src/types.ts, packages/providers/package.json
Registry bootstraps OpenCode provider registration. New OpencodeProviderDefaults type exported in types. Package.json adds community/opencode export and @opencode-ai/sdk dependency; test updated to verify both pi and opencode providers register.
E2E Smoke Test Workflow
.archon/workflows/test-workflows/e2e-opencode-smoke.yaml
New workflow using requesty/google/gemini-3-flash-preview model; runs a simple prompt node asking "What is 2+2?" with 60s idle timeout, then asserts non-empty output via bash script.

Sequence Diagram

sequenceDiagram
    participant Consumer as Consumer
    participant Provider as OpencodeProvider
    participant SDK as OpenCode SDK
    participant Bridge as Event Bridge

    Consumer->>Provider: sendQuery(prompt, cwd, options)
    Provider->>SDK: Initialize SDK (lazy, once)
    Note over Provider: Setup server, cache promise
    Provider->>SDK: Create/Resume Session
    alt Resume Requested
        Provider->>SDK: Resume existing session
        alt Resume Fails
            Provider->>Consumer: Emit warning chunk
            Provider->>SDK: Create new session
        end
    else New Session
        Provider->>SDK: Create new session
    end
    Note over Provider: Optionally augment prompt with JSON schema
    Provider->>SDK: Send prompt via session
    Provider->>SDK: Subscribe to SSE event stream
    
    loop Stream Events
        SDK->>Provider: Emit SSE events (async)
        Note over Provider: Buffer into queue
        Provider->>Bridge: Bridge queued events
        Bridge->>Consumer: Emit MessageChunk<br/>(text, thinking, tool, result)
    end
    
    Note over Bridge: On session.idle or session.error
    Bridge->>Consumer: Emit final result chunk<br/>(tokens, cost, isError)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • coleam00
  • Wirasm

Poem

🐰 A hop, a skip, the code bridge gleams,
OpenCode flows through Archon's streams!
Sessions resume with whisker-fine care,
JSON schemas float through the air,
From SSE to chunks, the magick is there! ✨

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Wirasm
Copy link
Copy Markdown
Collaborator

Wirasm commented Apr 28, 2026

This already has 2 open prs, please coordinate with other contributors

@Wirasm Wirasm closed this Apr 28, 2026
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