Skip to content

feat(llm): add opencode-go provider support - #224

Closed
skulldogged wants to merge 5 commits into
spacedriveapp:mainfrom
skulldogged:origin/opencode-go-provider
Closed

feat(llm): add opencode-go provider support#224
skulldogged wants to merge 5 commits into
spacedriveapp:mainfrom
skulldogged:origin/opencode-go-provider

Conversation

@skulldogged

@skulldogged skulldogged commented Feb 26, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds first-class support for OpenCode Go and cleans up model definitions by leveraging models.dev for providers that are now available there.

Changes

  • Added opencode_go_key and OPENCODE_GO_API_KEY support in config, with automatic provider registration
  • Added routing defaults for OpenCode Go (kimi-k2.5 for channels, kimi-k2 for workers)
  • Added models.dev provider mappings: opencodeopencode-zen, opencode-go, zai-coding-plan, minimax, moonshotaimoonshot
  • Removed 15 duplicate models from extra_models() that are now fetched from models.dev:
    • All opencode-zen models (7)
    • All zai-coding-plan models (3)
    • MiniMax M2.5
  • Kept only truly custom/private endpoints in extra_models(): minimax-cn, moonshot-v1-8k

Why

OpenCode Go is an OpenAI-compatible inference provider offering kimi-k2.5, glm-5, and minimax-m2.5. This integration makes it work out of the box with proper routing. Additionally, models.dev now hosts most of our previously hardcoded models, so we fetch them dynamically instead of maintaining duplicates.

@coderabbitai

coderabbitai Bot commented Feb 26, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds OpenCode Go as a new LLM provider across docs, UI, API types, configuration loading, provider discovery/registration, model mappings, routing defaults, and tests. Registers opencode_go_key and the OPENCODE_GO_API_KEY environment variable.

Changes

Cohort / File(s) Summary
Documentation
docs/content/docs/(configuration)/config.mdx, docs/content/docs/(deployment)/roadmap.mdx
Documented new opencode_go_key (env: OPENCODE_GO_API_KEY) and added OpenCode Go to provider fallback list.
Frontend UI
interface/src/components/ModelSelect.tsx, interface/src/lib/providerIcons.tsx, interface/src/routes/Settings.tsx
Added opencode-go label and ordering, mapped opencode-go to OpenCode icon, and added provider settings (env var, default model, description).
API Types
interface/src/api/client.ts
Extended ProviderStatus with opencode_go: boolean.
Config Core
src/config.rs
Added opencode_go_key: Option<String> to LlmConfig, TOML/env loading support, OPENCODE_GO_PROVIDER_BASE_URL, provider registration wiring, redaction in Debug impl, and updated tests/fixtures.
Provider Management
src/api/providers.rs
Added opencode_go flag, TOML/env key mapping for opencode-go, inclusion in provider lists/checks, normalized provider handling in test flow, and refined LLM init error message.
Model Mappings
src/api/models.rs
Added provider mappings for opencode-go (and others); pruned many pre-defined extra models and updated retained mappings.
LLM Routing & Init
src/llm/routing.rs, src/llm/providers.rs
Added routing defaults and prefix for opencode-go and an informational log when OpenCode Go is configured.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(llm): add opencode-go provider support' directly and clearly describes the primary change—adding OpenCode Go provider support to the LLM system.
Description check ✅ Passed The description provides detailed context about OpenCode Go support, routing configuration, models.dev integration, and cleanup of duplicate models—all changes reflected in the raw summary.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@skulldogged skulldogged changed the title Add opencode-go provider support with default_provider_config function Add opencode-go provider support Feb 26, 2026

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/config.rs (2)

4466-4483: ⚠️ Potential issue | 🔴 Critical

Onboarding provider selection is index-shifted and maps to wrong providers.

The menu list and match provider_idx mapping are out of sync. From index 10 onward, selections can bind to the wrong key/provider (e.g., choosing Ollama routes to the Gemini branch). Use one shared provider metadata table for both menu labels and selected mapping.

💡 Suggested pattern (single source of truth)
+struct ProviderOption {
+    label: &'static str,
+    input_name: &'static str,
+    toml_key: &'static str,
+    provider_id: &'static str,
+    is_secret: bool,
+}
+
+const PROVIDER_OPTIONS: &[ProviderOption] = &[
+    // ...
+];
+
+let labels: Vec<&str> = PROVIDER_OPTIONS.iter().map(|option| option.label).collect();
+let provider_idx = Select::new().items(&labels).default(0).interact()?;
+let selected = &PROVIDER_OPTIONS[provider_idx];

Also applies to: 4525-4548

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/config.rs` around lines 4466 - 4483, The provider menu and the match
provider_idx mapping are out of sync because the literal providers array
(providers) and the subsequent match provider_idx branches diverge after index
10; replace the separate hard-coded menu labels and match arms with a single
source of truth: define a Vec of structs or tuples (e.g., Provider { label, key
}) and use that same collection to render the menu and to look up the chosen
provider by index (used where match provider_idx currently appears), and apply
the same change for the similar block around the 4525-4548 range so both menu
labels and selection mapping always reference the same Provider entries.

2419-2425: ⚠️ Potential issue | 🟠 Major

KILO_API_KEY is considered configured, but it is not actually loaded into provider config.

needs_onboarding() returns false when KILO_API_KEY exists, yet load_from_env() doesn’t register a kilo provider from that env var. Either add full kilo env wiring or remove this bootstrap check.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/config.rs` around lines 2419 - 2425, The bootstrap check treats
KILO_API_KEY as a configured credential (in the has_legacy_bootstrap_vars list)
but load_from_env() never registers a kilo provider, causing needs_onboarding()
to be incorrect; either remove "KILO_API_KEY" from that list or add proper
wiring in load_from_env() to create and register a kilo provider from the
KILO_API_KEY env var. Locate the has_legacy_bootstrap_vars declaration and
either drop "KILO_API_KEY" or, if you choose wiring, update load_from_env() to
read std::env::var("KILO_API_KEY") and instantiate the corresponding kilo
provider/config (same pattern used for other providers) so the provider is
actually registered when the env var is present.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/content/docs/`(deployment)/roadmap.mdx:
- Line 21: Update the provider count in the roadmap bullet that mentions
SpacebotModel and LlmManager: the text currently reads “12 providers” but the
list contains 13 entries, so change the numeric count to “13 providers” (or
remove one provider from the listed providers if that was intended) to make the
count match the listed providers (identify the sentence containing
"SpacebotModel implements Rig's CompletionModel, routes through LlmManager via
HTTP with retries and fallback chains" and adjust the numeral accordingly).

In `@src/api/providers.rs`:
- Line 315: The match in build_test_llm_config is missing a branch for
"opencode-go", so provider_config becomes None and the providers map lacks
OpenCode Go; add a new match arm for "opencode-go" (similar to the
"opencode-zen" block) that constructs a ProviderConfig with the appropriate
Provider::OpencodeGo (or equivalent variant), sets base_url (verify correct URL,
eg. https://opencode.ai/go), and uses credential for opencode_go_key so
opencode_go_key is included in the providers HashMap; ensure the new arm returns
Some(provider_config) consistent with other cases.

In `@src/config.rs`:
- Around line 322-323: The new constants and helpers (KILO_PROVIDER_BASE_URL,
default_provider_config, add_shorthand_provider) are dead code and causing CI
failures; either remove them or wire them into the provider registration flow by
updating load_from_env and from_toml to recognize shorthand providers and apply
default_provider_config when a provider entry lacks full config, and call
add_shorthand_provider when parsing shorthand strings (e.g., mapping "kilo" to
KILO_PROVIDER_BASE_URL) so these symbols are actually used during provider
loading/registration; modify load_from_env and from_toml to consult
default_provider_config and invoke add_shorthand_provider during parsing, or
delete the unused constants/functions if you prefer removal.

---

Outside diff comments:
In `@src/config.rs`:
- Around line 4466-4483: The provider menu and the match provider_idx mapping
are out of sync because the literal providers array (providers) and the
subsequent match provider_idx branches diverge after index 10; replace the
separate hard-coded menu labels and match arms with a single source of truth:
define a Vec of structs or tuples (e.g., Provider { label, key }) and use that
same collection to render the menu and to look up the chosen provider by index
(used where match provider_idx currently appears), and apply the same change for
the similar block around the 4525-4548 range so both menu labels and selection
mapping always reference the same Provider entries.
- Around line 2419-2425: The bootstrap check treats KILO_API_KEY as a configured
credential (in the has_legacy_bootstrap_vars list) but load_from_env() never
registers a kilo provider, causing needs_onboarding() to be incorrect; either
remove "KILO_API_KEY" from that list or add proper wiring in load_from_env() to
create and register a kilo provider from the KILO_API_KEY env var. Locate the
has_legacy_bootstrap_vars declaration and either drop "KILO_API_KEY" or, if you
choose wiring, update load_from_env() to read std::env::var("KILO_API_KEY") and
instantiate the corresponding kilo provider/config (same pattern used for other
providers) so the provider is actually registered when the env var is present.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8582124 and ec33537.

📒 Files selected for processing (11)
  • docs/content/docs/(configuration)/config.mdx
  • docs/content/docs/(deployment)/roadmap.mdx
  • interface/src/api/client.ts
  • interface/src/components/ModelSelect.tsx
  • interface/src/lib/providerIcons.tsx
  • interface/src/routes/Settings.tsx
  • src/api/models.rs
  • src/api/providers.rs
  • src/config.rs
  • src/llm/providers.rs
  • src/llm/routing.rs

- **Multi-agent** — per-agent database isolation, `Agent` struct bundles all dependencies
- **Database connections** — SQLite + LanceDB + redb per-agent, migrations for all tables
- **LLM** — `SpacebotModel` implements Rig's `CompletionModel`, routes through `LlmManager` via HTTP with retries and fallback chains across 11 providers (Anthropic, OpenAI, OpenRouter, Z.ai, Groq, Together, Fireworks, DeepSeek, xAI, Mistral, OpenCode Zen)
- **LLM** — `SpacebotModel` implements Rig's `CompletionModel`, routes through `LlmManager` via HTTP with retries and fallback chains across 12 providers (Anthropic, OpenAI, OpenRouter, Kilo Gateway, Z.ai, Groq, Together, Fireworks, DeepSeek, xAI, Mistral, OpenCode Zen, OpenCode Go)

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.

⚠️ Potential issue | 🟡 Minor

Provider count is off by one in this roadmap bullet.

The sentence says “12 providers,” but the list names 13 providers. Please align the count to the listed items.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/content/docs/`(deployment)/roadmap.mdx at line 21, Update the provider
count in the roadmap bullet that mentions SpacebotModel and LlmManager: the text
currently reads “12 providers” but the list contains 13 entries, so change the
numeric count to “13 providers” (or remove one provider from the listed
providers if that was intended) to make the count match the listed providers
(identify the sentence containing "SpacebotModel implements Rig's
CompletionModel, routes through LlmManager via HTTP with retries and fallback
chains" and adjust the numeral accordingly).

Comment thread src/api/providers.rs
Comment thread src/config.rs Outdated

@coderabbitai coderabbitai Bot left a comment

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/config.rs (1)

4298-4315: ⚠️ Potential issue | 🟠 Major

Fix onboarding provider index drift (wrong provider gets configured).

After adding "OpenCode Go" in the menu, the numeric provider_idx mapping is misaligned. For example, selecting OpenCode Go (Line 4311) currently resolves to the OpenCode Zen branch, and downstream options are shifted as well.

💡 Minimal fix (realign menu and match)
     let providers = &[
         "Anthropic",
         "OpenRouter",
         "OpenAI",
         "Z.ai (GLM)",
         "Groq",
         "Together AI",
         "Fireworks AI",
         "DeepSeek",
         "xAI (Grok)",
         "Mistral AI",
+        "Google Gemini",
         "Ollama",
         "OpenCode Zen",
         "OpenCode Go",
         "MiniMax",
         "Moonshot AI (Kimi)",
         "Z.AI Coding Plan",
     ];
@@
-        16 => (
+        16 => (
             "Z.AI Coding Plan API key",
             "zai_coding_plan_key",
             "zai-coding-plan",
         ),
-        17 => ("Kilo Gateway API key", "kilo_key", "kilo"),
         _ => unreachable!(),
     };

Also applies to: 4357-4380

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/config.rs` around lines 4298 - 4315, The providers array in src/config.rs
is out of sync with the numeric provider_idx mapping causing selections (e.g.,
"OpenCode Go") to resolve to the wrong branch; update the providers list to
match the ordering expected by the code that reads provider_idx (and any
switch/if that branches on provider_idx around the provider handling code
between the providers declaration and the later mapping block around lines
referenced) so each string in the providers slice corresponds exactly to the
numeric indices used downstream (also check and realign the second occurrence
noted at the block around 4357-4380), ensuring the new "OpenCode Go" entry is
placed at the correct index and all subsequent provider entries are shifted
accordingly to preserve existing mappings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/config.rs`:
- Around line 4298-4315: The providers array in src/config.rs is out of sync
with the numeric provider_idx mapping causing selections (e.g., "OpenCode Go")
to resolve to the wrong branch; update the providers list to match the ordering
expected by the code that reads provider_idx (and any switch/if that branches on
provider_idx around the provider handling code between the providers declaration
and the later mapping block around lines referenced) so each string in the
providers slice corresponds exactly to the numeric indices used downstream (also
check and realign the second occurrence noted at the block around 4357-4380),
ensuring the new "OpenCode Go" entry is placed at the correct index and all
subsequent provider entries are shifted accordingly to preserve existing
mappings.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec33537 and a06a431.

📒 Files selected for processing (1)
  • src/config.rs

@skulldogged
skulldogged marked this pull request as draft February 26, 2026 02:40
@skulldogged skulldogged changed the title Add opencode-go provider support feat(llm): add opencode-go provider support Feb 26, 2026
Comment thread src/config.rs
@@ -4264,6 +4307,7 @@ pub fn run_onboarding() -> anyhow::Result<Option<PathBuf>> {
"Mistral AI",
"Ollama",

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.

The providers menu and the match provider_idx mapping are out of sync here: index 10 is treated as Gemini in the match, but the menu jumps from Mistral → Ollama.

Suggested change
"Ollama",
"Google Gemini",
"Ollama",

@coderabbitai coderabbitai Bot left a comment

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/config.rs (1)

4297-4314: ⚠️ Potential issue | 🟠 Major

Fix onboarding provider index mismatch (currently writes the wrong key/provider).

At Line 4297 the menu options no longer include Gemini, but the match provider_idx table (Line 4356+) still assumes Gemini at index 10. That makes “Ollama” map to gemini_key, shifts later providers, and leaves the last provider mapping unreachable from the UI.

🔧 Proposed fix (re-align indices by restoring the missing menu item)
     let providers = &[
         "Anthropic",
         "OpenRouter",
         "OpenAI",
         "Z.ai (GLM)",
         "Groq",
         "Together AI",
         "Fireworks AI",
         "DeepSeek",
         "xAI (Grok)",
         "Mistral AI",
+        "Google Gemini",
         "Ollama",
         "OpenCode Zen",
         "OpenCode Go",
         "MiniMax",
         "Moonshot AI (Kimi)",
         "Z.AI Coding Plan",
     ];

Also applies to: 4356-4378

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/config.rs` around lines 4297 - 4314, The provider menu array `providers`
is missing the "Gemini" entry which causes the `match provider_idx` mapping (the
arms that reference keys like `gemini_key`, `ollama_key`, etc.) to be shifted;
restore the missing "Gemini" item at the correct position in the `providers`
array (so indices align with the existing match arms), or alternatively update
the `match provider_idx` arms to reflect the current list order—ensure that the
arm referencing `gemini_key` corresponds to the "Gemini" label and that
`ollama_key` and subsequent keys map to their intended provider labels.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/config.rs`:
- Around line 4297-4314: The provider menu array `providers` is missing the
"Gemini" entry which causes the `match provider_idx` mapping (the arms that
reference keys like `gemini_key`, `ollama_key`, etc.) to be shifted; restore the
missing "Gemini" item at the correct position in the `providers` array (so
indices align with the existing match arms), or alternatively update the `match
provider_idx` arms to reflect the current list order—ensure that the arm
referencing `gemini_key` corresponds to the "Gemini" label and that `ollama_key`
and subsequent keys map to their intended provider labels.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a06a431 and bb345d0.

📒 Files selected for processing (3)
  • docs/content/docs/(deployment)/roadmap.mdx
  • src/api/providers.rs
  • src/config.rs
✅ Files skipped from review due to trivial changes (1)
  • src/api/providers.rs

@skulldogged

Copy link
Copy Markdown
Contributor Author

Superseded by #225

shipyard-ci Bot pushed a commit to marcmantei/spacebot that referenced this pull request Jul 15, 2026
… (fp:71617f0ad28f)

tool_workspace() no longer silently degrades to the shared checkout when
an isolated workspace was provisioned but has no worktrees. It now consults
the workspace's Isolation completeness signal: the empty-because-nothing-to-
isolate case falls back cleanly, but repos-present-yet-none-isolated trips a
debug_assert! in debug builds and logs at error (loud, greppable) in release,
documenting why the degradation is non-recoverable (re-opens issue spacedriveapp#224).
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