pantheon-opencode 1.4.1 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  <h1 align="center">Pantheon</h1>
3
3
 
4
4
  <p align="center">
5
- <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-v1.4.1--candidate-blue" alt="Version"></a>
5
+ <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-v1.4.2-blue" alt="Version"></a>
6
6
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="License"></a>
7
7
  <a href="docs/agents/README.md"><img src="https://img.shields.io/badge/agents-14-purple" alt="Agents"></a>
8
8
  <a href="src/skills/README.md"><img src="https://img.shields.io/badge/skills-21-orange" alt="Skills"></a>
@@ -218,97 +218,28 @@ incompatible schema.
218
218
 
219
219
  ### Background Delegation
220
220
 
221
- Zeus (and other root sessions) can dispatch agents as **background child sessions**
222
- via three delegation tools, tracked on a persistent job board
223
- (`.pantheon/board/state.json`, 24h TTL) with reports written to
224
- `.pantheon/delegations/<parent>/<alias>.md`:
225
-
226
- | Tool | Signature | Behavior |
227
- |------|-----------|----------|
228
- | `pantheon_delegate` | `{prompt, agent, description?, read_only?}` | Creates a child session (parentID = caller), registers it on the job board, arms a 15-minute timeout, and fire-and-forgets `promptAsync` on the child. Returns the readable alias (e.g. `apo-1`). Only root sessions may delegate (sub-sessions are rejected by the depth guard). |
229
- | `pantheon_delegation_read` | `{id}` | Blocks (`waitForTerminal`, up to 15 min) until the delegation reaches a terminal state, returns the report markdown, and marks the job reconciled. Resolves by alias or task ID. |
230
- | `pantheon_delegation_list` | `{}` | Lists the current session's delegations with `[unread]` on finished, unreconciled jobs. |
231
-
232
- **Agent activity visibility.** While `pantheon_delegation_read` blocks on a
233
- running job, it samples the child session's messages every ~2s and appends the
234
- collected lines to the report as a trailing `## Agent Activity` section (latest
235
- tool calls with truncated args, or user/assistant text, capped at ~200 chars per
236
- line) — so you can see what the agent is doing during the wait. Likewise,
237
- `pantheon_delegation_list` shows a `last activity:` line for running jobs.
238
- Fail-open: if the child session messages are unavailable (or empty), the read
239
- returns the report exactly as before — the activity sampling never breaks the
240
- delegation read.
221
+ Zeus (and other root sessions) dispatch agents as **background child sessions**
222
+ via OpenCode's native `task(background=true, ...)` API. The plugin layer keeps a
223
+ persistent job board (`BackgroundJobBoard`, `.pantheon/board/state.json`, 24h
224
+ TTL) that tracks in-flight work and carries it forward across context
225
+ compaction, so a compacted session does not lose track of running delegations.
226
+
227
+ The plugin no longer ships a delegate toolset (`pantheon_delegate`,
228
+ `pantheon_delegation_read`, `pantheon_delegation_list` were removed in 1.4.3).
229
+ Dispatch and result collection use the native `task()` / `task_status()` API.
241
230
 
242
231
  **Completion visibility — zero chat noise.** Delegation notifications are never
243
232
  injected into the chat transcript: neither `chat.message` nor any other chat
244
233
  hook or transcript marker is used as a delivery channel. When a job reaches a
245
- terminal state (completion observed via `session.idle`/`session.error` on the
246
- child, or the timeout finalize path), the plugin writes a file-only audit log
247
- line (echo opt-in via `PANTHEON_HOOKS_LOG`). Completion visibility lives in the
248
- legitimate channels: the board `[unread]` marker
249
- (`pantheon_delegation_list`), `pantheon_delegation_read`, TUI toasts
250
- (`PANTHEON_TOASTS` gate), and compaction carry-forward. Reconcile is an
251
- acknowledgment, not a completion — it never re-fires the terminal transition.
234
+ terminal state, the plugin writes a file-only audit log line (echo opt-in via
235
+ `PANTHEON_HOOKS_LOG`). Completion visibility lives in the legitimate channels:
236
+ the board `[unread]` marker, TUI toasts (`PANTHEON_TOASTS` gate), and compaction
237
+ carry-forward. Reconcile is an acknowledgment, not a completion — it never
238
+ re-fires the terminal transition.
252
239
 
253
240
  **Timeout:** `background_delegation.timeout_ms` (default `900000` = 15 min). A job
254
241
  that has not reached a terminal state is finalized as `error`/`timedOut`.
255
242
 
256
- **Runtime delegation environment variables:**
257
-
258
- | Variable | Default | Scope and behavior |
259
- |---|---:|---|
260
- | `PANTHEON_ATHENA_APOLLO_BUDGET` | `5` dispatches | In-memory per `createDelegationTools()` factory/process instance and parent session, for the `athena → apollo` read-only exception. |
261
- | `PANTHEON_HERMES_APOLLO_BUDGET` | `5` dispatches | In-memory per `createDelegationTools()` factory/process instance and parent session, for the `hermes → apollo` read-only exception. |
262
- | `PANTHEON_DELEGATION_TIMEOUT_MS` | `900000` ms (15 min) | Per delegated child wall-clock timeout. The value is read when the plugin factory is created; unset or invalid values use the default. |
263
-
264
- Budgets are reserved before asynchronous child-session creation, so real
265
- concurrent calls cannot overshoot them. They reset when the factory/process
266
- restarts. If `ToolContext.agent` is missing, the default runtime matrix rejects
267
- the delegation (fail-closed); no caller identity or budget is inferred from the
268
- target, prompt, or session state. An explicitly legacy host using
269
- `enforceRuntimeMatrix: false` skips the budget because the caller cannot be
270
- identified and emits a warning. These budgets are separate from
271
- `background_delegation.max_concurrent_per_agent`: concurrency limits the number
272
- of currently running children, while an exception budget limits total dispatch
273
- reservations for that parent session during the factory lifetime.
274
-
275
- **Read-only enforcement:** delegating with `read_only: true`, or delegating to an
276
- agent in `background_delegation.read_only_agents` (`apollo`, `gaia`), registers
277
- the child session as read-only — the `tool.execute.before` guard denies
278
- `edit`/`write`/`bash`/`task` inside that session.
279
-
280
- **R1 — Per-error-type retry + provider cooldown (LiteLLM pattern):**
281
- `retry_policy` in `src/routing.yml` maps an error class (`auth`, `rate_limit`,
282
- `timeout`, `other`) to max retries before escalating — `auth` is never retried
283
- (0), `rate_limit` gets 3, `timeout` 2, `other` 1. Retries use exponential
284
- backoff (base 1s, doubling, capped 30s). `cooldown` (`allowed_fails`,
285
- `cooldown_time_seconds`) skips a provider for the configured window after that
286
- many consecutive failures; a success resets the counter. Enforcement lives in
287
- `RetryPolicyEngine` (`src/pantheon/retry-policy.ts`) and the R1 path of
288
- `zeusDelegateWithRetry` (`src/pantheon/zeus-delegate-with-retry.ts`) — pass
289
- `retryPolicy`/`cooldown`/`provider` to `createZeusRetryHelper`. In-memory only
290
- (no Redis).
291
-
292
- **R4 — Per-agent step caps:** `agents.<name>.max_steps` in `src/routing.yml`
293
- gives each agent a step budget (e.g. `apollo: 25`, `themis: 25`, `athena: 15`).
294
- When an agent reaches `max_steps` it is forced to summarize-and-stop: a
295
- delegation to an already-capped agent is skipped with a `[STEP CAP REACHED]`
296
- summary (no child session created), and a dispatch that hits the cap appends a
297
- stop instruction to the prompt. Enforcement: `StepCapTracker`
298
- (`src/pantheon/step-cap.ts`) wired into `pantheon_delegate`. The tracker is
299
- **permanent-per-process** — counters accumulate for the process lifetime and
300
- are intentionally not reset on success/session end (a per-session reset would
301
- let an agent exceed its process budget).
302
-
303
- **O5 — Permission globs for delegation:** `permission.task` in `src/routing.yml`
304
- controls which subagents an agent may invoke via glob patterns (last matching
305
- rule wins). A deny removes the agent from the delegate tool description
306
- entirely (not just blocks the call) — preventing circular delegation at the
307
- permission layer. Default `"*": allow` keeps the existing runtime matrix
308
- (zeus → anyone; athena/hermes → apollo only). Enforcement:
309
- `src/pantheon/permission-globs.ts` + the `permissionTask` option on
310
- `createDelegationTools` / `createEnforcementGuard`.
311
-
312
243
  **Compaction carry-forward:** during context compaction, running and unread
313
244
  terminal delegations (capped at `background_delegation.max_compaction_items`,
314
245
  default 10) are carried into the compacted context so the parent doesn't lose
@@ -337,8 +268,7 @@ logged warn and pass-through.
337
268
 
338
269
  **Post-compaction state re-assertion (1.3.4):** on `session.compacted`, fresh
339
270
  state — running/unread delegations from the board + active goals, capped at 10
340
- lines — remains available through compaction carry-forward and the board
341
- (`pantheon_delegation_list` / `pantheon_delegation_read`). A session with
271
+ lines — remains available through compaction carry-forward. A session with
342
272
  nothing to assert is a silent skip; no chat transcript injection is performed.
343
273
 
344
274
  **Preemptive compaction check (1.3.4):** a pure threshold core
@@ -362,8 +292,8 @@ omits the child model.
362
292
  **Delegation log hygiene (1.3.4):** `delegations.log` now records the real
363
293
  `task_id` (omitted when empty, never `""`) and a **numeric** `duration_ms`
364
294
  (null when unset) so downstream aggregation works. Terminal events are
365
- file-only audit entries; completion is surfaced by TUI toast (when enabled),
366
- the board, and the list/read tools — never by chat delivery.
295
+ file-only audit entries; completion is surfaced by TUI toast (when enabled)
296
+ and the board — never by chat delivery.
367
297
 
368
298
  **Env vars & config:**
369
299
 
@@ -371,14 +301,13 @@ the board, and the list/read tools — never by chat delivery.
371
301
  - `PANTHEON_TOASTS` — TUI toast gate for the delegation lifecycle signals.
372
302
  Default `{errors, delegations, council}`; `PANTHEON_TOASTS=off` disables all
373
303
  TUI toasts (delegation signals then only surface via the board `[unread]`
374
- marker, `pantheon_delegation_read` and the on-disk audit log — never via
375
- chat.message injection from the plugin).
304
+ marker and the on-disk audit log — never via chat.message injection from the
305
+ plugin).
376
306
  - `background_delegation` section in `src/routing.yml` — `timeout_ms`,
377
- `poll_ms`, `max_compaction_items`, `prune_ttl_ms`, `read_only_agents`,
378
- `session_max`, `retry_count`.
307
+ `poll_ms`, `max_compaction_items`, `prune_ttl_ms`, `session_max`,
308
+ `retry_count`.
379
309
 
380
- See `src/agents/zeus.md` for the agent-facing delegation protocol and
381
- `src/pantheon/delegation.ts` for the tool implementations.
310
+ See `src/agents/zeus.md` for the agent-facing delegation protocol.
382
311
 
383
312
  ### Real-time Delegations panel (1.3.4)
384
313
 
@@ -386,7 +315,7 @@ The TUI sidebar ships a live **Delegations** panel (open by default, above the
386
315
  collapsed Sessions list). Its primary source is `api.client.session.children`,
387
316
  so it shows **both** kinds of background work in one place:
388
317
 
389
- - **`pantheon_delegate` children** — rendered with their board alias tag
318
+ - **Board-tracked children** — rendered with their board alias tag
390
319
  (`[apo-1]`) and enriched from the `.pantheon/delegations/` report.
391
320
  - **Native `task()` children** — rendered with a distinct `[task]` tag (info
392
321
  color) when no board report exists for the session.
@@ -641,112 +570,211 @@ on demand to perform specialized tasks. Skills are organized into domains:
641
570
  ## Model Tiers & Presets
642
571
 
643
572
  Pantheon agents declare abstract model tiers (`fast` / `default` / `coding` / `premium`) rather than
644
- hardcoded model names. The actual model resolved for each tier depends on your platform
645
- subscription (OpenCode Go, Copilot Pro, Claude Pro, etc.).
573
+ hardcoded model names. The actual model resolved for each tier depends on your chosen **preset**
574
+ and is pinned to concrete `provider/model` IDs in [src/routing.yml](src/routing.yml).
646
575
 
647
- | Tier | Purpose | Agents | Typical Models |
576
+ | Tier | Purpose | Agents | Typical Models (2026) |
648
577
  |------|---------|--------|----------------|
649
- | `premium` | Deep reasoning, critical | Zeus, Athena, Themis | DeepSeek V4 Pro, Claude Opus, o3 |
650
- | `default` | Balanced quality/speed | Hermes, Aphrodite, Demeter, Prometheus, Hephaestus, Gaia | Kimi K2.6, Claude Sonnet, GPT-4o |
651
- | `coding` | Heavy coding tasks | Hermes, Aphrodite, Demeter, Prometheus, Hephaestus, Talos | DeepSeek V4 Flash, Claude Sonnet |
652
- | `fast` | Quick, cheap ops | Apollo, Iris, Mnemosyne, Talos, Nyx | DeepSeek V4 Flash, MiniMax M2.7, Gemini Flash |
578
+ | `premium` | Deep reasoning, critical | Zeus, Athena, Themis | gpt-5.6-sol, qwen3.8-max, deepseek-v4-pro |
579
+ | `default` | Balanced quality/speed | Hermes, Aphrodite, Demeter, Prometheus, Hephaestus, Gaia | gpt-5.6-terra, kimi-k3, deepseek-v4-flash |
580
+ | `coding` | Heavy coding tasks | Hermes, Aphrodite, Demeter, Prometheus, Hephaestus, Talos | gpt-5.6-terra, deepseek-v4-flash, mimo-v2.5 |
581
+ | `fast` | Quick, cheap ops | Apollo, Iris, Mnemosyne, Talos, Nyx | gpt-5.6-luna-fast, mimo-v2.5-free, gpt-5.6-luna |
653
582
 
654
583
  ---
655
584
 
656
585
  ## Model Routing Presets
657
586
 
658
- The abstract tiers above are pinned to concrete `provider/model` IDs by **6 built-in model presets**. Each preset maps all 14 agents to a specific model plus a reasoning effort per role (planners/reviewers, implementers, scouts). **Zero-mutation default**: without an active preset, agents run on OpenCode's default model — behavior is unchanged.
587
+ The abstract tiers above are pinned to concrete `provider/model` IDs by **4 built-in model presets**.
588
+ Cada preset mapeia os 14 agentes para um modelo específico + `reasoning_effort` por papel (planners/reviewers, implementers, scouts).
589
+
590
+ > **Default = herdar do chat (sem `active-preset.json`)** — sem preset ativo, os delegates **herdam nativamente** o modelo do chat pai. O instalador **não grava** `active-preset.json` quando você escolhe `0`/`inherit` no wizard (ou não seleciona preset via `--preset`). A resolução do modelo delegado segue: modelo do agente-alvo no preset ativo > modelo atual da sessão pai > herança nativa (sem `model`, sem `small_model`). `small_model` nunca é usado para delegates.
591
+
592
+ Tabelas abaixo são **geradas a partir de [src/routing.yml](src/routing.yml)** — rode `node scripts/generate-preset-docs.mjs` para regenerar. Nenhum segredo é hardcoded: apenas nomes de env vars (`PANTHEON_OPENCODE_API_KEY`, `OPENAI_API_KEY`) e `baseURL`s.
593
+
594
+ <!-- Generated from src/routing.yml — run: node scripts/generate-preset-docs.mjs -->
595
+ ### Presets — resumo (provider / baseURL / key / pricing / vision)
596
+
597
+ | Preset | Provider / BaseURL | Key env (nome) | Pricing 2026 | Vision (fallback) | Papéis / Modelos |
598
+ |---|---|---|---|---|---|
599
+ | `go-free` | `opencode` `https://opencode.ai/zen/v1` (env: `PANTHEON_OPENCODE_API_KEY`) | `PANTHEON_OPENCODE_API_KEY` | Gratuito — Zen free, sem custo, quota limitada, só modelos `-free` | `opencode/mimo-v2.5-free` [low] 👁️ vision | zeus: `opencode/big-pickle` [medium]<br>athena: `opencode/nemotron-3-super-free` [high]<br>themis: `opencode/qwen3.6-plus-free` [high]<br>hermes,aphrodite,demeter,prometheus,hephaestus: `opencode/deepseek-v4-flash-free` [medium]<br>apollo,nyx,gaia,iris,mnemosyne,talos: `opencode/mimo-v2.5-free` [low] |
600
+ | `go-fast` | `opencode-go` `https://opencode.ai/zen/go/v1` (env: `PANTHEON_OPENCODE_API_KEY`) | `PANTHEON_OPENCODE_API_KEY` | Baixo custo — Go gateway, baixa latência (kimi-k2.7-code / glm-5.3-flash) | `opencode-go/mimo-v2.5` [low] 👁️ vision | athena: `opencode-go/kimi-k2.7-code` [high]<br>themis: `opencode-go/glm-5.3-flash` [high]<br>zeus: `opencode-go/kimi-k2.7-code` [medium]<br>hermes,prometheus: `opencode-go/deepseek-v4-flash` [medium]<br>aphrodite,hephaestus: `opencode-go/mimo-v2.5` [low]<br>demeter: `opencode-go/gpt-5.6-luna` [low]<br>apollo,nyx,gaia,iris,mnemosyne,talos: `opencode-go/gpt-5.6-luna-fast` [low] |
601
+ | `go-premium` | `opencode-go` `https://opencode.ai/zen/go/v1` (env: `PANTHEON_OPENCODE_API_KEY`) | `PANTHEON_OPENCODE_API_KEY` | Premium — Go gateway, melhor qualidade (gpt-5.6-sol / qwen3.8-max / deepseek-v4-pro) | `opencode-go/gpt-5.6-sol` [high] 👁️ vision | zeus: `opencode-go/gpt-5.6-sol` [medium]<br>athena: `opencode-go/deepseek-v4-pro` [high]<br>themis: `opencode-go/qwen3.8-max` [high]<br>hermes,demeter,hephaestus: `opencode-go/gpt-5.6-terra` [medium]<br>aphrodite,prometheus: `opencode-go/kimi-k3` [medium]<br>apollo,nyx,gaia,iris,mnemosyne,talos: `opencode-go/gpt-5.6-luna` [low] |
602
+ | `openai` | `openai` `https://api.openai.com/v1` (env: `OPENAI_API_KEY`) | `OPENAI_API_KEY` | Pago (OpenAI) — Direto OpenAI, `gpt-5.6` family | `openai/gpt-5.6-sol` [high] 👁️ vision | athena,themis,zeus: `openai/gpt-5.6-sol` [high]<br>hermes,aphrodite,demeter,prometheus,hephaestus: `openai/gpt-5.6-luna` [high]<br>apollo,nyx,gaia,iris,mnemosyne,talos: `openai/gpt-5.6-luna-fast` [low] |
603
+
604
+ > **Pricing 2026 verificado** via `scripts/install/model-picker.mjs` (`PRESET_PRICE`) e `routing.yml` descrições. `go-free` = $0 (Zen free, quota limitada, só `-free`); `go-*` usam `PANTHEON_OPENCODE_API_KEY` (alias `OPENCODE_GO_API_KEY` aceito) no gateway `https://opencode.ai/zen/go/v1`; `openai` usa `OPENAI_API_KEY` em `https://api.openai.com/v1`. Custos reais dependem de conta/assinatura.
605
+
606
+ ### 14 agentes × 4 presets — modelo + effort + vision
659
607
 
660
- ### Presets
608
+ | Agente | `go-free` | `go-fast` | `go-premium` | `openai` |
609
+ |---|---|---|---|---|
610
+ | `zeus` | `opencode/big-pickle` [medium] · | `opencode-go/kimi-k2.7-code` [medium] · | `opencode-go/gpt-5.6-sol` [medium] 👁️ | `openai/gpt-5.6-sol` [high] 👁️ |
611
+ | `athena` | `opencode/nemotron-3-super-free` [high] · | `opencode-go/kimi-k2.7-code` [high] · | `opencode-go/deepseek-v4-pro` [high] · | `openai/gpt-5.6-sol` [high] 👁️ |
612
+ | `themis` | `opencode/qwen3.6-plus-free` [high] · | `opencode-go/glm-5.3-flash` [high] · | `opencode-go/qwen3.8-max` [high] · | `openai/gpt-5.6-sol` [high] 👁️ |
613
+ | `hermes` | `opencode/deepseek-v4-flash-free` [medium] · | `opencode-go/deepseek-v4-flash` [medium] · | `opencode-go/gpt-5.6-terra` [medium] 👁️ | `openai/gpt-5.6-luna` [high] 👁️ |
614
+ | `aphrodite` | `opencode/deepseek-v4-flash-free` [medium] · | `opencode-go/mimo-v2.5` [low] 👁️ | `opencode-go/kimi-k3` [medium] · | `openai/gpt-5.6-luna` [high] 👁️ |
615
+ | `demeter` | `opencode/deepseek-v4-flash-free` [medium] · | `opencode-go/gpt-5.6-luna` [low] 👁️ | `opencode-go/gpt-5.6-terra` [medium] 👁️ | `openai/gpt-5.6-luna` [high] 👁️ |
616
+ | `prometheus` | `opencode/deepseek-v4-flash-free` [medium] · | `opencode-go/deepseek-v4-flash` [medium] · | `opencode-go/kimi-k3` [medium] · | `openai/gpt-5.6-luna` [high] 👁️ |
617
+ | `hephaestus` | `opencode/deepseek-v4-flash-free` [medium] · | `opencode-go/mimo-v2.5` [low] 👁️ | `opencode-go/gpt-5.6-terra` [medium] 👁️ | `openai/gpt-5.6-luna` [high] 👁️ |
618
+ | `apollo` | `opencode/mimo-v2.5-free` [low] 👁️ | `opencode-go/gpt-5.6-luna-fast` [low] 👁️ | `opencode-go/gpt-5.6-luna` [low] 👁️ | `openai/gpt-5.6-luna-fast` [low] 👁️ |
619
+ | `nyx` | `opencode/mimo-v2.5-free` [low] 👁️ | `opencode-go/gpt-5.6-luna-fast` [low] 👁️ | `opencode-go/gpt-5.6-luna` [low] 👁️ | `openai/gpt-5.6-luna-fast` [low] 👁️ |
620
+ | `gaia` | `opencode/mimo-v2.5-free` [low] 👁️ | `opencode-go/gpt-5.6-luna-fast` [low] 👁️ | `opencode-go/gpt-5.6-luna` [low] 👁️ | `openai/gpt-5.6-luna-fast` [low] 👁️ |
621
+ | `iris` | `opencode/mimo-v2.5-free` [low] 👁️ | `opencode-go/gpt-5.6-luna-fast` [low] 👁️ | `opencode-go/gpt-5.6-luna` [low] 👁️ | `openai/gpt-5.6-luna-fast` [low] 👁️ |
622
+ | `mnemosyne` | `opencode/mimo-v2.5-free` [low] 👁️ | `opencode-go/gpt-5.6-luna-fast` [low] 👁️ | `opencode-go/gpt-5.6-luna` [low] 👁️ | `openai/gpt-5.6-luna-fast` [low] 👁️ |
623
+ | `talos` | `opencode/mimo-v2.5-free` [low] 👁️ | `opencode-go/gpt-5.6-luna-fast` [low] 👁️ | `opencode-go/gpt-5.6-luna` [low] 👁️ | `openai/gpt-5.6-luna-fast` [low] 👁️ |
661
624
 
662
- | Preset | Provider | Planners/Reviewers | Implementers | Scouts |
663
- |--------|----------|--------------------|--------------|--------|
664
- | `go-deepseek` | opencode (Zen) | `opencode/deepseek-v4-pro` | `opencode/deepseek-v4-flash` | `opencode/deepseek-v4-flash-free` |
665
- | `go-fast` | opencode-go | `opencode-go/deepseek-v4-flash` — all 14 agents, effort `low` | | |
666
- | `go-claude` | anthropic | `anthropic/claude-opus-4-8` | `anthropic/claude-sonnet-5` | `anthropic/claude-haiku-4-5` |
667
- | `go-openai` | openai | `openai/gpt-5.6-sol` | `openai/gpt-5.6-terra` | `openai/gpt-5.6-luna-fast` |
668
- | `go-premium` | opencode-go | GLM-5.1 (zeus), DeepSeek V4 Pro (athena), Qwen3.7 Max (themis) | MiniMax M2.7 (hermes, hephaestus), Kimi K2.6 (aphrodite), Qwen3.7 Plus (demeter), GLM-5.2 (prometheus) | DeepSeek V4 Flash (scouts) |
669
- | `go-free` | opencode (Zen free, $0) | Big Pickle (zeus), Nemotron 3 Ultra Free (athena) | DeepSeek V4 Flash Free | North Mini Code Free (scouts) |
625
+ `·` = text-only, `👁️` = vision (image-input) per `CAPABILITY_TABLE` em [src/pantheon/presets.mjs](src/pantheon/presets.mjs) — ex.: `mimo-v2.5`/`mimo-v2.5-free` e `gpt-5.6-*` são multimodais; `deepseek-v4-pro/flash`, `kimi-k2.7-code`, `glm-5.3-flash`, `qwen3.6-plus-free`, `big-pickle`, `nemotron-3-super-free` são text-only.
670
626
 
671
- The exact per-agent mapping (model + reasoning effort + fallbacks) lives in the `presets:` block of [src/routing.yml](src/routing.yml).
627
+ O mapeamento exato por agente (modelo + `reasoning_effort` + `vision` fallback) vive no bloco `presets:` de [src/routing.yml](src/routing.yml) e é validado por `validatePresetDefs` + `capabilityEntry` / `hasVision`.
672
628
 
673
629
  ### Requirements
674
630
 
675
- - **Env vars** — checked fail-fast (CLI and plugin) when the selected preset uses the provider:
676
- - `PANTHEON_OPENCODE_API_KEY` — `opencode` + `opencode-go` providers (`go-deepseek`, `go-fast`, `go-premium`, `go-free`)
677
- - `PANTHEON_ANTHROPIC_API_KEY` — `anthropic` provider (`go-claude`)
678
- - `PANTHEON_OPENAI_API_KEY` — `openai` provider (`go-openai`)
679
- - **OpenCode Go subscription** required for `go-fast` / `go-premium`.
680
- - **OpenCode Zen free tier** for `go-free` — note `nemotron-3-ultra-free` has known intermittent failures ([opencode#38028](https://github.com/opencode/opencode/issues/38028)); fall back to `go-fast` if flaky.
631
+ - **Env vars** — checadas fail-fast (CLI e plugin) quando o preset usa o provider (sem hardcodar valores):
632
+ - `PANTHEON_OPENCODE_API_KEY` — `opencode` + `opencode-go` (`go-free`, `go-fast`, `go-premium`) — alias `OPENCODE_GO_API_KEY` também aceito (wizard Q2)
633
+ - `OPENAI_API_KEY` — `openai` provider (`openai` puro)
634
+ - **OpenCode Go subscription** para `go-fast` / `go-premium` (gateway `https://opencode.ai/zen/go/v1`).
635
+ - **OpenCode Zen free tier** para `go-free` (`https://opencode.ai/zen/v1`, só modelos `-free`, quota limitada).
636
+ - **Sem preset (default)**: zero-mutação — nenhum `.pantheon/active-preset.json` gravado, herança nativa do chat pai.
681
637
 
682
- ### Commands
638
+ ### Wizard — instalação interativa (3 perguntas)
683
639
 
684
- ```bash
685
- # Install + activate a preset
686
- npx pantheon-opencode init --preset go-fast
640
+ Durante `npx pantheon-opencode init` (TTY, sem `--preset`/`--headless`/`-y`):
687
641
 
688
- # Switch preset (global config; --project for project-local; --dry-run to preview)
689
- pantheon-opencode set-tier go-deepseek
690
- pantheon-opencode set-tier go-fast --project
691
- pantheon-opencode set-tier go-fast --dry-run
642
+ 1. **Perfil (Q1)** — `0` = herdar do chat (**default**, não grava `active-preset.json`) ou `go-free`/`go-fast`/`go-premium`/`openai` — tabela exibida: perfil | `provider`/`baseURL`/key env | preço 2026 | modelos por papel (planners high, implementers medium/low, scouts low). `askQuestions` quando disponível, fallback `readline` TTY.
643
+ 2. **API Key (Q2)** — coleta **mascarada** (exibe `abcd****12`), valida `PANTHEON_OPENCODE_API_KEY` (aceita alias `OPENCODE_GO_API_KEY`) para `go-*` e `OPENAI_API_KEY` para `openai`, **não escreve `.env`** — só seta `env` da sessão e loga `maskKey`. Se já configurada no ambiente, apenas loga mascarada e segue.
644
+ 3. **Escopo (Q3)** — `project` (`./.pantheon/active-preset.json`, seguro, default) ou `global` (`~/.config/opencode/.pantheon/active-preset.json`). Gravação **atômica** (`tmp`+`rename`) com backup `.bak` + health-check (lê JSON e valida `preset`).
692
645
 
693
- # Clear preset — back to the zero-mutation default
694
- pantheon-opencode set-tier none
646
+ Headless / CI: use `npx pantheon-opencode init --headless` ou `--preset <name>` (pula wizard). Veja [docs/INSTALLATION.md](docs/INSTALLATION.md) para `headless` + troubleshooting de chaves.
695
647
 
696
- # No name → lists available presets (none, go-deepseek, go-fast, go-claude, go-openai, go-premium, go-free)
697
- pantheon-opencode set-tier
648
+ ### Comandos
649
+
650
+ ```bash
651
+ # Instalação interativa (wizard 3 perguntas — Q1 default = herdar do chat)
652
+ npx pantheon-opencode init
653
+ npx pantheon-opencode init --project # escopo project-local
654
+ npx pantheon-opencode init --preset go-fast # pula wizard, ativa direto
655
+
656
+ # Alternar preset depois (global por padrão; --project para projeto; --dry-run para preview)
657
+ npx pantheon-opencode set-tier go-free
658
+ npx pantheon-opencode set-tier go-premium --project
659
+ npx pantheon-opencode set-tier openai --dry-run
660
+
661
+ # Limpar preset — volta ao default (herança nativa)
662
+ npx pantheon-opencode set-tier none
663
+
664
+ # Sem nome → lista presets (none, go-free, go-fast, go-premium, openai)
665
+ npx pantheon-opencode set-tier
666
+
667
+ # Per-agent customization (novo — sem top-level model/small_model)
668
+ # Lista 14 agentes com modelo/effort/origem (preset|override|env|none), sem segredos
669
+ /pantheon-model status # alias: show
670
+ /pantheon-model # sem args → wizard interativo (agente → modelo → effort → scope via askQuestions)
671
+ /pantheon-model set --agent hermes --model opencode-go/gpt-5.6-terra --effort medium --scope project
672
+ /pantheon-model set --agent apollo --model opencode/mimo-v2.5-free --effort low
673
+ /pantheon-model reset --agent hermes --scope project
698
674
  ```
699
675
 
700
- **Env override (CI/headless)** — wins over the file:
676
+ **Env override (CI/headless)** — vence o arquivo:
701
677
 
702
678
  ```bash
703
- export PANTHEON_MODEL_PRESET=go-deepseek
679
+ export PANTHEON_MODEL_PRESET=go-fast # ou go-free / go-premium / openai / none
680
+ export PANTHEON_OPENCODE_API_KEY=... # para go-* (ou OPENCODE_GO_API_KEY como alias)
681
+ export OPENAI_API_KEY=... # para openai puro
704
682
  ```
705
683
 
706
684
  ### How it works
707
685
 
708
- - The active selection is persisted to `.pantheon/active-preset.json` — `{version, preset, source, updated_at}` — written atomically (tmp file + rename) with a `.bak` backup of the previous file. It applies on the next OpenCode startup (no hot-swap); the plugin's `hooks.config` injects it.
709
- - **Resolution precedence**: `PANTHEON_MODEL_PRESET` env → first existing `.pantheon/active-preset.json` (project → `~/.config/opencode` → `~/.opencode`) → **none** (defaults).
710
- - **Partial semantics**: a preset overrides only the agents it lists; unlisted agents inherit the invoking primary agent's model.
711
- - Interactive picker during `init`: one prompt listing the 6 presets (select by number or name, blank to skip). It never touches your `opencode.json` — the choice is injected at startup instead. The file format also supports an optional `overrides` block (per-agent `model`/`variant`, per-provider `baseURL`/`apiKeyEnv`) merged over the preset definition.
712
- - **Capability normalization**: requested reasoning effort is clamped to each model family's ceiling (`deepseek-v4-flash` max `medium`; claude models strip the variant entirely — Anthropic uses thinking).
713
- - **fallback_models**: per-agent ordered fallback list where configured (e.g. `go-deepseek` sets `[opencode/mimo-v2.5]` for every agent).
686
+ - A seleção ativa é persistida (se não for `inherit`) em `.pantheon/active-preset.json` — `{version, preset, source, updated_at, overrides?}` — escrita atômica (`tmp`+`rename`) com backup `.bak`. Só aplica no próximo startup do OpenCode (sem hot-swap); o plugin em `hooks.config` injeta `provider`/`baseURL`/`apiKeyEnv`.
687
+ - **Precedência**: `PANTHEON_MODEL_PRESET` env → primeiro `.pantheon/active-preset.json` existente (project → `~/.config/opencode` → `~/.opencode`) → **none = herança nativa** (sem `active-preset.json`).
688
+ - **Herança nativa de delegates** (1.4.2): `src/pantheon/delegation.ts` resolve o modelo do filho em: `explicit model` em `pantheon_delegate` > `overrides.agents[agent].model` em `active-preset.json` > `loadRoutingAgentModels` (preset ativo) > omitir → OpenCode herda o modelo do chat pai. `small_model` nunca é enviado. Validação `provider/model-id` com `MODEL_REF_PATTERN`.
689
+ - **Partial & overrides**: um preset sobrescreve só os agentes listados; agentes não listados herdam do pai. O bloco `overrides.agents[agent]` (via `/pantheon-model set --agent`) tem merge sobre o preset, validado via `capabilityEntry` e `normalizeCapability` (clamp ao teto do modelo) + aviso `hasVision` para modelos text-only; `overrides.providers` permite `baseURL`/`apiKeyEnv` custom. Escrita atômica com lock por path + `.bak`.
690
+ - **Capability normalization**: `requested effort` é clamped ao teto da família em `CAPABILITY_TABLE` (`deepseek-v4-flash/-free` max `medium`; `gop-5.6-luna*`/`mimo-v2.5*` max `low`; `claude` strip; `qwen3.6-plus-free`/`big-pickle` etc. text-only).
691
+ - **Interactive picker / wizard**: `scripts/install/model-picker.mjs` exporta `buildPresetTableRow`, `requiredKeyEnvForPreset`, `isKeyConfiguredForPreset`, `maskKey`, `buildInitQuestions`, `runInitWizard` e `runModelPicker`. Nunca toca `opencode.json`; também expõe helper `maskKey` para logs.
714
692
 
715
693
  ### Quick smoke test
716
694
 
717
695
  ```bash
696
+ # 1) default (herança nativa) — sem preset
697
+ npx pantheon-opencode init --headless # escolha 0 no wizard interativo = inherit
698
+ opencode run "hello" 2>&1 | grep "Pantheon"
699
+ # sem log de preset → herança nativa
700
+
701
+ # 2) com preset
718
702
  export PANTHEON_OPENCODE_API_KEY=...
719
- pantheon-opencode set-tier go-fast --project
703
+ npx pantheon-opencode set-tier go-fast --project
720
704
  opencode run "hello" 2>&1 | grep "Pantheon"
721
705
  # expect: [Pantheon Plugin] Model preset active: go-fast (source: file)
706
+
707
+ # 3) override per-agent
708
+ # no chat OpenCode:
709
+ /pantheon-model status
710
+ /pantheon-model set --agent hermes --model openai/gpt-5.6-luna --effort high --scope project
711
+ # persiste em .pantheon/active-preset.json overrides.agents.hermes
722
712
  ```
723
713
 
714
+
724
715
  ---
725
716
 
726
717
  ## Quick Start
727
718
 
728
719
  ### 1. Install Pantheon
729
720
 
730
- Pantheon runs on **OpenCode**. Install it globally:
721
+ Pantheon runs on **OpenCode**. Instalação global com **wizard 3 perguntas** (default = herdar do chat):
731
722
 
732
723
  ```bash
733
724
  npx pantheon-opencode init
725
+ # Q1: perfil — 0=herdar do chat [default] (sem active-preset.json), ou go-free / go-fast / go-premium / openai
726
+ # tabela exibida: perfil | provider/baseURL/key | preço 2026 | modelos por papel
727
+ # Q2: API key — coleta mascarada (PANTHEON_OPENCODE_API_KEY alias OPENCODE_GO_API_KEY, ou OPENAI_API_KEY), não escreve .env
728
+ # Q3: escopo — project (./.pantheon/active-preset.json, default) ou global (~/.config/opencode/.pantheon/active-preset.json)
729
+ # gravação atômica tmp+rename com .bak + health-check
730
+ ```
731
+
732
+ Atalhos:
733
+
734
+ ```bash
735
+ npx pantheon-opencode init --preset go-fast --headless # pula wizard
736
+ npx pantheon-opencode init --project # escopo project-local
737
+ npx pantheon-opencode init --headless --no-mcp # minimal sem Python
734
738
  ```
735
739
 
736
- For MCP servers (memory, persistence):
740
+ MCP servers (memory, persistence) — opcional via:
737
741
 
738
742
  ```bash
739
743
  npm run setup
740
744
  ```
741
745
 
746
+ Ou já incluído no wizard se escolher instalação completa.
747
+
742
748
  ### 2. Launch OpenCode
743
749
 
744
750
  ```bash
745
751
  export OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true
746
752
  opencode
753
+ # ou
754
+ npm run start
747
755
  ```
748
756
 
749
- ### 3. Run your first feature
757
+ Dica: após instalar preset, `opencode run "hello" 2>&1 | grep "Pantheon"` deve mostrar `[Pantheon Plugin] Model preset active: <preset> (source: file)`; sem preset, fica em herança nativa (sem log de preset).
758
+
759
+ ### 3. Customize per-agent (opcional)
760
+
761
+ No chat OpenCode:
762
+
763
+ ```
764
+ # lista 14 agentes com modelo/effort/origem
765
+ /pantheon-model status
766
+
767
+ # wizard interativo (agente → modelo → effort → scope)
768
+ /pantheon-model
769
+
770
+ # override explícito por agente (validado via CAPABILITY_TABLE, clamp, hasVision)
771
+ /pantheon-model set --agent hermes --model opencode-go/gpt-5.6-terra --effort medium --scope project
772
+ /pantheon-model reset --agent hermes --scope project
773
+ ```
774
+
775
+ Overrides vivem em `.pantheon/active-preset.json` em `overrides.agents[agent]` — sem `model`/`small_model` top-level e sem `.env`.
776
+
777
+ ### 4. Run your first feature
750
778
 
751
779
  Once agents are loaded, invoke the orchestrator:
752
780
 
@@ -778,6 +806,7 @@ Type these in the OpenCode chat:
778
806
  | `/pantheon-remember` | Store in memory |
779
807
  | `/pantheon-search` | Search memory |
780
808
  | `/pantheon-status` | System health and agent status |
809
+ | `/pantheon-model` (wizard) / `status\|show\|set --agent\|reset --agent` | Herança nativa default; `status` lista 14 agentes (model/effort/origem); `set --agent X --model provider/model-id [--effort low|medium|high] [--scope project|global]` com validação CAPABILITY_TABLE + clamp + hasVision; `reset --agent X`; default scope `project`; global exige `confirm`+`authorize_global`; nunca escreve `.env` nem top-level `model`; persistência atômica `.bak` + health-check |
781
810
  | `/pantheon-verify` | Hash edit verification |
782
811
 
783
812
  ---
@@ -1025,16 +1054,15 @@ Use the isolated sandbox (`~/pantheon-sandbox/`) — **never** the dev environme
1025
1054
  **Happy path (clean edit):** any normal tool call (exit 0) is **silent** — no console output by design, even though the audit hooks append their log files (`sessions.log`, `delegations.log`). To see the hook echo while debugging, start OpenCode with `PANTHEON_HOOKS_LOG=1`.
1026
1055
 
1027
1056
  **Delegation path (zero chat noise):** delegation signals are surfaced through
1028
- TUI toasts (when enabled), the board's `[unread]` marker, and the
1029
- `pantheon_delegation_list` / `pantheon_delegation_read` tools. Ask something
1057
+ TUI toasts (when enabled) and the board's `[unread]` marker. Ask something
1030
1058
  that dispatches subagents (e.g. *"dispare 2 subagentes apollo em paralelo para
1031
1059
  listar arquivos e comparar resultados"*) and expect:
1032
1060
 
1033
1061
  - A TUI toast with `🚀 apollo em execução` / `✅ apollo concluiu` when
1034
1062
  `PANTHEON_TOASTS` permits it
1035
- - `[unread]` in `pantheon_delegation_list` until the terminal result is read
1063
+ - `[unread]` on the board until the terminal result is read
1036
1064
  - An honest append to `logs/agent-sessions/delegations.log`: the **real agent name** (extracted from `tool_input.subagent_type`, never `unknown` when present) and a **non-fabricated status** — `success` only on explicit completion evidence, `failure` for refusals/errors, `unknown` otherwise
1037
- - With `export PANTHEON_TOASTS=off` before starting OpenCode: no toasts; board/list/read and audit-log visibility remain available
1065
+ - With `export PANTHEON_TOASTS=off` before starting OpenCode: no toasts; board and audit-log visibility remain available
1038
1066
 
1039
1067
  ### Pre-commit hooks (local secret gate)
1040
1068
 
@@ -190,6 +190,11 @@ async function main() {
190
190
  const autoYes = args.includes('--yes') || args.includes('-y')
191
191
  const presetIndex = args.indexOf('--preset')
192
192
  const presetOpt = presetIndex >= 0 ? (args[presetIndex + 1] ?? null) : null
193
+ // Explicit top-level model overrides for the generated config.
194
+ const modelIndex = args.indexOf('--model')
195
+ const modelOpt = modelIndex >= 0 ? (args[modelIndex + 1] ?? null) : null
196
+ const smallModelIndex = args.indexOf('--small-model')
197
+ const smallModelOpt = smallModelIndex >= 0 ? (args[smallModelIndex + 1] ?? null) : null
193
198
  // --version v1|v2 labels the install target (informational; the config is
194
199
  // shared and V1-shaped under both versions). Invalid values fail fast.
195
200
  const versionIndex = args.indexOf('--version')
@@ -218,6 +223,8 @@ async function main() {
218
223
  interactive: forceInteractive,
219
224
  headless: forceHeadless,
220
225
  yes: autoYes,
226
+ model: modelOpt,
227
+ smallModel: smallModelOpt,
221
228
  preset: presetOpt,
222
229
  version: versionOpt ?? 'v1',
223
230
  })
@@ -0,0 +1,34 @@
1
+ ---
2
+ description: "Inspect or change per-agent model overrides in active-preset.json"
3
+ agent: zeus
4
+ ---
5
+ # /pantheon-model — Per-agent model overrides
6
+
7
+ Use the deterministic `pantheon_model` tool for this command. Operates exclusively
8
+ on `active-preset.json` `overrides.agents[agent]` (project or global). Never
9
+ writes `.env` and never injects top-level `model`/`small_model` into `opencode.json`.
10
+
11
+ ## Usage
12
+
13
+ - `/pantheon-model status` or `/pantheon-model show` — list 14 canonical agents
14
+ (`zeus`, `athena`, `apollo`, `hermes`, `aphrodite`, `demeter`, `themis`,
15
+ `prometheus`, `hephaestus`, `nyx`, `gaia`, `iris`, `mnemosyne`, `talos`)
16
+ with effective `model`, `effort`, and origin (`preset` | `override` | `env` | `none`)
17
+ and the active preset, without showing secrets.
18
+ - `/pantheon-model` (no args) — interactive wizard via `askQuestions`:
19
+ agente → modelo (`provider/model-id`) → effort (`low`/`medium`/`high`) → scope.
20
+
21
+ - `/pantheon-model set --agent <name> --model <provider/model-id> [--effort low|medium|high] [--scope project|global]`
22
+ — set per-agent override. Validates agent is one of the 14, `provider/model-id`
23
+ format, `CAPABILITY_TABLE` entry via `capabilityEntry()` and clamps effort via
24
+ `normalizeCapability()`; warns via `hasVision` for text-only models. Persists
25
+ atomically with `.bak` backup and per-path lock. Default scope is `project`.
26
+
27
+ - `/pantheon-model reset --agent <name> [--scope project|global]` — remove the
28
+ per-agent override from `overrides.agents[agent]`.
29
+
30
+ `--scope project|global` is supported by `set` and `reset`. Global changes require
31
+ explicit `confirm` and `authorize_global`. Values must use `provider/model-id`.
32
+ Changes are backed up (`.bak`) and written atomically; restart OpenCode after a
33
+ successful change. The tool never writes `.env` and never injects `model`/`small_model`
34
+ global keys — delegate inheritance is native (no model → inherits chat/preset model).
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "pantheon-opencode",
3
- "version": "1.4.1",
3
+ "version": "1.4.3",
4
4
  "description": "Multi-agent orchestration for OpenCode — 14 specialized agents, TDD, Themis review gates.",
5
5
  "publishConfig": {
6
6
  "access": "public",
7
7
  "registry": "https://registry.npmjs.org/"
8
8
  },
9
9
  "scripts": {
10
- "postinstall": "node scripts/postinstall.mjs",
10
+ "postinstall": "node scripts/postinstall.mjs && node scripts/sync-tui.mjs",
11
11
  "prepare": "husky",
12
12
  "setup": "node bin/pantheon-init.mjs init",
13
13
  "build:agents-md": "node scripts/build-agents-md.mjs",