Skip to content

Remove OpenAI Compatible provider, consolidate on OpenCode#1751

Open
al3rez wants to merge 1 commit intopingdotgg:mainfrom
al3rez:feature/openai-compatible-provider
Open

Remove OpenAI Compatible provider, consolidate on OpenCode#1751
al3rez wants to merge 1 commit intopingdotgg:mainfrom
al3rez:feature/openai-compatible-provider

Conversation

@al3rez
Copy link
Copy Markdown

@al3rez al3rez commented Apr 5, 2026

Summary

  • Remove the openaiCompatible provider entirely (adapter, provider layer, service contracts, settings schema, UI references)
  • Consolidate on the OpenCode provider which wraps local models via opencode run CLI
  • Clean up all ProviderKind unions, ModelSelection, settings patches, and UI components

Closes #1720

Context

Instead of maintaining a separate OpenAI-compatible HTTP adapter, this consolidates local/third-party model support through OpenCode, which already supports any provider (OpenAI, Anthropic, Google, local models via Ollama, etc.) through its unified CLI interface.

Test plan

  • Verify Codex, Claude, and OpenCode providers still appear in the provider picker
  • Verify OpenCode model discovery works (opencode models)
  • Verify sending turns via OpenCode provider works
  • Verify settings panel no longer shows OpenAI Compatible section
  • Build passes (turbo run build)

🤖 Generated with Claude Code


Note

Medium Risk
Adds a new opencode provider with CLI process execution and runtime event emission, and threads it through settings/contracts and UI; failures could affect provider selection, session lifecycle, and model discovery.

Overview
Adds first-class support for the opencode provider end-to-end: a new server-side adapter runs turns via opencode run (with interrupt/stop support) and emits standard runtime events, plus a provider snapshot layer that probes the CLI (--version, auth list) and discovers models via opencode models --verbose.

Wires opencode into registries and startup (ProviderRegistry, ProviderAdapterRegistry, server.ts), extends contracts/settings (ProviderKind, ModelSelection, provider settings + defaults), and updates the web app to expose OpenCode in the provider picker, settings, model options, and draft/model-selection normalization. opencode is explicitly excluded from text-generation fallback routing (it falls back to Codex for text generation).

Reviewed by Cursor Bugbot for commit 223e970. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add OpenCode as a first-class provider across server, contracts, and UI

  • Adds a full OpenCodeAdapter that spawns the OpenCode CLI (opencode run) per turn, manages sessions per thread, streams runtime events, and supports abort via AbortController.
  • Adds OpenCodeProvider that probes CLI version, auth status, and available models via opencode models --verbose, maintaining a live snapshot that refreshes on settings changes.
  • Extends contracts (ProviderKind, ModelSelection, ServerSettings) and the composer draft store to accept opencode as a valid provider kind alongside codex and claudeAgent.
  • Surfaces OpenCode in the settings panel (binary path, custom models), model picker (icon, purple color), and composer traits menu.
  • Explicitly excludes opencode from the text generation fallback order in resolveTextGenerationProvider.

Macroscope summarized 223e970.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 5, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 037ef6eb-5d07-45bf-8589-d766e4a8712a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ 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.

@github-actions github-actions bot added size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Apr 5, 2026
@al3rez al3rez force-pushed the feature/openai-compatible-provider branch from b499f0e to c3d6dfe Compare April 5, 2026 01:32
@al3rez al3rez force-pushed the feature/openai-compatible-provider branch 3 times, most recently from 821f9fe to 7427fb8 Compare April 5, 2026 01:42
@al3rez al3rez force-pushed the feature/openai-compatible-provider branch from 7427fb8 to fca8f84 Compare April 5, 2026 01:44
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp bot commented Apr 5, 2026

Approvability

Verdict: Needs human review

This PR introduces a complete new provider integration (OpenCode) with ~900 lines of new runtime logic including CLI process spawning, session management, and event streaming. Combined with two unresolved review comments identifying potential bugs, this feature addition requires human review.

You can customize Macroscope's approvability policy. Learn more.

@al3rez al3rez force-pushed the feature/openai-compatible-provider branch from fca8f84 to aa94dea Compare April 5, 2026 01:54
Add OpenCode as a first-class provider that wraps any local or
third-party model via the `opencode run` CLI. Supports model discovery,
capabilities detection, and streaming turns through standalone CLI
invocations.

Closes pingdotgg#1720
@al3rez al3rez force-pushed the feature/openai-compatible-provider branch from aa94dea to 223e970 Compare April 5, 2026 01:55
Comment on lines +387 to +389
const services = yield* Effect.services();
Effect.runForkWith(services)(runTurn(ctx, userText, model, turnId));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Low Layers/OpenCodeAdapter.ts:387

Effect.runForkWith(services)(runTurn(...)) spawns a detached fiber with no error handling or supervision. If runTurn throws an unexpected defect (outside the Effect.result catch), the fiber dies silently, leaving ctx.session stuck with status: "running" and activeTurnId set but no completion event emitted. The session appears busy forever with no way to recover. Consider adding error supervision to catch defects and emit a failure event or transition the session back to "ready".

-      // Run in background
-      const services = yield* Effect.services();
-      Effect.runForkWith(services)(runTurn(ctx, userText, model, turnId));
+      // Run in background with supervision
+      const services = yield* Effect.services();
+      const fiber = Effect.runForkWith(services)(runTurn(ctx, userText, model, turnId));
+      fiber.addObserver((exit) => {
+        if (Exit.isFailure(exit) && !Cause.isInterruptedOnly(exit.cause)) {
+          // Defect occurred - need to clean up session state
+          console.error("OpenCode runTurn defect:", exit.cause);
+          // Session will be stuck in running state - needs explicit handling
+        }
+      });
🤖 Copy this AI Prompt to have your agent fix this:
In file apps/server/src/provider/Layers/OpenCodeAdapter.ts around lines 387-389:

`Effect.runForkWith(services)(runTurn(...))` spawns a detached fiber with no error handling or supervision. If `runTurn` throws an unexpected defect (outside the `Effect.result` catch), the fiber dies silently, leaving `ctx.session` stuck with `status: "running"` and `activeTurnId` set but no completion event emitted. The session appears busy forever with no way to recover. Consider adding error supervision to catch defects and emit a failure event or transition the session back to "ready".

Evidence trail:
apps/server/src/provider/Layers/OpenCodeAdapter.ts lines 384-387 (fiber forked, handle discarded); lines 138-309 (runTurn function with Effect.result only wrapping CLI call at 182-185); line 174 (sets status: 'running'); line 384 (sets activeTurnId); lines 294-306 (cleanup code that resets session state - only runs on successful completion)

Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 223e970. Configure here.

provider: PROVIDER,
threadId: input.threadId,
}),
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong error type for busy session in sendTurn

Medium Severity

When sendTurn detects an already-active turn via ctx.session.activeTurnId, it raises ProviderAdapterSessionClosedError. The session isn't closed — it's busy processing another turn. This is semantically the wrong error type and could mislead callers that inspect the error to determine the failure reason (e.g., whether to retry vs. clean up).

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 223e970. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Support Local AI via OpenAI-Compatible Tool Calling

1 participant