pantheon-opencode 1.4.0 → 1.4.2
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 +201 -95
- package/bin/pantheon-init.mjs +7 -0
- package/commands/pantheon-model.md +34 -0
- package/opencode.json +0 -2
- package/package.json +2 -2
- package/scripts/generate-preset-docs.mjs +239 -0
- package/scripts/install/model-picker.mjs +367 -2
- package/scripts/install/opencode.mjs +150 -137
- package/src/pantheon/chat-reminders.ts +4 -74
- package/src/pantheon/compaction-assert.ts +28 -28
- package/src/pantheon/delegation-finalize.ts +44 -11
- package/src/pantheon/delegation-toast.ts +73 -0
- package/src/pantheon/delegation.ts +45 -121
- package/src/pantheon/model-command.ts +858 -0
- package/src/pantheon/presets.d.mts +4 -3
- package/src/pantheon/presets.mjs +47 -54
- package/src/pantheon/zeus-delegate-with-retry.ts +9 -4
- package/src/plugin.ts +17 -29
- package/src/plugins/pantheon-hooks.ts +15 -158
- package/src/plugins/tui/dist/tui.d.ts.map +1 -1
- package/src/plugins/tui/dist/tui.js +1 -1
- package/src/plugins/tui/dist/tui.tsx +13 -2
- package/src/plugins/tui/package-lock.json +2 -2
- package/src/plugins/tui/package.json +1 -1
- package/src/plugins/tui/src/index.tsx +13 -2
- package/src/plugins/tui/tsdown.config.ts +11 -0
- package/src/routing.yml +71 -123
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.
|
|
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>
|
|
@@ -225,7 +225,7 @@ via three delegation tools, tracked on a persistent job board
|
|
|
225
225
|
|
|
226
226
|
| Tool | Signature | Behavior |
|
|
227
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
|
|
228
|
+
| `pantheon_delegate` | `{prompt, agent, description?, read_only?, model?}` | Creates a child session (parentID = caller), registers it on the job board, arms a 15-minute timeout, and sends `promptAsync` to the child. `model` is optional and uses `provider/model-id`. Returns the readable alias (e.g. `apo-1`). Only root sessions may delegate (sub-sessions are rejected by the depth guard). |
|
|
229
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
230
|
| `pantheon_delegation_list` | `{}` | Lists the current session's delegations with `[unread]` on finished, unreconciled jobs. |
|
|
231
231
|
|
|
@@ -239,17 +239,16 @@ Fail-open: if the child session messages are unavailable (or empty), the read
|
|
|
239
239
|
returns the report exactly as before — the activity sampling never breaks the
|
|
240
240
|
delegation read.
|
|
241
241
|
|
|
242
|
-
**Completion visibility —
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
(
|
|
251
|
-
|
|
252
|
-
transition.
|
|
242
|
+
**Completion visibility — zero chat noise.** Delegation notifications are never
|
|
243
|
+
injected into the chat transcript: neither `chat.message` nor any other chat
|
|
244
|
+
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.
|
|
253
252
|
|
|
254
253
|
**Timeout:** `background_delegation.timeout_ms` (default `900000` = 15 min). A job
|
|
255
254
|
that has not reached a terminal state is finalized as `error`/`timedOut`.
|
|
@@ -278,6 +277,22 @@ agent in `background_delegation.read_only_agents` (`apollo`, `gaia`), registers
|
|
|
278
277
|
the child session as read-only — the `tool.execute.before` guard denies
|
|
279
278
|
`edit`/`write`/`bash`/`task` inside that session.
|
|
280
279
|
|
|
280
|
+
**Delegated model resolution:** the optional child model is resolved in this
|
|
281
|
+
order: (1) explicit `model` on `pantheon_delegate`; (2) the target agent's
|
|
282
|
+
model in the active preset; (3) the current model of the parent session; (4)
|
|
283
|
+
no model, allowing OpenCode's native inheritance. `small_model` is never used
|
|
284
|
+
for delegates. When a model resolves, the same `provider/model-id` is sent as
|
|
285
|
+
`{providerID, id}` to both `session.create` and `promptAsync`, including the
|
|
286
|
+
single safe bootstrap retry; the retry does not select a different model. If
|
|
287
|
+
the resolution lookup yields no model, the model field is omitted and the
|
|
288
|
+
delegation continues with native inheritance.
|
|
289
|
+
|
|
290
|
+
Model availability is not inferred from the string. The provider must exist in
|
|
291
|
+
OpenCode and the referenced model must be available through that provider's
|
|
292
|
+
account, subscription, or configured endpoint; otherwise the child host may
|
|
293
|
+
reject startup. An active preset supplies provider configuration and model
|
|
294
|
+
mappings, but does not make an unavailable provider or model available.
|
|
295
|
+
|
|
281
296
|
**R1 — Per-error-type retry + provider cooldown (LiteLLM pattern):**
|
|
282
297
|
`retry_policy` in `src/routing.yml` maps an error class (`auth`, `rate_limit`,
|
|
283
298
|
`timeout`, `other`) to max retries before escalating — `auth` is never retried
|
|
@@ -338,10 +353,9 @@ logged warn and pass-through.
|
|
|
338
353
|
|
|
339
354
|
**Post-compaction state re-assertion (1.3.4):** on `session.compacted`, fresh
|
|
340
355
|
state — running/unread delegations from the board + active goals, capped at 10
|
|
341
|
-
lines —
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
assert is a silent skip.
|
|
356
|
+
lines — remains available through compaction carry-forward and the board
|
|
357
|
+
(`pantheon_delegation_list` / `pantheon_delegation_read`). A session with
|
|
358
|
+
nothing to assert is a silent skip; no chat transcript injection is performed.
|
|
345
359
|
|
|
346
360
|
**Preemptive compaction check (1.3.4):** a pure threshold core
|
|
347
361
|
(`preemptive-compact.ts`) warns the model before the context fills: at 78%
|
|
@@ -350,36 +364,22 @@ dormant / ready-to-wire — opencode 1.18.x exposes no runtime context-usage
|
|
|
350
364
|
percentage, so nothing observes it yet; when a source appears, the caller
|
|
351
365
|
wires it in (the enqueue callback is injected).
|
|
352
366
|
|
|
353
|
-
**Model
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
`
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
Setting `PANTHEON_MODEL_PRESET` to a preset whose providers have keys, or
|
|
364
|
-
filling the required `PANTHEON_*_API_KEY` env var for the preset's provider,
|
|
365
|
-
resolves the fallback path. If nothing resolves at all (no model, no preset),
|
|
366
|
-
the child keeps using opencode's default model (warned).
|
|
367
|
-
|
|
368
|
-
**agentModels wiring (1.3.4):** the delegate now also resolves the child model
|
|
369
|
-
via `routing.yml` — `loadRoutingAgentModels` extracts the per-agent models of
|
|
370
|
-
the FIRST-listed preset (the static default, `go-deepseek` today) and passes
|
|
371
|
-
them as `options.agentModels`, branch (b) of the resolve precedence: explicit
|
|
372
|
-
`model` > `options.agentModels` > active preset > opencode default. Delegation
|
|
373
|
-
no longer depends exclusively on the active preset — a delegated child gets a
|
|
374
|
-
sane per-agent model even when no preset is active. Fail-open: a missing or
|
|
375
|
-
unparseable routing.yml yields `{}` (previous behavior, warned).
|
|
367
|
+
**Model selection (1.4.1):** the child session inherits the parent session's
|
|
368
|
+
model through OpenCode. A model override is supplied only when the active
|
|
369
|
+
routing profile defines one; no model API-key validation is performed here.
|
|
370
|
+
|
|
371
|
+
**agentModels wiring (1.3.4):** `loadRoutingAgentModels` extracts only the
|
|
372
|
+
per-agent models from the explicitly active routing profile and passes them as
|
|
373
|
+
`options.agentModels`. No active profile, missing profile entry, or profile
|
|
374
|
+
without `model` produces an empty map; there is no implicit first-preset or
|
|
375
|
+
DeepSeek fallback. A missing or unparseable `routing.yml` is fail-open and
|
|
376
|
+
omits the child model.
|
|
376
377
|
|
|
377
378
|
**Delegation log hygiene (1.3.4):** `delegations.log` now records the real
|
|
378
379
|
`task_id` (omitted when empty, never `""`) and a **numeric** `duration_ms`
|
|
379
|
-
(null when unset) so downstream aggregation works.
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
duplicate lines for the same notification.
|
|
380
|
+
(null when unset) so downstream aggregation works. Terminal events are
|
|
381
|
+
file-only audit entries; completion is surfaced by TUI toast (when enabled),
|
|
382
|
+
the board, and the list/read tools — never by chat delivery.
|
|
383
383
|
|
|
384
384
|
**Env vars & config:**
|
|
385
385
|
|
|
@@ -657,112 +657,211 @@ on demand to perform specialized tasks. Skills are organized into domains:
|
|
|
657
657
|
## Model Tiers & Presets
|
|
658
658
|
|
|
659
659
|
Pantheon agents declare abstract model tiers (`fast` / `default` / `coding` / `premium`) rather than
|
|
660
|
-
hardcoded model names. The actual model resolved for each tier depends on your
|
|
661
|
-
|
|
660
|
+
hardcoded model names. The actual model resolved for each tier depends on your chosen **preset**
|
|
661
|
+
and is pinned to concrete `provider/model` IDs in [src/routing.yml](src/routing.yml).
|
|
662
662
|
|
|
663
|
-
| Tier | Purpose | Agents | Typical Models |
|
|
663
|
+
| Tier | Purpose | Agents | Typical Models (2026) |
|
|
664
664
|
|------|---------|--------|----------------|
|
|
665
|
-
| `premium` | Deep reasoning, critical | Zeus, Athena, Themis |
|
|
666
|
-
| `default` | Balanced quality/speed | Hermes, Aphrodite, Demeter, Prometheus, Hephaestus, Gaia |
|
|
667
|
-
| `coding` | Heavy coding tasks | Hermes, Aphrodite, Demeter, Prometheus, Hephaestus, Talos |
|
|
668
|
-
| `fast` | Quick, cheap ops | Apollo, Iris, Mnemosyne, Talos, Nyx |
|
|
665
|
+
| `premium` | Deep reasoning, critical | Zeus, Athena, Themis | gpt-5.6-sol, qwen3.8-max, deepseek-v4-pro |
|
|
666
|
+
| `default` | Balanced quality/speed | Hermes, Aphrodite, Demeter, Prometheus, Hephaestus, Gaia | gpt-5.6-terra, kimi-k3, deepseek-v4-flash |
|
|
667
|
+
| `coding` | Heavy coding tasks | Hermes, Aphrodite, Demeter, Prometheus, Hephaestus, Talos | gpt-5.6-terra, deepseek-v4-flash, mimo-v2.5 |
|
|
668
|
+
| `fast` | Quick, cheap ops | Apollo, Iris, Mnemosyne, Talos, Nyx | gpt-5.6-luna-fast, mimo-v2.5-free, gpt-5.6-luna |
|
|
669
669
|
|
|
670
670
|
---
|
|
671
671
|
|
|
672
672
|
## Model Routing Presets
|
|
673
673
|
|
|
674
|
-
The abstract tiers above are pinned to concrete `provider/model` IDs by **
|
|
674
|
+
The abstract tiers above are pinned to concrete `provider/model` IDs by **4 built-in model presets**.
|
|
675
|
+
Cada preset mapeia os 14 agentes para um modelo específico + `reasoning_effort` por papel (planners/reviewers, implementers, scouts).
|
|
676
|
+
|
|
677
|
+
> **Default = herdar do chat (sem `active-preset.json`)** — sem preset ativo, os delegates **herdam nativamente** o modelo do chat pai ([herança nativa](src/pantheon/delegation.ts)). 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: `explicit model` em `pantheon_delegate` > 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.
|
|
678
|
+
|
|
679
|
+
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.
|
|
680
|
+
|
|
681
|
+
<!-- Generated from src/routing.yml — run: node scripts/generate-preset-docs.mjs -->
|
|
682
|
+
### Presets — resumo (provider / baseURL / key / pricing / vision)
|
|
683
|
+
|
|
684
|
+
| Preset | Provider / BaseURL | Key env (nome) | Pricing 2026 | Vision (fallback) | Papéis / Modelos |
|
|
685
|
+
|---|---|---|---|---|---|
|
|
686
|
+
| `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] |
|
|
687
|
+
| `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] |
|
|
688
|
+
| `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] |
|
|
689
|
+
| `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] |
|
|
690
|
+
|
|
691
|
+
> **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.
|
|
692
|
+
|
|
693
|
+
### 14 agentes × 4 presets — modelo + effort + vision
|
|
675
694
|
|
|
676
|
-
|
|
695
|
+
| Agente | `go-free` | `go-fast` | `go-premium` | `openai` |
|
|
696
|
+
|---|---|---|---|---|
|
|
697
|
+
| `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] 👁️ |
|
|
698
|
+
| `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] 👁️ |
|
|
699
|
+
| `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] 👁️ |
|
|
700
|
+
| `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] 👁️ |
|
|
701
|
+
| `aphrodite` | `opencode/deepseek-v4-flash-free` [medium] · | `opencode-go/mimo-v2.5` [low] 👁️ | `opencode-go/kimi-k3` [medium] · | `openai/gpt-5.6-luna` [high] 👁️ |
|
|
702
|
+
| `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] 👁️ |
|
|
703
|
+
| `prometheus` | `opencode/deepseek-v4-flash-free` [medium] · | `opencode-go/deepseek-v4-flash` [medium] · | `opencode-go/kimi-k3` [medium] · | `openai/gpt-5.6-luna` [high] 👁️ |
|
|
704
|
+
| `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] 👁️ |
|
|
705
|
+
| `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] 👁️ |
|
|
706
|
+
| `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] 👁️ |
|
|
707
|
+
| `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] 👁️ |
|
|
708
|
+
| `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] 👁️ |
|
|
709
|
+
| `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] 👁️ |
|
|
710
|
+
| `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] 👁️ |
|
|
677
711
|
|
|
678
|
-
|
|
679
|
-
|--------|----------|--------------------|--------------|--------|
|
|
680
|
-
| `go-deepseek` | opencode (Zen) | `opencode/deepseek-v4-pro` | `opencode/deepseek-v4-flash` | `opencode/deepseek-v4-flash-free` |
|
|
681
|
-
| `go-fast` | opencode-go | `opencode-go/deepseek-v4-flash` — all 14 agents, effort `low` | | |
|
|
682
|
-
| `go-claude` | anthropic | `anthropic/claude-opus-4-8` | `anthropic/claude-sonnet-5` | `anthropic/claude-haiku-4-5` |
|
|
683
|
-
| `go-openai` | openai | `openai/gpt-5.6-sol` | `openai/gpt-5.6-terra` | `openai/gpt-5.6-luna-fast` |
|
|
684
|
-
| `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) |
|
|
685
|
-
| `go-free` | opencode (Zen free, $0) | Big Pickle (zeus), Nemotron 3 Ultra Free (athena) | DeepSeek V4 Flash Free | North Mini Code Free (scouts) |
|
|
712
|
+
`·` = 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.
|
|
686
713
|
|
|
687
|
-
|
|
714
|
+
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`.
|
|
688
715
|
|
|
689
716
|
### Requirements
|
|
690
717
|
|
|
691
|
-
- **Env vars** —
|
|
692
|
-
- `PANTHEON_OPENCODE_API_KEY` — `opencode` + `opencode-go`
|
|
693
|
-
- `
|
|
694
|
-
|
|
695
|
-
- **OpenCode
|
|
696
|
-
- **
|
|
718
|
+
- **Env vars** — checadas fail-fast (CLI e plugin) quando o preset usa o provider (sem hardcodar valores):
|
|
719
|
+
- `PANTHEON_OPENCODE_API_KEY` — `opencode` + `opencode-go` (`go-free`, `go-fast`, `go-premium`) — alias `OPENCODE_GO_API_KEY` também aceito (wizard Q2)
|
|
720
|
+
- `OPENAI_API_KEY` — `openai` provider (`openai` puro)
|
|
721
|
+
- **OpenCode Go subscription** para `go-fast` / `go-premium` (gateway `https://opencode.ai/zen/go/v1`).
|
|
722
|
+
- **OpenCode Zen free tier** para `go-free` (`https://opencode.ai/zen/v1`, só modelos `-free`, quota limitada).
|
|
723
|
+
- **Sem preset (default)**: zero-mutação — nenhum `.pantheon/active-preset.json` gravado, herança nativa do chat pai.
|
|
697
724
|
|
|
698
|
-
###
|
|
725
|
+
### Wizard — instalação interativa (3 perguntas)
|
|
699
726
|
|
|
700
|
-
|
|
701
|
-
# Install + activate a preset
|
|
702
|
-
npx pantheon-opencode init --preset go-fast
|
|
727
|
+
Durante `npx pantheon-opencode init` (TTY, sem `--preset`/`--headless`/`-y`):
|
|
703
728
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
pantheon-opencode
|
|
707
|
-
pantheon-opencode set-tier go-fast --dry-run
|
|
729
|
+
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.
|
|
730
|
+
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.
|
|
731
|
+
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`).
|
|
708
732
|
|
|
709
|
-
|
|
710
|
-
pantheon-opencode set-tier none
|
|
733
|
+
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.
|
|
711
734
|
|
|
712
|
-
|
|
713
|
-
|
|
735
|
+
### Comandos
|
|
736
|
+
|
|
737
|
+
```bash
|
|
738
|
+
# Instalação interativa (wizard 3 perguntas — Q1 default = herdar do chat)
|
|
739
|
+
npx pantheon-opencode init
|
|
740
|
+
npx pantheon-opencode init --project # escopo project-local
|
|
741
|
+
npx pantheon-opencode init --preset go-fast # pula wizard, ativa direto
|
|
742
|
+
|
|
743
|
+
# Alternar preset depois (global por padrão; --project para projeto; --dry-run para preview)
|
|
744
|
+
npx pantheon-opencode set-tier go-free
|
|
745
|
+
npx pantheon-opencode set-tier go-premium --project
|
|
746
|
+
npx pantheon-opencode set-tier openai --dry-run
|
|
747
|
+
|
|
748
|
+
# Limpar preset — volta ao default (herança nativa)
|
|
749
|
+
npx pantheon-opencode set-tier none
|
|
750
|
+
|
|
751
|
+
# Sem nome → lista presets (none, go-free, go-fast, go-premium, openai)
|
|
752
|
+
npx pantheon-opencode set-tier
|
|
753
|
+
|
|
754
|
+
# Per-agent customization (novo — sem top-level model/small_model)
|
|
755
|
+
# Lista 14 agentes com modelo/effort/origem (preset|override|env|none), sem segredos
|
|
756
|
+
/pantheon-model status # alias: show
|
|
757
|
+
/pantheon-model # sem args → wizard interativo (agente → modelo → effort → scope via askQuestions)
|
|
758
|
+
/pantheon-model set --agent hermes --model opencode-go/gpt-5.6-terra --effort medium --scope project
|
|
759
|
+
/pantheon-model set --agent apollo --model opencode/mimo-v2.5-free --effort low
|
|
760
|
+
/pantheon-model reset --agent hermes --scope project
|
|
714
761
|
```
|
|
715
762
|
|
|
716
|
-
**Env override (CI/headless)** —
|
|
763
|
+
**Env override (CI/headless)** — vence o arquivo:
|
|
717
764
|
|
|
718
765
|
```bash
|
|
719
|
-
export PANTHEON_MODEL_PRESET=go-
|
|
766
|
+
export PANTHEON_MODEL_PRESET=go-fast # ou go-free / go-premium / openai / none
|
|
767
|
+
export PANTHEON_OPENCODE_API_KEY=... # para go-* (ou OPENCODE_GO_API_KEY como alias)
|
|
768
|
+
export OPENAI_API_KEY=... # para openai puro
|
|
720
769
|
```
|
|
721
770
|
|
|
722
771
|
### How it works
|
|
723
772
|
|
|
724
|
-
-
|
|
725
|
-
- **
|
|
726
|
-
- **
|
|
727
|
-
-
|
|
728
|
-
- **Capability normalization**: requested
|
|
729
|
-
- **
|
|
773
|
+
- 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`.
|
|
774
|
+
- **Precedência**: `PANTHEON_MODEL_PRESET` env → primeiro `.pantheon/active-preset.json` existente (project → `~/.config/opencode` → `~/.opencode`) → **none = herança nativa** (sem `active-preset.json`).
|
|
775
|
+
- **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`.
|
|
776
|
+
- **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`.
|
|
777
|
+
- **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).
|
|
778
|
+
- **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.
|
|
730
779
|
|
|
731
780
|
### Quick smoke test
|
|
732
781
|
|
|
733
782
|
```bash
|
|
783
|
+
# 1) default (herança nativa) — sem preset
|
|
784
|
+
npx pantheon-opencode init --headless # escolha 0 no wizard interativo = inherit
|
|
785
|
+
opencode run "hello" 2>&1 | grep "Pantheon"
|
|
786
|
+
# sem log de preset → herança nativa
|
|
787
|
+
|
|
788
|
+
# 2) com preset
|
|
734
789
|
export PANTHEON_OPENCODE_API_KEY=...
|
|
735
|
-
pantheon-opencode set-tier go-fast --project
|
|
790
|
+
npx pantheon-opencode set-tier go-fast --project
|
|
736
791
|
opencode run "hello" 2>&1 | grep "Pantheon"
|
|
737
792
|
# expect: [Pantheon Plugin] Model preset active: go-fast (source: file)
|
|
793
|
+
|
|
794
|
+
# 3) override per-agent
|
|
795
|
+
# no chat OpenCode:
|
|
796
|
+
/pantheon-model status
|
|
797
|
+
/pantheon-model set --agent hermes --model openai/gpt-5.6-luna --effort high --scope project
|
|
798
|
+
# persiste em .pantheon/active-preset.json overrides.agents.hermes
|
|
738
799
|
```
|
|
739
800
|
|
|
801
|
+
|
|
740
802
|
---
|
|
741
803
|
|
|
742
804
|
## Quick Start
|
|
743
805
|
|
|
744
806
|
### 1. Install Pantheon
|
|
745
807
|
|
|
746
|
-
Pantheon runs on **OpenCode**.
|
|
808
|
+
Pantheon runs on **OpenCode**. Instalação global com **wizard 3 perguntas** (default = herdar do chat):
|
|
747
809
|
|
|
748
810
|
```bash
|
|
749
811
|
npx pantheon-opencode init
|
|
812
|
+
# Q1: perfil — 0=herdar do chat [default] (sem active-preset.json), ou go-free / go-fast / go-premium / openai
|
|
813
|
+
# tabela exibida: perfil | provider/baseURL/key | preço 2026 | modelos por papel
|
|
814
|
+
# Q2: API key — coleta mascarada (PANTHEON_OPENCODE_API_KEY alias OPENCODE_GO_API_KEY, ou OPENAI_API_KEY), não escreve .env
|
|
815
|
+
# Q3: escopo — project (./.pantheon/active-preset.json, default) ou global (~/.config/opencode/.pantheon/active-preset.json)
|
|
816
|
+
# gravação atômica tmp+rename com .bak + health-check
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
Atalhos:
|
|
820
|
+
|
|
821
|
+
```bash
|
|
822
|
+
npx pantheon-opencode init --preset go-fast --headless # pula wizard
|
|
823
|
+
npx pantheon-opencode init --project # escopo project-local
|
|
824
|
+
npx pantheon-opencode init --headless --no-mcp # minimal sem Python
|
|
750
825
|
```
|
|
751
826
|
|
|
752
|
-
|
|
827
|
+
MCP servers (memory, persistence) — opcional via:
|
|
753
828
|
|
|
754
829
|
```bash
|
|
755
830
|
npm run setup
|
|
756
831
|
```
|
|
757
832
|
|
|
833
|
+
Ou já incluído no wizard se escolher instalação completa.
|
|
834
|
+
|
|
758
835
|
### 2. Launch OpenCode
|
|
759
836
|
|
|
760
837
|
```bash
|
|
761
838
|
export OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true
|
|
762
839
|
opencode
|
|
840
|
+
# ou
|
|
841
|
+
npm run start
|
|
763
842
|
```
|
|
764
843
|
|
|
765
|
-
|
|
844
|
+
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).
|
|
845
|
+
|
|
846
|
+
### 3. Customize per-agent (opcional)
|
|
847
|
+
|
|
848
|
+
No chat OpenCode:
|
|
849
|
+
|
|
850
|
+
```
|
|
851
|
+
# lista 14 agentes com modelo/effort/origem
|
|
852
|
+
/pantheon-model status
|
|
853
|
+
|
|
854
|
+
# wizard interativo (agente → modelo → effort → scope)
|
|
855
|
+
/pantheon-model
|
|
856
|
+
|
|
857
|
+
# override explícito por agente (validado via CAPABILITY_TABLE, clamp, hasVision)
|
|
858
|
+
/pantheon-model set --agent hermes --model opencode-go/gpt-5.6-terra --effort medium --scope project
|
|
859
|
+
/pantheon-model reset --agent hermes --scope project
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
Overrides vivem em `.pantheon/active-preset.json` em `overrides.agents[agent]` — sem `model`/`small_model` top-level e sem `.env`.
|
|
863
|
+
|
|
864
|
+
### 4. Run your first feature
|
|
766
865
|
|
|
767
866
|
Once agents are loaded, invoke the orchestrator:
|
|
768
867
|
|
|
@@ -794,6 +893,7 @@ Type these in the OpenCode chat:
|
|
|
794
893
|
| `/pantheon-remember` | Store in memory |
|
|
795
894
|
| `/pantheon-search` | Search memory |
|
|
796
895
|
| `/pantheon-status` | System health and agent status |
|
|
896
|
+
| `/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 |
|
|
797
897
|
| `/pantheon-verify` | Hash edit verification |
|
|
798
898
|
|
|
799
899
|
---
|
|
@@ -1040,11 +1140,17 @@ Use the isolated sandbox (`~/pantheon-sandbox/`) — **never** the dev environme
|
|
|
1040
1140
|
|
|
1041
1141
|
**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`.
|
|
1042
1142
|
|
|
1043
|
-
**Delegation path (chat
|
|
1143
|
+
**Delegation path (zero chat noise):** delegation signals are surfaced through
|
|
1144
|
+
TUI toasts (when enabled), the board's `[unread]` marker, and the
|
|
1145
|
+
`pantheon_delegation_list` / `pantheon_delegation_read` tools. Ask something
|
|
1146
|
+
that dispatches subagents (e.g. *"dispare 2 subagentes apollo em paralelo para
|
|
1147
|
+
listar arquivos e comparar resultados"*) and expect:
|
|
1044
1148
|
|
|
1045
|
-
- A
|
|
1149
|
+
- A TUI toast with `🚀 apollo em execução` / `✅ apollo concluiu` when
|
|
1150
|
+
`PANTHEON_TOASTS` permits it
|
|
1151
|
+
- `[unread]` in `pantheon_delegation_list` until the terminal result is read
|
|
1046
1152
|
- 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
|
|
1047
|
-
- With `export PANTHEON_TOASTS=off` before starting OpenCode: no toasts/
|
|
1153
|
+
- With `export PANTHEON_TOASTS=off` before starting OpenCode: no toasts; board/list/read and audit-log visibility remain available
|
|
1048
1154
|
|
|
1049
1155
|
### Pre-commit hooks (local secret gate)
|
|
1050
1156
|
|
package/bin/pantheon-init.mjs
CHANGED
|
@@ -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/opencode.json
CHANGED
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pantheon-opencode",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2",
|
|
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",
|