Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
455a996
feat(provider): add OpenCode Zen/Go subscription support
Gravirei May 24, 2026
f190744
feat(provider): add [Zen]/[Go] tags to OpenCode preset labels
Gravirei May 24, 2026
1b31f27
feat(provider): enable dynamic model discovery for OpenCode
Gravirei May 24, 2026
33ea351
test(provider): add comprehensive OpenCode Zen/Go test suite
Gravirei May 24, 2026
8603ef5
fix(provider): add per-model endpoint routing (P1)
Gravirei May 25, 2026
0e6cff7
refactor(opencode): model OpenCode Zen/Go as gateways (P2)
Gravirei May 25, 2026
aad0fb3
docs(provider): document OpenCode setup and move badge metadata to de…
Gravirei May 26, 2026
193a09c
fix(provider): match request body to endpoint format for OpenCode /me…
Gravirei May 26, 2026
5928643
fix(provider): add Google AI SDK body/response format for OpenCode Ze…
Gravirei May 26, 2026
f796b47
fix: prevent OpenCode model descriptors from shadowing canonical limits
Gravirei May 28, 2026
53cb00d
fix: align OpenCode Go descriptor metadata with Zen
Gravirei May 28, 2026
3448593
chore: merge upstream main (20 commits)
Gravirei May 28, 2026
2e58071
fix: accept OPENAI_API_KEY as fallback in OpenCode validation
Gravirei May 29, 2026
2993a3d
chore: trigger mergeability recheck
Gravirei May 29, 2026
53e67ff
chore: merge upstream main (4 commits)
Gravirei May 29, 2026
14c1c21
Merge branch 'main' into feat/opencode-zen-go-integration
Gravirei Jun 3, 2026
70dc3d9
feat(shim): forward effort/thinking to OpenCode Zen/Go endpoints
Gravirei May 26, 2026
1498b16
feat: update OpenCode Zen and Go model counts, add new models, and en…
Gravirei Jun 3, 2026
4bb3552
feat: implement xhigh effort support for specific models and adjust e…
Gravirei Jun 3, 2026
ecfa287
fix(effort): address reviewer feedback on xhigh + new models
Gravirei Jun 3, 2026
78a955e
fix(effort): address reviewer feedback on xhigh effort + new models
Gravirei Jun 3, 2026
6e2fce5
chore(effort): order xhigh before max in EFFORT_LEVELS
Gravirei Jun 3, 2026
bf45bea
chore(effort): order xhigh before max in settings + SDK schemas
Gravirei Jun 3, 2026
1aa600f
Merge remote-tracking branch 'upstream/main' into feat/opencode-zen-g…
Gravirei Jun 3, 2026
539a9d4
fix(effort): clamp ModelPicker selection and mark xhigh as current
Gravirei Jun 4, 2026
7420d65
docs(effort): fix stale EffortPicker comment about xhigh normalization
Gravirei Jun 4, 2026
3cf5de2
docs(effort): update /effort help to match xhigh support matrix
Gravirei Jun 4, 2026
857c55b
fix(sdk): address reviewer P2 — sync xhigh across override union, sch…
Gravirei Jun 4, 2026
7d65569
fix(effort): narrow allowlist to shim-serialized models; sync max des…
Gravirei Jun 5, 2026
2fcb07d
Merge remote-tracking branch 'upstream/main' into feat/opencode-zen-g…
Gravirei Jun 8, 2026
fee6c32
chore: trigger CodeRabbit re-review
Gravirei Jun 8, 2026
72fb746
fix(effort): gate modelSupportsXHighEffort on modelSupportsEffort
Gravirei Jun 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ Advanced and source-build guides:
| Codex OAuth | `/provider` | Opens ChatGPT sign-in in your browser and stores Codex credentials securely |
| Codex | `/provider` | Uses existing Codex CLI auth, OpenClaude secure storage, or env credentials |
| Gitlawb Opengateway | Startup default, `/provider`, or env vars | Smart gateway at `https://opengateway.gitlawb.com/v1`; requires an API key from https://gitlawb.com/opengateway/keys and routes Xiaomi MiMo and GMI Cloud partner models by `OPENAI_MODEL` |
| OpenCode Zen | `/provider` or env vars | Pay-as-you-go AI gateway (41 models); uses `OPENCODE_API_KEY` via `https://opencode.ai/zen/v1`; shared key with OpenCode Go |
| OpenCode Go | `/provider` or env vars | $10/mo subscription for open models (12 models); uses `OPENCODE_API_KEY` via `https://opencode.ai/zen/go/v1`; shared key with OpenCode Zen |
| OpenCode Zen | `/provider` or env vars | Pay-as-you-go AI gateway (43 models); uses `OPENCODE_API_KEY` via `https://opencode.ai/zen/v1`; shared key with OpenCode Go |
| OpenCode Go | `/provider` or env vars | $10/mo subscription for open models (13 models); uses `OPENCODE_API_KEY` via `https://opencode.ai/zen/go/v1`; shared key with OpenCode Zen |
| Xiaomi MiMo | `/provider` or env vars | OpenAI-compatible API at `https://mimo.mi.com`; uses `MIMO_API_KEY` and defaults to `mimo-v2.5-pro` |
| Ollama | `/provider` or env vars | Local inference with no API key |
| Atomic Chat | `/provider`, env vars, or `bun run dev:atomic-chat` | Local Model Provider; auto-detects loaded models |
Expand Down
4 changes: 2 additions & 2 deletions docs/advanced-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export OPENAI_MODEL=gpt-5.4
openclaude
```

OpenCode Zen is a pay-as-you-go AI gateway with 41 models (GPT, Claude, Gemini,
OpenCode Zen is a pay-as-you-go AI gateway with 43 models (GPT, Claude, Gemini,
Qwen, MiniMax, GLM, Kimi, Grok, Big Pickle, DeepSeek, Nemotron). Uses the same
`OPENCODE_API_KEY` as OpenCode Go. Get your key from https://opencode.ai.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Expand All @@ -209,7 +209,7 @@ export OPENAI_MODEL=glm-5.1
openclaude
```

OpenCode Go is a $10/mo subscription for 12 open models (GLM, Kimi, DeepSeek,
OpenCode Go is a $10/mo subscription for 13 open models (GLM, Kimi, DeepSeek,
MiMo, MiniMax, Qwen). Uses the same `OPENCODE_API_KEY` as OpenCode Zen.

### Gitlawb Opengateway
Expand Down
9 changes: 3 additions & 6 deletions src/cli/print.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,7 @@ import {
import { getModelOptions } from 'src/utils/model/modelOptions.js'
import {
modelSupportsEffort,
modelSupportsMaxEffort,
EFFORT_LEVELS,
getAvailableEffortLevels,
resolveAppliedEffort,
} from 'src/utils/effort.js'
import { modelSupportsAdaptiveThinking } from 'src/utils/thinking.js'
Expand Down Expand Up @@ -1194,7 +1193,7 @@ function runHeadlessStreaming(
}

const modelOptions = getModelOptions()
const modelInfos = modelOptions.map(option => {
const modelInfos: ModelInfo[] = modelOptions.map((option): ModelInfo => {
const modelId = option.value === null ? 'default' : option.value
const resolvedModel =
modelId === 'default'
Expand All @@ -1210,9 +1209,7 @@ function runHeadlessStreaming(
description: option.description,
...(hasEffort && {
supportsEffort: true,
supportedEffortLevels: modelSupportsMaxEffort(resolvedModel)
? [...EFFORT_LEVELS]
: EFFORT_LEVELS.filter(l => l !== 'max'),
supportedEffortLevels: getAvailableEffortLevels(resolvedModel),
}),
...(hasAdaptiveThinking && { supportsAdaptiveThinking: true }),
...(hasFastMode && { supportsFastMode: true }),
Expand Down
2 changes: 1 addition & 1 deletion src/commands/effort/effort.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ function ApplyEffortAndClose(t0) {
export async function call(onDone: LocalJSXCommandOnDone, _context: unknown, args?: string): Promise<React.ReactNode> {
args = args?.trim() || '';
if (COMMON_HELP_ARGS.includes(args)) {
onDone('Usage: /effort [low|medium|high|max|xhigh|auto]\n\nEffort levels:\n- low: Quick, straightforward implementation\n- medium: Balanced approach with standard testing\n- high: Comprehensive implementation with extensive testing\n- max: Maximum capability with deepest reasoning (Opus 4.6 only)\n- xhigh: Extra-high reasoning for OpenAI/Codex models (alias for max)\n- auto: Use the default effort level for your model');
onDone('Usage: /effort [low|medium|high|max|xhigh|auto]\n\nEffort levels:\n- low: Quick, straightforward implementation\n- medium: Balanced approach with standard testing\n- high: Comprehensive implementation with extensive testing\n- max: Maximum capability with deepest reasoning (Opus 4.6+)\n- xhigh: Extra-high reasoning (OpenAI/Codex and Opus 4.7+)\n- auto: Use the default effort level for your model');
return;
}
if (args === 'current' || args === 'status') {
Expand Down
14 changes: 7 additions & 7 deletions src/components/EffortPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ export function EffortPicker({ onSelect, onCancel }: Props) {
isAvailable: true,
},
...availableLevels.map(level => {
const displayLevel = usesOpenAIEffort
? (level === 'xhigh' ? 'max' : level)
: level
const isCurrent = currentDisplayedLevel === displayLevel
// xhigh is now the persisted level for OpenAI/Codex, so compare against
// it directly. The 'max' alias path is kept only for legacy settings
// that still hold a persisted 'max' from before xhigh was introduced.
const isCurrent = currentDisplayedLevel === level || (usesOpenAIEffort && level === 'xhigh' && currentDisplayedLevel === 'max')
return {
label: (
<EffortOptionLabel
Expand All @@ -78,9 +78,9 @@ export function EffortPicker({ onSelect, onCancel }: Props) {
}))
onSelect(undefined)
} else {
// Normalize OpenAI-shaped 'xhigh' to the standard EffortLevel ('max')
// so AppState + settings.json always hold a persistable value. The shim
// converts back to 'xhigh' at the request boundary.
// Normalize OpenAI-shaped effort to a standard EffortLevel for AppState
// and settings.json persistence. 'xhigh' passes through as-is; the shim
// converts it to 'max' at the Anthropic request boundary if needed.
const effortLevel = isOpenAIEffortLevel(value)
? openAIEffortToStandard(value)
: (value as EffortLevel)
Expand Down
36 changes: 23 additions & 13 deletions src/components/ModelPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { FAST_MODE_MODEL_DISPLAY, isFastModeAvailable, isFastModeCooldown, isFas
import { Box, Text } from '../ink.js';
import { useKeybindings } from '../keybindings/useKeybinding.js';
import { useAppState, useSetAppState } from '../state/AppState.js';
import { convertEffortValueToLevel, type EffortLevel, getDefaultEffortForModel, modelSupportsEffort, modelSupportsMaxEffort, resolvePickerEffortPersistence, toPersistableEffort } from '../utils/effort.js';
import { convertEffortValueToLevel, type EffortLevel, getAvailableEffortLevels, getDefaultEffortForModel, modelSupportsEffort, modelSupportsMaxEffort, resolvePickerEffortPersistence, toPersistableEffort } from '../utils/effort.js';
import { isModelAllowed } from '../utils/model/modelAllowlist.js';
import { getDefaultMainLoopModel, type ModelSetting, modelDisplayString, parseUserSpecifiedModel } from '../utils/model/model.js';
import { getModelOptions, type ModelOption } from '../utils/model/modelOptions.js';
Expand Down Expand Up @@ -182,6 +182,10 @@ export function ModelPicker(t0) {
t8 = $[22];
}
const focusedSupportsMax = t8;
const focusedAvailableLevels: EffortLevel[] = (() => {
const focusedModel = resolveOptionModel(focusedValue);
return focusedModel ? getAvailableEffortLevels(focusedModel) : [];
})();
let t9;
if ($[23] !== focusedValue) {
t9 = getDefaultEffortLevelForOption(focusedValue);
Expand All @@ -191,7 +195,7 @@ export function ModelPicker(t0) {
t9 = $[24];
}
const focusedDefaultEffort = t9;
const displayEffort = effort === "max" && !focusedSupportsMax ? "high" : effort;
const displayEffort = focusedAvailableLevels.includes(effort) ? effort : "high";
let t10;
if ($[25] !== effortValue || $[26] !== hasToggledEffort) {
t10 = value => {
Expand All @@ -208,20 +212,21 @@ export function ModelPicker(t0) {
}
const handleFocus = t10;
let t11;
if ($[28] !== focusedDefaultEffort || $[29] !== focusedSupportsEffort || $[30] !== focusedSupportsMax) {
if ($[28] !== focusedDefaultEffort || $[29] !== focusedSupportsEffort || $[30] !== focusedSupportsMax || $[31] !== focusedAvailableLevels) {
t11 = direction => {
if (!focusedSupportsEffort) {
return;
}
setEffort(prev => cycleEffortLevel(prev ?? focusedDefaultEffort, direction, focusedSupportsMax));
setEffort(prev => cycleEffortLevel(prev ?? focusedDefaultEffort, direction, focusedAvailableLevels));
setHasToggledEffort(true);
};
$[28] = focusedDefaultEffort;
$[29] = focusedSupportsEffort;
$[30] = focusedSupportsMax;
$[31] = t11;
$[31] = focusedAvailableLevels;
$[32] = t11;
} else {
t11 = $[31];
t11 = $[32];
}
const handleCycleEffort = t11;
const t12 = {
Expand All @@ -242,18 +247,22 @@ export function ModelPicker(t0) {
}
useKeybindings(t12, t13);
let t14;
if ($[35] !== effort || $[36] !== hasToggledEffort || $[37] !== onSelect || $[38] !== setAppState || $[39] !== skipSettingsWrite) {
if ($[35] !== effort || $[36] !== hasToggledEffort || $[37] !== onSelect || $[38] !== setAppState || $[39] !== skipSettingsWrite || $[46] !== focusedAvailableLevels || $[47] !== focusedDefaultEffort) {
t14 = function handleSelect(value_0) {
const selectedModel = resolveOptionModel(value_0);
if (value_0 !== NO_PREFERENCE && selectedModel && !isModelAllowed(selectedModel)) {
onSelect(value_0 === NO_PREFERENCE ? null : value_0, undefined);
return;
}
// Clamp effort to a value in the focused model's available levels so
// emitted/persisted values are always valid for the picked model
// (e.g. toggled 'xhigh' then picked a model that doesn't support it).
const clampedEffort = focusedAvailableLevels.includes(effort) ? effort : focusedDefaultEffort;
logEvent("tengu_model_command_menu_effort", {
effort: effort as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
effort: clampedEffort as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
});
if (!skipSettingsWrite) {
const effortLevel = resolvePickerEffortPersistence(effort, getDefaultEffortLevelForOption(value_0), getSettingsForSource("userSettings")?.effortLevel, hasToggledEffort);
const effortLevel = resolvePickerEffortPersistence(clampedEffort, getDefaultEffortLevelForOption(value_0), getSettingsForSource("userSettings")?.effortLevel, hasToggledEffort);
const persistable = toPersistableEffort(effortLevel);
if (persistable !== undefined) {
updateSettingsForSource("userSettings", {
Expand All @@ -265,7 +274,7 @@ export function ModelPicker(t0) {
effortValue: effortLevel
}));
}
const selectedEffort = hasToggledEffort && selectedModel && modelSupportsEffort(selectedModel) ? effort : undefined;
const selectedEffort = hasToggledEffort && selectedModel && modelSupportsEffort(selectedModel) ? clampedEffort : undefined;
if (value_0 === NO_PREFERENCE) {
onSelect(null, selectedEffort);
return;
Expand All @@ -277,6 +286,8 @@ export function ModelPicker(t0) {
$[37] = onSelect;
$[38] = setAppState;
$[39] = skipSettingsWrite;
$[46] = focusedAvailableLevels;
$[47] = focusedDefaultEffort;
$[40] = t14;
} else {
t14 = $[40];
Expand Down Expand Up @@ -447,10 +458,9 @@ function EffortLevelIndicator(t0) {
}
return t4;
}
function cycleEffortLevel(current: EffortLevel, direction: 'left' | 'right', includeMax: boolean): EffortLevel {
const levels: EffortLevel[] = includeMax ? ['low', 'medium', 'high', 'max'] : ['low', 'medium', 'high'];
function cycleEffortLevel(current: EffortLevel, direction: 'left' | 'right', levels: EffortLevel[]): EffortLevel {
// If the current level isn't in the cycle (e.g. 'max' after switching to a
// non-Opus model), clamp to 'high'.
// non-max model), clamp to 'high'.
const idx = levels.indexOf(current);
const currentIndex = idx !== -1 ? idx : levels.indexOf('high');
if (direction === 'right') {
Expand Down
2 changes: 1 addition & 1 deletion src/entrypoints/sdk/controlSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ export const SDKControlGetSettingsResponseSchema = lazySchema(() =>
model: z.string(),
// String levels only — numeric effort is internal-only and the
// Zod→proto generator can't emit enum∪number unions.
effort: z.enum(['low', 'medium', 'high', 'max']).nullable(),
effort: z.enum(['low', 'medium', 'high', 'xhigh', 'max']).nullable(),
})
.optional()
.describe(
Expand Down
4 changes: 2 additions & 2 deletions src/entrypoints/sdk/coreSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1081,7 +1081,7 @@ export const ModelInfoSchema = lazySchema(() =>
.optional()
.describe('Whether this model supports effort levels'),
supportedEffortLevels: z
.array(z.enum(['low', 'medium', 'high', 'max']))
.array(z.enum(['low', 'medium', 'high', 'xhigh', 'max']))
.optional()
.describe('Available effort levels for this model'),
supportsAdaptiveThinking: z
Expand Down Expand Up @@ -1190,7 +1190,7 @@ export const AgentDefinitionSchema = lazySchema(() =>
"Scope for auto-loading agent memory files. 'user' - ~/.claude/agent-memory/<agentType>/, 'project' - .claude/agent-memory/<agentType>/, 'local' - .claude/agent-memory-local/<agentType>/",
),
effort: z
.union([z.enum(['low', 'medium', 'high', 'max']), z.number().int()])
.union([z.enum(['low', 'medium', 'high', 'xhigh', 'max']), z.number().int()])
.optional()
.describe(
'Reasoning effort level for this agent. Either a named level or an integer',
Expand Down
4 changes: 2 additions & 2 deletions src/entrypoints/sdk/coreTypes.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1470,7 +1470,7 @@ export type ModelInfo = {
displayName: string
description: string
supportsEffort?: boolean
supportedEffortLevels?: ("low" | "medium" | "high" | "max")[]
supportedEffortLevels?: ("low" | "medium" | "high" | "xhigh" | "max")[]
supportsAdaptiveThinking?: boolean
supportsFastMode?: boolean
supportsAutoMode?: boolean
Expand Down Expand Up @@ -1534,7 +1534,7 @@ export type AgentDefinition = {
maxTurns?: number
background?: boolean
memory?: "user" | "project" | "local"
effort?: "low" | "medium" | "high" | "max" | number
effort?: "low" | "medium" | "high" | "xhigh" | "max" | number
permissionMode?: "default" | "acceptEdits" | "bypassPermissions" | "fullAccess" | "plan" | "dontAsk"
}

Expand Down
2 changes: 1 addition & 1 deletion src/entrypoints/sdk/runtimeTypes.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export type EffortLevel = 'low' | 'medium' | 'high' | 'max'
export type EffortLevel = 'low' | 'medium' | 'high' | 'max' | 'xhigh'
3 changes: 2 additions & 1 deletion src/integrations/gateways/opencode-go.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default defineGateway({
preset: {
id: 'opencode-go',
vendorId: 'openai',
description: 'OpenCode Go — $10/mo subscription for open models (12 models)',
description: 'OpenCode Go — $10/mo subscription for open models (13 models)',
apiKeyEnvVars: ['OPENCODE_API_KEY'],
modelEnvVars: ['OPENAI_MODEL'],
},
Expand All @@ -50,6 +50,7 @@ export default defineGateway({
{ id: 'opencode-go-minimax-m2.5', apiName: 'minimax-m2.5', label: 'MiniMax M2.5', modelDescriptorId: 'opencode-go-minimax-m2.5', transportOverrides: { openaiShim: { endpointPath: '/messages' } } },
{ id: 'opencode-go-qwen3.6-plus', apiName: 'qwen3.6-plus', label: 'Qwen3.6 Plus', modelDescriptorId: 'opencode-go-qwen3.6-plus', transportOverrides: { openaiShim: { endpointPath: '/messages' } } },
{ id: 'opencode-go-qwen3.5-plus', apiName: 'qwen3.5-plus', label: 'Qwen3.5 Plus', modelDescriptorId: 'opencode-go-qwen3.5-plus', transportOverrides: { openaiShim: { endpointPath: '/messages' } } },
{ id: 'opencode-go-minimax-m3', apiName: 'minimax-m3', label: 'MiniMax M3', modelDescriptorId: 'opencode-go-minimax-m3', transportOverrides: { openaiShim: { endpointPath: '/messages' } } },
],
},
usage: { supported: false },
Expand Down
4 changes: 2 additions & 2 deletions src/integrations/gateways/opencode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,12 +284,12 @@ describe('OpenCode model catalog', () => {

test('zen model count matches expected', () => {
const models = getCatalogEntriesForRoute('opencode')
expect(models.length).toBe(41)
expect(models.length).toBe(43)
})

test('go model count matches expected', () => {
const models = getCatalogEntriesForRoute('opencode-go')
expect(models.length).toBe(12)
expect(models.length).toBe(13)
})

test('all zen gpt models have modelDescriptorId', () => {
Expand Down
4 changes: 3 additions & 1 deletion src/integrations/gateways/opencode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default defineGateway({
preset: {
id: 'opencode',
vendorId: 'openai',
description: 'OpenCode Zen — pay-as-you-go AI gateway (41 models)',
description: 'OpenCode Zen — pay-as-you-go AI gateway (43 models)',
apiKeyEnvVars: ['OPENCODE_API_KEY'],
modelEnvVars: ['OPENAI_MODEL'],
},
Expand Down Expand Up @@ -56,6 +56,7 @@ export default defineGateway({
{ id: 'gpt-5-nano', apiName: 'gpt-5-nano', label: 'GPT 5 Nano', modelDescriptorId: 'opencode-gpt-5-nano', transportOverrides: { openaiShim: { endpointPath: '/responses' } } },
// Claude family — /zen/v1/messages
{ id: 'claude-opus-4-7', apiName: 'claude-opus-4-7', label: 'Claude Opus 4.7', modelDescriptorId: 'opencode-claude-opus-4-7', transportOverrides: { openaiShim: { endpointPath: '/messages' } } },
{ id: 'claude-opus-4-8', apiName: 'claude-opus-4-8', label: 'Claude Opus 4.8', modelDescriptorId: 'opencode-claude-opus-4-8', transportOverrides: { openaiShim: { endpointPath: '/messages' } } },
{ id: 'claude-opus-4-6', apiName: 'claude-opus-4-6', label: 'Claude Opus 4.6', modelDescriptorId: 'opencode-claude-opus-4-6', transportOverrides: { openaiShim: { endpointPath: '/messages' } } },
{ id: 'claude-opus-4-5', apiName: 'claude-opus-4-5', label: 'Claude Opus 4.5', modelDescriptorId: 'opencode-claude-opus-4-5', transportOverrides: { openaiShim: { endpointPath: '/messages' } } },
{ id: 'claude-opus-4-1', apiName: 'claude-opus-4-1', label: 'Claude Opus 4.1', modelDescriptorId: 'opencode-claude-opus-4-1', transportOverrides: { openaiShim: { endpointPath: '/messages' } } },
Expand All @@ -82,6 +83,7 @@ export default defineGateway({
{ id: 'big-pickle', apiName: 'big-pickle', label: 'Big Pickle', modelDescriptorId: 'opencode-big-pickle' },
{ id: 'deepseek-v4-flash-free', apiName: 'deepseek-v4-flash-free', label: 'DeepSeek V4 Flash Free', modelDescriptorId: 'opencode-deepseek-v4-flash-free' },
{ id: 'nemotron-3-super-free', apiName: 'nemotron-3-super-free', label: 'Nemotron 3 Super Free', modelDescriptorId: 'opencode-nemotron-3-super-free' },
{ id: 'mimo-v2.5-free', apiName: 'mimo-v2.5-free', label: 'MiMo V2.5 Free', modelDescriptorId: 'opencode-mimo-v2.5-free' },
],
},
usage: { supported: false },
Expand Down
4 changes: 2 additions & 2 deletions src/integrations/generated/integrationArtifacts.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ export const PROVIDER_PRESET_MANIFEST = [
"routeId": "opencode-go",
"vendorId": "openai",
"gatewayId": "opencode-go",
"description": "OpenCode Go — $10/mo subscription for open models (12 models)",
"description": "OpenCode Go — $10/mo subscription for open models (13 models)",
"apiKeyEnvVars": [
"OPENCODE_API_KEY"
],
Expand All @@ -323,7 +323,7 @@ export const PROVIDER_PRESET_MANIFEST = [
"routeId": "opencode",
"vendorId": "openai",
"gatewayId": "opencode",
"description": "OpenCode Zen — pay-as-you-go AI gateway (41 models)",
"description": "OpenCode Zen — pay-as-you-go AI gateway (43 models)",
"apiKeyEnvVars": [
"OPENCODE_API_KEY"
],
Expand Down
Loading