Skip to content

research: enable AQE routing through OpenCode-managed models without conflating host and provider #95

Description

@pacphi

Summary

Investigate and close the remaining AQE → OpenCode routing gap.

Today:

  • Agentic Kit can execute explicit OpenCode workers through ak run.
  • AQE agents and MCP tools can be used inside OpenCode.
  • AQE's HybridRouter cannot select OpenCode as a host-backed inference path.
  • Consequently, an OpenCode route cannot be projected into AQE's agentOverrides.

This is a follow-up to #76 and should not block closing the existing OpenCode host-routing work.

Desired outcome

Allow an AQE agent type to use a model available through the user's configured OpenCode installation:

{
  "providers": {
    "opencode": {
      "enabled": true,
      "defaultModel": "provider/model"
    }
  },
  "agentOverrides": {
    "qe-test-architect": {
      "provider": "opencode",
      "model": "provider/model"
    }
  }
}

The implementation must preserve the distinction between:

  • execution host/transport: opencode
  • observed inference provider: OpenCode's returned providerID
  • observed model: OpenCode's returned modelID
  • billing and cost: provider-reported evidence, never inferred from the host

Findings

AQE cannot currently be configured for this

Against agentic-qe@3.13.3:

  1. opencode is absent from LLMProviderType and ALL_PROVIDER_TYPES.
  2. It is absent from RUNTIME_CONSTRUCTIBLE_PROVIDERS.
  3. ProviderManager.createProvider() uses a closed switch with no OpenCode case.
  4. agentOverrides rejects unknown or non-constructible providers.
  5. createLLMRouterService({ providerManager }) supports in-process injection, but the normal AQE kernel, CLI, and MCP startup paths do not expose an on-disk provider-factory/plugin seam.

Relevant upstream files:

Upstream agentic-qe #568 provided the stable agentOverrides surface, but only for providers AQE can instantiate.

Existing AQE OpenCode integration is the reverse direction

Upstream agentic-qe #268 covers running AQE agents, skills, and MCP tools inside OpenCode. It does not make OpenCode an AQE HybridRouter backend.

OpenCode provides a viable transport, not an OpenAI-compatible proxy

opencode serve exposes:

  • GET /config/providers and GET /provider
  • session creation
  • POST /session/:id/prompt_async
  • SSE lifecycle events
  • POST /session/:id/abort
  • assistant messages containing observed provider/model/token/cost fields
  • loopback binding and basic authentication

It does not expose /v1/chat/completions. Therefore, setting AQE's OpenAI baseUrl to the OpenCode server will not work. The requested proxy feature, anomalyco/opencode #9736, was closed without implementation.

Agentic Kit already has a tested supervisor for this native session API in src/lib/execution/opencode.mjs, providing a useful reference implementation and fixture set.

Architectural issue: OpenCode is not an inference vendor

A first-class AQE adapter cannot simply label every response as provider opencode.

OpenCode may delegate a request to:

  • OpenRouter or another metered API
  • a local model
  • an OAuth/subscription-backed provider
  • a custom OpenAI-compatible service

AQE currently gives each LLMProviderType one static BillingMode, and LLMResponse.provider is a fixed provider union. An OpenCode-backed request has dynamic, observed provider and billing facts.

The upstream design must therefore answer:

  1. Should this be an opencode provider, a host-backed transport, or a generic provider plugin?
  2. How should AQE represent configured transport separately from observed inference provider?
  3. Does AQE need a delegated/mixed billing mode?
  4. How are provider-reported cost receipts preserved?
  5. How does qe-court avoid treating opencode itself as a distinct vendor?
  6. Are tools disabled by default so the adapter behaves as an LLM provider rather than a nested coding agent?

Until those questions are answered, OpenCode must not count toward AQE vendor-diversity or billing claims.

Recommended ownership split

Agentic-QE upstream

Implement one of:

  1. A first-class host-backed OpenCodeProvider, modeled operationally after the existing ClaudeCodeProvider and CodexProvider; or
  2. A stable external provider-factory/plugin seam that can register an OpenCode implementation without patching AQE internals.

The upstream implementation should own:

  • provider/router types and validation
  • ProviderManager construction
  • model selector parsing as providerID/modelID
  • OpenCode server lifecycle
  • session creation and result normalization
  • timeout, cancellation, and cleanup
  • dynamic provider/model/cost provenance
  • unsupported embedding behavior
  • fallback and circuit-breaker integration
  • billing and qe-court semantics

Agentic Kit

After an upstream release provides the contract:

  • version-gate OpenCode AQE projection
  • map eligible OpenCode routes into agentOverrides
  • configure providers.opencode without copying authentication secrets
  • detect CLI/login readiness
  • surface status and version incompatibility honestly
  • preserve user-owned AQE configuration
  • test setup, sync, drift, teardown, and cross-platform behavior
  • keep OpenCode routes explicit until billing and model provenance are sufficiently grounded for safe seeding

Rejected shortcuts

  • Patch or monkey-patch the globally installed AQE package.
  • Implement a private AQE-compatible router inside Agentic Kit.
  • Run an Agentic Kit-owned OpenAI-compatible proxy that translates requests into OpenCode sessions.
  • Treat opencode as the observed inference provider or vendor.
  • Assume a provider/model selector proves billing or actual execution.
  • Copy OpenCode credentials into .agentic-qe/llm-config.json.
  • Block this work indefinitely on OpenCode adding /v1/chat/completions.

A user can already configure AQE directly for OpenRouter, Ollama, or another provider that OpenCode also uses. That reaches the same underlying model, but it does not reuse OpenCode's authentication, catalog, subscription, or runtime and is not equivalent to AQE → OpenCode routing.

Investigation plan

  1. Pin the analysis to current AQE and OpenCode releases.
  2. Build a minimal upstream prototype using OpenCode's native server API.
  3. Execute one AQE HybridRouter request through a configured providerID/modelID.
  4. Verify cancellation, timeout, permission handling, and cleanup.
  5. Capture observed provider, model, tokens, cost, and finish state.
  6. Determine the required AQE identity/billing schema changes.
  7. Record the decision in an ADR.
  8. Open or link the upstream AQE issue/PR.
  9. Implement the version-gated Agentic Kit projection after the upstream contract is available.

Acceptance criteria

Research gate

  • Exact AQE and OpenCode versions are recorded.
  • Existing upstream work (#268 and #568) is distinguished from this direction.
  • A decision is recorded: first-class provider versus provider plugin seam.
  • Host, observed provider, model, cost, and billing semantics are specified independently.
  • qe-court vendor-diversity behavior is explicitly defined.
  • An upstream AQE issue or PR is linked.

Upstream proof

  • AQE can route one named agent type through OpenCode.
  • providerID/modelID is selected explicitly.
  • OpenCode credentials remain in OpenCode's own store.
  • The server is loopback-only and uses ephemeral authentication.
  • Timeout/cancellation aborts the session and terminates owned processes.
  • Permission requests are never auto-approved.
  • Provider/model/token/cost values come from observed OpenCode output.
  • OpenCode is not falsely classified as a vendor or fixed billing mode.
  • Fallback behavior remains bounded and observable.

Agentic Kit integration

  • Projection is enabled only for a verified minimum AQE version.
  • Older AQE versions retain explicit ak run routing and report the limitation.
  • ak sync merges OpenCode AQE entries without clobbering foreign entries.
  • ak status distinguishes configured, runnable, drifted, and upstream-incompatible states.
  • No API key, OAuth token, or OpenCode auth material is persisted by Agentic Kit.
  • OpenCode AQE routes remain opt-in and are not automatically seeded.
  • Linux, macOS, and Windows fixtures cover success, timeout, cancellation, malformed output, and missing CLI/auth.

Closure evidence

Before closing this issue, attach or link:

  • the accepted ADR/design decision
  • the upstream AQE issue and merged PR/release
  • the Agentic Kit implementation PR
  • exact-head CI for Linux, macOS, and Windows
  • focused AQE → OpenCode live proof showing configured and observed identities
  • teardown proof showing no orphaned OpenCode process and no persisted secret
  • documentation covering supported versions, configuration, limitations, and direct-provider alternatives

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions