diff --git a/AGENTS.md b/AGENTS.md index 2bccb157..fd6313bd 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 03f30735..5e067f86 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 6b60bcad..f47c5b02 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 f3cfae19..cef859de 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 8bff26ce..21366f68 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 abacd032..1638680d 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 5b7b80bd..67da0270 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 0ac986a3..6d3c7ef2 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 cd4d5ec2..9bea707d 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 e6f72ba5..d8cb85b0 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 2862e4ad..4d29f0fc 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 1510cbc4..961a359e 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 f636e638..7e893a28 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 81579f14..86d6e245 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 4e10a688..b82b7a90 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" }, ], },