pantheon-opencode 1.6.0-beta.1 → 1.6.0-beta.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/CHANGELOG.md +42 -0
- package/README.md +31 -5
- package/README.pt-BR.md +23 -0
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/pyproject.toml +1 -1
- package/scripts/install/config-migration.mjs +122 -1
- package/scripts/install/opencode.mjs +43 -10
- package/skills-lock.json +1 -1
- package/src/agents/aphrodite.md +0 -1
- package/src/agents/apollo.md +0 -1
- package/src/agents/athena.md +0 -1
- package/src/agents/demeter.md +0 -1
- package/src/agents/gaia.md +0 -1
- package/src/agents/hephaestus.md +0 -1
- package/src/agents/hermes.md +0 -1
- package/src/agents/iris.md +0 -1
- package/src/agents/mnemosyne.md +0 -1
- package/src/agents/nyx.md +0 -1
- package/src/agents/prometheus.md +0 -1
- package/src/agents/talos.md +0 -1
- package/src/agents/themis.md +0 -1
- package/src/agents/zeus.md +0 -1
- package/src/pantheon/presets.d.mts +0 -8
- package/src/pantheon/presets.mjs +0 -29
- package/src/plugins/tui/dist/tui.js +1 -1
- package/src/plugins/tui/package-lock.json +5 -5
- package/src/plugins/tui/package.json +1 -1
- package/src/routing.yml +0 -15
- package/src/skills/auto-continue/SKILL.md +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -18,6 +18,48 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
18
18
|
|
|
19
19
|
## ✅ Closed Issues
|
|
20
20
|
|
|
21
|
+
## [v1.6.0-beta.2] - 2026-10-02
|
|
22
|
+
|
|
23
|
+
## 🆕 What's New
|
|
24
|
+
- **`steps` não é mais definido pelo Pantheon**: removido dos 14 agentes em
|
|
25
|
+
`src/agents/`. No OpenCode 2 o campo é opcional e **sem default** — ausente
|
|
26
|
+
significa **sem teto nativo**. O host não impõe teto; o Pantheon estava
|
|
27
|
+
escrevendo um.
|
|
28
|
+
- **Instalador v2 remove `steps` residual**: configs já instalados passam a ter
|
|
29
|
+
o `steps` apagado dos agentes gerenciados. Escopo restrito aos agentes que o
|
|
30
|
+
Pantheon gerencia — um agente definido pelo usuário nunca é tocado. O bloco V1
|
|
31
|
+
singular `agent` é deliberadamente intocado (V1 em retirada).
|
|
32
|
+
- **Substitutos ao teto**: `task(background=true)` para trabalho fora da
|
|
33
|
+
foreground, `experimental.subagent_depth` para aninhamento de subagentes e
|
|
34
|
+
paralelismo entre delegações independentes.
|
|
35
|
+
- **Limpeza**: `max_steps` e `max_compaction_items` removidos de
|
|
36
|
+
`src/routing.yml`. `loadRoutingMaxSteps` nunca teve um único import — 2
|
|
37
|
+
matches no repo (definição e typedef), ambos removidos.
|
|
38
|
+
|
|
39
|
+
## 🐞 Fixed
|
|
40
|
+
- **`migrateV1toV2` descartava campos gerenciados**: com os blocos `agent` (V1)
|
|
41
|
+
e `agents` (V2) coexistindo — o caso de qualquer config já instalado — o
|
|
42
|
+
spread raso fazia um substituir o outro por inteiro. Na ordem de chaves do
|
|
43
|
+
`opencode.json` real, o lado perdedor era o do usuário. Agora **mescla**: a
|
|
44
|
+
base é o bloco V2, os campos gerenciados do V1 sobrescrevem, e os campos do
|
|
45
|
+
usuário são preservados. Mesma semântica já usada em `install/opencode.mjs`.
|
|
46
|
+
- **`docs/platforms/README.md` tinha tabela de step limits errada**: 14 linhas
|
|
47
|
+
listando limites por agente, **nenhum valor batendo** com `src/agents/`.
|
|
48
|
+
Tabela removida e a seção reescrita.
|
|
49
|
+
|
|
50
|
+
## ⚠️ Known Issues
|
|
51
|
+
- **Permissões de agente**: V1 usa `permission` e V2 usa `permissions`; ao mesclar esses blocos, a chave legada `permission` pode permanecer inerte ao lado de `permissions`.
|
|
52
|
+
- **Migração — rode o init uma vez**: `npx pantheon-opencode init
|
|
53
|
+
--opencode-version=v2` **uma única vez** limpa o `steps` residual. Sem isso o
|
|
54
|
+
config instalado continua carregando o teto antigo.
|
|
55
|
+
- **O `.md` de agente instalado é sobrescrito no próximo sync**: editar
|
|
56
|
+
`~/.config/opencode/agents/*.md` esperando persistência **não funciona**.
|
|
57
|
+
Comportamento **pré-existente**, não é regressão desta mudança — mas agora
|
|
58
|
+
está documentado para não ser reportado como uma.
|
|
59
|
+
- **`steps` definido à mão num agente gerenciado é removido a cada install v2**:
|
|
60
|
+
o instalador não distingue um valor que ele escreveu de um valor que você
|
|
61
|
+
escreveu (mesma chave, mesmo valor). Workaround: definir no frontmatter do
|
|
62
|
+
agente — e lembrar que ele **também** é sobrescrito no próximo sync.
|
|
21
63
|
## [v1.6.0-beta.1] - 2026-09-30
|
|
22
64
|
|
|
23
65
|
<!-- Add new changes here. Running `node scripts/versioning.mjs apply` will
|
package/README.md
CHANGED
|
@@ -78,11 +78,14 @@ clear handoff between stages of work.
|
|
|
78
78
|
|
|
79
79
|
## Status
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
and
|
|
81
|
+
Candidate version: the manifests in this checkout express the version being
|
|
82
|
+
prepared, not a confirmed publication. A beta is published only after the
|
|
83
|
+
Release workflow completes successfully. To check which version is actually
|
|
84
|
+
published, consult the npm `beta` dist-tag. Pantheon is designed for OpenCode
|
|
85
|
+
and depends on the availability and configuration of OpenCode and any optional
|
|
86
|
+
services you choose to use. Check the
|
|
87
|
+
[releases](https://github.com/ils15/pantheon-opencode/releases) and
|
|
88
|
+
[changelog](CHANGELOG.md) for the latest published changes.
|
|
86
89
|
|
|
87
90
|
## Delegation (native `task()`)
|
|
88
91
|
|
|
@@ -231,6 +234,29 @@ The installer still writes the compatibility settings required by the selected
|
|
|
231
234
|
OpenCode host, such as `experimental.subagent_depth`; this does not convert a
|
|
232
235
|
V1 plugin into V2 or provide V2 with V1 hooks.
|
|
233
236
|
|
|
237
|
+
Pantheon does not set a step ceiling on agents. On OpenCode 2 the `steps`
|
|
238
|
+
field is optional and has no default: absent means the host applies no native
|
|
239
|
+
limit. A config written before this change still carries the old value, and the
|
|
240
|
+
V2 install path strips it from every agent Pantheon manages — an agent you
|
|
241
|
+
define yourself is never touched, and the retiring V1 singular `agent` block
|
|
242
|
+
is left alone. Run the installer once to clear a stale value from an existing
|
|
243
|
+
config:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
npx pantheon-opencode init --opencode-version=v2
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Context control is not a Pantheon setting. Whatever budget an agent runs
|
|
250
|
+
against comes from the compaction settings of the OpenCode host you are
|
|
251
|
+
running, and Pantheon does not define them.
|
|
252
|
+
|
|
253
|
+
When a V1 `agent` block and a V2 `agents` block are both present — which is
|
|
254
|
+
what an installed `opencode.json` carries — the V1→V2 conversion merges them
|
|
255
|
+
instead of letting one replace the other. The V2 block is the base, the
|
|
256
|
+
framework-managed fields from the V1 block overwrite, and your own fields are
|
|
257
|
+
preserved, matching the precedence the installer already applies elsewhere.
|
|
258
|
+
Key order does not matter.
|
|
259
|
+
|
|
234
260
|
## Updating between releases (beta.5+)
|
|
235
261
|
|
|
236
262
|
One command keeps an existing installation current:
|
package/README.pt-BR.md
CHANGED
|
@@ -171,6 +171,29 @@ O instalador continua gravando as configurações de compatibilidade exigidas
|
|
|
171
171
|
pelo host OpenCode selecionado, como `experimental.subagent_depth`; isso não
|
|
172
172
|
converte um plugin V1 em V2 nem dá hooks V1 ao V2.
|
|
173
173
|
|
|
174
|
+
O Pantheon não define mais um teto de passos para os agentes. No OpenCode 2 o
|
|
175
|
+
campo `steps` é opcional e não tem default: ausente significa que o host não
|
|
176
|
+
aplica nenhum limite nativo. Uma config escrita antes dessa mudança ainda
|
|
177
|
+
carrega o valor antigo, e o caminho de instalação v2 o remove de todos os
|
|
178
|
+
agentes que o Pantheon gerencia — um agente definido por você nunca é tocado,
|
|
179
|
+
e o bloco V1 singular `agent`, em retirada, é deixado intacto. Rode o
|
|
180
|
+
instalador uma vez para limpar um valor antigo de uma config existente:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
npx pantheon-opencode init --opencode-version=v2
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
O controle de contexto não é uma configuração do Pantheon. Qualquer orçamento
|
|
187
|
+
que um agente terá vem das settings de compactação do próprio host OpenCode,
|
|
188
|
+
e o Pantheon não as define.
|
|
189
|
+
|
|
190
|
+
Quando um bloco V1 `agent` e um bloco V2 `agents` coexistem — o que acontece
|
|
191
|
+
em qualquer `opencode.json` já instalado — a conversão V1→V2 mescla os dois em
|
|
192
|
+
vez de deixar um substituir o outro. O bloco V2 é a base, os campos
|
|
193
|
+
gerenciados que vêm do V1 sobrescrevem, e os seus próprios campos são
|
|
194
|
+
preservados, com a mesma precedência que o instalador já aplica em outros
|
|
195
|
+
pontos. A ordem das chaves não muda o resultado.
|
|
196
|
+
|
|
174
197
|
## Atualizando entre releases (beta.5+)
|
|
175
198
|
|
|
176
199
|
Um comando mantém uma instalação existente em dia:
|
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pantheon",
|
|
3
3
|
"publisher": "ils15",
|
|
4
|
-
"version": "1.6.0-beta.
|
|
4
|
+
"version": "1.6.0-beta.2",
|
|
5
5
|
"displayName": "Pantheon",
|
|
6
6
|
"description": "Conductor-Delegate orchestration platform with 14 specialized agents, 21 skills, and OpenCode support.",
|
|
7
7
|
"agents": "./src/agents",
|
package/pyproject.toml
CHANGED
|
@@ -304,6 +304,114 @@ const V2_TO_V1_RENAMES = Object.fromEntries(
|
|
|
304
304
|
Object.entries(V1_TO_V2_RENAMES).map(([k, v]) => [v, k]),
|
|
305
305
|
)
|
|
306
306
|
|
|
307
|
+
/**
|
|
308
|
+
* Agent fields owned by the framework. Mirrors the exported MANAGED_FIELDS in
|
|
309
|
+
* install/opencode.mjs plus `source`, which the installer writes next to them.
|
|
310
|
+
* The migration runs before that merge, so it has to apply the same precedence
|
|
311
|
+
* itself when both `agent` and `agents` coexist: these come from the V1 block,
|
|
312
|
+
* every other field stays the user's.
|
|
313
|
+
*
|
|
314
|
+
* `permissions` is the V2 name — the converter renames the V1 `permission`
|
|
315
|
+
* block before the merge runs.
|
|
316
|
+
*
|
|
317
|
+
* `description` is deliberately absent, and this list is deliberately narrower
|
|
318
|
+
* than what the installer writes. The installer writes a description only when
|
|
319
|
+
* it creates an agent (install/opencode.mjs, the new-agent branch); on an agent
|
|
320
|
+
* that already exists it leaves the value alone, under its own comment "Existing
|
|
321
|
+
* agent fields belong to the user". So a description is framework-owned for a
|
|
322
|
+
* NEW agent and user-owned for an EXISTING one. Listing it here would make the
|
|
323
|
+
* migration stricter than the installer and would overwrite a description the
|
|
324
|
+
* installer deliberately preserves. mergeManagedAgents carries the value across
|
|
325
|
+
* instead, so it survives the merge without being treated as framework-owned.
|
|
326
|
+
*
|
|
327
|
+
* KNOWN DEBT: the installer still writes the V1 spelling `permission`, while V2
|
|
328
|
+
* reads `permissions`. An agent that goes through this merge can therefore end
|
|
329
|
+
* up carrying both keys, with `permission` left as dead weight that nothing
|
|
330
|
+
* reads. Tracked for the next slice; not fixed here, because picking a winner
|
|
331
|
+
* changes what an install writes.
|
|
332
|
+
*/
|
|
333
|
+
export const MANAGED_AGENT_FIELDS = Object.freeze([
|
|
334
|
+
'source',
|
|
335
|
+
'temperature',
|
|
336
|
+
'color',
|
|
337
|
+
'permissions',
|
|
338
|
+
'mode',
|
|
339
|
+
'hidden',
|
|
340
|
+
'disable_model_invocation',
|
|
341
|
+
])
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Compare this module's managed-agent list against the installer's.
|
|
345
|
+
*
|
|
346
|
+
* The two merge paths have to agree: the migration reimplements the installer's
|
|
347
|
+
* merge because it runs before it. A field present on only one side is silent
|
|
348
|
+
* divergence — either the migration overwrites a field the installer leaves
|
|
349
|
+
* alone, or it stops mirroring one the installer now writes. Both directions
|
|
350
|
+
* matter, so the result is reported as a pair of differences rather than a
|
|
351
|
+
* boolean.
|
|
352
|
+
*
|
|
353
|
+
* Names are compared after the converter's renames, because that is the
|
|
354
|
+
* spelling the merge actually sees.
|
|
355
|
+
*
|
|
356
|
+
* @param {string[]} installerFields - MANAGED_FIELDS as exported by install/opencode.mjs
|
|
357
|
+
* @returns {{ onlyInMigration: string[], onlyInInstaller: string[] }}
|
|
358
|
+
*/
|
|
359
|
+
export function managedAgentFieldDrift(installerFields) {
|
|
360
|
+
const toV2Name = (field) => V1_TO_V2_RENAMES[field] ?? field
|
|
361
|
+
const migration = new Set(MANAGED_AGENT_FIELDS.map(toV2Name))
|
|
362
|
+
const installer = new Set(installerFields.map(toV2Name))
|
|
363
|
+
return {
|
|
364
|
+
onlyInMigration: [...migration].filter((f) => !installer.has(f)).sort(),
|
|
365
|
+
onlyInInstaller: [...installer].filter((f) => !migration.has(f)).sort(),
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/** @returns {boolean} true for a plain name→config map (not null/array) */
|
|
370
|
+
function isAgentMap(value) {
|
|
371
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Merge the converted V1 `agent` block into an existing V2 `agents` base.
|
|
376
|
+
*
|
|
377
|
+
* Agents present in both are merged field by field: the base is kept, keys the
|
|
378
|
+
* base does not have are filled in from the V1 block, and MANAGED_AGENT_FIELDS
|
|
379
|
+
* are overwritten by the V1 values. Agents present in only one block are taken
|
|
380
|
+
* as they are — a union, not a replacement.
|
|
381
|
+
*
|
|
382
|
+
* Filling the gaps matters, and it is not description-specific: any key present
|
|
383
|
+
* only in the V1 block used to vanish here — `model`, `provider` and `mcp` too.
|
|
384
|
+
* `description` is the visible case, because the installer never writes one for
|
|
385
|
+
* an existing agent, so the V1 block is the only place that value can come from
|
|
386
|
+
* and the agent lost it on every install, permanently. Filling gaps can never
|
|
387
|
+
* destroy a base value; on conflict the base still wins, as before.
|
|
388
|
+
*
|
|
389
|
+
* @param {object} base - existing V2 `agents` map
|
|
390
|
+
* @param {object} managed - converted V1 `agent` map
|
|
391
|
+
* @returns {object} merged map
|
|
392
|
+
*/
|
|
393
|
+
function mergeManagedAgents(base, managed) {
|
|
394
|
+
const merged = { ...base }
|
|
395
|
+
|
|
396
|
+
for (const [name, agentConfig] of Object.entries(managed)) {
|
|
397
|
+
const existing = merged[name]
|
|
398
|
+
if (!isAgentMap(existing) || !isAgentMap(agentConfig)) {
|
|
399
|
+
merged[name] = agentConfig
|
|
400
|
+
continue
|
|
401
|
+
}
|
|
402
|
+
const entry = { ...existing }
|
|
403
|
+
for (const [field, value] of Object.entries(agentConfig)) {
|
|
404
|
+
if (!(field in entry)) entry[field] = value
|
|
405
|
+
}
|
|
406
|
+
for (const field of MANAGED_AGENT_FIELDS) {
|
|
407
|
+
if (field in agentConfig) entry[field] = agentConfig[field]
|
|
408
|
+
}
|
|
409
|
+
merged[name] = entry
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return merged
|
|
413
|
+
}
|
|
414
|
+
|
|
307
415
|
// ---------------------------------------------------------------------------
|
|
308
416
|
// Public API
|
|
309
417
|
// ---------------------------------------------------------------------------
|
|
@@ -333,7 +441,20 @@ export function migrateV1toV2(config) {
|
|
|
333
441
|
}
|
|
334
442
|
agents[agentName] = ac
|
|
335
443
|
}
|
|
336
|
-
|
|
444
|
+
// An `agents` (V2) block may already exist — the installed opencode.json
|
|
445
|
+
// carries both, in either key order. Renaming onto it with a plain
|
|
446
|
+
// replace dropped the whole managed merge, so merge instead.
|
|
447
|
+
const base = result.agents
|
|
448
|
+
result.agents = isAgentMap(base) ? mergeManagedAgents(base, agents) : agents
|
|
449
|
+
} else if (key === 'agents') {
|
|
450
|
+
// V2 block: it is the base. The singular `agent` key may already have
|
|
451
|
+
// been converted above, in which case merge the two.
|
|
452
|
+
const managed = result.agents
|
|
453
|
+
if (isAgentMap(value)) {
|
|
454
|
+
result.agents = isAgentMap(managed) ? mergeManagedAgents(value, managed) : value
|
|
455
|
+
} else if (!isAgentMap(managed)) {
|
|
456
|
+
result.agents = value
|
|
457
|
+
}
|
|
337
458
|
} else if (key === 'provider' && typeof value === 'object' && value !== null) {
|
|
338
459
|
const providers = {}
|
|
339
460
|
for (const [provName, provConfig] of Object.entries(value)) {
|
|
@@ -61,6 +61,33 @@ const COMPONENT_NAMES = [
|
|
|
61
61
|
'runtime',
|
|
62
62
|
]
|
|
63
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Per-agent fields owned by the framework: for an agent that already exists in
|
|
66
|
+
* the target config these are overwritten from the canonical source, and for a
|
|
67
|
+
* new agent they are the seed. Everything else on an existing entry is the
|
|
68
|
+
* user's and is left alone.
|
|
69
|
+
*
|
|
70
|
+
* `source` is written right next to these (for both new and existing agents) but
|
|
71
|
+
* is kept out of the loop so it can also be set independently — the migration in
|
|
72
|
+
* config-migration.mjs mirrors this list plus `source`, and tests assert the two
|
|
73
|
+
* stay equal as sets.
|
|
74
|
+
*
|
|
75
|
+
* KNOWN DEBT: `permission` is the V1 spelling. V2 reads `permissions`, so an
|
|
76
|
+
* agent can carry both keys after an install and the V1 one becomes dead weight.
|
|
77
|
+
* Tracked for the next slice; changing it here would change what an install
|
|
78
|
+
* writes.
|
|
79
|
+
*
|
|
80
|
+
* @type {readonly string[]}
|
|
81
|
+
*/
|
|
82
|
+
export const MANAGED_FIELDS = Object.freeze([
|
|
83
|
+
'temperature',
|
|
84
|
+
'color',
|
|
85
|
+
'permission',
|
|
86
|
+
'mode',
|
|
87
|
+
'hidden',
|
|
88
|
+
'disable_model_invocation',
|
|
89
|
+
])
|
|
90
|
+
|
|
64
91
|
function deepClone(value) {
|
|
65
92
|
return JSON.parse(JSON.stringify(value))
|
|
66
93
|
}
|
|
@@ -836,7 +863,6 @@ export async function installOpenCode(
|
|
|
836
863
|
if (fm.mode) agent.mode = fm.mode
|
|
837
864
|
if (fm.hidden) agent.hidden = fm.hidden
|
|
838
865
|
if (fm.temperature !== undefined) agent.temperature = fm.temperature
|
|
839
|
-
if (fm.steps !== undefined) agent.steps = fm.steps
|
|
840
866
|
// Support both hyphen (YAML) and underscore (JSON) key variants
|
|
841
867
|
if (fm['disable-model-invocation'] !== undefined)
|
|
842
868
|
agent.disable_model_invocation = fm['disable-model-invocation']
|
|
@@ -855,15 +881,6 @@ export async function installOpenCode(
|
|
|
855
881
|
|
|
856
882
|
const canonicalAgentConfig = readAgentConfigFromCanonical()
|
|
857
883
|
const agentSources = getAgentSources(agentPrefix)
|
|
858
|
-
const MANAGED_FIELDS = [
|
|
859
|
-
'steps',
|
|
860
|
-
'temperature',
|
|
861
|
-
'color',
|
|
862
|
-
'permission',
|
|
863
|
-
'mode',
|
|
864
|
-
'hidden',
|
|
865
|
-
'disable_model_invocation',
|
|
866
|
-
]
|
|
867
884
|
|
|
868
885
|
if (config.agent === undefined) config.agent = {}
|
|
869
886
|
|
|
@@ -1222,6 +1239,22 @@ export async function installOpenCode(
|
|
|
1222
1239
|
if (version === 'v2') {
|
|
1223
1240
|
info(S.v2Migrating)
|
|
1224
1241
|
configToWrite = migrateV1toV2(config)
|
|
1242
|
+
|
|
1243
|
+
// Pantheon no longer sets a step ceiling. Any `steps` sitting on a managed
|
|
1244
|
+
// agent was written by an earlier install and never chosen by the user —
|
|
1245
|
+
// the merge above is additive by design (no delete path), so drop it here
|
|
1246
|
+
// and let the host default apply. This runs after the migration because
|
|
1247
|
+
// migrateV1toV2 copies the V1 `agent` block across verbatim (including any
|
|
1248
|
+
// stale `steps`), which is exactly how the value reappears in V2.
|
|
1249
|
+
// User-defined agents are out of scope and keep their value; the V1
|
|
1250
|
+
// singular `agent` block is deliberately untouched (V1 is retiring).
|
|
1251
|
+
const v2Agents = configToWrite.agents
|
|
1252
|
+
if (v2Agents && typeof v2Agents === 'object' && !Array.isArray(v2Agents)) {
|
|
1253
|
+
for (const name of Object.keys(canonicalAgentConfig)) {
|
|
1254
|
+
const entry = v2Agents[name]
|
|
1255
|
+
if (entry && typeof entry === 'object' && !Array.isArray(entry)) delete entry.steps
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1225
1258
|
}
|
|
1226
1259
|
|
|
1227
1260
|
const configContent = `${JSON.stringify(configToWrite, null, 2)}\n`
|
package/skills-lock.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"src/skills/agent-coordination/SKILL.md": "cfd040ef29e3dd0fd5e0e67773874facf7c06e3284898afe1fddba4456c3f1aa",
|
|
3
3
|
"src/skills/artifact-management/SKILL.md": "c60e493666bedf46e9113d0dd20106489d5c5a73905e1370fcfc1c0d71c59185",
|
|
4
|
-
"src/skills/auto-continue/SKILL.md": "
|
|
4
|
+
"src/skills/auto-continue/SKILL.md": "4fe256d44ee9828d622a0d8b63cfc6bb39a317189a9ccf19494a6efd4527a7a9",
|
|
5
5
|
"src/skills/clonedeps/SKILL.md": "3e0b43cf96da98c83699dc48db3fd58fbfda84b9022bb70d3747875c81c3e124",
|
|
6
6
|
"src/skills/code-review-checklist/SKILL.md": "0e59367c65ef4608db80a0674279f32cfc3f67dca7236f233b61a47fe506579f",
|
|
7
7
|
"src/skills/codemap/SKILL.md": "87af5271e1576e154cadff313eab16264b726e43d094520736b7a5b03b409a4a",
|
package/src/agents/aphrodite.md
CHANGED
package/src/agents/apollo.md
CHANGED
package/src/agents/athena.md
CHANGED
package/src/agents/demeter.md
CHANGED
package/src/agents/gaia.md
CHANGED
package/src/agents/hephaestus.md
CHANGED
package/src/agents/hermes.md
CHANGED
package/src/agents/iris.md
CHANGED
package/src/agents/mnemosyne.md
CHANGED
package/src/agents/nyx.md
CHANGED
package/src/agents/prometheus.md
CHANGED
package/src/agents/talos.md
CHANGED
package/src/agents/themis.md
CHANGED
package/src/agents/zeus.md
CHANGED
|
@@ -104,14 +104,6 @@ export interface RoutingRetryPolicyOptions {
|
|
|
104
104
|
logger?: { warn?: (msg: string) => void }
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
/**
|
|
108
|
-
* R4: per-agent step caps from routing.yml `agents.<name>.max_steps`.
|
|
109
|
-
* Fail-open → {} (no agent capped).
|
|
110
|
-
*/
|
|
111
|
-
export declare function loadRoutingMaxSteps(
|
|
112
|
-
options?: RoutingRetryPolicyOptions,
|
|
113
|
-
): Record<string, number>
|
|
114
|
-
|
|
115
107
|
/**
|
|
116
108
|
* O5: permission.task glob rules from routing.yml `permission.task`
|
|
117
109
|
* (glob pattern → 'allow' | 'deny'). Fail-open → null.
|
package/src/pantheon/presets.mjs
CHANGED
|
@@ -213,35 +213,6 @@ function loadRoutingYaml(routingPath) {
|
|
|
213
213
|
return routing && typeof routing === 'object' ? routing : null
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
/**
|
|
217
|
-
* Load the R4 per-agent step caps from routing.yml
|
|
218
|
-
* (`agents.<name>.max_steps`). Fail-open: missing config yields {}.
|
|
219
|
-
*
|
|
220
|
-
* @param {object} [opts]
|
|
221
|
-
* @param {string} [opts.routingPath]
|
|
222
|
-
* @param {{warn?: Function}} [opts.logger]
|
|
223
|
-
* @returns {Record<string, number>} lowercase agent → max_steps
|
|
224
|
-
*/
|
|
225
|
-
export function loadRoutingMaxSteps({ routingPath, logger = console } = {}) {
|
|
226
|
-
try {
|
|
227
|
-
const routing = loadRoutingYaml(routingPath)
|
|
228
|
-
const agents = routing?.agents
|
|
229
|
-
if (!agents || typeof agents !== 'object') return {}
|
|
230
|
-
const out = {}
|
|
231
|
-
for (const [agent, spec] of Object.entries(agents)) {
|
|
232
|
-
const maxSteps = spec && typeof spec === 'object' ? spec.max_steps : undefined
|
|
233
|
-
if (Number.isSafeInteger(maxSteps) && maxSteps > 0) {
|
|
234
|
-
out[agent.toLowerCase()] = maxSteps
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
return out
|
|
238
|
-
} catch (err) {
|
|
239
|
-
const reason = err instanceof Error ? err.message : String(err)
|
|
240
|
-
logger.warn?.(`presets: routing.yml max_steps unavailable (${reason})`)
|
|
241
|
-
return {}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
216
|
/**
|
|
246
217
|
* Load the O5 permission.task glob rules from routing.yml
|
|
247
218
|
* (`permission.task:`). Fail-open: missing config yields null (caller keeps
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pantheon-tui",
|
|
3
|
-
"version": "1.6.0-beta.
|
|
3
|
+
"version": "1.6.0-beta.2",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pantheon-tui",
|
|
9
|
-
"version": "1.6.0-beta.
|
|
9
|
+
"version": "1.6.0-beta.2",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@opencode-ai/plugin": "1.18.30",
|
|
@@ -1529,9 +1529,9 @@
|
|
|
1529
1529
|
}
|
|
1530
1530
|
},
|
|
1531
1531
|
"node_modules/brace-expansion": {
|
|
1532
|
-
"version": "2.1.
|
|
1533
|
-
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.
|
|
1534
|
-
"integrity": "sha512-
|
|
1532
|
+
"version": "2.1.7",
|
|
1533
|
+
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz",
|
|
1534
|
+
"integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==",
|
|
1535
1535
|
"license": "MIT",
|
|
1536
1536
|
"dependencies": {
|
|
1537
1537
|
"balanced-match": "^1.0.0"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pantheon-tui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.6.0-beta.
|
|
4
|
+
"version": "1.6.0-beta.2",
|
|
5
5
|
"description": "Pantheon TUI plugin — sidebar (version, preset, sessions, real-time delegations) + AI subscription usage gauges incl. OpenCode Go/Zen dollar limits (vendored, MIT)",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"engines": {
|
package/src/routing.yml
CHANGED
|
@@ -99,7 +99,6 @@ presets:
|
|
|
99
99
|
agents:
|
|
100
100
|
zeus:
|
|
101
101
|
role: Central orchestrator
|
|
102
|
-
max_steps: 40 # R4: step budget — at max_steps the agent is forced to summarize-and-stop. Tracker is permanent-per-process (no reset wiring).
|
|
103
102
|
reasoning_effort: medium
|
|
104
103
|
user_invocable: true
|
|
105
104
|
can_delegate: true
|
|
@@ -137,7 +136,6 @@ agents:
|
|
|
137
136
|
- incremental-implementation
|
|
138
137
|
athena:
|
|
139
138
|
role: Strategic planner
|
|
140
|
-
max_steps: 15 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
|
|
141
139
|
reasoning_effort: high
|
|
142
140
|
user_invocable: true
|
|
143
141
|
can_delegate: true
|
|
@@ -157,7 +155,6 @@ agents:
|
|
|
157
155
|
- memory-bank
|
|
158
156
|
apollo:
|
|
159
157
|
role: Investigation scout
|
|
160
|
-
max_steps: 25 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
|
|
161
158
|
reasoning_effort: low
|
|
162
159
|
user_invocable: false
|
|
163
160
|
can_delegate: false
|
|
@@ -175,7 +172,6 @@ agents:
|
|
|
175
172
|
- auto-continue
|
|
176
173
|
hermes:
|
|
177
174
|
role: Backend specialist
|
|
178
|
-
max_steps: 60 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
|
|
179
175
|
reasoning_effort: medium
|
|
180
176
|
user_invocable: true
|
|
181
177
|
can_delegate: true
|
|
@@ -198,7 +194,6 @@ agents:
|
|
|
198
194
|
- incremental-implementation
|
|
199
195
|
aphrodite:
|
|
200
196
|
role: Frontend specialist
|
|
201
|
-
max_steps: 60 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
|
|
202
197
|
reasoning_effort: medium
|
|
203
198
|
user_invocable: true
|
|
204
199
|
can_delegate: false
|
|
@@ -219,7 +214,6 @@ agents:
|
|
|
219
214
|
- file-prompts
|
|
220
215
|
demeter:
|
|
221
216
|
role: Database specialist
|
|
222
|
-
max_steps: 50 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
|
|
223
217
|
reasoning_effort: medium
|
|
224
218
|
user_invocable: true
|
|
225
219
|
can_delegate: false
|
|
@@ -239,7 +233,6 @@ agents:
|
|
|
239
233
|
- incremental-implementation
|
|
240
234
|
themis:
|
|
241
235
|
role: Quality gate
|
|
242
|
-
max_steps: 25 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
|
|
243
236
|
reasoning_effort: high
|
|
244
237
|
user_invocable: true
|
|
245
238
|
can_delegate: false
|
|
@@ -261,7 +254,6 @@ agents:
|
|
|
261
254
|
- context-compression
|
|
262
255
|
prometheus:
|
|
263
256
|
role: Infrastructure specialist
|
|
264
|
-
max_steps: 30 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
|
|
265
257
|
reasoning_effort: medium
|
|
266
258
|
user_invocable: true
|
|
267
259
|
can_delegate: false
|
|
@@ -280,7 +272,6 @@ agents:
|
|
|
280
272
|
- incremental-implementation
|
|
281
273
|
hephaestus:
|
|
282
274
|
role: AI pipelines
|
|
283
|
-
max_steps: 50 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
|
|
284
275
|
reasoning_effort: medium
|
|
285
276
|
user_invocable: true
|
|
286
277
|
can_delegate: false
|
|
@@ -299,7 +290,6 @@ agents:
|
|
|
299
290
|
- auto-continue
|
|
300
291
|
nyx:
|
|
301
292
|
role: Observability
|
|
302
|
-
max_steps: 25 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
|
|
303
293
|
reasoning_effort: low
|
|
304
294
|
user_invocable: true
|
|
305
295
|
can_delegate: false
|
|
@@ -318,7 +308,6 @@ agents:
|
|
|
318
308
|
- auto-continue
|
|
319
309
|
gaia:
|
|
320
310
|
role: Remote sensing domain specialist
|
|
321
|
-
max_steps: 25 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
|
|
322
311
|
reasoning_effort: low
|
|
323
312
|
user_invocable: false
|
|
324
313
|
can_delegate: false
|
|
@@ -333,7 +322,6 @@ agents:
|
|
|
333
322
|
- auto-continue
|
|
334
323
|
iris:
|
|
335
324
|
role: GitHub operations
|
|
336
|
-
max_steps: 20 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
|
|
337
325
|
reasoning_effort: low
|
|
338
326
|
user_invocable: true
|
|
339
327
|
can_delegate: false
|
|
@@ -351,7 +339,6 @@ agents:
|
|
|
351
339
|
- artifact-management
|
|
352
340
|
mnemosyne:
|
|
353
341
|
role: Memory bank
|
|
354
|
-
max_steps: 20 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
|
|
355
342
|
reasoning_effort: low
|
|
356
343
|
user_invocable: true
|
|
357
344
|
can_delegate: false
|
|
@@ -375,7 +362,6 @@ agents:
|
|
|
375
362
|
- session-goal
|
|
376
363
|
talos:
|
|
377
364
|
role: Hotfix agent
|
|
378
|
-
max_steps: 15 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
|
|
379
365
|
reasoning_effort: low
|
|
380
366
|
user_invocable: true
|
|
381
367
|
can_delegate: false
|
|
@@ -529,7 +515,6 @@ background_job_board:
|
|
|
529
515
|
background_delegation:
|
|
530
516
|
timeout_ms: 900000 # 15 min
|
|
531
517
|
poll_ms: 250
|
|
532
|
-
max_compaction_items: 10
|
|
533
518
|
prune_ttl_ms: 86400000 # 24h
|
|
534
519
|
read_only_agents: [apollo, gaia]
|
|
535
520
|
session_max: 3
|
|
@@ -43,7 +43,7 @@ Disciplined automatic continuation through multi-step tasks. Eliminates unnecess
|
|
|
43
43
|
- A todo requires a decision not covered by the plan
|
|
44
44
|
- An unexpected error changes the approach
|
|
45
45
|
- A dependency is missing or broken
|
|
46
|
-
-
|
|
46
|
+
- Remaining context is too thin to carry the task through — write an explicit handoff instead
|
|
47
47
|
|
|
48
48
|
---
|
|
49
49
|
|
|
@@ -70,7 +70,7 @@ Disciplined automatic continuation through multi-step tasks. Eliminates unnecess
|
|
|
70
70
|
- [ ] Previous step completed successfully (tests pass, no errors)
|
|
71
71
|
- [ ] Next step is within approved plan scope
|
|
72
72
|
- [ ] No new blocking issues emerged
|
|
73
|
-
- [ ]
|
|
73
|
+
- [ ] Remaining context can carry the next step, or an explicit handoff will be written
|
|
74
74
|
|
|
75
75
|
---
|
|
76
76
|
|