diff --git a/.github/assets/building-in-public.png b/.github/assets/building-in-public.png new file mode 100644 index 000000000..f22e3131b Binary files /dev/null and b/.github/assets/building-in-public.png differ diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 32f44fbe3..8a6f6e50d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -57,6 +57,7 @@ jobs: bun test src/cli/doctor/format-default.test.ts bun test src/tools/call-omo-agent/sync-executor.test.ts bun test src/tools/call-omo-agent/session-creator.test.ts + bun test src/tools/session-manager bun test src/features/opencode-skill-loader/loader.test.ts bun test src/hooks/anthropic-context-window-limit-recovery/recovery-hook.test.ts bun test src/hooks/anthropic-context-window-limit-recovery/executor.test.ts @@ -66,9 +67,8 @@ jobs: # Enumerate subdirectories/files explicitly to EXCLUDE mock-heavy files # that were already run in isolation above. # Excluded from src/cli: doctor/formatter.test.ts, doctor/format-default.test.ts - # Excluded from src/tools: call-omo-agent/sync-executor.test.ts, call-omo-agent/session-creator.test.ts + # Excluded from src/tools: call-omo-agent/sync-executor.test.ts, call-omo-agent/session-creator.test.ts, session-manager (all) # Excluded from src/hooks/anthropic-context-window-limit-recovery: recovery-hook.test.ts, executor.test.ts - # Excluded from src/tools: call-omo-agent/sync-executor.test.ts, call-omo-agent/session-creator.test.ts bun test bin script src/config src/mcp src/index.test.ts \ src/agents src/shared \ src/cli/run src/cli/config-manager src/cli/mcp-oauth \ @@ -77,7 +77,7 @@ jobs: src/cli/doctor/runner.test.ts src/cli/doctor/checks \ src/tools/ast-grep src/tools/background-task src/tools/delegate-task \ src/tools/glob src/tools/grep src/tools/interactive-bash \ - src/tools/look-at src/tools/lsp src/tools/session-manager \ + src/tools/look-at src/tools/lsp \ src/tools/skill src/tools/skill-mcp src/tools/slashcommand src/tools/task \ src/tools/call-omo-agent/background-agent-executor.test.ts \ src/tools/call-omo-agent/background-executor.test.ts \ diff --git a/.github/workflows/refresh-model-capabilities.yml b/.github/workflows/refresh-model-capabilities.yml new file mode 100644 index 000000000..dd34e43ed --- /dev/null +++ b/.github/workflows/refresh-model-capabilities.yml @@ -0,0 +1,46 @@ +name: Refresh Model Capabilities + +on: + schedule: + - cron: "17 4 * * 1" + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + refresh: + runs-on: ubuntu-latest + if: github.repository == 'code-yeongyu/oh-my-openagent' + steps: + - uses: actions/checkout@v4 + + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + env: + BUN_INSTALL_ALLOW_SCRIPTS: "@ast-grep/napi" + + - name: Refresh bundled model capabilities snapshot + run: bun run build:model-capabilities + + - name: Validate capability guardrails + run: bun run test:model-capabilities + + - name: Create refresh pull request + uses: peter-evans/create-pull-request@v7 + with: + commit-message: "chore: refresh model capabilities snapshot" + title: "chore: refresh model capabilities snapshot" + body: | + Automated refresh of `src/generated/model-capabilities.generated.json` from `https://models.dev/api.json`. + + This keeps the bundled capability snapshot aligned with upstream model metadata without relying on manual refreshes. + branch: automation/refresh-model-capabilities + delete-branch: true + labels: | + maintenance diff --git a/README.ja.md b/README.ja.md index 09217d775..c456f9234 100644 --- a/README.ja.md +++ b/README.ja.md @@ -4,6 +4,17 @@ > コアメンテナーのQが負傷したため、今週は Issue/PR への返信とリリースが遅れる可能性があります。 > ご理解とご支援に感謝します。 +> [!TIP] +> **Building in Public** +> +> メンテナーが Jobdori を使い、oh-my-opencode をリアルタイムで開発・メンテナンスしています。Jobdori は OpenClaw をベースに大幅カスタマイズされた AI アシスタントです。 +> すべての機能開発、修正、Issue トリアージを Discord でライブでご覧いただけます。 +> +> [![Building in Public](./.github/assets/building-in-public.png)](https://discord.gg/PUwSMR9XNk) +> +> [**→ #building-in-public で確認する**](https://discord.gg/PUwSMR9XNk) + + > [!NOTE] > > [![Sisyphus Labs - Sisyphus is the agent that codes like your team.](./.github/assets/sisyphuslabs.png?v=2)](https://sisyphuslabs.ai) diff --git a/README.ko.md b/README.ko.md index a6bd40ea3..560ea7e6b 100644 --- a/README.ko.md +++ b/README.ko.md @@ -4,6 +4,17 @@ > 핵심 메인테이너 Q가 부상을 입어, 이번 주에는 이슈/PR 응답 및 릴리스가 지연될 수 있습니다. > 양해와 응원에 감사드립니다. +> [!TIP] +> **Building in Public** +> +> 메인테이너가 Jobdori를 통해 oh-my-opencode를 실시간으로 개발하고 있습니다. Jobdori는 OpenClaw를 기반으로 대폭 커스터마이징된 AI 어시스턴트입니다. +> 모든 기능 개발, 버그 수정, 이슈 트리아지를 Discord에서 실시간으로 확인하세요. +> +> [![Building in Public](./.github/assets/building-in-public.png)](https://discord.gg/PUwSMR9XNk) +> +> [**→ #building-in-public에서 확인하기**](https://discord.gg/PUwSMR9XNk) + + > [!TIP] > 저희와 함께 하세요! > diff --git a/README.md b/README.md index 81d3af043..b6c500d5d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,13 @@ +> [!TIP] +> **Building in Public** +> +> The maintainer builds and maintains oh-my-opencode in real-time with Jobdori, an AI assistant built on a heavily customized fork of OpenClaw. +> Every feature, every fix, every issue triage — live in our Discord. +> +> [![Building in Public](./.github/assets/building-in-public.png)](https://discord.gg/PUwSMR9XNk) +> +> [**→ Watch it happen in #building-in-public**](https://discord.gg/PUwSMR9XNk) + > [!NOTE] > > [![Sisyphus Labs - Sisyphus is the agent that codes like your team.](./.github/assets/sisyphuslabs.png?v=2)](https://sisyphuslabs.ai) diff --git a/README.ru.md b/README.ru.md index 474470915..d52d964b6 100644 --- a/README.ru.md +++ b/README.ru.md @@ -4,6 +4,17 @@ > Ключевой мейнтейнер Q получил травму, поэтому на этой неделе ответы по issue/PR и релизы могут задерживаться. > Спасибо за терпение и поддержку. +> [!TIP] +> **Building in Public** +> +> Мейнтейнер разрабатывает и поддерживает oh-my-opencode в режиме реального времени с помощью Jobdori — ИИ-ассистента на базе глубоко кастомизированной версии OpenClaw. +> Каждая фича, каждый фикс, каждый триаж issue — в прямом эфире в нашем Discord. +> +> [![Building in Public](./.github/assets/building-in-public.png)](https://discord.gg/PUwSMR9XNk) +> +> [**→ Смотрите в #building-in-public**](https://discord.gg/PUwSMR9XNk) + + > [!NOTE] > > [![Sisyphus Labs - Sisyphus is the agent that codes like your team.](./.github/assets/sisyphuslabs.png?v=2)](https://sisyphuslabs.ai) diff --git a/README.zh-cn.md b/README.zh-cn.md index 06b42cad7..f0f0bd300 100644 --- a/README.zh-cn.md +++ b/README.zh-cn.md @@ -4,6 +4,17 @@ > 核心维护者 Q 因受伤,本周 issue/PR 回复和发布可能会延迟。 > 感谢你的耐心与支持。 +> [!TIP] +> **Building in Public** +> +> 维护者正在使用 Jobdori 实时开发和维护 oh-my-opencode。Jobdori 是基于 OpenClaw 深度定制的 AI 助手。 +> 每个功能开发、每次修复、每次 Issue 分类,都在 Discord 上实时进行。 +> +> [![Building in Public](./.github/assets/building-in-public.png)](https://discord.gg/PUwSMR9XNk) +> +> [**→ 在 #building-in-public 频道中查看**](https://discord.gg/PUwSMR9XNk) + + > [!NOTE] > > [![Sisyphus Labs - Sisyphus is the agent that codes like your team.](./.github/assets/sisyphuslabs.png?v=2)](https://sisyphuslabs.ai) diff --git a/assets/oh-my-opencode.schema.json b/assets/oh-my-opencode.schema.json index 223aba61a..3ab34f714 100644 --- a/assets/oh-my-opencode.schema.json +++ b/assets/oh-my-opencode.schema.json @@ -90,7 +90,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -247,6 +309,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -309,7 +373,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -466,6 +592,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -528,7 +656,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -685,6 +875,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -747,7 +939,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -904,6 +1158,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -969,7 +1225,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -1126,6 +1444,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -1188,7 +1508,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -1345,6 +1727,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -1407,7 +1791,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -1564,6 +2010,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -1626,7 +2074,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -1783,6 +2293,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -1845,7 +2357,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -2002,6 +2576,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -2064,7 +2640,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -2221,6 +2859,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -2283,7 +2923,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -2440,6 +3142,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -2502,7 +3206,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -2659,6 +3425,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -2721,7 +3489,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -2878,6 +3708,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -2940,7 +3772,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -3097,6 +3991,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -3170,7 +4066,69 @@ { "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "model": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "reasoningEffort": { + "type": "string", + "enum": [ + "none", + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + }, + "temperature": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "top_p": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "maxTokens": { + "type": "number" + }, + "thinking": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + }, + "budgetTokens": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "required": [ + "model" + ], + "additionalProperties": false + } + ] } } ] @@ -3213,6 +4171,8 @@ "reasoningEffort": { "type": "string", "enum": [ + "none", + "minimal", "low", "medium", "high", @@ -3736,6 +4696,168 @@ }, "additionalProperties": false }, + "model_capabilities": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "auto_refresh_on_start": { + "type": "boolean" + }, + "refresh_timeout_ms": { + "type": "integer", + "exclusiveMinimum": 0, + "maximum": 9007199254740991 + }, + "source_url": { + "type": "string", + "format": "uri" + } + }, + "additionalProperties": false + }, + "openclaw": { + "type": "object", + "properties": { + "enabled": { + "default": false, + "type": "boolean" + }, + "gateways": { + "default": {}, + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": { + "type": "object", + "properties": { + "type": { + "default": "http", + "type": "string", + "enum": [ + "http", + "command" + ] + }, + "url": { + "type": "string" + }, + "method": { + "default": "POST", + "type": "string" + }, + "headers": { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": { + "type": "string" + } + }, + "command": { + "type": "string" + }, + "timeout": { + "type": "number" + } + }, + "required": [ + "type", + "method" + ], + "additionalProperties": false + } + }, + "hooks": { + "default": {}, + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": { + "type": "object", + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "gateway": { + "type": "string" + }, + "instruction": { + "type": "string" + } + }, + "required": [ + "enabled", + "gateway", + "instruction" + ], + "additionalProperties": false + } + }, + "replyListener": { + "type": "object", + "properties": { + "discordBotToken": { + "type": "string" + }, + "discordChannelId": { + "type": "string" + }, + "discordMention": { + "type": "string" + }, + "authorizedDiscordUserIds": { + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "telegramBotToken": { + "type": "string" + }, + "telegramChatId": { + "type": "string" + }, + "pollIntervalMs": { + "default": 3000, + "type": "number" + }, + "rateLimitPerMinute": { + "default": 10, + "type": "number" + }, + "maxMessageLength": { + "default": 500, + "type": "number" + }, + "includePrefix": { + "default": true, + "type": "boolean" + } + }, + "required": [ + "authorizedDiscordUserIds", + "pollIntervalMs", + "rateLimitPerMinute", + "maxMessageLength", + "includePrefix" + ], + "additionalProperties": false + } + }, + "required": [ + "enabled", + "gateways", + "hooks" + ], + "additionalProperties": false + }, "babysitting": { "type": "object", "properties": { diff --git a/docs/guide/agent-model-matching.md b/docs/guide/agent-model-matching.md index ad1f80b7d..a0861c540 100644 --- a/docs/guide/agent-model-matching.md +++ b/docs/guide/agent-model-matching.md @@ -8,7 +8,7 @@ Think of AI models as developers on a team. Each has a different brain, differen This isn't a bug. It's the foundation of the entire system. -Oh My OpenCode assigns each agent a model that matches its _working style_ — like building a team where each person is in the role that fits their personality. +Oh My OpenAgent assigns each agent a model that matches its _working style_ — like building a team where each person is in the role that fits their personality. ### Sisyphus: The Sociable Lead @@ -187,7 +187,7 @@ See the [Orchestration System Guide](./orchestration.md) for how agents dispatch ```jsonc { - "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json", + "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json", "agents": { // Main orchestrator: Claude Opus or Kimi K2.5 work best diff --git a/docs/guide/installation.md b/docs/guide/installation.md index fd1a2367b..3bd1b410e 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -5,7 +5,7 @@ Paste this into your llm agent session: ``` -Install and configure oh-my-opencode by following the instructions here: +Install and configure oh-my-openagent by following the instructions here: https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/refs/heads/dev/docs/guide/installation.md ``` @@ -14,8 +14,8 @@ https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/refs/heads/dev/do Run the interactive installer: ```bash -bunx oh-my-opencode install # recommended -npx oh-my-opencode install # alternative +bunx oh-my-openagent install # recommended +npx oh-my-openagent install # alternative ``` > **Note**: The CLI ships with standalone binaries for all major platforms. No runtime (Bun/Node.js) is required for CLI execution after installation. @@ -34,7 +34,7 @@ After you install it, you can read this [overview guide](./overview.md) to under > curl -fsSL https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/refs/heads/dev/docs/guide/installation.md > ``` -If you're an LLM Agent helping set up oh-my-opencode, Welcome! You'll now help your user to install the best agent harness, OhMyOpenCode. Tell user this with greetings, with test 'oMoMoMoMo...' +If you're an LLM Agent helping set up oh-my-openagent, Welcome! You'll now help your user to install the best agent harness, OhMyOpenAgent. Tell user this with greetings, with test 'oMoMoMoMo...' follow these steps: @@ -96,19 +96,19 @@ Spawn a subagent to handle installation and report back - to save context. Based on user's answers, run the CLI installer with appropriate flags: ```bash -bunx oh-my-opencode install --no-tui --claude= --gemini= --copilot= [--openai=] [--opencode-go=] [--opencode-zen=] [--zai-coding-plan=] +bunx oh-my-openagent install --no-tui --claude= --gemini= --copilot= [--openai=] [--opencode-go=] [--opencode-zen=] [--zai-coding-plan=] ``` **Examples:** -- User has all native subscriptions: `bunx oh-my-opencode install --no-tui --claude=max20 --openai=yes --gemini=yes --copilot=no` -- User has only Claude: `bunx oh-my-opencode install --no-tui --claude=yes --gemini=no --copilot=no` -- User has Claude + OpenAI: `bunx oh-my-opencode install --no-tui --claude=yes --openai=yes --gemini=no --copilot=no` -- User has only GitHub Copilot: `bunx oh-my-opencode install --no-tui --claude=no --gemini=no --copilot=yes` -- User has Z.ai for Librarian: `bunx oh-my-opencode install --no-tui --claude=yes --gemini=no --copilot=no --zai-coding-plan=yes` -- User has only OpenCode Zen: `bunx oh-my-opencode install --no-tui --claude=no --gemini=no --copilot=no --opencode-zen=yes` -- User has OpenCode Go only: `bunx oh-my-opencode install --no-tui --claude=no --openai=no --gemini=no --copilot=no --opencode-go=yes` -- User has no subscriptions: `bunx oh-my-opencode install --no-tui --claude=no --gemini=no --copilot=no` +- User has all native subscriptions: `bunx oh-my-openagent install --no-tui --claude=max20 --openai=yes --gemini=yes --copilot=no` +- User has only Claude: `bunx oh-my-openagent install --no-tui --claude=yes --gemini=no --copilot=no` +- User has Claude + OpenAI: `bunx oh-my-openagent install --no-tui --claude=yes --openai=yes --gemini=no --copilot=no` +- User has only GitHub Copilot: `bunx oh-my-openagent install --no-tui --claude=no --gemini=no --copilot=yes` +- User has Z.ai for Librarian: `bunx oh-my-openagent install --no-tui --claude=yes --gemini=no --copilot=no --zai-coding-plan=yes` +- User has only OpenCode Zen: `bunx oh-my-openagent install --no-tui --claude=no --gemini=no --copilot=no --opencode-zen=yes` +- User has OpenCode Go only: `bunx oh-my-openagent install --no-tui --claude=no --openai=no --gemini=no --copilot=no --opencode-go=yes` +- User has no subscriptions: `bunx oh-my-openagent install --no-tui --claude=no --gemini=no --copilot=no` The CLI will: @@ -120,7 +120,7 @@ The CLI will: ```bash opencode --version # Should be 1.0.150 or higher -cat ~/.config/opencode/opencode.json # Should contain "oh-my-opencode" in plugin array +cat ~/.config/opencode/opencode.json # Should contain "oh-my-openagent" in plugin array ``` ### Step 4: Configure Authentication @@ -145,7 +145,7 @@ First, add the opencode-antigravity-auth plugin: ```json { - "plugin": ["oh-my-opencode", "opencode-antigravity-auth@latest"] + "plugin": ["oh-my-openagent", "opencode-antigravity-auth@latest"] } ``` @@ -154,9 +154,9 @@ First, add the opencode-antigravity-auth plugin: You'll also need full model settings in `opencode.json`. Read the [opencode-antigravity-auth documentation](https://github.com/NoeFabris/opencode-antigravity-auth), copy the full model configuration from the README, and merge carefully to avoid breaking the user's existing setup. The plugin now uses a **variant system** — models like `antigravity-gemini-3-pro` support `low`/`high` variants instead of separate `-low`/`-high` model entries. -##### oh-my-opencode Agent Model Override +##### oh-my-openagent Agent Model Override -The `opencode-antigravity-auth` plugin uses different model names than the built-in Google auth. Override the agent models in `oh-my-opencode.json` (or `.opencode/oh-my-opencode.json`): +The `opencode-antigravity-auth` plugin uses different model names than the built-in Google auth. Override the agent models in `oh-my-openagent.json` (or `.opencode/oh-my-openagent.json`): ```json { @@ -176,7 +176,7 @@ The `opencode-antigravity-auth` plugin uses different model names than the built **Available models (Gemini CLI quota)**: -- `google/gemini-2.5-flash`, `google/gemini-2.5-pro`, `google/gemini-3-flash-preview`, `google/gemini-3-pro-preview` +- `google/gemini-2.5-flash`, `google/gemini-2.5-pro`, `google/gemini-3-flash-preview`, `google/gemini-3.1-pro-preview` > **Note**: Legacy tier-suffixed names like `google/antigravity-gemini-3-pro-high` still work but variants are recommended. Use `--variant=high` with the base model name instead. @@ -201,11 +201,11 @@ GitHub Copilot is supported as a **fallback provider** when native providers are ##### Model Mappings -When GitHub Copilot is the best available provider, oh-my-opencode uses these model assignments: +When GitHub Copilot is the best available provider, oh-my-openagent uses these model assignments: | Agent | Model | | ------------- | --------------------------------- | -| **Sisyphus** | `github-copilot/claude-opus-4-6` | +| **Sisyphus** | `github-copilot/claude-opus-4.6` | | **Oracle** | `github-copilot/gpt-5.4` | | **Explore** | `github-copilot/grok-code-fast-1` | | **Librarian** | `github-copilot/gemini-3-flash` | @@ -243,7 +243,7 @@ When OpenCode Zen is the best available provider (no native or Copilot), these m Run the installer and select "Yes" for GitHub Copilot: ```bash -bunx oh-my-opencode install +bunx oh-my-openagent install # Select your subscriptions (Claude, ChatGPT, Gemini) # When prompted: "Do you have a GitHub Copilot subscription?" → Select "Yes" ``` @@ -251,7 +251,7 @@ bunx oh-my-opencode install Or use non-interactive mode: ```bash -bunx oh-my-opencode install --no-tui --claude=no --openai=no --gemini=no --copilot=yes +bunx oh-my-openagent install --no-tui --claude=no --openai=no --gemini=no --copilot=yes ``` Then authenticate with GitHub: @@ -263,7 +263,7 @@ opencode auth login ### Step 5: Understand Your Model Setup -You've just configured oh-my-opencode. Here's what got set up and why. +You've just configured oh-my-openagent. Here's what got set up and why. #### Model Families: What You're Working With @@ -294,7 +294,7 @@ Not all models behave the same way. Understanding which models are "similar" hel | Model | Provider(s) | Notes | | --------------------- | -------------------------------- | ----------------------------------------------------------- | -| **Gemini 3 Pro** | google, github-copilot, opencode | Excels at visual/frontend tasks. Different reasoning style. | +| **Gemini 3.1 Pro** | google, github-copilot, opencode | Excels at visual/frontend tasks. Different reasoning style. | | **Gemini 3 Flash** | google, github-copilot, opencode | Fast, good for doc search and light tasks. | | **MiniMax M2.7** | venice, opencode-go | Fast and smart. Good for utility tasks. Upgraded from M2.5. | | **MiniMax M2.7 Highspeed** | opencode | Ultra-fast MiniMax variant. Optimized for latency. | @@ -306,7 +306,7 @@ Not all models behave the same way. Understanding which models are "similar" hel | **Grok Code Fast 1** | github-copilot, venice | Very fast | Optimized for code grep/search. Default for Explore. | | **Claude Haiku 4.5** | anthropic, opencode | Fast | Good balance of speed and intelligence. | | **MiniMax M2.7 Highspeed** | opencode | Very fast | Ultra-fast MiniMax variant. Smart for its speed class. | -| **GPT-5.3-codex-spark** | openai | Extremely fast | Blazing fast but compacts so aggressively that oh-my-opencode's context management doesn't work well with it. Not recommended for omo agents. | +| **GPT-5.3-codex-spark** | openai | Extremely fast | Blazing fast but compacts so aggressively that oh-my-openagent's context management doesn't work well with it. Not recommended for omo agents. | #### What Each Agent Does and Which Model It Got @@ -317,7 +317,7 @@ Based on your subscriptions, here's how the agents were configured: | Agent | Role | Default Chain | What It Does | | ------------ | ---------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------- | | **Sisyphus** | Main ultraworker | Opus (max) → Kimi K2.5 → GLM 5 → Big Pickle | Primary coding agent. Orchestrates everything. **Never use GPT — no GPT prompt exists.** | -| **Metis** | Plan review | Opus (max) → Kimi K2.5 → GPT-5.4 → Gemini 3 Pro | Reviews Prometheus plans for gaps. | +| **Metis** | Plan review | Opus (max) → Kimi K2.5 → GPT-5.4 → Gemini 3.1 Pro | Reviews Prometheus plans for gaps. | **Dual-Prompt Agents** (auto-switch between Claude and GPT prompts): @@ -327,7 +327,7 @@ Priority: **Claude > GPT > Claude-like models** | Agent | Role | Default Chain | GPT Prompt? | | -------------- | ----------------- | ---------------------------------------------------------- | ---------------------------------------------------------------- | -| **Prometheus** | Strategic planner | Opus (max) → **GPT-5.4 (high)** → Kimi K2.5 → Gemini 3 Pro | Yes — XML-tagged, principle-driven (~300 lines vs ~1,100 Claude) | +| **Prometheus** | Strategic planner | Opus (max) → **GPT-5.4 (high)** → Kimi K2.5 → Gemini 3.1 Pro | Yes — XML-tagged, principle-driven (~300 lines vs ~1,100 Claude) | | **Atlas** | Todo orchestrator | **Kimi K2.5** → Sonnet → GPT-5.4 | Yes — GPT-optimized todo management | **GPT-Native Agents** (built for GPT, don't override to Claude): @@ -335,8 +335,8 @@ Priority: **Claude > GPT > Claude-like models** | Agent | Role | Default Chain | Notes | | -------------- | ---------------------- | -------------------------------------- | ------------------------------------------------------ | | **Hephaestus** | Deep autonomous worker | GPT-5.3-codex (medium) only | "Codex on steroids." No fallback. Requires GPT access. | -| **Oracle** | Architecture/debugging | GPT-5.4 (high) → Gemini 3 Pro → Opus | High-IQ strategic backup. GPT preferred. | -| **Momus** | High-accuracy reviewer | GPT-5.4 (medium) → Opus → Gemini 3 Pro | Verification agent. GPT preferred. | +| **Oracle** | Architecture/debugging | GPT-5.4 (high) → Gemini 3.1 Pro → Opus | High-IQ strategic backup. GPT preferred. | +| **Momus** | High-accuracy reviewer | GPT-5.4 (medium) → Opus → Gemini 3.1 Pro | Verification agent. GPT preferred. | **Utility Agents** (speed over intelligence): @@ -365,7 +365,7 @@ This is why Prometheus and Atlas ship separate prompts per model family — they #### Custom Model Configuration -If the user wants to override which model an agent uses, you can customize in `oh-my-opencode.json`: +If the user wants to override which model an agent uses, you can customize in `oh-my-openagent.json`: ```jsonc { @@ -407,7 +407,7 @@ GPT (5.3-codex, 5.2) > Claude Opus (decent fallback) > Gemini (acceptable) #### Provider Priority Chain -When multiple providers are available, oh-my-opencode uses this priority: +When multiple providers are available, oh-my-openagent uses this priority: ``` Native (anthropic/, openai/, google/) > Kimi for Coding > GitHub Copilot > Venice > OpenCode Zen > Z.ai Coding Plan @@ -425,7 +425,7 @@ Read this document again, think about you have done everything correctly. #### Say 'Congratulations! 🎉' to the user -Say to user: Congratulations! 🎉 You have successfully set up OhMyOpenCode! Type `opencode` in your terminal to start using it. +Say to user: Congratulations! 🎉 You have successfully set up OhMyOpenAgent! Type `opencode` in your terminal to start using it. #### Free advertising diff --git a/docs/guide/orchestration.md b/docs/guide/orchestration.md index babc5c0e8..44ef65ca9 100644 --- a/docs/guide/orchestration.md +++ b/docs/guide/orchestration.md @@ -1,6 +1,6 @@ # Orchestration System Guide -Oh My OpenCode's orchestration system transforms a simple AI agent into a coordinated development team through **separation of planning and execution**. +Oh My OpenAgent's orchestration system transforms a simple AI agent into a coordinated development team through **separation of planning and execution**. --- @@ -475,7 +475,7 @@ Use the `ulw` keyword in Sisyphus when: ## Configuration -You can control related features in `oh-my-opencode.json`: +You can control related features in `oh-my-openagent.json`: ```jsonc { diff --git a/docs/guide/overview.md b/docs/guide/overview.md index 3d44d543e..1d671d314 100644 --- a/docs/guide/overview.md +++ b/docs/guide/overview.md @@ -1,6 +1,6 @@ -# What Is Oh My OpenCode? +# What Is Oh My OpenAgent? -Oh My OpenCode is a multi-model agent orchestration harness for OpenCode. It transforms a single AI agent into a coordinated development team that actually ships code. +Oh My OpenAgent is a multi-model agent orchestration harness for OpenCode. It transforms a single AI agent into a coordinated development team that actually ships code. Not locked to Claude. Not locked to OpenAI. Not locked to anyone. @@ -15,7 +15,7 @@ Just better results, cheaper models, real orchestration. Paste this into your LLM agent session: ``` -Install and configure oh-my-opencode by following the instructions here: +Install and configure oh-my-openagent by following the instructions here: https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/refs/heads/dev/docs/guide/installation.md ``` @@ -41,13 +41,13 @@ We used to call this "Claude Code on steroids." That was wrong. This isn't about making Claude Code better. It's about breaking free from the idea that one model, one provider, one way of working is enough. Anthropic wants you locked in. OpenAI wants you locked in. Everyone wants you locked in. -Oh My OpenCode doesn't play that game. It orchestrates across models, picking the right brain for the right job. Claude for orchestration. GPT for deep reasoning. Gemini for frontend. GPT-5.4 Mini for quick tasks. All working together, automatically. +Oh My OpenAgent doesn't play that game. It orchestrates across models, picking the right brain for the right job. Claude for orchestration. GPT for deep reasoning. Gemini for frontend. GPT-5.4 Mini for quick tasks. All working together, automatically. --- ## How It Works: Agent Orchestration -Instead of one agent doing everything, Oh My OpenCode uses **specialized agents that delegate to each other** based on task type. +Instead of one agent doing everything, Oh My OpenAgent uses **specialized agents that delegate to each other** based on task type. **The Architecture:** @@ -154,7 +154,7 @@ Use Prometheus for multi-day projects, critical production changes, complex refa ## Agent Model Matching -Different agents work best with different models. Oh My OpenCode automatically assigns optimal models, but you can customize everything. +Different agents work best with different models. Oh My OpenAgent automatically assigns optimal models, but you can customize everything. ### Default Configuration @@ -168,7 +168,7 @@ You can override specific agents or categories in your config: ```jsonc { - "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json", + "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json", "agents": { // Main orchestrator: Claude Opus or Kimi K2.5 work best @@ -220,7 +220,7 @@ You can override specific agents or categories in your config: **Different-behavior models**: -- Gemini 3 Pro — excels at visual/frontend tasks +- Gemini 3.1 Pro — excels at visual/frontend tasks - MiniMax M2.7 / M2.7-highspeed — fast and smart for utility tasks - Grok Code Fast 1 — optimized for code grep/search @@ -232,7 +232,7 @@ See the [Agent-Model Matching Guide](./agent-model-matching.md) for complete det Claude Code is good. But it's a single agent running a single model doing everything alone. -Oh My OpenCode turns that into a coordinated team: +Oh My OpenAgent turns that into a coordinated team: **Parallel execution.** Claude Code processes one thing at a time. OmO fires background agents in parallel — research, implementation, and verification happening simultaneously. Like having 5 engineers instead of 1. @@ -246,7 +246,7 @@ Oh My OpenCode turns that into a coordinated team: **Discipline enforcement.** Todo enforcer yanks idle agents back to work. Comment checker strips AI slop. Ralph Loop keeps going until 100% done. The system doesn't let the agent slack off. -**The fundamental advantage.** Models have different temperaments. Claude thinks deeply. GPT reasons architecturally. Gemini visualizes. Haiku moves fast. Single-model tools force you to pick one personality for all tasks. Oh My OpenCode leverages them all, routing by task type. This isn't a temporary hack — it's the only architecture that makes sense as models specialize further. The gap between multi-model orchestration and single-model limitation widens every month. We're betting on that future. +**The fundamental advantage.** Models have different temperaments. Claude thinks deeply. GPT reasons architecturally. Gemini visualizes. Haiku moves fast. Single-model tools force you to pick one personality for all tasks. Oh My OpenAgent leverages them all, routing by task type. This isn't a temporary hack — it's the only architecture that makes sense as models specialize further. The gap between multi-model orchestration and single-model limitation widens every month. We're betting on that future. --- @@ -256,7 +256,7 @@ Before acting on any request, Sisyphus classifies your true intent. Are you asking for research? Implementation? Investigation? A fix? The Intent Gate figures out what you actually want, not just the literal words you typed. This means the agent understands context, nuance, and the real goal behind your request. -Claude Code doesn't have this. It takes your prompt and runs. Oh My OpenCode thinks first, then acts. +Claude Code doesn't have this. It takes your prompt and runs. Oh My OpenAgent thinks first, then acts. --- diff --git a/docs/manifesto.md b/docs/manifesto.md index 1d93a2195..89e6ccdea 100644 --- a/docs/manifesto.md +++ b/docs/manifesto.md @@ -1,6 +1,6 @@ # Manifesto -The principles and philosophy behind Oh My OpenCode. +The principles and philosophy behind Oh My OpenAgent. --- @@ -20,7 +20,7 @@ When you find yourself: That's not "human-AI collaboration." That's the AI failing to do its job. -**Oh My OpenCode is built on this premise**: Human intervention during agentic work is fundamentally a wrong signal. If the system is designed correctly, the agent should complete the work without requiring you to babysit it. +**Oh My OpenAgent is built on this premise**: Human intervention during agentic work is fundamentally a wrong signal. If the system is designed correctly, the agent should complete the work without requiring you to babysit it. --- @@ -144,7 +144,7 @@ Human Intent → Agent Execution → Verified Result (intervention only on true failure) ``` -Everything in Oh My OpenCode is designed to make this loop work: +Everything in Oh My OpenAgent is designed to make this loop work: | Feature | Purpose | |---------|---------| diff --git a/docs/model-capabilities-maintenance.md b/docs/model-capabilities-maintenance.md new file mode 100644 index 000000000..4f6d6bbce --- /dev/null +++ b/docs/model-capabilities-maintenance.md @@ -0,0 +1,33 @@ +# Model Capabilities Maintenance + +This project treats model capability resolution as a layered system: + +1. runtime metadata from connected providers +2. `models.dev` bundled/runtime snapshot data +3. explicit compatibility aliases +4. heuristic fallback as the last resort + +## Internal policy + +- Built-in OmO agent/category requirement models must use canonical model IDs. +- Aliases exist only to preserve compatibility with historical OmO names or provider-specific decorations. +- New decorated names like `-high`, `-low`, or `-thinking` should not be added to built-in requirements when a canonical model ID plus structured settings can express the same thing. +- If a provider or config input still uses an alias, normalize it at the edge and continue internally with the canonical ID. + +## When adding an alias + +- Add the alias rule to `src/shared/model-capability-aliases.ts`. +- Include a rationale for why the alias exists. +- Add or update tests so the alias is covered explicitly. +- Ensure the alias canonical target exists in the bundled `models.dev` snapshot. + +## Guardrails + +`bun run test:model-capabilities` enforces the following invariants: + +- exact alias targets must exist in the bundled snapshot +- exact alias keys must not silently become canonical `models.dev` IDs +- pattern aliases must not rewrite canonical snapshot IDs +- built-in requirement models must stay canonical and snapshot-backed + +The scheduled `refresh-model-capabilities` workflow runs these guardrails before opening an automated snapshot refresh PR. diff --git a/docs/reference/cli.md b/docs/reference/cli.md index fcac716cf..2d47a59ce 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -1,15 +1,15 @@ # CLI Reference -Complete reference for the `oh-my-opencode` command-line interface. +Complete reference for the `oh-my-openagent` command-line interface. ## Basic Usage ```bash # Display help -bunx oh-my-opencode +bunx oh-my-openagent # Or with npx -npx oh-my-opencode +npx oh-my-openagent ``` ## Commands @@ -27,20 +27,20 @@ npx oh-my-opencode ## install -Interactive installation tool for initial Oh-My-OpenCode setup. Provides a TUI based on `@clack/prompts`. +Interactive installation tool for initial Oh-My-OpenAgent setup. Provides a TUI based on `@clack/prompts`. ### Usage ```bash -bunx oh-my-opencode install +bunx oh-my-openagent install ``` ### Installation Process 1. **Provider Selection**: Choose your AI provider (Claude, ChatGPT, or Gemini) 2. **API Key Input**: Enter the API key for your selected provider -3. **Configuration File Creation**: Generates `opencode.json` or `oh-my-opencode.json` files -4. **Plugin Registration**: Automatically registers the oh-my-opencode plugin in OpenCode settings +3. **Configuration File Creation**: Generates `opencode.json` or `oh-my-openagent.json` files +4. **Plugin Registration**: Automatically registers the oh-my-openagent plugin in OpenCode settings ### Options @@ -53,12 +53,12 @@ bunx oh-my-opencode install ## doctor -Diagnoses your environment to ensure Oh-My-OpenCode is functioning correctly. Performs 17+ health checks. +Diagnoses your environment to ensure Oh-My-OpenAgent is functioning correctly. Performs 17+ health checks. ### Usage ```bash -bunx oh-my-opencode doctor +bunx oh-my-openagent doctor ``` ### Diagnostic Categories @@ -83,10 +83,10 @@ bunx oh-my-opencode doctor ### Example Output ``` -oh-my-opencode doctor +oh-my-openagent doctor ┌──────────────────────────────────────────────────┐ -│ Oh-My-OpenCode Doctor │ +│ Oh-My-OpenAgent Doctor │ └──────────────────────────────────────────────────┘ Installation @@ -94,7 +94,7 @@ Installation ✓ Plugin registered in opencode.json Configuration - ✓ oh-my-opencode.json is valid + ✓ oh-my-openagent.json is valid ⚠ categories.visual-engineering: using default model Authentication @@ -119,7 +119,7 @@ Executes OpenCode sessions and monitors task completion. ### Usage ```bash -bunx oh-my-opencode run [prompt] +bunx oh-my-openagent run [prompt] ``` ### Options @@ -148,16 +148,16 @@ Manages OAuth 2.1 authentication for remote MCP servers. ```bash # Login to an OAuth-protected MCP server -bunx oh-my-opencode mcp oauth login --server-url https://api.example.com +bunx oh-my-openagent mcp oauth login --server-url https://api.example.com # Login with explicit client ID and scopes -bunx oh-my-opencode mcp oauth login my-api --server-url https://api.example.com --client-id my-client --scopes "read,write" +bunx oh-my-openagent mcp oauth login my-api --server-url https://api.example.com --client-id my-client --scopes "read,write" # Remove stored OAuth tokens -bunx oh-my-opencode mcp oauth logout +bunx oh-my-openagent mcp oauth logout # Check OAuth token status -bunx oh-my-opencode mcp oauth status [server-name] +bunx oh-my-openagent mcp oauth status [server-name] ``` ### Options @@ -178,8 +178,8 @@ Tokens are stored in `~/.config/opencode/mcp-oauth.json` with `0600` permissions The CLI searches for configuration files in the following locations (in priority order): -1. **Project Level**: `.opencode/oh-my-opencode.json` -2. **User Level**: `~/.config/opencode/oh-my-opencode.json` +1. **Project Level**: `.opencode/oh-my-openagent.json` +2. **User Level**: `~/.config/opencode/oh-my-openagent.json` ### JSONC Support @@ -219,17 +219,17 @@ bun install -g opencode@latest ```bash # Reinstall plugin -bunx oh-my-opencode install +bunx oh-my-openagent install ``` ### Doctor Check Failures ```bash # Diagnose with detailed information -bunx oh-my-opencode doctor --verbose +bunx oh-my-openagent doctor --verbose # Check specific category only -bunx oh-my-opencode doctor --category authentication +bunx oh-my-openagent doctor --category authentication ``` --- @@ -240,10 +240,10 @@ Use the `--no-tui` option for CI/CD environments. ```bash # Run doctor in CI environment -bunx oh-my-opencode doctor --no-tui --json +bunx oh-my-openagent doctor --no-tui --json # Save results to file -bunx oh-my-opencode doctor --json > doctor-report.json +bunx oh-my-openagent doctor --json > doctor-report.json ``` --- diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index f39760322..a927f656a 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -1,6 +1,6 @@ # Configuration Reference -Complete reference for `oh-my-opencode.jsonc` configuration. This document covers every available option with examples. +Complete reference for `oh-my-openagent.jsonc` configuration. This document covers every available option with examples. --- @@ -44,13 +44,13 @@ Complete reference for `oh-my-opencode.jsonc` configuration. This document cover Priority order (project overrides user): -1. `.opencode/oh-my-opencode.jsonc` / `.opencode/oh-my-opencode.json` +1. `.opencode/oh-my-openagent.jsonc` / `.opencode/oh-my-openagent.json` 2. User config (`.jsonc` preferred over `.json`): | Platform | Path | | ----------- | ----------------------------------------- | -| macOS/Linux | `~/.config/opencode/oh-my-opencode.jsonc` | -| Windows | `%APPDATA%\opencode\oh-my-opencode.jsonc` | +| macOS/Linux | `~/.config/opencode/oh-my-openagent.jsonc` | +| Windows | `%APPDATA%\opencode\oh-my-openagent.jsonc` | JSONC supports `// line comments`, `/* block comments */`, and trailing commas. @@ -58,11 +58,11 @@ Enable schema autocomplete: ```json { - "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json" + "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json" } ``` -Run `bunx oh-my-opencode install` for guided setup. Run `opencode models` to list available models. +Run `bunx oh-my-openagent install` for guided setup. Run `opencode models` to list available models. ### Quick Start Example @@ -70,7 +70,7 @@ Here's a practical starting configuration: ```jsonc { - "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json", + "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-openagent.schema.json", "agents": { // Main orchestrator: Claude Opus or Kimi K2.5 work best @@ -291,7 +291,7 @@ Disable categories: `{ "disabled_categories": ["ultrabrain"] }` | **unspecified-high** | `claude-opus-4-6` | `claude-opus-4-6` → `gpt-5.4 (high)` → `glm-5` → `k2p5` → `kimi-k2.5` | | **writing** | `gemini-3-flash` | `gemini-3-flash` → `claude-sonnet-4-6` → `minimax-m2.7` | -Run `bunx oh-my-opencode doctor --verbose` to see effective model resolution for your config. +Run `bunx oh-my-openagent doctor --verbose` to see effective model resolution for your config. --- diff --git a/docs/reference/features.md b/docs/reference/features.md index 5240424b4..63fc37204 100644 --- a/docs/reference/features.md +++ b/docs/reference/features.md @@ -1,8 +1,8 @@ -# Oh-My-OpenCode Features Reference +# Oh-My-OpenAgent Features Reference ## Agents -Oh-My-OpenCode provides 11 specialized AI agents. Each has distinct expertise, optimized models, and tool permissions. +Oh-My-OpenAgent provides 11 specialized AI agents. Each has distinct expertise, optimized models, and tool permissions. ### Core Agents @@ -90,7 +90,7 @@ When running inside tmux: - Each pane shows agent output live - Auto-cleanup when agents complete -Customize agent models, prompts, and permissions in `oh-my-opencode.json`. +Customize agent models, prompts, and permissions in `oh-my-openagent.json`. ## Category System @@ -129,7 +129,7 @@ task({ ### Custom Categories -You can define custom categories in `oh-my-opencode.json`. +You can define custom categories in `oh-my-openagent.json`. #### Category Configuration Schema @@ -237,7 +237,7 @@ Skills provide specialized workflows with embedded MCP servers and detailed inst ### Browser Automation Options -Oh-My-OpenCode provides two browser automation providers, configurable via `browser_automation_engine.provider`. +Oh-My-OpenAgent provides two browser automation providers, configurable via `browser_automation_engine.provider`. #### Option 1: Playwright MCP (Default) @@ -558,7 +558,7 @@ Requires `experimental.task_system: true` in config. #### Task System Details -**Note on Claude Code Alignment**: This implementation follows Claude Code's internal Task tool signatures (`TaskCreate`, `TaskUpdate`, `TaskList`, `TaskGet`) and field naming conventions (`subject`, `blockedBy`, `blocks`, etc.). However, Anthropic has not published official documentation for these tools. This is Oh My OpenCode's own implementation based on observed Claude Code behavior and internal specifications. +**Note on Claude Code Alignment**: This implementation follows Claude Code's internal Task tool signatures (`TaskCreate`, `TaskUpdate`, `TaskList`, `TaskGet`) and field naming conventions (`subject`, `blockedBy`, `blocks`, etc.). However, Anthropic has not published official documentation for these tools. This is Oh My OpenAgent's own implementation based on observed Claude Code behavior and internal specifications. **Task Schema**: @@ -844,7 +844,7 @@ When a skill MCP has `oauth` configured: Pre-authenticate via CLI: ```bash -bunx oh-my-opencode mcp oauth login --server-url https://api.example.com +bunx oh-my-openagent mcp oauth login --server-url https://api.example.com ``` ## Context Injection diff --git a/docs/superpowers/plans/2026-03-17-model-settings-compatibility-resolver.md b/docs/superpowers/plans/2026-03-17-model-settings-compatibility-resolver.md new file mode 100644 index 000000000..3c22296bf --- /dev/null +++ b/docs/superpowers/plans/2026-03-17-model-settings-compatibility-resolver.md @@ -0,0 +1,86 @@ +# Model Settings Compatibility Resolver Implementation Plan + +> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Centralize compatibility handling for `variant` and `reasoningEffort` so an already-selected model receives the best valid settings for that exact model. + +**Architecture:** Introduce a pure shared resolver in `src/shared/` that computes compatible settings and records downgrades/removals. Integrate it first in `chat.params`, then keep Claude-specific effort logic as a thin layer rather than a special-case policy owner. + +**Tech Stack:** TypeScript, Bun test, existing shared model normalization/utilities, OpenCode plugin `chat.params` path. + +--- + +### Task 1: Create the pure compatibility resolver + +**Files:** +- Create: `src/shared/model-settings-compatibility.ts` +- Create: `src/shared/model-settings-compatibility.test.ts` +- Modify: `src/shared/index.ts` + +- [ ] **Step 1: Write failing tests for exact keep behavior** +- [ ] **Step 2: Write failing tests for downgrade behavior (`max` -> `high`, `xhigh` -> `high` where needed)** +- [ ] **Step 3: Write failing tests for unsupported-value removal** +- [ ] **Step 4: Write failing tests for model-family distinctions (Opus vs Sonnet/Haiku, GPT-family variants)** +- [ ] **Step 5: Implement the pure resolver with explicit capability ladders** +- [ ] **Step 6: Export the resolver from `src/shared/index.ts`** +- [ ] **Step 7: Run `bun test src/shared/model-settings-compatibility.test.ts`** +- [ ] **Step 8: Commit** + +### Task 2: Integrate resolver into chat.params + +**Files:** +- Modify: `src/plugin/chat-params.ts` +- Modify: `src/plugin/chat-params.test.ts` + +- [ ] **Step 1: Write failing tests showing `chat.params` applies resolver output to runtime settings** +- [ ] **Step 2: Ensure tests cover both `variant` and `reasoningEffort` decisions** +- [ ] **Step 3: Update `chat-params.ts` to call the shared resolver before hook-specific adjustments** +- [ ] **Step 4: Preserve existing prompt-param-store merging behavior** +- [ ] **Step 5: Run `bun test src/plugin/chat-params.test.ts`** +- [ ] **Step 6: Commit** + +### Task 3: Re-scope anthropic-effort around the resolver + +**Files:** +- Modify: `src/hooks/anthropic-effort/hook.ts` +- Modify: `src/hooks/anthropic-effort/index.test.ts` + +- [ ] **Step 1: Write failing tests that codify the intended remaining Anthropic-specific behavior after centralization** +- [ ] **Step 2: Reduce `anthropic-effort` to Claude/Anthropic-specific effort injection where still needed** +- [ ] **Step 3: Remove duplicated compatibility policy from the hook if the shared resolver now owns it** +- [ ] **Step 4: Run `bun test src/hooks/anthropic-effort/index.test.ts`** +- [ ] **Step 5: Commit** + +### Task 4: Add integration/regression coverage across real request paths + +**Files:** +- Modify: `src/plugin/chat-params.test.ts` +- Modify: `src/hooks/anthropic-effort/index.test.ts` +- Add tests only where needed in nearby suites + +- [ ] **Step 1: Add regression test for non-Opus Claude with `variant=max` resolving to compatible settings without ad hoc path-only logic** +- [ ] **Step 2: Add regression test for GPT-style `reasoningEffort` compatibility** +- [ ] **Step 3: Add regression test showing supported values remain unchanged** +- [ ] **Step 4: Run the focused test set** +- [ ] **Step 5: Commit** + +### Task 5: Verify full quality bar + +**Files:** +- No intended code changes + +- [ ] **Step 1: Run `bun run typecheck`** +- [ ] **Step 2: Run a focused suite for the touched files** +- [ ] **Step 3: If clean, run `bun test`** +- [ ] **Step 4: Review diff for accidental scope creep** +- [ ] **Step 5: Commit any final cleanup** + +### Task 6: Prepare PR metadata + +**Files:** +- No repo file change required unless docs are updated further + +- [ ] **Step 1: Write a human summary explaining this is settings compatibility, not model fallback** +- [ ] **Step 2: Document scope: Phase 1 covers `variant` and `reasoningEffort` only** +- [ ] **Step 3: Document explicit non-goals: no model switching, no automatic upscaling in Phase 1** +- [ ] **Step 4: Request review** diff --git a/docs/superpowers/specs/2026-03-17-model-settings-compatibility-design.md b/docs/superpowers/specs/2026-03-17-model-settings-compatibility-design.md new file mode 100644 index 000000000..0046bfe7b --- /dev/null +++ b/docs/superpowers/specs/2026-03-17-model-settings-compatibility-design.md @@ -0,0 +1,164 @@ +# Model Settings Compatibility Resolver Design + +## Goal + +Introduce a central resolver that takes an already-selected model and a set of desired model settings, then returns the best compatible configuration for that exact model. + +This is explicitly separate from model fallback. + +## Problem + +Today, logic for `variant` and `reasoningEffort` compatibility is scattered across multiple places: +- `hooks/anthropic-effort` +- `plugin/chat-params` +- agent/category/fallback config layers +- delegate/background prompt plumbing + +That creates inconsistent behavior: +- some paths clamp unsupported levels +- some paths pass them through unchanged +- some paths silently drop them +- some paths use model-family-specific assumptions that do not generalize + +The result is brittle request behavior even when the chosen model itself is valid. + +## Scope + +Phase 1 covers only: +- `variant` +- `reasoningEffort` + +Out of scope for Phase 1: +- model fallback itself +- `thinking` +- `maxTokens` +- `temperature` +- `top_p` +- automatic upward remapping of settings + +## Desired behavior + +Given a fixed model and desired settings: +1. If a desired value is supported, keep it. +2. If not supported, downgrade to the nearest lower compatible value. +3. If no compatible value exists, drop the field. +4. Do not switch models. +5. Do not automatically upgrade settings in Phase 1. + +## Architecture + +Add a central module: +- `src/shared/model-settings-compatibility.ts` + +Core API: + +```ts +type DesiredModelSettings = { + variant?: string + reasoningEffort?: string +} + +type ModelSettingsCompatibilityInput = { + providerID: string + modelID: string + desired: DesiredModelSettings +} + +type ModelSettingsCompatibilityChange = { + field: "variant" | "reasoningEffort" + from: string + to?: string + reason: string +} + +type ModelSettingsCompatibilityResult = { + variant?: string + reasoningEffort?: string + changes: ModelSettingsCompatibilityChange[] +} +``` + +## Compatibility model + +Phase 1 should be **metadata-first where the platform exposes reliable capability data**, and only fall back to family-based rules when that metadata is absent. + +### Variant compatibility + +Preferred source of truth: +- OpenCode/provider model metadata (`variants`) + +Fallback when metadata is unavailable: +- family-based ladders + +Examples of fallback ladders: +- Claude Opus family: `low`, `medium`, `high`, `max` +- Claude Sonnet/Haiku family: `low`, `medium`, `high` +- OpenAI GPT family: conservative family fallback only when metadata is missing +- Unknown family: drop unsupported values conservatively + +### Reasoning effort compatibility + +Current Phase 1 source of truth: +- conservative model/provider family heuristics + +Reason: +- the currently available OpenCode SDK/provider metadata exposes model `variants`, but does not expose an equivalent per-model capability list for `reasoningEffort` levels + +Examples: +- GPT/OpenAI-style models: `low`, `medium`, `high`, `xhigh` where supported by family heuristics +- Claude family via current OpenCode path: treat `reasoningEffort` as unsupported in Phase 1 and remove it + +The resolver should remain pure model/settings logic only. Transport restrictions remain the responsibility of the request-building path. + +## Separation of concerns + +This design intentionally separates: +- model selection (`resolveModel...`, fallback chains) +- settings compatibility (this resolver) +- request transport compatibility (`chat.params`, prompt body constraints) + +That keeps responsibilities clear: +- choose model first +- normalize settings second +- build request third + +## First integration point + +Phase 1 should first integrate into `chat.params`. + +Why: +- it is already the centralized path for request-time tuning +- it can influence provider-facing options without leaking unsupported fields into prompt payload bodies +- it avoids trying to patch every prompt constructor at once + +## Rollout plan + +### Phase 1 +- add resolver module and tests +- integrate into `chat.params` +- migrate `anthropic-effort` to either use the resolver or become a thin Claude-specific supplement around it + +### Phase 2 +- expand to `thinking`, `maxTokens`, `temperature`, `top_p` +- formalize request-path capability tables if needed + +### Phase 3 +- centralize all variant/reasoning normalization away from scattered hooks and ad hoc callers + +## Risks + +- Overfitting family rules to current model naming conventions +- Accidentally changing request semantics on paths that currently rely on implicit behavior +- Mixing provider transport limitations with model capability logic + +## Mitigations + +- Keep resolver pure and narrowly scoped in Phase 1 +- Add explicit regression tests for keep/downgrade/drop decisions +- Integrate at one central point first (`chat.params`) +- Preserve existing behavior where desired values are already valid + +## Recommendation + +Proceed with the central resolver as a new, isolated implementation in a dedicated branch/worktree. +This is the clean long-term path and is more reviewable than continuing to add special-case clamps in hooks. diff --git a/docs/troubleshooting/ollama.md b/docs/troubleshooting/ollama.md index 454be264d..986b7239b 100644 --- a/docs/troubleshooting/ollama.md +++ b/docs/troubleshooting/ollama.md @@ -4,7 +4,7 @@ ### Problem -When using Ollama as a provider with oh-my-opencode agents, you may encounter: +When using Ollama as a provider with oh-my-openagent agents, you may encounter: ``` JSON Parse error: Unexpected EOF @@ -26,7 +26,7 @@ Claude Code SDK expects a single JSON object, not multiple NDJSON lines, causing **Why this happens:** - **Ollama API**: Returns streaming responses as NDJSON by design - **Claude Code SDK**: Doesn't properly handle NDJSON responses for tool calls -- **oh-my-opencode**: Passes through the SDK's behavior (can't fix at this layer) +- **oh-my-openagent**: Passes through the SDK's behavior (can't fix at this layer) ## Solutions @@ -114,7 +114,7 @@ curl -s http://localhost:11434/api/chat \ ## Related Issues -- **oh-my-opencode**: https://github.com/code-yeongyu/oh-my-openagent/issues/1124 +- **oh-my-openagent**: https://github.com/code-yeongyu/oh-my-openagent/issues/1124 - **Ollama API Docs**: https://github.com/ollama/ollama/blob/main/docs/api.md ## Getting Help diff --git a/package.json b/package.json index 952fdbcfc..2c4a4e857 100644 --- a/package.json +++ b/package.json @@ -25,10 +25,12 @@ "build:all": "bun run build && bun run build:binaries", "build:binaries": "bun run script/build-binaries.ts", "build:schema": "bun run script/build-schema.ts", + "build:model-capabilities": "bun run script/build-model-capabilities.ts", "clean": "rm -rf dist", "prepare": "bun run build", "postinstall": "node postinstall.mjs", "prepublishOnly": "bun run clean && bun run build", + "test:model-capabilities": "bun test src/shared/model-capability-aliases.test.ts src/shared/model-capability-guardrails.test.ts src/shared/model-capabilities.test.ts src/cli/doctor/checks/model-resolution.test.ts --bail", "typecheck": "tsc --noEmit", "test": "bun test" }, diff --git a/script/build-model-capabilities.ts b/script/build-model-capabilities.ts new file mode 100644 index 000000000..64f1d84f2 --- /dev/null +++ b/script/build-model-capabilities.ts @@ -0,0 +1,13 @@ +import { writeFileSync } from "fs" +import { resolve } from "path" +import { + fetchModelCapabilitiesSnapshot, + MODELS_DEV_SOURCE_URL, +} from "../src/shared/model-capabilities-cache" + +const OUTPUT_PATH = resolve(import.meta.dir, "../src/generated/model-capabilities.generated.json") + +console.log(`Fetching model capabilities snapshot from ${MODELS_DEV_SOURCE_URL}...`) +const snapshot = await fetchModelCapabilitiesSnapshot() +writeFileSync(OUTPUT_PATH, `${JSON.stringify(snapshot, null, 2)}\n`) +console.log(`Generated ${OUTPUT_PATH} with ${Object.keys(snapshot.models).length} models`) diff --git a/signatures/cla.json b/signatures/cla.json index 7aeafb4ab..54511aade 100644 --- a/signatures/cla.json +++ b/signatures/cla.json @@ -2271,6 +2271,62 @@ "created_at": "2026-03-20T07:34:22Z", "repoId": 1108837393, "pullRequestNo": 2718 + }, + { + "name": "whackur", + "id": 26926041, + "comment_id": 4102330445, + "created_at": "2026-03-21T05:27:17Z", + "repoId": 1108837393, + "pullRequestNo": 2733 + }, + { + "name": "ndaemy", + "id": 18691542, + "comment_id": 4103008804, + "created_at": "2026-03-21T10:18:22Z", + "repoId": 1108837393, + "pullRequestNo": 2734 + }, + { + "name": "0xYiliu", + "id": 3838688, + "comment_id": 4104738337, + "created_at": "2026-03-21T22:59:33Z", + "repoId": 1108837393, + "pullRequestNo": 2738 + }, + { + "name": "hunghoang3011", + "id": 65234777, + "comment_id": 4107900881, + "created_at": "2026-03-23T04:28:20Z", + "repoId": 1108837393, + "pullRequestNo": 2758 + }, + { + "name": "anas-asghar4831", + "id": 110368394, + "comment_id": 4128950310, + "created_at": "2026-03-25T18:48:19Z", + "repoId": 1108837393, + "pullRequestNo": 2837 + }, + { + "name": "clansty", + "id": 18461360, + "comment_id": 4129934858, + "created_at": "2026-03-25T21:33:35Z", + "repoId": 1108837393, + "pullRequestNo": 2839 + }, + { + "name": "ventsislav-georgiev", + "id": 5616486, + "comment_id": 4130417794, + "created_at": "2026-03-25T23:11:32Z", + "repoId": 1108837393, + "pullRequestNo": 2840 } ] } \ No newline at end of file diff --git a/src/agents/builtin-agents/agent-overrides.ts b/src/agents/builtin-agents/agent-overrides.ts index 89873def6..4220f713b 100644 --- a/src/agents/builtin-agents/agent-overrides.ts +++ b/src/agents/builtin-agents/agent-overrides.ts @@ -44,6 +44,10 @@ export function mergeAgentConfig( const { prompt_append, ...rest } = migratedOverride const merged = deepMerge(base, rest as Partial) + if (merged.prompt && typeof merged.prompt === 'string' && merged.prompt.startsWith('file://')) { + merged.prompt = resolvePromptAppend(merged.prompt, directory) + } + if (prompt_append && merged.prompt) { merged.prompt = merged.prompt + "\n" + resolvePromptAppend(prompt_append, directory) } diff --git a/src/agents/builtin-agents/atlas-agent.ts b/src/agents/builtin-agents/atlas-agent.ts index f1658ebc9..bea50480b 100644 --- a/src/agents/builtin-agents/atlas-agent.ts +++ b/src/agents/builtin-agents/atlas-agent.ts @@ -39,7 +39,7 @@ export function maybeCreateAtlasConfig(input: { const atlasRequirement = AGENT_MODEL_REQUIREMENTS["atlas"] const atlasResolution = applyModelResolution({ - uiSelectedModel: orchestratorOverride?.model ? undefined : uiSelectedModel, + uiSelectedModel: orchestratorOverride?.model !== undefined ? undefined : uiSelectedModel, userModel: orchestratorOverride?.model, requirement: atlasRequirement, availableModels, diff --git a/src/agents/builtin-agents/general-agents.ts b/src/agents/builtin-agents/general-agents.ts index 7727cf999..f5fd1d920 100644 --- a/src/agents/builtin-agents/general-agents.ts +++ b/src/agents/builtin-agents/general-agents.ts @@ -8,6 +8,7 @@ import { buildAgent, isFactory } from "../agent-builder" import { applyOverrides } from "./agent-overrides" import { applyEnvironmentContext } from "./environment-context" import { applyModelResolution, getFirstFallbackModel } from "./model-resolution" +import { log } from "../../shared/logger" export function collectPendingBuiltinAgents(input: { agentSources: Record @@ -69,13 +70,19 @@ export function collectPendingBuiltinAgents(input: { const isPrimaryAgent = isFactory(source) && source.mode === "primary" let resolution = applyModelResolution({ - uiSelectedModel: (isPrimaryAgent && !override?.model) ? uiSelectedModel : undefined, + uiSelectedModel: (isPrimaryAgent && override?.model === undefined) ? uiSelectedModel : undefined, userModel: override?.model, requirement, availableModels, systemDefaultModel, }) - if (!resolution && isFirstRunNoCache && !override?.model) { + if (!resolution) { + if (override?.model) { + log("[agent-registration] User-configured model could not be resolved, falling back", { + agent: agentName, + configuredModel: override.model, + }) + } resolution = getFirstFallbackModel(requirement) } if (!resolution) continue diff --git a/src/agents/builtin-agents/sisyphus-agent.ts b/src/agents/builtin-agents/sisyphus-agent.ts index a28879b7a..d326f9a6a 100644 --- a/src/agents/builtin-agents/sisyphus-agent.ts +++ b/src/agents/builtin-agents/sisyphus-agent.ts @@ -52,7 +52,7 @@ export function maybeCreateSisyphusConfig(input: { if (disabledAgents.includes("sisyphus") || !meetsSisyphusAnyModelRequirement) return undefined let sisyphusResolution = applyModelResolution({ - uiSelectedModel: sisyphusOverride?.model ? undefined : uiSelectedModel, + uiSelectedModel: sisyphusOverride?.model !== undefined ? undefined : uiSelectedModel, userModel: sisyphusOverride?.model, requirement: sisyphusRequirement, availableModels, diff --git a/src/agents/dynamic-agent-prompt-builder.test.ts b/src/agents/dynamic-agent-prompt-builder.test.ts index 1fb47e4b4..7fab72a75 100644 --- a/src/agents/dynamic-agent-prompt-builder.test.ts +++ b/src/agents/dynamic-agent-prompt-builder.test.ts @@ -181,7 +181,7 @@ describe("buildParallelDelegationSection", () => { it("#given non-Claude model with deep category #when building #then returns aggressive delegation section", () => { //#given - const model = "google/gemini-3-pro" + const model = "google/gemini-3.1-pro" const categories = [deepCategory, otherCategory] //#when @@ -237,7 +237,7 @@ describe("buildParallelDelegationSection", () => { describe("buildNonClaudePlannerSection", () => { it("#given non-Claude model #when building #then returns plan agent section", () => { //#given - const model = "google/gemini-3-pro" + const model = "google/gemini-3.1-pro" //#when const result = buildNonClaudePlannerSection(model) @@ -272,4 +272,3 @@ describe("buildNonClaudePlannerSection", () => { }) }) - diff --git a/src/agents/hephaestus/gpt-5-3-codex.ts b/src/agents/hephaestus/gpt-5-3-codex.ts index 9a5e43b18..2bde48495 100644 --- a/src/agents/hephaestus/gpt-5-3-codex.ts +++ b/src/agents/hephaestus/gpt-5-3-codex.ts @@ -162,6 +162,10 @@ Asking the user is the LAST resort after exhausting creative alternatives. - User asks a question implying work → Answer briefly, DO the implied work in the same turn - You wrote a plan in your response → EXECUTE the plan before ending turn — plans are starting lines, not finish lines +### Task Scope Clarification + +You handle multi-step sub-tasks of a SINGLE GOAL. What you receive is ONE goal that may require multiple steps to complete — this is your primary use case. Only reject when given MULTIPLE INDEPENDENT goals in one request. + ## Hard Constraints ${hardBlocks} diff --git a/src/agents/hephaestus/gpt-5-4.ts b/src/agents/hephaestus/gpt-5-4.ts index 43fd0b787..6aa8c4c20 100644 --- a/src/agents/hephaestus/gpt-5-4.ts +++ b/src/agents/hephaestus/gpt-5-4.ts @@ -121,6 +121,10 @@ When blocked: try a different approach → decompose the problem → challenge a - User asks a question implying work → Answer briefly, DO the implied work in the same turn - You wrote a plan in your response → EXECUTE the plan before ending turn — plans are starting lines, not finish lines +### Task Scope Clarification + +You handle multi-step sub-tasks of a SINGLE GOAL. What you receive is ONE goal that may require multiple steps to complete — this is your primary use case. Only reject when given MULTIPLE INDEPENDENT goals in one request. + ## Hard Constraints ${hardBlocks} diff --git a/src/agents/hephaestus/gpt.ts b/src/agents/hephaestus/gpt.ts index c29d69609..8d12f2d5e 100644 --- a/src/agents/hephaestus/gpt.ts +++ b/src/agents/hephaestus/gpt.ts @@ -112,6 +112,10 @@ Asking the user is the LAST resort after exhausting creative alternatives. - Note assumptions in final message, not as questions mid-work - Need context? Fire explore/librarian in background IMMEDIATELY — continue only with non-overlapping work while they search +### Task Scope Clarification + +You handle multi-step sub-tasks of a SINGLE GOAL. What you receive is ONE goal that may require multiple steps to complete — this is your primary use case. Only reject when given MULTIPLE INDEPENDENT goals in one request. + ## Hard Constraints ${hardBlocks} diff --git a/src/agents/prometheus/system-prompt.test.ts b/src/agents/prometheus/system-prompt.test.ts new file mode 100644 index 000000000..14c9c346f --- /dev/null +++ b/src/agents/prometheus/system-prompt.test.ts @@ -0,0 +1,42 @@ +import { describe, it, expect } from "bun:test" +import { getPrometheusPrompt } from "./system-prompt" + +describe("getPrometheusPrompt", () => { + describe("#given question tool is not disabled", () => { + describe("#when generating prompt", () => { + it("#then should include Question tool references", () => { + const prompt = getPrometheusPrompt(undefined, []) + + expect(prompt).toContain("Question({") + }) + }) + }) + + describe("#given question tool is disabled via disabled_tools", () => { + describe("#when generating prompt", () => { + it("#then should strip Question tool code examples", () => { + const prompt = getPrometheusPrompt(undefined, ["question"]) + + expect(prompt).not.toContain("Question({") + }) + }) + + describe("#when disabled_tools includes question among other tools", () => { + it("#then should strip Question tool code examples", () => { + const prompt = getPrometheusPrompt(undefined, ["todowrite", "question", "interactive_bash"]) + + expect(prompt).not.toContain("Question({") + }) + }) + }) + + describe("#given no disabled_tools provided", () => { + describe("#when generating prompt with undefined", () => { + it("#then should include Question tool references", () => { + const prompt = getPrometheusPrompt(undefined, undefined) + + expect(prompt).toContain("Question({") + }) + }) + }) +}) diff --git a/src/agents/prometheus/system-prompt.ts b/src/agents/prometheus/system-prompt.ts index 4595d8ad0..768eb17c1 100644 --- a/src/agents/prometheus/system-prompt.ts +++ b/src/agents/prometheus/system-prompt.ts @@ -52,16 +52,34 @@ export function getPrometheusPromptSource(model?: string): PrometheusPromptSourc * Gemini models → Gemini-optimized prompt (aggressive tool-call enforcement, thinking checkpoints) * Default (Claude, etc.) → Claude-optimized prompt (modular sections) */ -export function getPrometheusPrompt(model?: string): string { +export function getPrometheusPrompt(model?: string, disabledTools?: readonly string[]): string { const source = getPrometheusPromptSource(model) + const isQuestionDisabled = disabledTools?.includes("question") ?? false + let prompt: string switch (source) { case "gpt": - return getGptPrometheusPrompt() + prompt = getGptPrometheusPrompt() + break case "gemini": - return getGeminiPrometheusPrompt() + prompt = getGeminiPrometheusPrompt() + break case "default": default: - return PROMETHEUS_SYSTEM_PROMPT + prompt = PROMETHEUS_SYSTEM_PROMPT } + + if (isQuestionDisabled) { + prompt = stripQuestionToolReferences(prompt) + } + + return prompt +} + +/** + * Removes Question tool usage examples from prompt text when question tool is disabled. + */ +function stripQuestionToolReferences(prompt: string): string { + // Remove Question({...}) code blocks (multi-line) + return prompt.replace(/```typescript\n\s*Question\(\{[\s\S]*?\}\)\s*\n```/g, "") } diff --git a/src/agents/sisyphus-junior/default.ts b/src/agents/sisyphus-junior/default.ts index bdd5467e7..d53a815b6 100644 --- a/src/agents/sisyphus-junior/default.ts +++ b/src/agents/sisyphus-junior/default.ts @@ -35,6 +35,11 @@ Task NOT complete without: - ${verificationText} + +STOP after first successful verification. Do NOT re-verify. +Maximum status checks: 2. Then stop regardless. + +