@open-agent-toolkit/cli 0.1.39 → 0.1.40
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/assets/docs/cli-utilities/configuration.md +2 -0
- package/assets/docs/workflows/projects/dispatch-ceiling.md +14 -3
- package/assets/docs/workflows/projects/implementation-execution.md +16 -2
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-project-implement/SKILL.md +41 -10
- package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
- package/dist/commands/project/dispatch-ceiling/index.js +80 -4
- package/package.json +2 -2
|
@@ -232,6 +232,8 @@ reading config keys directly:
|
|
|
232
232
|
|
|
233
233
|
```bash
|
|
234
234
|
oat project dispatch-ceiling resolve --provider codex --json
|
|
235
|
+
oat project dispatch-ceiling resolve --provider codex --role implementer --preferred medium --json
|
|
236
|
+
oat project dispatch-ceiling resolve --provider claude --role implementer --preferred sonnet --orchestrator-tier sonnet --json
|
|
235
237
|
oat project dispatch-ceiling resolve --provider claude --orchestrator-tier sonnet --json
|
|
236
238
|
```
|
|
237
239
|
|
|
@@ -61,11 +61,20 @@ Before dispatching a subagent, the orchestrator calls:
|
|
|
61
61
|
oat project dispatch-ceiling resolve --provider <provider> --role <implementer|reviewer> --preflight --json
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
For implementer or fix dispatch, pass the runtime classification too. In Codex
|
|
65
|
+
this is the preferred effort; in Claude it is the preferred model tier:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
oat project dispatch-ceiling resolve --provider codex --role implementer --preferred medium --json
|
|
69
|
+
oat project dispatch-ceiling resolve --provider claude --role implementer --preferred sonnet --json
|
|
70
|
+
```
|
|
71
|
+
|
|
64
72
|
The resolver:
|
|
65
73
|
|
|
66
74
|
1. reads the concrete `providers.<provider>` value (config precedence, then project state) — **never the preset label**;
|
|
67
75
|
2. looks up that provider's **adapter** in the provider ceiling registry;
|
|
68
|
-
3.
|
|
76
|
+
3. applies `--preferred` for implementer/fix dispatch, capping it against the ceiling;
|
|
77
|
+
4. returns a per-provider result: `{ value, mode, mechanism, dispatchArgs, selection }`.
|
|
69
78
|
|
|
70
79
|
`mode` is the honest enforcement status, computed right there and never persisted:
|
|
71
80
|
|
|
@@ -89,8 +98,8 @@ The same ceiling intent produces different — but honest — behavior per provi
|
|
|
89
98
|
|
|
90
99
|
### Why the mechanisms differ
|
|
91
100
|
|
|
92
|
-
- **Codex** dispatches through **pinned, sync-time role variants**. Per-call reasoning-effort proved unreliable in practice, so OAT generates committed `oat-phase-implementer-{low..xhigh}` / `oat-reviewer-{low..xhigh}` role files
|
|
93
|
-
- **Claude** uses the **per-call Task `model` parameter**, which is reliable and bidirectional (a Sonnet orchestrator can dispatch an Opus subagent and vice-versa) and overrides agent frontmatter
|
|
101
|
+
- **Codex** dispatches through **pinned, sync-time role variants**. Per-call reasoning-effort proved unreliable in practice, so OAT generates committed `oat-phase-implementer-{low..xhigh}` / `oat-reviewer-{low..xhigh}` role files. Implementer/fix dispatch passes `--preferred` so `dispatchArgs.variant` matches the selected capped effort; reviewer dispatch uses the variant matching the resolved ceiling.
|
|
102
|
+
- **Claude** uses the **per-call Task `model` parameter**, which is reliable and bidirectional (a Sonnet orchestrator can dispatch an Opus subagent and vice-versa) and overrides agent frontmatter. Implementer/fix dispatch passes `--preferred` as the preferred model tier and receives the capped selected `model`; reviewer dispatch uses the ceiling model. OAT needs no variant files.
|
|
94
103
|
- **Unsupported providers** (any without a registered adapter) resolve to `unsupported` with `dispatchArgs: null`. The resolve command **returns cleanly and never blocks** — the ceiling is recorded as intent and applied if/when an adapter ships, while the provider runs at its own capabilities.
|
|
95
104
|
|
|
96
105
|
A **provider adapter registry** is what lets these genuinely different mechanisms sit behind one resolver, so the lifecycle skills consume `dispatchArgs` without ever branching on provider.
|
|
@@ -104,6 +113,8 @@ The ceiling means slightly different things for the two dispatch roles:
|
|
|
104
113
|
|
|
105
114
|
Both providers honor this distinction (Codex selects the matching variant; Claude passes the matching model).
|
|
106
115
|
|
|
116
|
+
Generic sidecars such as built-in `explorer` are outside this implementer/reviewer/fix contract. They may run at provider default when they are read-only advisory helpers. In that case, dispatch logs should say `Preferred effort: provider-default`, `Selected effort: provider-default`, and `Effort axis: provider-default`; only log a concrete selected effort when the actual sidecar payload pins a reliable provider control.
|
|
117
|
+
|
|
107
118
|
## Verify-on-upgrade
|
|
108
119
|
|
|
109
120
|
Only a request for a tier **above** the orchestrator's current tier risks a silent plan/entitlement fallback. So the adapter verifies the actually-dispatched model **only** on that upgrade path; capping down or staying lateral needs no check. OAT never logs `enforced` unless the requested control was actually honored.
|
|
@@ -108,9 +108,9 @@ Model and effort are separate axes. Each axis logs one of these states:
|
|
|
108
108
|
- `not-applicable` — this host/API has no meaningful per-dispatch concept for that axis.
|
|
109
109
|
- `host-auto` — exceptional; the host uses that axis internally but the orchestrator cannot read or pin it.
|
|
110
110
|
|
|
111
|
-
In Codex, implementation and fix dispatch classify a preferred effort (`low`, `medium`, `high`, or `xhigh`) and
|
|
111
|
+
In Codex, implementation and fix dispatch classify a preferred effort (`low`, `medium`, `high`, or `xhigh`) and pass it to `oat project dispatch-ceiling resolve --provider codex --role implementer --preferred <effort>`. The resolver selects `min(preferred, resolved_ceiling)` and returns the matching pinned role: `oat-phase-implementer-low`, `oat-phase-implementer-medium`, `oat-phase-implementer-high`, or `oat-phase-implementer-xhigh`. Reviewer dispatch uses the reviewer variant matching the resolved ceiling (`oat-reviewer-low|medium|high|xhigh`) for deterministic quality gates. Base/unpinned Codex roles are provider-default fallbacks; they should be logged as `provider-default`, not as inherited parent-session ceiling.
|
|
112
112
|
|
|
113
|
-
In Claude Code,
|
|
113
|
+
In Claude Code, implementation and fix dispatch classify a preferred model tier (`haiku`, `sonnet`, or `opus`) and pass it to `oat project dispatch-ceiling resolve --provider claude --role implementer --preferred <model> --orchestrator-tier <current-orchestrator-tier>`. The resolver selects `min(preferred, resolved_ceiling)` and returns the `model` argument to pass at dispatch. Reviewer dispatch targets the resolved Claude ceiling directly. The separate effort axis is `not-applicable`.
|
|
114
114
|
|
|
115
115
|
Dispatch logs use a consistent structured block so provider behavior is comparable without flattening the model and effort axes:
|
|
116
116
|
|
|
@@ -151,10 +151,24 @@ Model axis: host-auto
|
|
|
151
151
|
Effort axis: host-auto
|
|
152
152
|
Dispatch target: host default
|
|
153
153
|
Rationale: host does not expose readable or pinnable dispatch controls; rationale maps to standard effort.
|
|
154
|
+
|
|
155
|
+
OAT Dispatch: p02-t10 sidecar exploration
|
|
156
|
+
Host: Codex
|
|
157
|
+
Preferred effort: provider-default
|
|
158
|
+
Dispatch ceiling: xhigh
|
|
159
|
+
Selected effort: provider-default
|
|
160
|
+
Ceiling source: project state
|
|
161
|
+
Provider default effort: xhigh
|
|
162
|
+
Model axis: inherited
|
|
163
|
+
Effort axis: provider-default
|
|
164
|
+
Dispatch target: explorer
|
|
165
|
+
Rationale: read-only sidecar exploration; generic explorer payload does not pin an OAT-managed effort variant.
|
|
154
166
|
```
|
|
155
167
|
|
|
156
168
|
Phase and review scope packets include dispatch context when the orchestrator has resolved it: `model_axis`, `effort_axis`, `dispatch_ceiling`, `ceiling_source`, `provider_default_effort`, and `dispatch_rationale`.
|
|
157
169
|
|
|
170
|
+
Generic sidecars such as built-in `explorer` are not OAT-managed implementer, reviewer, or fix roles. If a sidecar payload does not pin a reliable effort/model control, log it as provider-default rather than classifying the task complexity as a selected effort. Sidecar results are advisory context; implementation and review/fix gates still follow the OAT-managed dispatch rules above.
|
|
171
|
+
|
|
158
172
|
### Dispatch Profile overrides
|
|
159
173
|
|
|
160
174
|
`plan.md` should omit `## Dispatch Profile` by default. Missing dispatch rows are normal, because runtime selection has fresher phase context and host capability information at execution time.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-project-implement
|
|
3
|
-
version: 2.0.
|
|
3
|
+
version: 2.0.24
|
|
4
4
|
description: Use when plan.md is ready for execution. Dispatches phase-level subagents with bounded fix loops; supports plan-declared parallel phase groups with worktree-isolated execution and ordered fan-in.
|
|
5
5
|
oat_gateable: true
|
|
6
6
|
argument-hint: '[--retry-limit <N>] [--dry-run]'
|
|
@@ -204,7 +204,13 @@ Resolution order:
|
|
|
204
204
|
"mode": "enforced",
|
|
205
205
|
"mechanism": "pinned-variant",
|
|
206
206
|
"dispatchArgs": { "variant": "oat-phase-implementer-high" },
|
|
207
|
-
"verifyOnDispatch": false
|
|
207
|
+
"verifyOnDispatch": false,
|
|
208
|
+
"selection": {
|
|
209
|
+
"role": "implementer",
|
|
210
|
+
"preferredValue": null,
|
|
211
|
+
"selectedValue": "high",
|
|
212
|
+
"capped": false
|
|
213
|
+
}
|
|
208
214
|
}
|
|
209
215
|
}
|
|
210
216
|
}
|
|
@@ -212,8 +218,10 @@ Resolution order:
|
|
|
212
218
|
|
|
213
219
|
Read `providers.<active-provider>` for the concrete dispatch controls. The
|
|
214
220
|
`dispatchArgs` field carries the provider-specific argument to pass through
|
|
215
|
-
(Codex: `variant` name; Claude: `model` string).
|
|
216
|
-
|
|
221
|
+
(Codex: `variant` name; Claude: `model` string). For implementer/fix dispatch,
|
|
222
|
+
pass `--preferred <preferred-effort>` and use `selection.selectedValue` as the
|
|
223
|
+
selected axis value. Never re-derive these from the preset label or a ceiling-only
|
|
224
|
+
variant — the resolver is the single compilation/join point.
|
|
217
225
|
|
|
218
226
|
Print before phase work:
|
|
219
227
|
|
|
@@ -311,7 +319,7 @@ Codex rules:
|
|
|
311
319
|
- `high`: broad architecture, security/auth/redaction boundaries, subtle state behavior, or repeated substantive review failures
|
|
312
320
|
- `xhigh`: highest-risk work that requires the configured ceiling to allow xhigh
|
|
313
321
|
3. Selected effort is `min(preferred, resolved_ceiling)` for implementer/fix work.
|
|
314
|
-
4. For implementer/fix dispatch: call `oat project dispatch-ceiling resolve --provider codex --role implementer
|
|
322
|
+
4. For implementer/fix dispatch: call `oat project dispatch-ceiling resolve --provider codex --role implementer --preferred <preferred-effort>`; read `providers.codex.selection.selectedValue` and `providers.codex.dispatchArgs.variant` for the selected role name (e.g., `oat-phase-implementer-medium`). The resolver caps the preferred effort against the ceiling; never pass a ceiling-only implementer variant when `selection.selectedValue` is lower.
|
|
315
323
|
5. For review dispatch: call `oat project dispatch-ceiling resolve --provider codex --role reviewer`; read `providers.codex.dispatchArgs.variant` for the reviewer role name (e.g., `oat-reviewer-high`). Reviewer always targets the ceiling for deterministic quality gate behavior.
|
|
316
324
|
6. Use base/unpinned Codex roles only as a fallback or explicit provider-default choice. Log `Selected effort: provider-default`, display provider default effort when known, and do not describe this as parent-ceiling inheritance.
|
|
317
325
|
7. Do not use top-level per-call `reasoning_effort` as the standard OAT selected-effort path; dogfooding showed that path can be inconsistent.
|
|
@@ -319,9 +327,9 @@ Codex rules:
|
|
|
319
327
|
Claude rules:
|
|
320
328
|
|
|
321
329
|
- Claude ceiling is model-based: `haiku < sonnet < opus`.
|
|
322
|
-
- Implementer dispatch:
|
|
330
|
+
- Implementer/fix dispatch: classify the preferred model (`haiku`, `sonnet`, or `opus`) and pass it to the resolver as `--preferred <preferred-model>`. The resolver selects the lowest sufficient model capped by the resolved Claude ceiling (`min(preferred, ceiling)`).
|
|
323
331
|
- Review dispatch: target the resolved Claude ceiling directly.
|
|
324
|
-
-
|
|
332
|
+
- For implementer/fix dispatch, call `oat project dispatch-ceiling resolve --provider claude --role implementer --preferred <preferred-model> --orchestrator-tier <current-orchestrator-tier>`; for review dispatch, call the same resolver with `--role reviewer` and no `--preferred`. Read `providers.claude.selection.selectedValue` and `providers.claude.dispatchArgs.model` for the selected model string to pass. Pass `--orchestrator-tier` so the resolver can flag above-orchestrator upgrade requests and set `verifyOnDispatch` correctly.
|
|
325
333
|
- Pass `model: "<value>"` when `model_axis=selected:<value>` on the Task tool call.
|
|
326
334
|
- Keep `effort_axis=not-applicable`; Claude Code has no separate per-dispatch effort axis.
|
|
327
335
|
|
|
@@ -336,7 +344,7 @@ Structured dispatch log:
|
|
|
336
344
|
```text
|
|
337
345
|
OAT Dispatch: Phase {phase_id} {implementation | fix | review}
|
|
338
346
|
Host: {Claude Code | Codex | Cursor | other host}
|
|
339
|
-
Preferred effort: {low | medium | high | xhigh | not-applicable}
|
|
347
|
+
Preferred effort: {low | medium | high | xhigh | provider-default | not-applicable}
|
|
340
348
|
Dispatch ceiling: {resolved ceiling value}
|
|
341
349
|
Selected effort: {low | medium | high | xhigh | provider-default | not-applicable}
|
|
342
350
|
Ceiling source: {repo config | project state | preflight prompt}
|
|
@@ -395,6 +403,29 @@ Dispatch target: oat-reviewer
|
|
|
395
403
|
Rationale: base unpinned role fallback; effective effort follows Codex provider default.
|
|
396
404
|
```
|
|
397
405
|
|
|
406
|
+
Generic sidecar/explorer dispatch:
|
|
407
|
+
|
|
408
|
+
- Built-in or generic sidecars such as `explorer` are not OAT-managed implementer, reviewer, or fix roles.
|
|
409
|
+
- If a sidecar spawn payload does not explicitly pin a reliable effort/model control, log `Preferred effort: provider-default`, `Selected effort: provider-default`, and `Effort axis: provider-default`.
|
|
410
|
+
- Do not classify a generic sidecar as `Preferred effort: low|medium|high|xhigh` unless the actual host invocation contains the corresponding reliable selection. If the host has no reliable effort control for that sidecar, use provider-default wording instead.
|
|
411
|
+
- Sidecar outputs are advisory context only. Implementation work and review/fix gates still follow the OAT-managed dispatch rules above.
|
|
412
|
+
|
|
413
|
+
Codex generic explorer example:
|
|
414
|
+
|
|
415
|
+
```text
|
|
416
|
+
OAT Dispatch: p02-t10 sidecar exploration
|
|
417
|
+
Host: Codex
|
|
418
|
+
Preferred effort: provider-default
|
|
419
|
+
Dispatch ceiling: xhigh
|
|
420
|
+
Selected effort: provider-default
|
|
421
|
+
Ceiling source: project state
|
|
422
|
+
Provider default effort: xhigh
|
|
423
|
+
Model axis: inherited
|
|
424
|
+
Effort axis: provider-default
|
|
425
|
+
Dispatch target: explorer
|
|
426
|
+
Rationale: read-only sidecar exploration; generic explorer payload does not pin an OAT-managed effort variant.
|
|
427
|
+
```
|
|
428
|
+
|
|
398
429
|
Include resolved dispatch context in scope packets when known:
|
|
399
430
|
|
|
400
431
|
```yaml
|
|
@@ -740,8 +771,8 @@ For each phase `pNN` in the plan (or each phase in the current parallel group),
|
|
|
740
771
|
|
|
741
772
|
2. Perform a pre-dispatch assertion against the host invocation parameters. The Phase Scope fields are audit/context fields; selected axes must also be represented in the actual host dispatch call.
|
|
742
773
|
- Codex implementer/fix dispatch:
|
|
743
|
-
- Before building the `spawn_agent` argument map, classify the phase complexity and choose preferred effort (`low`, `medium`, `high`, or `xhigh`), then
|
|
744
|
-
- Build the `spawn_agent` argument map before logging the dispatch. If `effort_axis=selected:low|medium|high|xhigh`, the argument map MUST use the matching `agent_type`: `"oat-phase-implementer-low"`, `"oat-phase-implementer-medium"`, `"oat-phase-implementer-high"`, or `"oat-phase-implementer-xhigh"`. Then derive the `OAT Dispatch:` block `Effort axis:` field from that same argument map.
|
|
774
|
+
- Before building the `spawn_agent` argument map, classify the phase complexity and choose preferred effort (`low`, `medium`, `high`, or `xhigh`), then call `oat project dispatch-ceiling resolve --provider codex --role implementer --preferred <preferred-effort>`.
|
|
775
|
+
- Build the `spawn_agent` argument map from `providers.codex.selection.selectedValue` and `providers.codex.dispatchArgs.variant` before logging the dispatch. If `effort_axis=selected:low|medium|high|xhigh`, the argument map MUST use the matching `agent_type`: `"oat-phase-implementer-low"`, `"oat-phase-implementer-medium"`, `"oat-phase-implementer-high"`, or `"oat-phase-implementer-xhigh"`. Then derive the `OAT Dispatch:` block `Effort axis:` field from that same argument map.
|
|
745
776
|
- Example selected low payload shape: `agent_type: "oat-phase-implementer-low"` and a Phase Scope message containing `effort_axis: selected:low`.
|
|
746
777
|
- Immediately after spawning, compare the returned Codex status line with the selected effort before waiting on the agent. If the spawned status reports a different effort than the selected value (for example, the log says `effort_axis=selected:medium` but the spawn result reports `gpt-5.5 high`), treat this as an orchestration deviation. Stop, record the deviation in `implementation.md`, and redispatch with corrected parameters before continuing. Do not use work from the mismatched dispatch.
|
|
747
778
|
- If `effort_axis=provider-default`, use base `agent_type: "oat-phase-implementer"` and omit `reasoning_effort`. The dispatch rationale MUST say this is a base/unpinned fallback and include provider default effort when known.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch-ceiling/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAEL,KAAK,uBAAuB,EAG7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AASzB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch-ceiling/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAEL,KAAK,uBAAuB,EAG7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AASzB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6BpC,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;AAknBD,wBAAgB,mCAAmC,CACjD,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,OAAO,CAqDT"}
|
|
@@ -173,12 +173,67 @@ function readResolvedConfigCeiling(provider, resolvedConfig) {
|
|
|
173
173
|
function normalizeRole(value) {
|
|
174
174
|
return value === 'reviewer' ? 'reviewer' : 'implementer';
|
|
175
175
|
}
|
|
176
|
+
function providerValueOrder(provider) {
|
|
177
|
+
if (provider === 'codex') {
|
|
178
|
+
return CODEX_VALUES;
|
|
179
|
+
}
|
|
180
|
+
if (provider === 'claude') {
|
|
181
|
+
return CLAUDE_VALUES;
|
|
182
|
+
}
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
function normalizePreferredValue(provider, value) {
|
|
186
|
+
if (!value) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
const normalized = value.trim();
|
|
190
|
+
if (!normalized) {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
const order = providerValueOrder(provider);
|
|
194
|
+
if (!order) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
if (!isValidProviderValue(provider, normalized)) {
|
|
198
|
+
const validValues = order.join(', ');
|
|
199
|
+
throw new Error(`Invalid preferred dispatch value "${normalized}" for ${provider}. Valid values: ${validValues}.`);
|
|
200
|
+
}
|
|
201
|
+
return normalized;
|
|
202
|
+
}
|
|
203
|
+
function selectDispatchValue(provider, role, ceilingValue, preferredValue) {
|
|
204
|
+
if (role === 'reviewer' || preferredValue === null) {
|
|
205
|
+
return {
|
|
206
|
+
role,
|
|
207
|
+
preferredValue,
|
|
208
|
+
selectedValue: ceilingValue,
|
|
209
|
+
capped: false,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
const order = providerValueOrder(provider);
|
|
213
|
+
const preferredIndex = order?.indexOf(preferredValue) ?? -1;
|
|
214
|
+
const ceilingIndex = order?.indexOf(ceilingValue) ?? -1;
|
|
215
|
+
if (!order || preferredIndex < 0 || ceilingIndex < 0) {
|
|
216
|
+
return {
|
|
217
|
+
role,
|
|
218
|
+
preferredValue,
|
|
219
|
+
selectedValue: ceilingValue,
|
|
220
|
+
capped: false,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
const selectedIndex = Math.min(preferredIndex, ceilingIndex);
|
|
224
|
+
return {
|
|
225
|
+
role,
|
|
226
|
+
preferredValue,
|
|
227
|
+
selectedValue: order[selectedIndex],
|
|
228
|
+
capped: preferredIndex > ceilingIndex,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
176
231
|
/**
|
|
177
232
|
* Join a resolved ceiling value with the active provider's adapter to compute
|
|
178
233
|
* the enforcement mode, mechanism, dispatch args, and verify-on-upgrade flag.
|
|
179
234
|
* Mode is computed here at call time — it is never read from persisted state.
|
|
180
235
|
*/
|
|
181
|
-
function buildProviderResolution(provider, value, role, orchestratorTier) {
|
|
236
|
+
function buildProviderResolution(provider, value, role, orchestratorTier, preferredValue) {
|
|
182
237
|
const adapter = getCeilingAdapter(provider);
|
|
183
238
|
if (value === null) {
|
|
184
239
|
return {
|
|
@@ -187,9 +242,17 @@ function buildProviderResolution(provider, value, role, orchestratorTier) {
|
|
|
187
242
|
mechanism: adapter.mechanism,
|
|
188
243
|
dispatchArgs: null,
|
|
189
244
|
verifyOnDispatch: false,
|
|
245
|
+
selection: {
|
|
246
|
+
role,
|
|
247
|
+
preferredValue,
|
|
248
|
+
selectedValue: null,
|
|
249
|
+
capped: false,
|
|
250
|
+
},
|
|
190
251
|
};
|
|
191
252
|
}
|
|
192
|
-
const
|
|
253
|
+
const selection = selectDispatchValue(provider, role, value, preferredValue);
|
|
254
|
+
const dispatchValue = selection.selectedValue ?? value;
|
|
255
|
+
const dispatchArgs = adapter.compileToDispatchArgs(dispatchValue, role, {
|
|
193
256
|
orchestratorTier,
|
|
194
257
|
});
|
|
195
258
|
let mode;
|
|
@@ -207,7 +270,10 @@ function buildProviderResolution(provider, value, role, orchestratorTier) {
|
|
|
207
270
|
mode,
|
|
208
271
|
mechanism: adapter.mechanism,
|
|
209
272
|
dispatchArgs,
|
|
210
|
-
verifyOnDispatch: adapter.verifyOnDispatch(
|
|
273
|
+
verifyOnDispatch: adapter.verifyOnDispatch(dispatchValue, {
|
|
274
|
+
orchestratorTier,
|
|
275
|
+
}),
|
|
276
|
+
selection,
|
|
211
277
|
};
|
|
212
278
|
}
|
|
213
279
|
function readCodexDefaultFromToml(content) {
|
|
@@ -257,8 +323,9 @@ async function resolveDispatchCeiling(context, dependencies, options) {
|
|
|
257
323
|
const providerDefaultEffort = provider === 'codex'
|
|
258
324
|
? await resolveCodexProviderDefaultEffort(repoRoot, context, dependencies)
|
|
259
325
|
: 'not-applicable';
|
|
326
|
+
const preferredValue = normalizePreferredValue(provider, options.preferred);
|
|
260
327
|
const resolvedValue = await resolveCeilingValue(provider, resolvedConfig, projectPath, dependencies);
|
|
261
|
-
const providerResolution = buildProviderResolution(provider, resolvedValue?.value ?? null, role, orchestratorTier);
|
|
328
|
+
const providerResolution = buildProviderResolution(provider, resolvedValue?.value ?? null, role, orchestratorTier, preferredValue);
|
|
262
329
|
const providers = {
|
|
263
330
|
[provider]: providerResolution,
|
|
264
331
|
};
|
|
@@ -332,9 +399,17 @@ function writeHumanResolution(context, resolution) {
|
|
|
332
399
|
if (resolution.provider === 'codex') {
|
|
333
400
|
context.logger.info(`Codex provider default effort: ${resolution.providerDefaultEffort}`);
|
|
334
401
|
context.logger.info(`Note: OAT will use pinned subagent variants up to ${resolution.value ?? 'the resolved ceiling'}. Base/unpinned roles resolve through the provider default.`);
|
|
402
|
+
if (providerResolution?.selection.selectedValue &&
|
|
403
|
+
providerResolution.selection.preferredValue) {
|
|
404
|
+
context.logger.info(`Selected Codex effort: ${providerResolution.selection.selectedValue}`);
|
|
405
|
+
}
|
|
335
406
|
}
|
|
336
407
|
else {
|
|
337
408
|
context.logger.info('Effort axis: not-applicable');
|
|
409
|
+
if (providerResolution?.selection.selectedValue &&
|
|
410
|
+
providerResolution.selection.preferredValue) {
|
|
411
|
+
context.logger.info(`Selected dispatch value: ${providerResolution.selection.selectedValue}`);
|
|
412
|
+
}
|
|
338
413
|
}
|
|
339
414
|
}
|
|
340
415
|
async function runDispatchCeilingResolve(context, dependencies, options) {
|
|
@@ -370,6 +445,7 @@ export function createProjectDispatchCeilingCommand(overrides = {}) {
|
|
|
370
445
|
.requiredOption('--provider <provider>', 'Provider name: codex or claude are enforced; any other provider resolves as advisory (unsupported)')
|
|
371
446
|
.option('--role <role>', 'Dispatch role for variant compilation: implementer (default) or reviewer')
|
|
372
447
|
.option('--orchestrator-tier <tier>', 'Orchestrator tier, used to flag verify-on-upgrade for above-orchestrator requests')
|
|
448
|
+
.option('--preferred <value>', 'Preferred implementer/fix dispatch value before capping by the resolved ceiling')
|
|
373
449
|
.option('--project-path <path>', 'Read project-state ceiling from an explicit project path')
|
|
374
450
|
.option('--preflight', 'Treat unresolved non-interactive resolution as an implementation block')
|
|
375
451
|
.option('--non-interactive', 'Force non-interactive block behavior when the ceiling is unresolved')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-agent-toolkit/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.40",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Open Agent Toolkit CLI",
|
|
6
6
|
"homepage": "https://github.com/voxmedia/open-agent-toolkit/tree/main/packages/cli",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"ora": "^9.0.0",
|
|
35
35
|
"yaml": "2.8.2",
|
|
36
36
|
"zod": "^3.25.76",
|
|
37
|
-
"@open-agent-toolkit/control-plane": "0.1.
|
|
37
|
+
"@open-agent-toolkit/control-plane": "0.1.40"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^22.10.0",
|