diff --git a/AGENTS.md b/AGENTS.md index 2bccb1579..fd6313bdd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -101,7 +101,7 @@ oh-my-opencode/ | Sisyphus | anthropic/claude-opus-4-5 | Primary orchestrator | | Atlas | anthropic/claude-opus-4-5 | Master orchestrator | | oracle | openai/gpt-5.2 | Consultation, debugging | -| librarian | opencode/big-pickle | Docs, GitHub search | +| librarian | opencode/glm-4.7-free | Docs, GitHub search | | explore | opencode/gpt-5-nano | Fast codebase grep | | multimodal-looker | google/gemini-3-flash | PDF/image analysis | | Prometheus | anthropic/claude-opus-4-5 | Strategic planning | diff --git a/docs/configurations.md b/docs/configurations.md index 03f30735f..5e067f86e 100644 --- a/docs/configurations.md +++ b/docs/configurations.md @@ -896,7 +896,7 @@ Each agent has a defined provider priority chain. The system tries providers in |-------|-------------------|-------------------------| | **Sisyphus** | `claude-opus-4-5` | anthropic → github-copilot → opencode → antigravity → google | | **oracle** | `gpt-5.2` | openai → anthropic → google → github-copilot → opencode | -| **librarian** | `big-pickle` | opencode → github-copilot → anthropic | +| **librarian** | `glm-4.7-free` | opencode → github-copilot → anthropic | | **explore** | `gpt-5-nano` | anthropic → opencode | | **multimodal-looker** | `gemini-3-flash` | google → openai → zai-coding-plan → anthropic → opencode | | **Prometheus (Planner)** | `claude-opus-4-5` | anthropic → github-copilot → opencode → antigravity → google | diff --git a/docs/features.md b/docs/features.md index 6b60bcad3..f47c5b029 100644 --- a/docs/features.md +++ b/docs/features.md @@ -12,7 +12,7 @@ Oh-My-OpenCode provides 10 specialized AI agents. Each has distinct expertise, o |-------|-------|---------| | **Sisyphus** | `anthropic/claude-opus-4-5` | **The default orchestrator.** Plans, delegates, and executes complex tasks using specialized subagents with aggressive parallel execution. Todo-driven workflow with extended thinking (32k budget). | | **oracle** | `openai/gpt-5.2` | Architecture decisions, code review, debugging. Read-only consultation - stellar logical reasoning and deep analysis. Inspired by AmpCode. | -| **librarian** | `opencode/big-pickle` | Multi-repo analysis, documentation lookup, OSS implementation examples. Deep codebase understanding with evidence-based answers. Inspired by AmpCode. | +| **librarian** | `opencode/glm-4.7-free` | Multi-repo analysis, documentation lookup, OSS implementation examples. Deep codebase understanding with evidence-based answers. Inspired by AmpCode. | | **explore** | `opencode/gpt-5-nano` | Fast codebase exploration and contextual grep. Uses Gemini 3 Flash when Antigravity auth is configured, Haiku when Claude max20 is available, otherwise Grok. Inspired by Claude Code. | | **multimodal-looker** | `google/gemini-3-flash` | Visual content specialist. Analyzes PDFs, images, diagrams to extract information. Saves tokens by having another agent process media. | diff --git a/docs/guide/installation.md b/docs/guide/installation.md index f3cfae198..cef859de4 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -213,7 +213,7 @@ If Z.ai is the only provider available, all agents will use GLM models: #### OpenCode Zen -OpenCode Zen provides access to `opencode/` prefixed models including `opencode/claude-opus-4-5`, `opencode/gpt-5.2`, `opencode/gpt-5-nano`, and `opencode/big-pickle`. +OpenCode Zen provides access to `opencode/` prefixed models including `opencode/claude-opus-4-5`, `opencode/gpt-5.2`, `opencode/gpt-5-nano`, and `opencode/glm-4.7-free`. When OpenCode Zen is the best available provider (no native or Copilot), these models are used: @@ -222,7 +222,7 @@ When OpenCode Zen is the best available provider (no native or Copilot), these m | **Sisyphus** | `opencode/claude-opus-4-5` | | **Oracle** | `opencode/gpt-5.2` | | **Explore** | `opencode/gpt-5-nano` | -| **Librarian** | `opencode/big-pickle` | +| **Librarian** | `opencode/glm-4.7-free` | ##### Setup diff --git a/src/agents/AGENTS.md b/src/agents/AGENTS.md index 8bff26ce2..21366f685 100644 --- a/src/agents/AGENTS.md +++ b/src/agents/AGENTS.md @@ -28,7 +28,7 @@ agents/ | Sisyphus | anthropic/claude-opus-4-5 | 0.1 | Primary orchestrator | | Atlas | anthropic/claude-opus-4-5 | 0.1 | Master orchestrator | | oracle | openai/gpt-5.2 | 0.1 | Consultation, debugging | -| librarian | opencode/big-pickle | 0.1 | Docs, GitHub search | +| librarian | opencode/glm-4.7-free | 0.1 | Docs, GitHub search | | explore | opencode/gpt-5-nano | 0.1 | Fast contextual grep | | multimodal-looker | google/gemini-3-flash | 0.1 | PDF/image analysis | | Prometheus | anthropic/claude-opus-4-5 | 0.1 | Strategic planning | diff --git a/src/agents/librarian.ts b/src/agents/librarian.ts index abacd0326..1638680d6 100644 --- a/src/agents/librarian.ts +++ b/src/agents/librarian.ts @@ -1,7 +1,9 @@ import type { AgentConfig } from "@opencode-ai/sdk" -import type { AgentPromptMetadata } from "./types" +import type { AgentMode, AgentPromptMetadata } from "./types" import { createAgentToolRestrictions } from "../shared/permission-compat" +const MODE: AgentMode = "subagent" + export const LIBRARIAN_PROMPT_METADATA: AgentPromptMetadata = { category: "exploration", cost: "CHEAP", @@ -31,7 +33,7 @@ export function createLibrarianAgent(model: string): AgentConfig { return { description: "Specialized codebase understanding agent for multi-repository analysis, searching remote codebases, retrieving official documentation, and finding implementation examples using GitHub CLI, Context7, and Web Search. MUST BE USED when users ask to look up code in remote repositories, explain library internals, or find usage examples in open source. (Librarian - OhMyOpenCode)", - mode: "subagent" as const, + mode: MODE, model, temperature: 0.1, ...restrictions, diff --git a/src/agents/oracle.ts b/src/agents/oracle.ts index 5b7b80bd3..67da02703 100644 --- a/src/agents/oracle.ts +++ b/src/agents/oracle.ts @@ -1,8 +1,10 @@ import type { AgentConfig } from "@opencode-ai/sdk" -import type { AgentPromptMetadata } from "./types" +import type { AgentMode, AgentPromptMetadata } from "./types" import { isGptModel } from "./types" import { createAgentToolRestrictions } from "../shared/permission-compat" +const MODE: AgentMode = "subagent" + export const ORACLE_PROMPT_METADATA: AgentPromptMetadata = { category: "advisor", cost: "EXPENSIVE", @@ -106,7 +108,7 @@ export function createOracleAgent(model: string): AgentConfig { const base = { description: "Read-only consultation agent. High-IQ reasoning specialist for debugging hard problems and high-difficulty architecture design. (Oracle - OhMyOpenCode)", - mode: "subagent" as const, + mode: MODE, model, temperature: 0.1, ...restrictions, @@ -119,4 +121,5 @@ export function createOracleAgent(model: string): AgentConfig { return { ...base, thinking: { type: "enabled", budgetTokens: 32000 } } as AgentConfig } +createOracleAgent.mode = MODE diff --git a/src/cli/__snapshots__/model-fallback.test.ts.snap b/src/cli/__snapshots__/model-fallback.test.ts.snap index 0ac986a36..6d3c7ef29 100644 --- a/src/cli/__snapshots__/model-fallback.test.ts.snap +++ b/src/cli/__snapshots__/model-fallback.test.ts.snap @@ -5,54 +5,54 @@ exports[`generateModelConfig no providers available returns ULTIMATE_FALLBACK fo "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json", "agents": { "atlas": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "explore": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "librarian": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "metis": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "momus": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "multimodal-looker": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "oracle": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "prometheus": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "sisyphus": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, }, "categories": { "artistry": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "quick": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "ultrabrain": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "unspecified-high": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "unspecified-low": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "visual-engineering": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "writing": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, }, } @@ -199,7 +199,7 @@ exports[`generateModelConfig single native provider uses OpenAI models when only "model": "opencode/gpt-5-nano", }, "librarian": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "metis": { "model": "openai/gpt-5.2", @@ -230,7 +230,7 @@ exports[`generateModelConfig single native provider uses OpenAI models when only "model": "openai/gpt-5.2", }, "quick": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "ultrabrain": { "model": "openai/gpt-5.2-codex", @@ -266,7 +266,7 @@ exports[`generateModelConfig single native provider uses OpenAI models with isMa "model": "opencode/gpt-5-nano", }, "librarian": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "metis": { "model": "openai/gpt-5.2", @@ -297,7 +297,7 @@ exports[`generateModelConfig single native provider uses OpenAI models with isMa "model": "openai/gpt-5.2", }, "quick": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "ultrabrain": { "model": "openai/gpt-5.2-codex", @@ -333,7 +333,7 @@ exports[`generateModelConfig single native provider uses Gemini models when only "model": "opencode/gpt-5-nano", }, "librarian": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "metis": { "model": "google/gemini-3-pro", @@ -394,7 +394,7 @@ exports[`generateModelConfig single native provider uses Gemini models with isMa "model": "opencode/gpt-5-nano", }, "librarian": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "metis": { "model": "google/gemini-3-pro", @@ -585,7 +585,7 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models when on "model": "opencode/claude-haiku-4-5", }, "librarian": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "metis": { "model": "opencode/claude-opus-4-5", @@ -649,7 +649,7 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models with is "model": "opencode/claude-haiku-4-5", }, "librarian": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "metis": { "model": "opencode/claude-opus-4-5", @@ -839,7 +839,7 @@ exports[`generateModelConfig fallback providers uses ZAI model for librarian whe "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json", "agents": { "atlas": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "explore": { "model": "opencode/gpt-5-nano", @@ -848,42 +848,42 @@ exports[`generateModelConfig fallback providers uses ZAI model for librarian whe "model": "zai-coding-plan/glm-4.7", }, "metis": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "momus": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "multimodal-looker": { "model": "zai-coding-plan/glm-4.6v", }, "oracle": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "prometheus": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "sisyphus": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, }, "categories": { "artistry": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "quick": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "ultrabrain": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "unspecified-high": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "unspecified-low": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "visual-engineering": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "writing": { "model": "zai-coding-plan/glm-4.7", @@ -897,7 +897,7 @@ exports[`generateModelConfig fallback providers uses ZAI model for librarian wit "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json", "agents": { "atlas": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "explore": { "model": "opencode/gpt-5-nano", @@ -906,19 +906,19 @@ exports[`generateModelConfig fallback providers uses ZAI model for librarian wit "model": "zai-coding-plan/glm-4.7", }, "metis": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "momus": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "multimodal-looker": { "model": "zai-coding-plan/glm-4.6v", }, "oracle": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "prometheus": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "sisyphus": { "model": "zai-coding-plan/glm-4.7", @@ -926,22 +926,22 @@ exports[`generateModelConfig fallback providers uses ZAI model for librarian wit }, "categories": { "artistry": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "quick": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "ultrabrain": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "unspecified-high": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "unspecified-low": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "visual-engineering": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "writing": { "model": "zai-coding-plan/glm-4.7", @@ -961,7 +961,7 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen "model": "anthropic/claude-haiku-4-5", }, "librarian": { - "model": "opencode/big-pickle", + "model": "opencode/glm-4.7-free", }, "metis": { "model": "anthropic/claude-opus-4-5", diff --git a/src/cli/config-manager.test.ts b/src/cli/config-manager.test.ts index cd4d5ec25..9bea707df 100644 --- a/src/cli/config-manager.test.ts +++ b/src/cli/config-manager.test.ts @@ -316,7 +316,7 @@ describe("generateOmoConfig - model fallback system", () => { // #then should use ultimate fallback for all agents expect(result.$schema).toBe("https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json") - expect((result.agents as Record).sisyphus.model).toBe("opencode/big-pickle") + expect((result.agents as Record).sisyphus.model).toBe("opencode/glm-4.7-free") }) test("uses zai-coding-plan/glm-4.7 for librarian when Z.ai available", () => { diff --git a/src/cli/install.ts b/src/cli/install.ts index e6f72ba5c..d8cb85b05 100644 --- a/src/cli/install.ts +++ b/src/cli/install.ts @@ -178,7 +178,7 @@ async function runTuiMode(detected: DetectedConfig): Promise { } if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen) { - printWarning("No model providers configured. Using opencode/big-pickle as fallback.") + printWarning("No model providers configured. Using opencode/glm-4.7-free as fallback.") } console.log(`${SYMBOLS.star} ${color.bold(color.green(isUpdate ? "Configuration updated!" : "Installation complete!"))}`) @@ -480,7 +480,7 @@ export async function install(args: InstallArgs): Promise { } if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen) { - p.log.warn("No model providers configured. Using opencode/big-pickle as fallback.") + p.log.warn("No model providers configured. Using opencode/glm-4.7-free as fallback.") } p.note(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete") diff --git a/src/cli/model-fallback.ts b/src/cli/model-fallback.ts index 2862e4ad1..4d29f0fcc 100644 --- a/src/cli/model-fallback.ts +++ b/src/cli/model-fallback.ts @@ -36,7 +36,7 @@ export interface GeneratedOmoConfig { const ZAI_MODEL = "zai-coding-plan/glm-4.7" -const ULTIMATE_FALLBACK = "opencode/big-pickle" +const ULTIMATE_FALLBACK = "opencode/glm-4.7-free" const SCHEMA_URL = "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json" function toProviderAvailability(config: InstallConfig): ProviderAvailability { diff --git a/src/shared/agent-config-integration.test.ts b/src/shared/agent-config-integration.test.ts index 1510cbc44..961a359ed 100644 --- a/src/shared/agent-config-integration.test.ts +++ b/src/shared/agent-config-integration.test.ts @@ -46,7 +46,7 @@ describe("Agent Config Integration", () => { const config = { sisyphus: { model: "anthropic/claude-opus-4-5" }, oracle: { model: "openai/gpt-5.2" }, - librarian: { model: "opencode/big-pickle" }, + librarian: { model: "opencode/glm-4.7-free" }, } // #when - migration is applied @@ -65,7 +65,7 @@ describe("Agent Config Integration", () => { Sisyphus: { model: "anthropic/claude-opus-4-5" }, oracle: { model: "openai/gpt-5.2" }, "Prometheus (Planner)": { model: "anthropic/claude-opus-4-5" }, - librarian: { model: "opencode/big-pickle" }, + librarian: { model: "opencode/glm-4.7-free" }, } // #when - migration is applied diff --git a/src/shared/model-availability.test.ts b/src/shared/model-availability.test.ts index f636e638c..7e893a283 100644 --- a/src/shared/model-availability.test.ts +++ b/src/shared/model-availability.test.ts @@ -547,13 +547,13 @@ describe("fetchAvailableModels with provider-models cache (whitelist-filtered)", it("should prefer provider-models cache over models.json", async () => { writeProviderModelsCache({ models: { - opencode: ["big-pickle", "gpt-5-nano"], + opencode: ["glm-4.7-free", "gpt-5-nano"], anthropic: ["claude-opus-4-5"] }, connected: ["opencode", "anthropic"] }) writeModelsCache({ - opencode: { models: { "big-pickle": {}, "gpt-5-nano": {}, "gpt-5.2": {} } }, + opencode: { models: { "glm-4.7-free": {}, "gpt-5-nano": {}, "gpt-5.2": {} } }, anthropic: { models: { "claude-opus-4-5": {}, "claude-sonnet-4-5": {} } } }) @@ -562,7 +562,7 @@ describe("fetchAvailableModels with provider-models cache (whitelist-filtered)", }) expect(result.size).toBe(3) - expect(result.has("opencode/big-pickle")).toBe(true) + expect(result.has("opencode/glm-4.7-free")).toBe(true) expect(result.has("opencode/gpt-5-nano")).toBe(true) expect(result.has("anthropic/claude-opus-4-5")).toBe(true) expect(result.has("opencode/gpt-5.2")).toBe(false) @@ -574,7 +574,7 @@ describe("fetchAvailableModels with provider-models cache (whitelist-filtered)", //#then falls back to models.json (no whitelist filtering) it("should fallback to models.json when provider-models cache not found", async () => { writeModelsCache({ - opencode: { models: { "big-pickle": {}, "gpt-5-nano": {}, "gpt-5.2": {} } }, + opencode: { models: { "glm-4.7-free": {}, "gpt-5-nano": {}, "gpt-5.2": {} } }, }) const result = await fetchAvailableModels(undefined, { @@ -582,7 +582,7 @@ describe("fetchAvailableModels with provider-models cache (whitelist-filtered)", }) expect(result.size).toBe(3) - expect(result.has("opencode/big-pickle")).toBe(true) + expect(result.has("opencode/glm-4.7-free")).toBe(true) expect(result.has("opencode/gpt-5-nano")).toBe(true) expect(result.has("opencode/gpt-5.2")).toBe(true) }) @@ -593,7 +593,7 @@ describe("fetchAvailableModels with provider-models cache (whitelist-filtered)", it("should filter by connectedProviders even with provider-models cache", async () => { writeProviderModelsCache({ models: { - opencode: ["big-pickle"], + opencode: ["glm-4.7-free"], anthropic: ["claude-opus-4-5"], google: ["gemini-3-pro"] }, @@ -605,7 +605,7 @@ describe("fetchAvailableModels with provider-models cache (whitelist-filtered)", }) expect(result.size).toBe(1) - expect(result.has("opencode/big-pickle")).toBe(true) + expect(result.has("opencode/glm-4.7-free")).toBe(true) expect(result.has("anthropic/claude-opus-4-5")).toBe(false) expect(result.has("google/gemini-3-pro")).toBe(false) }) diff --git a/src/shared/model-requirements.test.ts b/src/shared/model-requirements.test.ts index 81579f14b..86d6e245c 100644 --- a/src/shared/model-requirements.test.ts +++ b/src/shared/model-requirements.test.ts @@ -353,7 +353,7 @@ describe("FallbackEntry type", () => { // #given - a FallbackEntry without variant const entry: FallbackEntry = { providers: ["opencode", "anthropic"], - model: "big-pickle", + model: "glm-4.7-free", } // #when - accessing variant @@ -383,7 +383,7 @@ describe("ModelRequirement type", () => { test("ModelRequirement variant is optional", () => { // #given - a ModelRequirement without top-level variant const requirement: ModelRequirement = { - fallbackChain: [{ providers: ["opencode"], model: "big-pickle" }], + fallbackChain: [{ providers: ["opencode"], model: "glm-4.7-free" }], } // #when - accessing variant diff --git a/src/shared/model-requirements.ts b/src/shared/model-requirements.ts index 4e10a6885..b82b7a90b 100644 --- a/src/shared/model-requirements.ts +++ b/src/shared/model-requirements.ts @@ -28,7 +28,7 @@ export const AGENT_MODEL_REQUIREMENTS: Record = { librarian: { fallbackChain: [ { providers: ["zai-coding-plan"], model: "glm-4.7" }, - { providers: ["opencode"], model: "big-pickle" }, + { providers: ["opencode"], model: "glm-4.7-free" }, { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" }, ], },