# pi-oc-style-agent-switcher

[**English**](README.md)

為 [Pi](https://pi.dev) 提供鍵盤驅動的主 agent **model** 切換功能，靈感來自
opencode 的 `<a-left>` / `<a-right>` agent 切換。

## 安裝

```bash
pi install npm:pi-oc-style-agent-switcher
```

重新載入 Pi：`/reload`

## Agent 設定檔

`agent` 區塊可視為參考 OpenCode 的 primary-agent 配置方式。在
`~/.pi/agent/settings.json` 定義可切換的 profile；本套件只會讀取其 `model`
欄位。`mode` 是選填；未填時仍可切換。若明確設為 `mode: "subagent"`，目前
只保留語意，不會進入切換清單，未來才可能擴充相關行為。

為了相容 OpenCode，`agent.<name>` 也可使用同層的 `variant` 欄位；但同一個
agent entry 不可同時設定 `thinking` 與 `variant`。

### 範例：OpenCode 風格的 `agent`

```json
{
  "agent": {
    "opencodezen": {
      "model": "opencode/deepseek-v4-flash-free",
      "tools": {
        "write": true,
        "edit": true,
        "bash": true
      }
    },
    "build": {
      "mode": "primary",
      "model": "opencode/deepseek-v4-flash-free",
      "tools": {
        "write": true,
        "edit": true,
        "bash": true
      }
    },
    "orchestrator": {
      "model": "github-copilot/claude-sonnet-4.6",
      "variant": "high"
    }
  }
}
```

`<project>/.pi/settings.json` 會逐欄覆寫 global 設定。

### 範例：專案覆寫

```json
{
  "agent": {
    "orchestrator": {
      "mode": "primary",
      "model": "openai-codex/gpt-5.4"
    }
  }
}
```

若 global 設定內有 `opencodezen`、`build`、`orchestrator`，而這個專案只覆寫
`orchestrator.model`，則切換器仍會看到相同的 primary profiles，只是使用這個
專案專屬的 orchestrator model。

切換器在有設定時會讀取 `agent.<name>.model` 來切 Pi 目前使用的 model；若
選到的 `build` 或 `orchestrator` profile 沒有設定 `agent.<name>.model`，就沿用
目前 session 的 model，並保留當前 thinking level 不變。當選到
`orchestrator` 時，本套件會依照以下順序取第一個可用的 prompt 正文並附加到主
session 的 system prompt：專案內 `.pi/agents/orchestrator.md` → 全域
`~/.pi/agent/agents/orchestrator.md` → 套件內 fallback
`templates/agents/orchestrator.md`。`build` 則維持普通主 session 模式，不會
自動注入特殊 prompt。為了相容 OpenCode，它也接受 `tools` 的布林物件寫法，但
目前不會實際套用這些 tools。`thinking` 與所有 `/run <agent>` child session
行為，仍交由 Pi 與已安裝的 subagent 套件處理。本套件不會呼叫 subagent。

`mode: "subagent"` 的語意保留給未來功能；目前 child agent 的執行方式仍由
subagent 套件自行管理。

合法：

```json
{
  "agent": {
    "A": { "thinking": "high" },
    "B": { "variant": "low" }
  }
}
```

不合法：

```json
{
  "agent": {
    "A": {
      "thinking": "high",
      "variant": "low"
    }
  }
}
```

### Subagent 設定

child agent 的行為應依你使用的 subagent 套件來配置。若是 `pi-subagents`，
則使用 `subagents.agentOverrides`。

```json
{
  "subagents": {
    "agentOverrides": {
      "orchestrator": {
        "model": "github-copilot/claude-sonnet-4.6",
        "thinking": "high",
        "tools": [
          "read",
          "grep",
          "find",
          "ls",
          "bash",
          "edit",
          "write",
          "subagent",
          "wait",
          "web_search",
          "fetch_content",
          "get_search_content"
        ]
      },
      "explorer": {
        "model": "github-copilot/gpt-5-mini",
        "thinking": "low",
        "tools": ["read", "grep", "find", "ls", "bash"]
      }
    }
  }
}
```

這裡就是用來微調 `orchestrator` 作為 child session 時的細節。若你偏好，也可以
把這些細節直接寫在 `~/.pi/agent/agents/orchestrator.md` 的 frontmatter，而不是
放在 JSON。

首次載入時，若 `~/.pi/agent/agents/orchestrator.md` 與
`<project>/.pi/agents/orchestrator.md` 都不存在，套件會把內建 fallback 模板
複製到 `~/.pi/agent/agents/orchestrator.md`，讓 `/run orchestrator` 無須額外設定
即可使用。

## 按鍵

| 按鍵 | 功能 |
|---|---|
| `Alt+Shift+←` `Alt+Shift+→` | 選擇並套用上一個／下一個主 agent model |
| `/agents` | 顯示可切換 profile 與按鍵 |

### 改用 `Alt+←/→`

本套件自己的快捷鍵設定讀自 `~/.pi/agent/agent-switcher.json`。
只改 `~/.pi/agent/keybindings.json` 並不夠。

`~/.pi/agent/agent-switcher.json`：

```json
{ "cyclePrev": "alt+left", "cycleNext": "alt+right" }
```

在 `~/.pi/agent/keybindings.json` 釋放 Pi 的衝突鍵位：

```json
{
  "tui.editor.cursorWordLeft": [],
  "tui.editor.cursorWordRight": [],
  "app.tree.foldOrUp": [],
  "app.tree.unfoldOrDown": [],
  "app.model.cycleBackward": ["alt+shift+left"],
  "app.model.cycleForward": ["alt+shift+right"]
}
```

## 從 oh-my-opencode-slim 遷移

本套件內建兩個互補 skill：

```text
/skill:omo-slim-conf-mig [all|global|local]
/skill:omo-slim-mig      [all|global|local]
```

`omo-slim-conf-mig` 讀取使用者本機 global/local OpenCode JSONC，遷移明確設定；
`omo-slim-mig` 則讀取 upstream raw GitHub README 與 agent prompt，只補齊未設定
的值。若已存在 `orchestrator.md`，`omo-slim-mig` 會先和 upstream 轉換後的 Pi
版本比對，再詢問是否同步。兩者都支援 `all`、`global`、`local`；都會確保全域
orchestrator prompt 存在，且即使來源缺少，也會建立 `agent.orchestrator`。

將 oh-my-opencode-slim 作為 agent prompt 與 JSON 配置的遷移參考。可切換的主
model 設定在 `agent`；child agent 的 model、thinking、tools 與 prompt 則設定在
`subagents.agentOverrides`。

### 必備的全域 Orchestrator Prompt

每次遷移預設都必須建立：

```text
~/.pi/agent/agents/orchestrator.md
```

此檔案承載 orchestrator 的角色 prompt。使用 YAML frontmatter 定義身分與 Pi
行為，並在其後放入轉換後的系統提示詞本體：

```markdown
---
name: orchestrator
description: Master delegator and strategic coordinator
systemPromptMode: replace
inheritProjectContext: true
inheritSkills: false
---

<Role>
Converted orchestrator instructions from oh-my-opencode-slim.
</Role>
```

除非專案確實需要不同的角色 prompt，否則不要建立 project-local
`orchestrator.md`。model、thinking、tools 可留在此檔案、
`subagents.agentOverrides`，或使用 Pi 預設；若預期由 `agentOverrides`
控制某欄位，請勿在 frontmatter 重複該欄位。

### 遷移方法

若要直接採用 HTTP upstream 遷移、而非執行 `/skill:omo-slim-mig`，可複製其中
一組 prompt 給 LLM agent（Claude Code、Cursor 等）。LLM 應把連結中的指南當作
參考，**不可**安裝或修改 oh-my-opencode-slim。

**global**：遷移全域配置

```
Use oh-my-opencode-slim as a migration reference:
https://raw.githubusercontent.com/alvinunreal/oh-my-opencode-slim/refs/heads/master/README.md

Do not install or modify oh-my-opencode-slim. Read its README and relevant
src/agents/*.ts files, then migrate my global configuration to Pi:

1. Put switchable primary model profiles in ~/.pi/agent/settings.json → agent.
   Keep only agents intended for model switching, with mode: "primary".
2. Put child-agent model, thinking, tools, and prompt overrides in
   ~/.pi/agent/settings.json → subagents.agentOverrides.
3. Always ensure ~/.pi/agent/agents/orchestrator.md exists using the required
   frontmatter/body format documented above.
4. If an orchestrator.md already exists, compare it with the upstream-based Pi
   version instead of overwriting it blindly. Summarize differences and ask
   whether to keep it, sync only Pi/subagent integration parts, or fully sync.
5. Create other global agent markdown files only when their role prompts are
   needed.
6. Preserve existing unrelated Pi settings.
```

**local**：遷移單一專案

```
Use oh-my-opencode-slim as a migration reference:
https://raw.githubusercontent.com/alvinunreal/oh-my-opencode-slim/refs/heads/master/README.md

Do not install or modify oh-my-opencode-slim. Read its README and relevant
src/agents/*.ts files, then migrate configuration for this Pi project only:

1. Write project primary-model overrides to .pi/settings.json → agent.
2. Write project child-agent overrides to
   .pi/settings.json → subagents.agentOverrides.
3. Keep ~/.pi/agent/agents/orchestrator.md as the default orchestrator prompt.
4. If an orchestrator.md already exists, compare it against the upstream-based
   Pi version first. Summarize differences and ask whether to keep it, sync
   only Pi/subagent integration details, or fully sync.
5. Create .pi/agents/orchestrator.md only when this project needs a genuinely
   different orchestrator role prompt.
6. Create other .pi/agents/*.md only for project-specific prompt overrides.
7. Preserve global Pi configuration and unrelated project settings.
```

**global+local**：遷移共用配置與專案覆寫

```
Use oh-my-opencode-slim as a migration reference:
https://raw.githubusercontent.com/alvinunreal/oh-my-opencode-slim/refs/heads/master/README.md

Do not install or modify oh-my-opencode-slim. Migrate shared configuration to
~/.pi/agent/settings.json, then add only differing project values to
.pi/settings.json:

1. Primary model switch profiles belong in agent.
2. Child subagent behavior belongs in subagents.agentOverrides.
3. Always ensure ~/.pi/agent/agents/orchestrator.md exists as the shared
   default prompt.
4. If an orchestrator.md already exists, do not overwrite it blindly. Compare
   the current file with the upstream-based Pi version, summarize the
   differences (especially Pi/subagent integration vs upstream workflow drift),
   and ask whether to keep it, sync only integration parts, or fully sync.
5. Create a project-local replacement only for a genuinely different role
   prompt.
6. Use project settings only to override model/thinking/tools/prompt fields
   that differ from global settings.
7. Preserve all unrelated existing JSON fields and agent files.
```

### 概念對照

| oh-my-opencode-slim | Pi 對應 |
|---|---|
| OpenCode primary `agent` | `settings.json → agent` |
| oh-my agent model/variant | `subagents.agentOverrides.<name>.model/thinking` |
| `@agentName` | `subagent({ agent: "name", ... })` |
| `task(background: true)` | `subagent({ async: true })` |
| Agent prompt 在 `src/agents/*.ts` | `~/.pi/agent/agents/*.md` 或 `.pi/agents/*.md` |

## License

MIT
