# pi-oc-style-agent-switcher

[**中文**](README-zh-TW.md)

Keyboard-driven primary-agent **model** switching for [Pi](https://pi.dev),
inspired by opencode's `<a-left>` / `<a-right>` agent switching.

## Install

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

Reload Pi: `/reload`

## Omo-style ULW for orchestrator

When the selected primary profile is `orchestrator`, the package uses Pi
lifecycle hooks inspired by `oh-my-opencode-slim` to keep the agent in an
orchestration workflow. ULW is enabled by default: missing
`agent.orchestrator.ulw` is treated as `true`.

Set `ulw: false` to keep the older, lighter reminder mode instead of the more
active omo-slim-like ULW prompt:

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

ULW mode prompts orchestrator to perform a delegation check before main work:
split non-trivial multi-file, multi-stage, research, architecture, review, or
parallelizable work into lanes and dispatch at least one suitable specialist.
The orchestrator prefers the installed `@esso0428/pi-subagents` tools when
available. If they are unavailable, it inspects the subagent capabilities in
the current session and chooses an alternative; it does not assume OpenCode
`task` or an unavailable package/API. Prompts, child tracking, reconciliation,
and verification remain capability-dependent. If no subagent capability is
available, it proceeds proportionately and reports that limitation. Delegation
recovery is also prompt-mediated: inspect aborted, errored, stopped, partial, or
incomplete children and adjust budget, scope, access, specialist/model, or
resume/respawn before considering takeover; never issue an unchanged duplicate.
`ulw: false` still injects the orchestrator prompt plus the normal
workflow/file-operation reminders from earlier releases. The `/ulw` command
toggles ULW for the current session only and does not write back to settings.
Hooks only remind; they never spawn subagents automatically.

## Agent Profiles

The `agent` section follows the same idea as OpenCode's primary-agent config.
Use it for switchable profiles in `~/.pi/agent/settings.json`. The extension
reads only each profile's `model` field. `mode` is optional; when omitted, the
profile is still switchable. An explicit `mode: "subagent"` is reserved for
future features and is currently excluded from the switcher.

For OpenCode compatibility, `agent.<name>` may also use `variant` as a sibling
field. Do not set both `thinking` and `variant` on the same agent entry.

### Example: OpenCode-style `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 settings in `<project>/.pi/settings.json` override global settings
field-by-field.

### Example: project override

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

If the global config contains `opencodezen`, `build`, and `orchestrator`, but
this project overrides only `orchestrator.model`, then the switcher will still
see the same primary profiles while using the project-specific orchestrator
model.

The switcher reads `agent.<name>.model` when it is configured; otherwise a
selected `build` or `orchestrator` profile inherits the current session model
and keeps the current thinking level unchanged. `agent.orchestrator.ulw`
controls whether orchestrator starts in active ULW mode; omit it to use the
default `true`, or set it to `false` for normal reminder mode. When
`orchestrator` is
selected, the extension appends the first available prompt body in this order:
project-local `.pi/agents/orchestrator.md` → global
`~/.pi/agent/agents/orchestrator.md` → packaged fallback
`templates/agents/orchestrator.md`. The `build` profile stays in normal
main-session mode and does not auto-inject a special prompt. It accepts
OpenCode-style `tools` object syntax for compatibility, but does not apply
those tools today. `thinking` and all `/run <agent>` child-session behavior
remain owned by Pi and installed subagent packages. This extension never
invokes a subagent.

Subagent-oriented `mode: "subagent"` behavior may be added in a future release;
for now, child-agent execution is still configured by your subagent package.

Valid:

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

Invalid:

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

### Subagent configuration

Configure child-agent behavior according to the subagent package you use. For
`pi-subagents`, use `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"]
      }
    }
  }
}
```

This is where you tune the child-session details for `orchestrator`. If you
prefer, you may also place those details directly in the agent file frontmatter
of `~/.pi/agent/agents/orchestrator.md` instead of JSON. If the orchestrator
prompt body names additional child helpers such as `researcher`, `reviewer`,
`scout`, or `worker`, keep those names aligned with your Pi child-agent
definitions too — either define them in `subagents.agentOverrides` or
intentionally rely on builtin subagent defaults.

The bundled `templates/agents/orchestrator.md` is an immutable fallback. Prompt
resolution prefers `<project>/.pi/agents/orchestrator.md`, then
`~/.pi/agent/agents/orchestrator.md`, then the packaged template. The package
never copies the fallback into the global agents directory, so package upgrades
can update the default prompt without overwriting user files.

## Keys

| Key | Action |
|---|---|
| `Alt+Shift+←` `Alt+Shift+→` | Select and apply previous/next primary model |
| `/agents` | Show switchable profiles and bindings |

### Use `Alt+←/→` instead

The package reads its own shortcut config from `~/.pi/agent/agent-switcher.json`.
Changing only `~/.pi/agent/keybindings.json` is not enough.

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

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

Free Pi's conflicting built-ins in `~/.pi/agent/keybindings.json`:

```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"]
}
```

## Migration from oh-my-opencode-slim

This package includes two complementary skills:

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

`omo-slim-conf-mig` reads the user's local/global OpenCode JSONC and migrates
explicit values. `omo-slim-mig` reads the upstream raw GitHub README and agent
prompts, then fills only missing values. If an `orchestrator.md` already
exists, `omo-slim-mig` compares it with the upstream-based Pi version and asks
before syncing. Both support `all`, `global`, and `local`; both preserve any
existing project/global prompt and use the packaged fallback when no override
exists. They create `agent.orchestrator` even if the relevant source lacks it.

Use oh-my-opencode-slim as a reference for converting agent prompts and JSON
configuration. Configure switchable primary models under `agent`; configure
child-agent model, thinking, tools, and prompts under
`subagents.agentOverrides`.

### Packaged Orchestrator Fallback

The package ships the default role prompt at:

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

Prompt resolution still allows a project or global override, but migration does
not create a global file automatically. Use YAML frontmatter for identity and
Pi behavior, followed by the converted system prompt body:

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

Do not create a project-local `orchestrator.md` unless the project genuinely
needs a different role prompt. Model, thinking, and tools may remain in this
file, in `subagents.agentOverrides`, or fall back to Pi defaults; do not repeat
a field in frontmatter if you expect `agentOverrides` to control it. When you
create or sync this prompt, 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 those child-agent names are available.
Do not list main-session profiles such as `build` or `opencodezen` as child
specialists.

### Migration Method

Copy one prompt to your LLM agent (Claude Code, Cursor, etc.) when you prefer
the direct HTTP-based migration rather than `/skill:omo-slim-mig`. The LLM
should use the linked guide as reference; it must not install or modify
oh-my-opencode-slim itself.

**global:** migrate global configuration

```
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 to the upstream-based Pi
   version instead of overwriting it blindly. Summarize the 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:** migrate one project

```
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 existing project/global orchestrator files unchanged. When 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:** migrate shared config and project overrides

```
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. When 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.
```

### Concept Mapping

| 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 in `src/agents/*.ts` | `~/.pi/agent/agents/*.md` or `.pi/agents/*.md` |

## License

MIT
