@liangjie559567/ultrapower 5.5.0 → 5.5.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/.claude-plugin/marketplace.json +2 -2
- package/bridge/codex-server.cjs +2 -3
- package/bridge/gemini-server.cjs +2 -3
- package/bridge/mcp-server.cjs +7 -0
- package/dist/__tests__/delegation-enforcer-integration.test.d.ts +0 -4
- package/dist/__tests__/delegation-enforcer-integration.test.d.ts.map +1 -1
- package/dist/__tests__/delegation-enforcer-integration.test.js +1 -5
- package/dist/__tests__/delegation-enforcer-integration.test.js.map +1 -1
- package/dist/features/auto-update.d.ts.map +1 -1
- package/dist/features/auto-update.js +3 -1
- package/dist/features/auto-update.js.map +1 -1
- package/dist/features/delegation-enforcer.d.ts.map +1 -1
- package/dist/features/delegation-enforcer.js +51 -8
- package/dist/features/delegation-enforcer.js.map +1 -1
- package/dist/hooks/bridge.d.ts.map +1 -1
- package/dist/hooks/bridge.js +5 -0
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/recovery/session-recovery.js +1 -1
- package/dist/hooks/recovery/session-recovery.js.map +1 -1
- package/dist/hooks/subagent-tracker/index.js +2 -2
- package/dist/hooks/subagent-tracker/index.js.map +1 -1
- package/dist/mcp/job-management.d.ts.map +1 -1
- package/dist/mcp/job-management.js +2 -4
- package/dist/mcp/job-management.js.map +1 -1
- package/dist/tools/python-repl/tool.d.ts.map +1 -1
- package/dist/tools/python-repl/tool.js +4 -0
- package/dist/tools/python-repl/tool.js.map +1 -1
- package/docs/design/delegation-enforcer-integration.md +183 -0
- package/package.json +1 -1
- package/skills/ax-export/SKILL.md +39 -6
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Delegation Enforcer Integration Design
|
|
2
|
+
|
|
3
|
+
**Status:** IMPLEMENTED (v5.5.2)
|
|
4
|
+
**Scope:** `src/hooks/bridge.ts`, `src/features/delegation-enforcer.ts`
|
|
5
|
+
**Reviewer:** Product Gate — confirmed
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Problem
|
|
10
|
+
|
|
11
|
+
When Claude Code orchestrators dispatch sub-agents via `Task` or `Agent` calls,
|
|
12
|
+
the `model` parameter is often omitted. The Claude Code SDK does **not**
|
|
13
|
+
automatically apply the default model from agent definitions — every call must
|
|
14
|
+
include it explicitly. This causes most delegated agents to run on the caller's
|
|
15
|
+
model (typically opus) rather than the cost-appropriate tier.
|
|
16
|
+
|
|
17
|
+
**Impact:** Explore agents (should be haiku) run as opus; executor agents (should
|
|
18
|
+
be sonnet) run as opus → 3–10× cost amplification for typical swarm workloads.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 2. Architecture
|
|
23
|
+
|
|
24
|
+
### 2.1 Module Boundaries
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
src/hooks/bridge.ts ← orchestrates all pre-tool-use processing
|
|
28
|
+
└─ processPreToolUse()
|
|
29
|
+
├─ processOrchestratorPreTool() ← delegation BLOCKING (omc-orchestrator)
|
|
30
|
+
├─ ... (AskUserQuestion, pkill, background guard, file ownership)
|
|
31
|
+
└─ enforceDelegationModel() ← model INJECTION (delegation-enforcer) ← NEW
|
|
32
|
+
└─ src/features/delegation-enforcer.ts
|
|
33
|
+
├─ isAgentCall()
|
|
34
|
+
├─ enforceModel()
|
|
35
|
+
└─ processPreToolUse() (called as enforceDelegationModel)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Note:** `processOrchestratorPreTool` (omc-orchestrator) handles whether an
|
|
39
|
+
orchestrator *should* delegate. `processPreToolUse` in delegation-enforcer handles
|
|
40
|
+
*how* to route that delegation (which model tier to use).
|
|
41
|
+
|
|
42
|
+
### 2.2 Relationship with processOrchestratorPreTool
|
|
43
|
+
|
|
44
|
+
| Concern | Module | Action |
|
|
45
|
+
|---------|--------|--------|
|
|
46
|
+
| Should orchestrator direct-edit? | omc-orchestrator | Block / warn |
|
|
47
|
+
| Which model for Task/Agent? | delegation-enforcer | Inject model |
|
|
48
|
+
|
|
49
|
+
These are orthogonal concerns. delegation-enforcer only activates for Task/Agent
|
|
50
|
+
tool calls; omc-orchestrator activates for Edit/Write/Bash tool calls.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 3. Hook Type Scope
|
|
55
|
+
|
|
56
|
+
**Trigger:** `pre-tool-use` only.
|
|
57
|
+
|
|
58
|
+
**Tool filter:** `toolName === 'Task' || toolName === 'Agent'`
|
|
59
|
+
|
|
60
|
+
All other tools (Bash, Edit, Write, Read, Glob, etc.) pass through unchanged.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 4. modifiedInput Protocol
|
|
65
|
+
|
|
66
|
+
The Claude Code SDK reads `modifiedInput` from the hook's JSON output and
|
|
67
|
+
substitutes it for the original tool input when `continue: true`.
|
|
68
|
+
|
|
69
|
+
### 4.1 Injection Position
|
|
70
|
+
|
|
71
|
+
`model` is injected at the **top level** of the tool input object (alongside
|
|
72
|
+
`description`, `prompt`, `subagent_type`):
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"description": "Explore the codebase",
|
|
77
|
+
"prompt": "Find all TypeScript files",
|
|
78
|
+
"subagent_type": "ultrapower:explore",
|
|
79
|
+
"model": "haiku"
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 4.2 Injection Rules
|
|
84
|
+
|
|
85
|
+
| Condition | Behavior |
|
|
86
|
+
|-----------|----------|
|
|
87
|
+
| `model` already present | Preserve original; no injection |
|
|
88
|
+
| `model` absent, agent type known | Inject from agent definition |
|
|
89
|
+
| `model` absent, agent type unknown | Pass through unchanged (no throw) |
|
|
90
|
+
| Tool is not Task/Agent | Pass through unchanged |
|
|
91
|
+
|
|
92
|
+
### 4.3 Model Tier Mapping
|
|
93
|
+
|
|
94
|
+
Default models come from `getAgentDefinitions()`. Key mappings:
|
|
95
|
+
|
|
96
|
+
| Agent | Default Model |
|
|
97
|
+
|-------|--------------|
|
|
98
|
+
| explore, explore-low | haiku |
|
|
99
|
+
| executor, executor-medium | sonnet |
|
|
100
|
+
| executor-high, deep-executor | opus |
|
|
101
|
+
| architect, critic | opus |
|
|
102
|
+
| designer, writer | sonnet / haiku |
|
|
103
|
+
|
|
104
|
+
The `-low`/`-medium`/`-high` suffix variants follow the tiered agent convention.
|
|
105
|
+
|
|
106
|
+
### 4.4 HookOutput format
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
{
|
|
110
|
+
continue: true,
|
|
111
|
+
modifiedInput: { ...originalInput, model: 'haiku' }, // when injected
|
|
112
|
+
message?: string, // optional dashboard / enforcement message
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
When no injection occurs (model already set or non-agent tool):
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
{
|
|
120
|
+
continue: true,
|
|
121
|
+
modifiedInput: originalInput, // unchanged reference
|
|
122
|
+
message?: string,
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 5. Error Handling
|
|
129
|
+
|
|
130
|
+
- Unknown agent types: log debug warning, return `modifiedInput: originalInput`
|
|
131
|
+
(no throw — robustness over strictness in hot path)
|
|
132
|
+
- `getAgentDefinitions()` failure: catch, log error, pass through unchanged
|
|
133
|
+
- Preserves `run_in_background`, `resume`, and all other input fields
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 6. Debug Logging
|
|
138
|
+
|
|
139
|
+
When `OMC_DEBUG=true`, `console.warn` outputs:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
[OMC] Auto-injecting model: haiku for explore
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
No output when `OMC_DEBUG` is unset or `false`.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## 7. Integration Point in bridge.ts
|
|
150
|
+
|
|
151
|
+
Inside `processPreToolUse()`, after all blocking checks and before the final
|
|
152
|
+
return, the delegation-enforcer is called:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
// Enforce model parameter for Task/Agent calls
|
|
156
|
+
const delegationResult = enforceDelegationModel(
|
|
157
|
+
input.toolName || '',
|
|
158
|
+
input.toolInput,
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
continue: true,
|
|
163
|
+
modifiedInput: delegationResult.modifiedInput,
|
|
164
|
+
...(finalMessage ? { message: finalMessage } : {}),
|
|
165
|
+
};
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
The `modifiedInput` is always returned (even when unchanged) so the SDK can
|
|
169
|
+
route cleanly.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 8. Test Coverage (T-2.5c)
|
|
174
|
+
|
|
175
|
+
`src/__tests__/delegation-enforcer-integration.test.ts` covers:
|
|
176
|
+
|
|
177
|
+
1. Task call without model → model injected (executor → sonnet)
|
|
178
|
+
2. Task call with explicit model → model preserved
|
|
179
|
+
3. Agent tool name → model injected
|
|
180
|
+
4. Non-agent tool (Bash) → unchanged, no `model` field
|
|
181
|
+
5. All agent tiers (-low, -medium, -high, -high variants)
|
|
182
|
+
6. OMC_DEBUG=false → no console.warn
|
|
183
|
+
7. OMC_DEBUG=true → console.warn with model name
|
package/package.json
CHANGED
|
@@ -64,15 +64,17 @@ skills/ax-*/SKILL.md
|
|
|
64
64
|
|
|
65
65
|
### Step 3: 生成导出包
|
|
66
66
|
|
|
67
|
+
**macOS / Linux (bash):**
|
|
68
|
+
|
|
67
69
|
```bash
|
|
68
|
-
#
|
|
69
|
-
mkdir -p
|
|
70
|
+
# 创建临时目录(使用 $TMPDIR 兼容 macOS;Linux 回退到 /tmp)
|
|
71
|
+
mkdir -p ${TMPDIR:-/tmp}/axiom-export-[timestamp]
|
|
70
72
|
|
|
71
73
|
# 复制文件
|
|
72
|
-
cp -r [文件列表]
|
|
74
|
+
cp -r [文件列表] ${TMPDIR:-/tmp}/axiom-export-[timestamp]/
|
|
73
75
|
|
|
74
76
|
# 生成 README
|
|
75
|
-
cat >
|
|
77
|
+
cat > ${TMPDIR:-/tmp}/axiom-export-[timestamp]/README.md << 'EOF'
|
|
76
78
|
# Axiom Export
|
|
77
79
|
- 导出时间: [timestamp]
|
|
78
80
|
- 导出模式: [template/full]
|
|
@@ -85,7 +87,38 @@ cat > /tmp/axiom-export-[timestamp]/README.md << 'EOF'
|
|
|
85
87
|
EOF
|
|
86
88
|
|
|
87
89
|
# 打包
|
|
88
|
-
cd
|
|
90
|
+
cd ${TMPDIR:-/tmp} && zip -r axiom-export-[timestamp].zip axiom-export-[timestamp]/
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Windows (PowerShell):**
|
|
94
|
+
|
|
95
|
+
```powershell
|
|
96
|
+
# 获取系统临时目录($env:TEMP 或 GetTempPath())
|
|
97
|
+
$tmpDir = [System.IO.Path]::GetTempPath()
|
|
98
|
+
$exportDir = Join-Path $tmpDir "axiom-export-[timestamp]"
|
|
99
|
+
|
|
100
|
+
# 创建临时目录
|
|
101
|
+
New-Item -ItemType Directory -Path $exportDir -Force
|
|
102
|
+
|
|
103
|
+
# 复制文件
|
|
104
|
+
Copy-Item -Recurse [文件列表] $exportDir
|
|
105
|
+
|
|
106
|
+
# 生成 README
|
|
107
|
+
@"
|
|
108
|
+
# Axiom Export
|
|
109
|
+
- 导出时间: [timestamp]
|
|
110
|
+
- 导出模式: [template/full]
|
|
111
|
+
- 源项目: [project-name]
|
|
112
|
+
|
|
113
|
+
## 安装说明
|
|
114
|
+
1. 解压到目标项目根目录
|
|
115
|
+
2. 运行 /ultrapower:deepinit 初始化
|
|
116
|
+
3. 运行 /ax-status 验证安装
|
|
117
|
+
"@ | Set-Content -Path (Join-Path $exportDir "README.md") -Encoding UTF8
|
|
118
|
+
|
|
119
|
+
# 打包(使用 Compress-Archive 替代 zip)
|
|
120
|
+
$zipPath = Join-Path $tmpDir "axiom-export-[timestamp].zip"
|
|
121
|
+
Compress-Archive -Path $exportDir -DestinationPath $zipPath -Force
|
|
89
122
|
```
|
|
90
123
|
|
|
91
124
|
### Step 4: 输出结果
|
|
@@ -93,7 +126,7 @@ cd /tmp && zip -r axiom-export-[timestamp].zip axiom-export-[timestamp]/
|
|
|
93
126
|
```
|
|
94
127
|
✓ 导出完成
|
|
95
128
|
|
|
96
|
-
文件:
|
|
129
|
+
文件: ${TMPDIR:-/tmp}/axiom-export-[timestamp].zip(Windows: %TEMP%\axiom-export-[timestamp].zip)
|
|
97
130
|
大小: [X] KB
|
|
98
131
|
包含:
|
|
99
132
|
- 工作流: X 个
|