# 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`

## Omo-style ULW for orchestrator

當目前選取的 primary profile 是 `orchestrator` 時，本套件會採用受
`oh-my-opencode-slim` 啟發的 Pi lifecycle hook，讓 agent 維持在編排工作流中。
ULW 預設開啟；若沒有設定 `agent.orchestrator.ulw`，會視為 `true`。

若想保留較輕量的舊版提醒模式，可設定 `ulw: false`：

```json
{
  "agent": {
    "orchestrator": {
      "ulw": false
    }
  }
}
```

ULW 模式會推動 orchestrator 把非 trivial 工作拆成 lanes，透過 `Agent` 派遣
specialist，追蹤結果、整合輸出並驗證。`ulw: false` 仍會注入 orchestrator
prompt，以及舊版的一般 workflow / 檔案操作提醒；它不是停用 `Agent` 能力。
`/ulw` 指令只切換目前 session，不會寫回 settings。這些 hook 只負責提醒，
不會自動建立 subagent；child agent 的實際執行仍由 `@esso0428/pi-subagents`
提供。

## 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 不變。`agent.orchestrator.ulw`
控制 orchestrator 是否以積極 ULW 模式啟動；未填時預設為 `true`，若要使用一般
提醒模式則設為 `false`。當選到 `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。若 orchestrator prompt 正文還會點名 `researcher`、`reviewer`、
`scout`、`worker` 這類額外 child helper，也要讓這些名稱和 Pi 的 child-agent
定義對齊：不是補進 `subagents.agentOverrides`，就是明確依賴 builtin subagent
預設。

套件內的 `templates/agents/orchestrator.md` 是不可變的 fallback。Prompt
解析順序仍是 `<project>/.pi/agents/orchestrator.md`、
`~/.pi/agent/agents/orchestrator.md`，最後才使用套件內 template。套件不會
自動把 fallback 複製到全域 agents 目錄，因此套件更新時可以更新預設 prompt，
也不會覆蓋使用者檔案。

## 按鍵

| 按鍵 | 功能 |
|---|---|
| `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`；會保留既有的
project/global prompt，若兩者都不存在則使用套件內 fallback，不會自動建立全域
檔案；即使來源缺少，也會建立 `agent.orchestrator`。

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

### 套件內 Orchestrator Fallback

套件將預設角色 prompt 放在：

```text
templates/agents/orchestrator.md
```

仍可用 project/global 檔案覆寫，但 migration 不會自動建立全域檔案。使用 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 重複該欄位。建立或同步這份 prompt 時，請保留
明確的 Pi child-agent roster：`explorer`、`librarian`、`oracle`、`designer`、
`fixer`、`observer`、`council` 應作為主要 specialists；若這些 child-agent
名稱可用，則再把 `researcher`、`reviewer`、`scout`、`worker` 補成 workflow
helpers。不要把 `build`、`opencodezen` 這種 main-session profile 寫成 child
specialist。

### 遷移方法

若要直接採用 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. Preserve existing project/global orchestrator files. If neither exists, use
   the packaged `templates/agents/orchestrator.md` fallback; do not create a
   global file automatically.
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. When you create or sync orchestrator.md, preserve an explicit Pi child-agent
   roster. Keep `explorer`, `librarian`, `oracle`, `designer`, `fixer`,
   `observer`, and `council` as primary specialists, and add `researcher`,
   `reviewer`, `scout`, and `worker` as workflow helpers when available. Do not
   list main-session profiles like `build` or `opencodezen` as specialists.
6. Create other global agent markdown files only when their role prompts are
   needed.
7. 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. Preserve existing project/global orchestrator files. If neither exists, use
   the packaged `templates/agents/orchestrator.md` fallback.
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. When you create or sync orchestrator.md, preserve an explicit Pi child-agent
   roster. Keep `explorer`, `librarian`, `oracle`, `designer`, `fixer`,
   `observer`, and `council` as primary specialists, and add `researcher`,
   `reviewer`, `scout`, and `worker` as workflow helpers when available. Do not
   list main-session profiles like `build` or `opencodezen` as specialists.
6. Create .pi/agents/orchestrator.md only when this project needs a genuinely
   different orchestrator role prompt.
7. Create other .pi/agents/*.md only for project-specific prompt overrides.
8. 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. Preserve existing project/global orchestrator files. If neither exists, use
   the packaged `templates/agents/orchestrator.md` as the shared fallback; do
   not create a global file automatically.
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. When you create or sync orchestrator.md, preserve an explicit Pi child-agent
   roster. Keep `explorer`, `librarian`, `oracle`, `designer`, `fixer`,
   `observer`, and `council` as primary specialists, and add `researcher`,
   `reviewer`, `scout`, and `worker` as workflow helpers when available. Do not
   list main-session profiles like `build` or `opencodezen` as specialists.
6. Create a project-local replacement only for a genuinely different role
   prompt.
7. Use project settings only to override model/thinking/tools/prompt fields
   that differ from global settings.
8. 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
