diff --git a/packages/adapters/codex-local/src/index.ts b/packages/adapters/codex-local/src/index.ts index afb2cd9b..ca795cb5 100644 --- a/packages/adapters/codex-local/src/index.ts +++ b/packages/adapters/codex-local/src/index.ts @@ -24,7 +24,7 @@ Core fields: - cwd (string, optional): default absolute working directory fallback for the agent process (created if missing when possible) - instructionsFilePath (string, optional): absolute path to a markdown instructions file prepended to stdin prompt at runtime - model (string, optional): Codex model id -- modelReasoningEffort (string, optional): reasoning effort override (minimal|low|medium|high) passed via -c model_reasoning_effort=... +- modelReasoningEffort (string, optional): reasoning effort override (minimal|low|medium|high|xhigh) passed via -c model_reasoning_effort=... - promptTemplate (string, optional): run prompt template - search (boolean, optional): run codex with --search - dangerouslyBypassApprovalsAndSandbox (boolean, optional): run with bypass flag diff --git a/packages/adapters/opencode-local/src/index.ts b/packages/adapters/opencode-local/src/index.ts index bbe75c26..c8f37a81 100644 --- a/packages/adapters/opencode-local/src/index.ts +++ b/packages/adapters/opencode-local/src/index.ts @@ -1,7 +1,15 @@ export const type = "opencode_local"; export const label = "OpenCode (local)"; -export const models: Array<{ id: string; label: string }> = []; +export const DEFAULT_OPENCODE_LOCAL_MODEL = "openai/gpt-5.2-codex"; + +export const models: Array<{ id: string; label: string }> = [ + { id: DEFAULT_OPENCODE_LOCAL_MODEL, label: DEFAULT_OPENCODE_LOCAL_MODEL }, + { id: "openai/gpt-5.4", label: "openai/gpt-5.4" }, + { id: "openai/gpt-5.2", label: "openai/gpt-5.2" }, + { id: "openai/gpt-5.1-codex-max", label: "openai/gpt-5.1-codex-max" }, + { id: "openai/gpt-5.1-codex-mini", label: "openai/gpt-5.1-codex-mini" }, +]; export const agentConfigurationDoc = `# opencode_local agent configuration @@ -21,7 +29,7 @@ Core fields: - cwd (string, optional): default absolute working directory fallback for the agent process (created if missing when possible) - instructionsFilePath (string, optional): absolute path to a markdown instructions file prepended to the run prompt - model (string, required): OpenCode model id in provider/model format (for example anthropic/claude-sonnet-4-5) -- variant (string, optional): provider-specific model variant (for example minimal|low|medium|high|max) +- variant (string, optional): provider-specific reasoning/profile variant passed as --variant (for example minimal|low|medium|high|xhigh|max) - dangerouslySkipPermissions (boolean, optional): inject a runtime OpenCode config that allows \`external_directory\` access without interactive prompts; defaults to true for unattended Paperclip runs - promptTemplate (string, optional): run prompt template - command (string, optional): defaults to "opencode" diff --git a/server/src/__tests__/adapter-models.test.ts b/server/src/__tests__/adapter-models.test.ts index 7ec3f965..a6c5eb35 100644 --- a/server/src/__tests__/adapter-models.test.ts +++ b/server/src/__tests__/adapter-models.test.ts @@ -1,6 +1,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import { models as codexFallbackModels } from "@paperclipai/adapter-codex-local"; import { models as cursorFallbackModels } from "@paperclipai/adapter-cursor-local"; +import { models as opencodeFallbackModels } from "@paperclipai/adapter-opencode-local"; import { resetOpenCodeModelsCacheForTests } from "@paperclipai/adapter-opencode-local/server"; import { listAdapterModels } from "../adapters/index.js"; import { resetCodexModelsCacheForTests } from "../adapters/codex-models.js"; @@ -76,6 +77,14 @@ describe("adapter model listing", () => { expect(models).toEqual(cursorFallbackModels); }); + it("returns opencode fallback models including gpt-5.4", async () => { + process.env.PAPERCLIP_OPENCODE_COMMAND = "__paperclip_missing_opencode_command__"; + + const models = await listAdapterModels("opencode_local"); + + expect(models).toEqual(opencodeFallbackModels); + }); + it("loads cursor models dynamically and caches them", async () => { const runner = vi.fn(() => ({ status: 0, @@ -95,10 +104,4 @@ describe("adapter model listing", () => { expect(first.some((model) => model.id === "composer-1")).toBe(true); }); - it("returns no opencode models when opencode command is unavailable", async () => { - process.env.PAPERCLIP_OPENCODE_COMMAND = "__paperclip_missing_opencode_command__"; - - const models = await listAdapterModels("opencode_local"); - expect(models).toEqual([]); - }); }); diff --git a/server/src/adapters/registry.ts b/server/src/adapters/registry.ts index 3db7cdf9..1f195f86 100644 --- a/server/src/adapters/registry.ts +++ b/server/src/adapters/registry.ts @@ -44,6 +44,7 @@ import { } from "@paperclipai/adapter-opencode-local/server"; import { agentConfigurationDoc as openCodeAgentConfigurationDoc, + models as openCodeModels, } from "@paperclipai/adapter-opencode-local"; import { execute as openclawGatewayExecute, @@ -153,8 +154,8 @@ const openCodeLocalAdapter: ServerAdapterModule = { listSkills: listOpenCodeSkills, syncSkills: syncOpenCodeSkills, sessionCodec: openCodeSessionCodec, + models: openCodeModels, sessionManagement: getAdapterSessionManagement("opencode_local") ?? undefined, - models: [], listModels: listOpenCodeModels, supportsLocalAgentJwt: true, agentConfigurationDoc: openCodeAgentConfigurationDoc, diff --git a/ui/src/components/AgentConfigForm.tsx b/ui/src/components/AgentConfigForm.tsx index b9781a05..06c74e65 100644 --- a/ui/src/components/AgentConfigForm.tsx +++ b/ui/src/components/AgentConfigForm.tsx @@ -140,6 +140,7 @@ const codexThinkingEffortOptions = [ { id: "low", label: "Low" }, { id: "medium", label: "Medium" }, { id: "high", label: "High" }, + { id: "xhigh", label: "X-High" }, ] as const; const openCodeThinkingEffortOptions = [ @@ -148,6 +149,7 @@ const openCodeThinkingEffortOptions = [ { id: "low", label: "Low" }, { id: "medium", label: "Medium" }, { id: "high", label: "High" }, + { id: "xhigh", label: "X-High" }, { id: "max", label: "Max" }, ] as const; diff --git a/ui/src/components/NewIssueDialog.tsx b/ui/src/components/NewIssueDialog.tsx index 8db828ec..559a2055 100644 --- a/ui/src/components/NewIssueDialog.tsx +++ b/ui/src/components/NewIssueDialog.tsx @@ -99,6 +99,7 @@ const ISSUE_THINKING_EFFORT_OPTIONS = { { value: "low", label: "Low" }, { value: "medium", label: "Medium" }, { value: "high", label: "High" }, + { value: "xhigh", label: "X-High" }, ], opencode_local: [ { value: "", label: "Default" }, @@ -106,6 +107,7 @@ const ISSUE_THINKING_EFFORT_OPTIONS = { { value: "low", label: "Low" }, { value: "medium", label: "Medium" }, { value: "high", label: "High" }, + { value: "xhigh", label: "X-High" }, { value: "max", label: "Max" }, ], } as const;