pi-ui-extend 1.0.39 → 1.0.41

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.
Files changed (113) hide show
  1. package/README.md +1 -1
  2. package/dist/app/commands/command-registry.js +2 -2
  3. package/dist/app/commands/command-session-actions.d.ts +0 -1
  4. package/dist/app/commands/command-session-actions.js +22 -13
  5. package/dist/app/icons.d.ts +14 -0
  6. package/dist/app/icons.js +33 -0
  7. package/dist/app/rendering/conversation-tool-renderer.js +2 -2
  8. package/dist/app/rendering/dcp-stats.d.ts +6 -1
  9. package/dist/app/rendering/dcp-stats.js +214 -46
  10. package/dist/app/rendering/editor-panels.js +8 -5
  11. package/dist/app/session/lazy-session-manager.js +12 -1
  12. package/dist/app/session/tabs-controller.d.ts +2 -5
  13. package/dist/app/session/tabs-controller.js +12 -21
  14. package/dist/app/subagents/subagents-model.d.ts +14 -1
  15. package/dist/app/subagents/subagents-model.js +34 -15
  16. package/dist/app/types.d.ts +2 -0
  17. package/dist/bundled-extensions/session-title/config.js +1 -1
  18. package/dist/markdown-format.js +27 -9
  19. package/dist/schemas/pi-tools-suite-schema.d.ts +29 -16
  20. package/dist/schemas/pi-tools-suite-schema.js +46 -31
  21. package/external/pi-tools-suite/README.md +392 -52
  22. package/external/pi-tools-suite/docs/browser-qa-subagent.md +31 -21
  23. package/external/pi-tools-suite/docs/context-gateway-p00-adr.md +216 -0
  24. package/external/pi-tools-suite/docs/context-gateway-p01n-gate-review.md +122 -0
  25. package/external/pi-tools-suite/docs/context-gateway-p01n-measurement.md +133 -0
  26. package/external/pi-tools-suite/docs/context-gateway-p01r-ra-evidence.md +111 -0
  27. package/external/pi-tools-suite/docs/context-gateway-p01r-rb-evidence.md +100 -0
  28. package/external/pi-tools-suite/docs/context-gateway-p01r-rc-evidence.md +69 -0
  29. package/external/pi-tools-suite/docs/context-gateway-p01r-rd-evidence.md +100 -0
  30. package/external/pi-tools-suite/docs/context-gateway-p01r-re-evidence.md +74 -0
  31. package/external/pi-tools-suite/docs/context-gateway-p01r-rf-evidence.md +153 -0
  32. package/external/pi-tools-suite/docs/context-gateway-p01r-rg-evidence.md +235 -0
  33. package/external/pi-tools-suite/docs/evals.md +684 -0
  34. package/external/pi-tools-suite/docs/subagent-model-pools.md +109 -0
  35. package/external/pi-tools-suite/package.json +10 -3
  36. package/external/pi-tools-suite/src/async-subagents/{private-skills → agents}/browser-qa/scripts/browser-qa-runner.mjs +82 -1
  37. package/external/pi-tools-suite/src/async-subagents/{private-skills/browser-qa/SKILL.md → agents/browser-qa.md} +261 -12
  38. package/external/pi-tools-suite/src/async-subagents/agents/implement.md +20 -0
  39. package/external/pi-tools-suite/src/async-subagents/agents/oracle.md +16 -0
  40. package/external/pi-tools-suite/src/async-subagents/agents/research.md +18 -0
  41. package/external/pi-tools-suite/src/async-subagents/agents/verify.md +18 -0
  42. package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +27 -243
  43. package/external/pi-tools-suite/src/async-subagents/commands.ts +6 -2
  44. package/external/pi-tools-suite/src/async-subagents/core/agent-catalog.ts +41 -0
  45. package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +13 -93
  46. package/external/pi-tools-suite/src/async-subagents/core/agents-dir.ts +494 -0
  47. package/external/pi-tools-suite/src/async-subagents/core/browser-qa.ts +9 -0
  48. package/external/pi-tools-suite/src/async-subagents/core/config.ts +200 -143
  49. package/external/pi-tools-suite/src/async-subagents/core/model-fallback.ts +1 -1
  50. package/external/pi-tools-suite/src/async-subagents/core/model-selection.ts +54 -0
  51. package/external/pi-tools-suite/src/async-subagents/core/prompt.ts +7 -6
  52. package/external/pi-tools-suite/src/async-subagents/core/routing.ts +52 -45
  53. package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +12 -4
  54. package/external/pi-tools-suite/src/async-subagents/index.ts +11 -1
  55. package/external/pi-tools-suite/src/async-subagents/lib.ts +6 -2
  56. package/external/pi-tools-suite/src/async-subagents/tools/spawn.ts +46 -18
  57. package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +3 -2
  58. package/external/pi-tools-suite/src/async-subagents/types.ts +2 -0
  59. package/external/pi-tools-suite/src/coding-discipline/index.ts +41 -142
  60. package/external/pi-tools-suite/src/config.ts +1 -22
  61. package/external/pi-tools-suite/src/context-gateway/accounting.ts +151 -0
  62. package/external/pi-tools-suite/src/context-gateway/config.ts +111 -0
  63. package/external/pi-tools-suite/src/context-gateway/index.ts +160 -0
  64. package/external/pi-tools-suite/src/context-gateway/metadata-normalization.ts +88 -0
  65. package/external/pi-tools-suite/src/context-gateway/storeless-capabilities.ts +89 -0
  66. package/external/pi-tools-suite/src/context-gateway/telemetry.ts +429 -0
  67. package/external/pi-tools-suite/src/context-gateway/test-output-parser.ts +326 -0
  68. package/external/pi-tools-suite/src/context-gateway/types.ts +152 -0
  69. package/external/pi-tools-suite/src/dcp/auto-compress-budget.ts +106 -0
  70. package/external/pi-tools-suite/src/dcp/auto-compress.ts +810 -106
  71. package/external/pi-tools-suite/src/dcp/commands.ts +64 -139
  72. package/external/pi-tools-suite/src/dcp/compress-tool.ts +369 -35
  73. package/external/pi-tools-suite/src/dcp/compression-blocks.ts +510 -64
  74. package/external/pi-tools-suite/src/dcp/compression-preview.ts +113 -0
  75. package/external/pi-tools-suite/src/dcp/compression-progress.ts +70 -0
  76. package/external/pi-tools-suite/src/dcp/config.ts +36 -61
  77. package/external/pi-tools-suite/src/dcp/conversation-index.ts +421 -0
  78. package/external/pi-tools-suite/src/dcp/debug-log.ts +7 -5
  79. package/external/pi-tools-suite/src/dcp/index.ts +617 -203
  80. package/external/pi-tools-suite/src/dcp/journal.ts +566 -0
  81. package/external/pi-tools-suite/src/dcp/progress-controller.ts +244 -0
  82. package/external/pi-tools-suite/src/dcp/prompts.ts +10 -7
  83. package/external/pi-tools-suite/src/dcp/provider-tool-results.ts +189 -0
  84. package/external/pi-tools-suite/src/dcp/pruner-candidates.ts +298 -78
  85. package/external/pi-tools-suite/src/dcp/pruner-compression-blocks.ts +173 -281
  86. package/external/pi-tools-suite/src/dcp/pruner-emergency.ts +2 -4
  87. package/external/pi-tools-suite/src/dcp/pruner-message-ids.ts +17 -5
  88. package/external/pi-tools-suite/src/dcp/pruner-metadata.ts +11 -1
  89. package/external/pi-tools-suite/src/dcp/pruner-nudge.ts +30 -82
  90. package/external/pi-tools-suite/src/dcp/pruner-tools.ts +22 -133
  91. package/external/pi-tools-suite/src/dcp/pruner.ts +18 -33
  92. package/external/pi-tools-suite/src/dcp/recovery.ts +129 -0
  93. package/external/pi-tools-suite/src/dcp/shadow-plan.ts +127 -0
  94. package/external/pi-tools-suite/src/dcp/state-transaction.ts +102 -0
  95. package/external/pi-tools-suite/src/dcp/state.ts +158 -580
  96. package/external/pi-tools-suite/src/dcp/ui.ts +1 -0
  97. package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +55 -220
  98. package/external/pi-tools-suite/src/index.ts +9 -0
  99. package/external/pi-tools-suite/src/model-tools/index.ts +76 -42
  100. package/external/pi-tools-suite/src/repo-discovery/index.ts +84 -18
  101. package/external/pi-tools-suite/src/repo-discovery/native-compact.ts +458 -0
  102. package/external/pi-tools-suite/src/session-recovery/index.ts +189 -43
  103. package/external/pi-tools-suite/src/tool-descriptions.ts +43 -38
  104. package/external/pi-tools-suite/src/truncation-metadata-normalizer/index.ts +17 -0
  105. package/package.json +6 -6
  106. package/schemas/pi-tools-suite.json +159 -78
  107. package/external/pi-tools-suite/src/async-subagents/private-skills/browser-qa/references/auth-scaffold-spec.md +0 -78
  108. package/external/pi-tools-suite/src/async-subagents/private-skills/browser-qa/references/qa-design.md +0 -223
  109. package/external/pi-tools-suite/src/dcp/state-persistence.ts +0 -195
  110. /package/external/pi-tools-suite/src/async-subagents/{private-skills/browser-qa/references → agents/browser-qa/examples}/qa-auth.example.jsonc +0 -0
  111. /package/external/pi-tools-suite/src/async-subagents/{private-skills/browser-qa/references → agents/browser-qa/examples}/qa-flow.example.jsonc +0 -0
  112. /package/external/pi-tools-suite/src/async-subagents/{private-skills → agents}/browser-qa/vendor/fflate.LICENSE +0 -0
  113. /package/external/pi-tools-suite/src/async-subagents/{private-skills → agents}/browser-qa/vendor/fflate.mjs +0 -0
@@ -1,38 +1,10 @@
1
1
  {
2
- // This sample is the value for `asyncSubagents` in ~/.config/pi/pi-tools-suite.jsonc.
2
+ // Value of asyncSubagents in pi-tools-suite.jsonc.
3
+ // Bundled role definitions and ordered models live in agents/*.md.
3
4
  // Full config schema: https://unpkg.com/pi-ui-extend/schemas/pi-tools-suite.json
4
-
5
- // Global async-subagents routing.
6
- // Rule of thumb:
7
- // - GLM: cheap/fast discovery, grep-style scanning, docs/test inventory.
8
- // - GLM-5.3 Flash: frontend/UI/UX, visual/product polish, and multimodal-heavy analysis.
9
- // - GPT/Claude: review/audit, deep reasoning, tests, and implementation/refactoring.
10
- // Override exact model IDs here if your pi provider uses different names.
11
- "defaultType": "quick",
12
-
13
- // Maximum concurrent sub-agent processes for this project/session.
14
- // 0 means unlimited. Excess agents stay queued as planned until a slot opens.
5
+ "defaultType": "research",
15
6
  "maxConcurrent": 5,
16
-
17
- // Optional global retry defaults. Per-type `retry` overrides these values.
18
- // `retryableExitCodes` omitted = retry any non-zero exit; [] = disable retry by exit-code filter.
19
- // "retry": { "maxRetries": 1, "backoffMs": 2000, "retryableExitCodes": [1, 124] },
20
-
21
- // Maximum bytes copied from raw result.md into result.json's `resultText`.
22
- // result.md itself remains the full raw sub-agent output.
23
7
  "maxResultBytes": 100000,
24
-
25
- // Optional wall-clock timeout for each spawned agent in milliseconds.
26
- // The built-in default is 30 minutes when this is omitted. You can also set
27
- // `timeoutMs` per type/preset, or pass `timeoutSeconds` to a spawn call/task
28
- // for short synthetic tests.
29
- // "timeoutMs": 1800000,
30
-
31
- // Parent-model image-capability overrides. Pi provider metadata can be missing
32
- // or stale after switching models, so async-subagents treats these glob-like
33
- // model refs as text-only when dynamic detection is inconclusive. Blind-model
34
- // screenshot inspection should use lookup; this only keeps guidance honest.
35
- // Matching is case-insensitive and supports `*` wildcards.
36
8
  "vision": {
37
9
  "blindModelPatterns": [
38
10
  "zai/glm-4.5*", "glm-4.5*", "*/glm-4.5*",
@@ -40,231 +12,43 @@
40
12
  "zai/glm-5.3", "glm-5.3", "*/glm-5.3"
41
13
  ]
42
14
  },
43
-
44
- // Optional per-type prompt customization (leave commented until needed):
45
- // - promptAppend: append extra instructions after the generated prompt.
46
- // - promptOverride: replace the generated prompt entirely.
47
- // Supports placeholders: {id}, {task}, {scope}, {parentObjective}, {subagentType}, {model}, {thinking}.
48
- // Example inside any type profile:
49
- // "promptAppend": [
50
- // "Use this role-specific checklist.",
51
- // "Return file paths before conclusions."
52
- // ],
53
- // "promptOverride": "You are a specialized {subagentType} sub-agent.\nParent: {parentObjective}\nTask: {task}\nScope: {scope}",
54
-
55
- // Parent-model-aware model selection (optional, any type profile).
56
- // modelByParent maps glob model refs (matched against the current parent
57
- // model, e.g. "zai/*") to a model for this role. The first matching key wins.
58
- // Values may be a model string or { model, fallbackModels? }. It is resolved
59
- // after an explicit task.model / forcedModel, but before the preset/static
60
- // profile model, so a role like an "oracle" can always pick a flagship from a
61
- // DIFFERENT provider than the parent. Example:
62
- // "modelByParent": {
63
- // "zai/*": { "model": "openai-codex/gpt-5.6-sol", "fallbackModels": ["zai/glm-5.3"] },
64
- // "openai-codex/*": "zai/glm-5.3",
65
- // "antigravity/*": { "model": "zai/glm-5.3", "fallbackModels": ["openai-codex/gpt-5.6-sol"] }
66
- // }
67
-
68
- // Role auto-selection when subagentType is omitted is handled by a small LLM
69
- // router request. The router receives each task plus the configured type
70
- // descriptions, then returns one allowed subagentType per task. Explicit
71
- // task subagentType still wins. If the router model is unavailable or returns
72
- // invalid JSON, async-subagents falls back to defaultType.
15
+ // Only omitted roles use the LLM router. Model selection itself is deterministic.
73
16
  "routing": {
74
17
  "enabled": true,
75
- "model": "zai/glm-4.5-air",
76
- // Ordered router model fallbacks tried when the primary routing model is
77
- // unavailable or fails. The current parent model is always tried last.
18
+ "model": "zai/glm-5-turbo",
78
19
  "fallbackModels": ["openai-codex/gpt-5.6-luna"],
79
20
  "maxTaskChars": 1200,
80
21
  "maxTokens": 512,
81
- "maxRetries": 3,
82
- "timeoutMs": 10000,
22
+ "maxRetries": 1,
23
+ "timeoutMs": 12000,
83
24
  "debug": false
84
25
  },
85
-
86
- // Presets are named agent/model configurations selected with /subagent-preset.
87
- // They do not replace role routing below: `types` still defines what each role means.
88
- // A preset overrides the models/thinking used by roles.
89
- // Set AGENTS_PRESET=<name> before launching Pi to override the saved
90
- // /subagent-preset selection for only the current process/session without
91
- // modifying the saved selection file. If Pi is already running, use
92
- // /subagent-preset session <name> and /subagent-preset session-clear instead.
93
- // Shape:
94
- // "presets": {
95
- // "name": {
96
- // "description": "shown in the selector",
97
- // "model": "optional fallback model for roles not listed in types",
98
- // "fallbackModels": ["optional/session fallback when model quota is exhausted"],
99
- // "thinking": "optional fallback thinking level",
100
- // "extraArgs": ["optional", "global", "pi", "args"],
101
- // "timeoutMs": 1800000,
102
- // "types": {
103
- // "roleName": { "model": "provider/model", "fallbackModels": ["provider/backup"], "thinking": "off|low|medium|high|xhigh|max", "timeoutMs": 1800000 }
104
- // }
105
- // }
106
- // }
107
- // Fallbacks are intended to cross provider boundaries: zai/* roles usually omit
108
- // fallbackModels when that provider is effectively unlimited. If GPT/openai-codex
109
- // is exhausted, use the matching zai/* role model. If Antigravity is exhausted,
110
- // use the matching GPT/openai-codex role model, then matching zai/*. Exhausted
111
- // providers are skipped for the current Pi process/session.
112
- // Explicit task model/thinking and FORCE_CURRENT_MODEL still take precedence.
113
-
26
+ // A preset is an available model pool, NOT a role-to-model mapping.
27
+ // Choose the first usable entry in each agent's models that is in
28
+ // this pool. Pool order does not reorder agent preferences. The remaining
29
+ // matching candidates are the only quota fallbacks; never leave the pool.
30
+ // Oracle uses its strong candidate list, preferring another provider when
31
+ // possible, but also respects this pool. An empty intersection is an error.
32
+ // Explicit task.model, CLI --model, and FORCE_CURRENT_MODEL remain overrides.
33
+ // Legacy preset model/types/fallbackModels fields still load for compatibility.
114
34
  "presets": {
115
35
  "cheap": {
116
- "description": "Use GLM models by role, including GLM-5.3 Flash for multimodal work.",
117
- "types": {
118
- "quick": { "model": "zai/glm-4.5-air", "thinking": "off" },
119
- "scan": { "model": "zai/glm-4.5-air", "thinking": "off" },
120
- "research": { "model": "zai/glm-5-turbo", "thinking": "low" },
121
- "docs": { "model": "zai/glm-4.5-air", "thinking": "low" },
122
- "frontend": { "model": "zai/glm-5.3-flash", "thinking": "medium" },
123
- "browser-qa": { "model": "zai/glm-5.3-flash", "fallbackModels": ["openai-codex/gpt-5.6-luna"], "thinking": "low" },
124
- "tests": { "model": "zai/glm-5-turbo", "thinking": "medium" },
125
- "review": { "model": "zai/glm-5.3", "thinking": "high" },
126
- "implement": { "model": "zai/glm-5.3", "thinking": "high" },
127
- "deep": { "model": "zai/glm-5.3", "thinking": "high" }
128
- }
36
+ "description": "GLM pool: economical workers plus GLM-5.3 for oracle.",
37
+ "models": ["zai/glm-5-turbo", "zai/glm-5.3-flash", "zai/glm-5.3"]
129
38
  },
130
-
131
39
  "gpt": {
132
- "description": "Use the GPT-5.6 family by role: luna for fast tasks, terra for balanced work, and sol for heavy reasoning; fallback cross-provider on quota.",
133
- "types": {
134
- "quick": { "model": "openai-codex/gpt-5.6-luna", "fallbackModels": ["zai/glm-4.5-air"], "thinking": "off" },
135
- "scan": { "model": "openai-codex/gpt-5.6-luna", "fallbackModels": ["zai/glm-4.5-air"], "thinking": "off" },
136
- "research": { "model": "openai-codex/gpt-5.6-terra", "fallbackModels": ["zai/glm-5-turbo"], "thinking": "low" },
137
- "docs": { "model": "openai-codex/gpt-5.6-luna", "fallbackModels": ["zai/glm-4.5-air"], "thinking": "low" },
138
- "frontend": { "model": "openai-codex/gpt-5.6-terra", "fallbackModels": ["antigravity/gemini-3-flash-preview", "zai/glm-5.3"], "thinking": "medium" },
139
- "browser-qa": { "model": "zai/glm-5.3-flash", "fallbackModels": ["openai-codex/gpt-5.6-luna"], "thinking": "low" },
140
- "tests": { "model": "openai-codex/gpt-5.6-terra", "fallbackModels": ["zai/glm-5-turbo"], "thinking": "medium" },
141
- "review": { "model": "openai-codex/gpt-5.6-sol", "fallbackModels": ["zai/glm-5.3"], "thinking": "high" },
142
- "implement": { "model": "openai-codex/gpt-5.6-sol", "fallbackModels": ["zai/glm-5.3"], "thinking": "high" },
143
- "deep": { "model": "openai-codex/gpt-5.6-sol", "fallbackModels": ["zai/glm-5.3"], "thinking": "high" }
144
- }
40
+ "description": "GPT pool: Luna/Terra workers; Sol is available to oracle.",
41
+ "models": ["openai-codex/gpt-5.6-luna", "openai-codex/gpt-5.6-terra", "openai-codex/gpt-5.6-sol"]
145
42
  },
146
-
147
43
  "deep": {
148
- "description": "Use only enabled strong models, mixing GPT, Claude, and Gemini by role.",
149
- "types": {
150
- "quick": { "model": "openai-codex/gpt-5.6-luna", "fallbackModels": ["zai/glm-4.5-air"], "thinking": "low" },
151
- "scan": { "model": "antigravity/gemini-3-flash-preview", "fallbackModels": ["openai-codex/gpt-5.6-luna", "zai/glm-4.5-air"], "thinking": "off" },
152
- "research": { "model": "antigravity/gemini-3.1-pro-preview", "fallbackModels": ["openai-codex/gpt-5.6-luna", "zai/glm-5-turbo"], "thinking": "medium" },
153
- "docs": { "model": "antigravity/gemini-2.5-flash", "fallbackModels": ["openai-codex/gpt-5.6-luna", "zai/glm-4.5-air"], "thinking": "medium" },
154
- "frontend": { "model": "antigravity/gemini-3.1-pro-preview-customtools", "fallbackModels": ["openai-codex/gpt-5.6-luna", "zai/glm-5.3"], "thinking": "low" },
155
- "browser-qa": { "model": "zai/glm-5.3-flash", "fallbackModels": ["openai-codex/gpt-5.6-luna"], "thinking": "low" },
156
- "tests": { "model": "antigravity/antigravity-claude-sonnet-4-6", "fallbackModels": ["openai-codex/gpt-5.6-luna", "zai/glm-5-turbo"], "thinking": "high" },
157
- "review": { "model": "antigravity/antigravity-claude-sonnet-4-6", "fallbackModels": ["openai-codex/gpt-5.6-sol", "zai/glm-5.3"], "thinking": "high" },
158
- "implement": { "model": "openai-codex/gpt-5.6-sol", "fallbackModels": ["zai/glm-5.3"], "thinking": "high" },
159
- "deep": { "model": "antigravity/antigravity-claude-opus-4-6-thinking", "fallbackModels": ["openai-codex/gpt-5.6-sol", "zai/glm-5.3"], "thinking": "high" }
160
- }
44
+ "description": "Legacy preset name for the mixed pool; workers retain economical candidate order, oracle uses strong models.",
45
+ "models": ["zai/glm-5-turbo", "zai/glm-5.3-flash", "openai-codex/gpt-5.6-luna", "openai-codex/gpt-5.6-terra", "openai-codex/gpt-5.6-sol", "zai/glm-5.3"]
161
46
  }
162
47
  },
163
-
164
- "types": {
165
- "quick": {
166
- "description": "Use for tiny cheap tasks: answer a simple question, inspect one known file, or verify one fact. Not for broad repo search.",
167
- "model": "openai-codex/gpt-5.6-luna",
168
- "fallbackModels": ["zai/glm-4.5-air"],
169
- "thinking": "off"
170
- },
171
-
172
- "scan": {
173
- "description": "Use for finding files, symbols, text, or inventory across a repo. Return paths/facts; do not judge code quality.",
174
- "model": "openai-codex/gpt-5.6-luna",
175
- "fallbackModels": ["zai/glm-4.5-air"],
176
- "thinking": "off",
177
- "tools": ["read", "grep"]
178
- },
179
-
180
- "research": {
181
- "description": "Use for multi-file codebase research: read several files and explain how something works. No edits.",
182
- "model": "openai-codex/gpt-5.6-terra",
183
- "fallbackModels": ["zai/glm-5-turbo"],
184
- "thinking": "low",
185
- "tools": ["read", "grep"]
186
- },
187
-
188
- "docs": {
189
- "description": "Use for documentation work: README/API docs review, docs gaps, changelog, migration notes, examples.",
190
- "model": "openai-codex/gpt-5.6-luna",
191
- "fallbackModels": ["zai/glm-4.5-air"],
192
- "thinking": "low"
193
- },
194
-
195
- "frontend": {
196
- "description": "Use for frontend UI/UX visual work: styling, layout, typography, animation, responsive states, component polish, accessibility. Avoid backend/business logic unless needed for UI behavior.",
197
- "model": "antigravity/gemini-3-flash-preview",
198
- "fallbackModels": ["openai-codex/gpt-5.6-luna", "zai/glm-5.3"],
199
- "thinking": "medium",
200
- "promptAppend": [
201
- "Act as a frontend UI/UX engineer for visual and product-facing work.",
202
- "Prioritize layout, typography, spacing, color, motion, responsive states, accessibility, and consistency with the existing design system.",
203
- "Before editing, inspect nearby components/styles and infer the project's design language. Avoid backend/business-logic changes unless required for UI behavior.",
204
- "When no mockup exists, choose a clear aesthetic direction and explain it briefly. Verify with targeted build/lint/tests or screenshot-relevant checks when possible."
205
- ]
206
- },
207
-
208
- "browser-qa": {
209
- "description": "Use for browser-based visual QA: reproduce UI bugs and verify fixes with deterministic assertions, screenshots, video, and traces.",
210
- "model": "zai/glm-5.3-flash",
211
- "fallbackModels": ["openai-codex/gpt-5.6-luna"],
212
- "thinking": "low",
213
- "timeoutMs": 300000,
214
- "tools": ["read", "grep", "bash"]
215
- },
216
-
217
- "tests": {
218
- "description": "Use for tests: locate coverage, find gaps, run/check targeted test commands, diagnose failing tests.",
219
- "model": "openai-codex/gpt-5.6-terra",
220
- "fallbackModels": ["zai/glm-5-turbo"],
221
- "thinking": "medium",
222
- "tools": ["read", "grep", "bash"]
223
- },
224
-
225
- "review": {
226
- "description": "Use for review/audit of existing code or changes: correctness, security, performance, maintainability, API risks, quality. Do not implement new code.",
227
- "model": "openai-codex/gpt-5.6-sol",
228
- "fallbackModels": ["zai/glm-5.3"],
229
- "thinking": "high",
230
- "tools": ["read", "grep"]
231
- },
232
-
233
- "implement": {
234
- "description": "Use when the sub-agent should make or plan code changes for a feature, bug fix, or refactor.",
235
- "model": "openai-codex/gpt-5.6-sol",
236
- "fallbackModels": ["zai/glm-5.3"],
237
- // Avoid Sol recursively doing routine implementation work for a Sol parent.
238
- // Luna also escalates substantial implementation to Terra. modelByParent
239
- // wins over preset role models, so this prevents both Luna -> Sol and
240
- // Sol -> Sol for implement tasks under the built-in `gpt` preset.
241
- "modelByParent": {
242
- "openai-codex/gpt-5.6-luna*": { "model": "openai-codex/gpt-5.6-terra", "fallbackModels": ["zai/glm-5.3"] },
243
- "openai-codex/gpt-5.6-sol*": { "model": "openai-codex/gpt-5.6-terra", "fallbackModels": ["zai/glm-5.3"] }
244
- },
245
- "thinking": "high"
246
- },
247
-
248
- "deep": {
249
- "description": "Use for broad hard reasoning: architecture, system design, cross-module impact, complex tradeoffs.",
250
- "model": "openai-codex/gpt-5.6-sol",
251
- "fallbackModels": ["zai/glm-5.3"],
252
- "thinking": "high"
253
- },
254
-
255
- "oracle": {
256
- "description": "Oracle: cross-provider flagship second opinion for hard or high-stakes uncertainty. Use sparingly to pressure-test architecture, plans, root-cause hypotheses, risk/security calls, or final recommendations when independent disagreement is valuable. Read-only; advise, do not edit.",
257
- "model": "openai-codex/gpt-5.6-sol",
258
- "fallbackModels": ["zai/glm-5.3"],
259
- "thinking": "max",
260
- "tools": ["read", "grep", "bash"],
261
- "modelByParent": {
262
- "zai/*": { "model": "openai-codex/gpt-5.6-sol", "fallbackModels": ["zai/glm-5.3"] },
263
- "openai-codex/*": { "model": "zai/glm-5.3", "fallbackModels": ["openai-codex/gpt-5.6-sol"] },
264
- "antigravity/*": { "model": "zai/glm-5.3", "fallbackModels": ["openai-codex/gpt-5.6-sol"] },
265
- "anthropic/*": { "model": "openai-codex/gpt-5.6-sol", "fallbackModels": ["zai/glm-5.3"] }
266
- },
267
- "promptAppend": "You are an oracle: a flagship model from a different provider giving a second opinion to the parent agent. Give a concise, decisive recommendation with key tradeoffs and risks. Disagree when warranted; do not rubber-stamp. Do not edit unless explicitly asked."
268
- }
269
- }
48
+ // Override role behavior here or define project specialists in .pi/agents/.
49
+ // Old builtin names are not aliases; define them explicitly only when you
50
+ // intentionally want custom types with those exact names.
51
+ // Per-type "icon" names the agent glyph for UI widgets (agent, search, code,
52
+ // flask, globe, sparkles, brain, wrench, terminal, bug, book, eye, zap, rocket).
53
+ "types": {}
270
54
  }
@@ -53,13 +53,13 @@ const COPY_SAMPLE_CONFIG_LABEL = "Copy sample asyncSubagents config";
53
53
 
54
54
  export const ULTRAWORK_PROMPT = `Run ultrawork mode for the current objective.
55
55
 
56
- Use subagents when independent parallel tracks help. Pick subagentType from configured roles: quick, scan, research, docs, frontend, implement, tests, review, deep, oracle. Use review for security/performance/audit tracks, implement for refactors, deep for debugging/root-cause. Use frontend for UI/UX and visual frontend implementation; use oracle sparingly for cross-provider second opinions on high-stakes uncertainty.
56
+ Use subagents when a lower-cost worker or isolation of noisy evidence helps, including one bounded sequential task. Pick subagentType from the effective catalog: research for reading/review, implement for code/docs/tests/UI changes, verify for running checks, browser-qa for real-browser testing, and oracle only for a deliberate strong independent opinion. Prefer an appropriate project-local specialist. Keep decisions and integration in the parent; do not create agents just to assign a discipline.
57
57
 
58
58
  Keep parent context lean: spawn for broad parallel work, read results only when needed, and finish unless genuinely blocked.`;
59
59
 
60
60
  const HYPERPLAN_PROMPT = `Run hyperplan mode for the current objective.
61
61
 
62
- Before implementation, use subagents to pressure-test the plan with configured roles such as deep, implement, frontend, tests, review, and docs. Synthesize the strongest objections into a revised plan before editing.`;
62
+ Before implementation, use bounded research tasks to gather constraints and independently pressure-test the plan. Use oracle only when a strong second opinion is justified. Synthesize the evidence and objections in the parent before editing.`;
63
63
 
64
64
  export function buildUltraworkPrompt(objective: string): string {
65
65
  const trimmed = objective.trim();
@@ -368,6 +368,10 @@ function sortedPresetNames(presets: Record<string, SubagentPreset>, activePreset
368
368
  function subagentPresetDescription(preset: SubagentPreset): string {
369
369
  const parts: string[] = [];
370
370
  if (preset.description) parts.push(preset.description);
371
+ if (preset.models !== undefined) {
372
+ parts.push(`models:${preset.models.join(",") || "(none)"}`);
373
+ return parts.join(", ");
374
+ }
371
375
  if (preset.model) parts.push(`model:${preset.model}`);
372
376
  if (preset.fallbackModels && preset.fallbackModels.length > 0) parts.push(`fallbacks:${preset.fallbackModels.join(",")}`);
373
377
  if (preset.thinking) parts.push(`thinking:${preset.thinking}`);
@@ -0,0 +1,41 @@
1
+ import type { SubagentConfig } from "./config.js";
2
+ import { SUBAGENT_DELEGATION_GUIDANCE } from "./agent-strategy.js";
3
+
4
+ export const SUBAGENT_TYPE_SELECTION_GUIDANCE = "Choose and set subagentType from the available catalog when a role clearly matches, preferring a matching project-local specialist. Preserve a user-requested role. Omit subagentType only when unsure or when the user explicitly requests automatic routing; the LLM router handles omissions only. Model/thinking overrides are not substitutes for choosing a role.";
5
+
6
+ const MAX_DESCRIPTION_CHARS = 500;
7
+
8
+ /**
9
+ * Render the effective sub-agent type catalog for the parent system prompt.
10
+ * The config has already merged built-ins, config files, and project-local
11
+ * `.pi/agents/*.md`, so this stays aligned with what spawn/routing can use.
12
+ */
13
+ export function buildSubagentCatalogPrompt(config: SubagentConfig): string | undefined {
14
+ const entries = Object.entries(config.types).sort(([left], [right]) => left.localeCompare(right));
15
+ if (entries.length === 0) return undefined;
16
+
17
+ return [
18
+ '<available_subagent_types>',
19
+ "Effective sub-agent types available to the `subagents` tool for this project.",
20
+ "These names are valid explicit `subagentType` values. Project-local `.pi/agents/*.md` roles are included when enabled by the current config.",
21
+ SUBAGENT_TYPE_SELECTION_GUIDANCE,
22
+ SUBAGENT_DELEGATION_GUIDANCE,
23
+ ...entries.map(([name, profile]) => `- ${escapePromptText(name)}: ${catalogDescription(profile.description)}`),
24
+ '</available_subagent_types>',
25
+ ].join("\n");
26
+ }
27
+
28
+ function catalogDescription(description: string | undefined): string {
29
+ const text = description?.trim() || "No description; use only when the task explicitly names this type.";
30
+ const bounded = text.length <= MAX_DESCRIPTION_CHARS
31
+ ? text
32
+ : `${text.slice(0, MAX_DESCRIPTION_CHARS - 1).trimEnd()}…`;
33
+ return escapePromptText(bounded.replace(/\s+/g, " "));
34
+ }
35
+
36
+ function escapePromptText(value: string): string {
37
+ return value
38
+ .replace(/&/g, "&amp;")
39
+ .replace(/</g, "&lt;")
40
+ .replace(/>/g, "&gt;");
41
+ }
@@ -1,5 +1,3 @@
1
- import { isGptLikeModel } from "./ultrawork-auto.js";
2
-
3
1
  export type AgentStrategyName = "parallel-first" | "deep-work" | "escalation-aware" | "cost-aware-orchestrator";
4
2
 
5
3
  export interface AgentStrategyOptions {
@@ -8,106 +6,28 @@ export interface AgentStrategyOptions {
8
6
  env?: NodeJS.ProcessEnv;
9
7
  }
10
8
 
11
- const FALSE_ENV_PATTERN = /^(0|false|off|no|disabled|none)$/i;
12
- const TRUE_ENV_PATTERN = /^(1|true|on|yes|auto)$/i;
13
-
14
- const PARALLEL_FIRST_STRATEGY_PROMPT = `<agent_strategy name="parallel-first">
15
- Execution hint for Pi, not a replacement for system/developer/user instructions.
16
-
17
- Default: orchestration-first. For broad, multi-file, ambiguous, review/audit, frontend, test-strategy, architecture, or root-cause work, prefer ultrawork: split independent tracks into focused async subagents, adding one oracle only for high-stakes uncertainty. Keep parent context lean, read compact results when needed, synthesize, then verify.
18
-
19
- Do not over-delegate simple questions, known-file work, exact lookups, typos, or narrow edits; solve them directly with the cheapest suitable tool. If compressing unfinished work, preserve active objective + next step via todo/DCP rules.
20
- </agent_strategy>`;
21
-
22
- const DEEP_WORK_STRATEGY_PROMPT = `<agent_strategy name="deep-work">
23
- Execution hint for Pi, not a replacement for system/developer/user instructions.
24
-
25
- Default: autonomous deep worker. Build context directly, make progress, edit, and verify end-to-end. Use async subagents/ultrawork only when the user asks for delegation or independent tracks clearly reduce risk; do not force orchestration onto narrow tasks.
9
+ /** Shared by the strategy, tool description and role catalog. */
10
+ export const SUBAGENT_DELEGATION_GUIDANCE = "Delegate bounded work when a lower-cost worker can do it or noisy intermediate evidence should stay out of the parent context; one sequential task can qualify. Keep planning, decisions, integration and the final answer in the parent. Use research for evidence/review, implement for code/docs/tests/UI changes, verify for running checks, browser-qa for browser testing. Reserve oracle for a deliberate strong independent opinion, not automatic escalation. Do trivial lookups/edits directly; redirect a noisy command to a log instead of spawning an LLM when no interpretation is needed.";
26
11
 
27
- For broad work, keep delegation explicit and bounded: focused review/research/tests/frontend/deep tracks, plus one oracle only for high-stakes uncertainty or final plan checks. Read compact results, decide in the parent session, and report only what matters. If compressing unfinished work, preserve active objective + next step via todo/DCP rules.
28
- </agent_strategy>`;
29
-
30
- const ESCALATION_AWARE_STRATEGY_PROMPT = `<agent_strategy name="escalation-aware">
12
+ export function agentStrategyPrompt(options: AgentStrategyOptions = {}): string | undefined {
13
+ const env = options.env ?? process.env;
14
+ const override = env.PI_AGENT_STRATEGY?.trim() || env.ASYNC_SUBAGENTS_AGENT_STRATEGY?.trim();
15
+ if (/^(0|false|off|no|disabled|none)$/i.test(override ?? "")) return undefined;
16
+ const allowCustom = env.PI_AGENT_STRATEGY_WITH_CUSTOM_PROMPT ?? env.ASYNC_SUBAGENTS_AGENT_STRATEGY_WITH_CUSTOM_PROMPT;
17
+ if (options.customPrompt && !/^(1|true|on|yes|auto)$/i.test(allowCustom?.trim() ?? "")) return undefined;
18
+ // Old strategy names remain accepted, but no longer cause hidden tier escalation.
19
+ return `<agent_strategy name="cost-aware-orchestrator">
31
20
  Execution hint for Pi, not a replacement for system/developer/user instructions.
32
21
 
33
- Default: self-sufficient with tiered escalation. Solve narrow, well-bounded work directly, but do not grind through a large or uncertain task at the current model tier when a stronger focused subagent is appropriate. Use todo for the plan and async subagents for escalation; read compact results first and keep the parent context lean.
34
-
35
- For a Luna parent, prefer Terra workers for substantial multi-file research, tests, or implementation, and escalate deep root-cause analysis, architecture/security review, high-risk decisions, or repeatedly failing complex work to Sol through the deep/review roles. For a Terra parent, handle routine research/tests/implementation directly; escalate deep root-cause analysis, architecture/security review, high-risk decisions, or stubborn complex failures to Sol through deep/review. Do not escalate merely because a plan has several steps, and do not delegate a tiny known-file edit or exact lookup.
36
-
37
- Keep user questions, plan/todo changes, integration decisions, and the final report in the parent. Independent read-only escalations may run in parallel; serialize overlapping edits unless scopes are clearly disjoint. When work is delegated, synchronize its todo lifecycle: mark it in progress, collect and verify the worker result, then complete/update it before moving on.
38
- </agent_strategy>`;
39
-
40
- const COST_AWARE_ORCHESTRATOR_STRATEGY_PROMPT = `<agent_strategy name="cost-aware-orchestrator">
41
- Execution hint for Pi, not a replacement for system/developer/user instructions.
22
+ ${SUBAGENT_DELEGATION_GUIDANCE}
42
23
 
43
- Default: cost-aware orchestration. You are an expensive parent model, so keep the parent session focused on planning, decisions, integration, verification, and the final user-facing answer. For non-trivial todo work, prefer focused async subagents for repo scanning, multi-file research, documentation, tests, frontend work, and implementation steps that would otherwise require several repository tool calls. Read compact subagent results first; inspect raw artifacts or redo work in the parent only when verification or uncertainty requires it.
24
+ Give each worker a scoped task, necessary context, acceptance criteria, and a compact return contract. Put task-specific discipline in the brief, not a new persona. Respect the configured worker budget; do not force the parent model or repeatedly retry with stronger workers. On a capability or reasoning blocker, collect the evidence and decide in the parent whether an oracle is justified.
44
25
 
45
- Keep user questions, todo/plan changes, architecture tradeoffs, cross-worker integration decisions, high-stakes review, and the final report in the parent. Do not delegate merely to avoid one cheap exact lookup or a tiny known-file edit. Independent read-only tracks may run in parallel; serialize overlapping edits unless scopes are clearly disjoint. When a todo item is delegated, keep its lifecycle synchronized: mark it in progress, collect and verify the worker result, then complete/update it before moving on.
26
+ Read compact results first and verify selectively; do not reload every source file or repeat the worker's whole investigation. Independent tracks may run in parallel; serialize overlapping edits. Keep delegated todo lifecycle synchronized, preserve active objective + next step via todo/DCP rules, and do not poll merely for progress.
46
27
  </agent_strategy>`;
47
-
48
- export function agentStrategyPrompt(options: AgentStrategyOptions = {}): string | undefined {
49
- const env = options.env ?? process.env;
50
- const override = strategyOverride(env);
51
- if (override === "off") return undefined;
52
- if (options.customPrompt && shouldSkipCustomPrompt(env)) return undefined;
53
-
54
- const strategy = override
55
- ?? (isExpensiveGptParent(options.modelRef)
56
- ? "cost-aware-orchestrator"
57
- : isEscalationAwareGptParent(options.modelRef)
58
- ? "escalation-aware"
59
- : isGptLikeModel(options.modelRef)
60
- ? "deep-work"
61
- : "parallel-first");
62
- if (strategy === "cost-aware-orchestrator") return COST_AWARE_ORCHESTRATOR_STRATEGY_PROMPT;
63
- if (strategy === "escalation-aware") return ESCALATION_AWARE_STRATEGY_PROMPT;
64
- return strategy === "deep-work" ? DEEP_WORK_STRATEGY_PROMPT : PARALLEL_FIRST_STRATEGY_PROMPT;
65
28
  }
66
29
 
67
30
  export function appendAgentStrategyPrompt(systemPrompt: string, strategyPrompt: string): string {
68
31
  const base = systemPrompt.trimEnd();
69
32
  return base ? `${base}\n\n${strategyPrompt}` : strategyPrompt;
70
33
  }
71
-
72
- function strategyOverride(env: NodeJS.ProcessEnv): AgentStrategyName | "off" | undefined {
73
- const raw = firstEnv(env, "PI_AGENT_STRATEGY", "ASYNC_SUBAGENTS_AGENT_STRATEGY");
74
- if (!raw) return undefined;
75
- const value = normalizeStrategyName(raw);
76
- if (FALSE_ENV_PATTERN.test(value)) return "off";
77
- if (value === "parallel-first") return "parallel-first";
78
- if (value === "deep-work") return "deep-work";
79
- if (value === "escalation" || value === "escalation-aware") return "escalation-aware";
80
- if (value === "cost-aware" || value === "cost-aware-orchestrator" || value === "orchestrator") return "cost-aware-orchestrator";
81
- if (TRUE_ENV_PATTERN.test(value)) return undefined;
82
- return undefined;
83
- }
84
-
85
- function isExpensiveGptParent(modelRef: string | undefined): boolean {
86
- if (!modelRef) return false;
87
- return /(?:^|\/)gpt-5\.6-sol(?:$|[-.:])/i.test(modelRef.trim());
88
- }
89
-
90
- function isEscalationAwareGptParent(modelRef: string | undefined): boolean {
91
- if (!modelRef) return false;
92
- return /(?:^|\/)gpt-5\.6-(?:luna|terra)(?:$|[-.:])/i.test(modelRef.trim());
93
- }
94
-
95
- function shouldSkipCustomPrompt(env: NodeJS.ProcessEnv): boolean {
96
- const raw = firstEnv(env, "PI_AGENT_STRATEGY_WITH_CUSTOM_PROMPT", "ASYNC_SUBAGENTS_AGENT_STRATEGY_WITH_CUSTOM_PROMPT");
97
- return raw ? !TRUE_ENV_PATTERN.test(raw.trim()) : true;
98
- }
99
-
100
- function normalizeStrategyName(raw: string): string {
101
- const value = raw.trim().toLowerCase().replace(/_/g, "-");
102
- if (value === "parallel" || value === "parallel-first") return "parallel-first";
103
- if (value === "deep" || value === "deep-work") return "deep-work";
104
- return value;
105
- }
106
-
107
- function firstEnv(env: NodeJS.ProcessEnv, ...keys: string[]): string | undefined {
108
- for (const key of keys) {
109
- const value = env[key];
110
- if (typeof value === "string" && value.trim()) return value;
111
- }
112
- return undefined;
113
- }