@open-agent-toolkit/cli 0.3.1 → 0.3.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/assets/agents/oat-reviewer.md +7 -2
- package/assets/bundle-metadata.json +1 -1
- package/assets/config/dispatch-matrix-recommendation.json +63 -43
- package/assets/docs/cli-utilities/configuration.md +20 -8
- package/assets/docs/cli-utilities/workflow-gates.md +1 -1
- package/assets/docs/contributing/index.md +1 -0
- package/assets/docs/contributing/updating-model-guidance.md +106 -0
- package/assets/docs/contributing/verifying-cursor-pins.md +30 -18
- package/assets/docs/provider-sync/providers.md +5 -2
- package/assets/docs/reference/cli-reference.md +1 -1
- package/assets/docs/reference/oat-directory-structure.md +1 -1
- package/assets/docs/workflows/projects/artifacts.md +1 -1
- package/assets/docs/workflows/projects/dispatch-ceiling.md +67 -50
- package/assets/docs/workflows/projects/evidence-layers.md +6 -2
- package/assets/docs/workflows/projects/implementation-execution.md +9 -4
- package/assets/docs/workflows/projects/lifecycle.md +8 -6
- package/assets/docs/workflows/projects/programmatic-execution.md +4 -3
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-dispatch-subagents/SKILL.md +1 -1
- package/assets/skills/oat-dispatch-subagents/references/provider-claude.md +20 -7
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +4 -4
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-implement/SKILL.md +1 -1
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +2 -0
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +82 -25
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-implement/references/phase-execution.md +16 -8
- package/assets/skills/oat-project-import-plan/SKILL.md +7 -4
- package/assets/skills/oat-project-lite/SKILL.md +5 -3
- package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-plan/SKILL.md +7 -4
- package/assets/skills/oat-project-plan-writing/SKILL.md +28 -16
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-quick-start/SKILL.md +7 -4
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-review-provide/SKILL.md +7 -4
- package/assets/skills/subagent-orchestration/SKILL.md +1 -1
- package/assets/skills/subagent-orchestration/references/evidence-and-refresh.md +30 -29
- package/assets/skills/subagent-orchestration/references/provider-claude.md +41 -36
- package/assets/skills/subagent-orchestration/references/provider-codex.md +30 -35
- package/assets/skills/subagent-orchestration/references/provider-cursor.md +46 -38
- package/assets/templates/plan.md +5 -5
- package/dist/commands/project/dispatch/record.d.ts.map +1 -1
- package/dist/commands/project/dispatch/record.js +27 -5
- package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
- package/dist/commands/project/dispatch-ceiling/index.js +112 -35
- package/dist/config/dispatch-matrix.d.ts.map +1 -1
- package/dist/config/dispatch-matrix.js +13 -0
- package/dist/providers/ceiling/registry.d.ts +7 -2
- package/dist/providers/ceiling/registry.d.ts.map +1 -1
- package/dist/providers/ceiling/registry.js +35 -11
- package/dist/providers/claude/codec/materialize.d.ts +33 -0
- package/dist/providers/claude/codec/materialize.d.ts.map +1 -0
- package/dist/providers/claude/codec/materialize.js +149 -0
- package/dist/providers/claude/codec/sync-extension.d.ts +24 -0
- package/dist/providers/claude/codec/sync-extension.d.ts.map +1 -0
- package/dist/providers/claude/codec/sync-extension.js +312 -0
- package/dist/providers/claude/dispatch-envelope.d.ts +34 -0
- package/dist/providers/claude/dispatch-envelope.d.ts.map +1 -0
- package/dist/providers/claude/dispatch-envelope.js +233 -0
- package/dist/providers/claude/targets.d.ts +48 -0
- package/dist/providers/claude/targets.d.ts.map +1 -0
- package/dist/providers/claude/targets.js +228 -0
- package/dist/providers/codex/codec/shared.d.ts +6 -0
- package/dist/providers/codex/codec/shared.d.ts.map +1 -1
- package/dist/providers/codex/codec/shared.js +8 -0
- package/dist/providers/cursor/codec/catalog.d.ts.map +1 -1
- package/dist/providers/cursor/codec/catalog.js +47 -45
- package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts +35 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts.map +1 -1
- package/dist/providers/identity/claude-runtime-observation.fixtures.js +225 -12
- package/dist/providers/shared/registry.d.ts.map +1 -1
- package/dist/providers/shared/registry.js +5 -2
- package/package.json +2 -2
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
guidance_version: 2026-
|
|
3
|
-
last_verified: 2026-
|
|
4
|
-
review_after: 2026-
|
|
2
|
+
guidance_version: 2026-09-23
|
|
3
|
+
last_verified: 2026-09-23
|
|
4
|
+
review_after: 2026-12-22
|
|
5
5
|
catalog_basis:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
subagentStart lifecycle hooks
|
|
6
|
+
Cursor desktop 3.20.14 resolved all five Opus 5.5 effort selectors in native
|
|
7
|
+
subagent hooks; GPT-6 Sol/Luna were absent from the observed Cursor catalog
|
|
9
8
|
---
|
|
10
9
|
|
|
11
10
|
# Cursor Model Selection
|
|
@@ -45,25 +44,40 @@ does not by itself prove lower user-observed elapsed time.
|
|
|
45
44
|
|
|
46
45
|
## Dated Task-Class Matrix
|
|
47
46
|
|
|
48
|
-
Use exact aliases from the
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
47
|
+
Use currently approved exact aliases from the Cursor catalogue. On 2026-09-23,
|
|
48
|
+
Cursor desktop 3.20.14 resolved all five `claude-opus-5-5[effort=...]`
|
|
49
|
+
selectors to corresponding flat IDs in native hooks. See the
|
|
50
|
+
probe record at `packages/cli/src/providers/cursor/codec/__fixtures__/README.md`.
|
|
51
|
+
GPT-6 Sol/Luna were absent from the observed Cursor catalogue, so their Codex
|
|
52
|
+
availability does not authorize Cursor routes.
|
|
53
|
+
|
|
54
|
+
| Task class | Default | Economy | Escalation | Floor notes |
|
|
55
|
+
| ------------------------ | ------------------------------------------------------------------- | -------------------------------------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
56
|
+
| `mechanical-recon` | `composer-2.5` | Same with mechanical verification | `gpt-5.6-luna-high` | Fast aliases select service tier, not capability. |
|
|
57
|
+
| `intelligent-recon` | `cursor-grok-4.5-medium` or `gpt-5.6-sol-medium` | `gpt-5.6-terra-high` | `gpt-5.6-sol-high` | Verify silent-miss-prone conclusions. |
|
|
58
|
+
| `default-implementation` | `gpt-5.6-sol-medium` | `composer-2.5` for bounded, testable changes | `gpt-5.6-sol-high` | `cursor-grok-4.5-medium` remains an available judgment-heavy alternative. |
|
|
59
|
+
| `hard-reasoning` | `gpt-5.6-sol-high` | `cursor-grok-4.5-high` with corroborating evidence | `gpt-5.6-sol-xhigh` | Opus 5.5 high/xhigh are verified cross-family alternatives; qualify task performance separately. |
|
|
60
|
+
| `consequential` | An eligible high-effort author with independent cross-family review | No routine economy route | Sol xhigh for a depth bottleneck; max only after evaluation | If independent review cannot be met among approved Cursor mappings, use a separately qualified provider or stop. |
|
|
61
|
+
|
|
62
|
+
## Current Opus 5.5 Pin Evidence
|
|
63
|
+
|
|
64
|
+
Cursor desktop 3.20.14 resolved `claude-opus-5-5[effort=low|medium|high|xhigh|max]`
|
|
65
|
+
to `claude-opus-5-5-low|medium|high|xhigh|max`, respectively, on 2026-09-23.
|
|
66
|
+
Both the `subagentStart.subagent_model` and the subagent Shell `preToolUse.model`
|
|
67
|
+
agreed for every rung. The Sonnet 5 high positive control resolved to
|
|
68
|
+
`claude-sonnet-5-thinking-high`. An unknown family fell back to
|
|
69
|
+
`cursor-grok-4.6-high-fast`; an unknown effort on Opus 5.5 fell back to
|
|
70
|
+
`claude-opus-5-5-medium`. The provenance summary at `packages/cli/src/providers/cursor/codec/__fixtures__/README.md`
|
|
71
|
+
links the adjacent redacted summary and native-event JSONL records containing
|
|
72
|
+
the exact observations. Recheck live availability before launch.
|
|
73
|
+
|
|
74
|
+
## Historical Opus Cursor Probe Evidence (Retired)
|
|
75
|
+
|
|
76
|
+
The following observations document Cursor 3.12.30 behavior on 2026-07-25.
|
|
77
|
+
They no longer qualify those generations for current recommendations or the
|
|
78
|
+
active approved mapping catalogue. A new family needs its own live probe.
|
|
79
|
+
|
|
80
|
+
Five Opus 5 effort rungs plus an Opus 4.8 rung were
|
|
67
81
|
probe-verified on 2026-07-25 against Cursor 3.12.30, using `subagentStart`
|
|
68
82
|
lifecycle hooks to read the resolved model that Cursor itself reports:
|
|
69
83
|
|
|
@@ -80,21 +94,15 @@ Every rung resolves to the thinking variant. This is a verified fact, not an
|
|
|
80
94
|
inference: the catalog carries distinct non-thinking IDs at low, medium, and
|
|
81
95
|
high, and none were selected.
|
|
82
96
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
route; Opus is generally stronger for interpretation-heavy work. Exact
|
|
89
|
-
cross-provider substitutions remain provisional.
|
|
90
|
-
|
|
91
|
-
Opus 4.8 xhigh is catalogued so the cyber-sensitive route is dispatchable, but it
|
|
92
|
-
is deliberately excluded from the bundled recommendation. Select it explicitly
|
|
93
|
-
when the cyber-sensitive refusal profile is required.
|
|
97
|
+
That historical result did not validate an Opus 5.5 selector; the 2026-09-23
|
|
98
|
+
probe above independently qualifies its five selectors. Even where the
|
|
99
|
+
requested effort has the same spelling across generations, preserve the old
|
|
100
|
+
probe only as evidence of past behavior and use the current approved catalogue
|
|
101
|
+
for dispatch.
|
|
94
102
|
|
|
95
103
|
### Unresolvable selectors fall back to a default, silently
|
|
96
104
|
|
|
97
|
-
|
|
105
|
+
The historical probe showed that Cursor did not reject a malformed pin. It substitutes a
|
|
98
106
|
default for whichever component it cannot resolve, with no error or warning:
|
|
99
107
|
|
|
100
108
|
- An unknown family falls back to the default model. `claude-opus-9[effort=high]`
|
|
@@ -102,7 +110,7 @@ default for whichever component it cannot resolve, with no error or warning:
|
|
|
102
110
|
- An unknown effort falls back to the family's default rung.
|
|
103
111
|
`claude-opus-5[effort=ultra]` resolved to `claude-opus-5-thinking-high`.
|
|
104
112
|
|
|
105
|
-
The default rung is family-specific, not a fixed value. In
|
|
113
|
+
The default rung is family-specific, not a fixed value. In that catalog snapshot
|
|
106
114
|
exactly one rung per family carries an unqualified display label, and that marks
|
|
107
115
|
the default: `claude-opus-5-high` shows as `Opus 5 1M` while
|
|
108
116
|
`claude-opus-5-medium` shows as `Opus 5 1M Medium`. The default is not always
|
package/assets/templates/plan.md
CHANGED
|
@@ -55,13 +55,13 @@ Default is `[]` (fully sequential, no worktrees). Only declare parallelism when
|
|
|
55
55
|
|
|
56
56
|
_Optional override surface. Use only for explicit user-authored constraints or preferences. Omit this section when runtime selection should choose the lowest confident tier._
|
|
57
57
|
|
|
58
|
-
Blank or `auto` means there is no explicit constraint
|
|
58
|
+
Blank or `auto` means there is no explicit phase constraint. Do not generate rows by default; a missing phase row uses runtime selection.
|
|
59
59
|
|
|
60
|
-
| Phase |
|
|
61
|
-
| ----- |
|
|
62
|
-
| pNN |
|
|
60
|
+
| Phase | Named ceiling | Rationale |
|
|
61
|
+
| ----- | --------------------------------------- | ----------------------------- |
|
|
62
|
+
| pNN | economy\|balanced\|high\|frontier\|auto | why this constraint is needed |
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
The named ceiling is a maximum candidate tier, not an exact provider, model family, or effort preference. `oat-project-implement` chooses one exact phase-implementer target from the complete configured ladder at runtime.
|
|
65
65
|
|
|
66
66
|
---
|
|
67
67
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch/record.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch/record.ts"],"names":[],"mappings":"AAkBA,OAAO,EAKL,KAAK,qBAAqB,EAC3B,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAOL,KAAK,wBAAwB,EAE7B,KAAK,4BAA4B,EAElC,MAAM,yCAAyC,CAAC;AAWjD;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAoCD;;;;;;;;;GASG;AAEH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,KAAK,GAAE;IACL,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjB,GACL,MAAM,CAcR;AAaD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,KAAK,EAAE,wBAAwB,CAAC;IAChC,uEAAuE;IACvE,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,WAAW,6BAA6B;IAC5C,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,CAAC;IACF,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,GAAG,IAAI,CAAC;IACT,KAAK,EAAE,UAAU,GAAG,aAAa,GAAG,gBAAgB,GAAG,IAAI,CAAC;IAC5D;;;OAGG;IACH,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC;;;;OAIG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,UAAU,GAAG,cAAc,CAAC;CACrC;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,MAAM,EAAE,WAAW,GAAG,gBAAgB,CAAC;IACvC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,4BAA4B,CAAC;IACrC,eAAe,EAAE,6BAA6B,CAAC;CAChD,CAAC;AAsEF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CA0G5E;AAgKD;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,KAAK,EAAE;IACjD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,0BAA0B,CAAC;CAC3C,GAAG,OAAO,CAAC,2BAA2B,CAAC,CA6HvC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFile, readdir } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { publishContainedJsonRevision, redactedFsError, withContainedWriterLock, } from '../../../fs/io.js';
|
|
4
|
+
import { acceptClaudeLaunchEnvelope, buildClaudeDispatchRecord, } from '../../../providers/claude/dispatch-envelope.js';
|
|
4
5
|
import { assertJournalIdentityHasNoAbsolutePath, redactAbsolutePaths, } from '../../../providers/identity/absolute-paths.js';
|
|
5
6
|
import { CLAUDE_OBSERVATION_SOURCE } from '../../../providers/identity/claude-runtime-observation.js';
|
|
6
7
|
import { CODEX_OBSERVATION_SOURCE } from '../../../providers/identity/codex-runtime-observation.js';
|
|
@@ -127,12 +128,34 @@ export function parseDispatchRecordInput(value) {
|
|
|
127
128
|
throw new Error('Dispatch record input must be a JSON object.');
|
|
128
129
|
}
|
|
129
130
|
const keys = Object.keys(value).sort();
|
|
130
|
-
|
|
131
|
-
|
|
131
|
+
const isGenericInput = keys.length === 2 && keys[0] === 'event' && keys[1] === 'record';
|
|
132
|
+
const isManagedClaudeInput = keys.length === 3 &&
|
|
133
|
+
keys[0] === 'claudeLaunch' &&
|
|
134
|
+
keys[1] === 'event' &&
|
|
135
|
+
keys[2] === 'recordBase';
|
|
136
|
+
if (!isGenericInput && !isManagedClaudeInput) {
|
|
137
|
+
throw new Error('Dispatch record input accepts record and event, or claudeLaunch, event, and recordBase.');
|
|
132
138
|
}
|
|
133
139
|
if (!isRecord(value.event)) {
|
|
134
140
|
throw new Error('Dispatch record event must be a JSON object.');
|
|
135
141
|
}
|
|
142
|
+
const record = isManagedClaudeInput
|
|
143
|
+
? buildClaudeDispatchRecord({
|
|
144
|
+
envelope: acceptClaudeLaunchEnvelope({
|
|
145
|
+
resolution: isRecord(value.claudeLaunch)
|
|
146
|
+
? value.claudeLaunch.resolution
|
|
147
|
+
: undefined,
|
|
148
|
+
definition: isRecord(value.claudeLaunch)
|
|
149
|
+
? String(value.claudeLaunch.definition ?? '')
|
|
150
|
+
: '',
|
|
151
|
+
launch: isRecord(value.claudeLaunch)
|
|
152
|
+
? value.claudeLaunch.payload
|
|
153
|
+
: undefined,
|
|
154
|
+
}),
|
|
155
|
+
recordBase: value.recordBase,
|
|
156
|
+
})
|
|
157
|
+
: parseGenericDispatchRecord(value.record);
|
|
158
|
+
const boundedInput = { record, event: value.event };
|
|
136
159
|
// Raw provider metadata is the one input a caller may legitimately supply
|
|
137
160
|
// unmodified, so it is projected through the owning parser's allowlist and
|
|
138
161
|
// asserted as the projection. Everything else is asserted exactly as given.
|
|
@@ -143,15 +166,14 @@ export function parseDispatchRecordInput(value) {
|
|
|
143
166
|
? value.event.metadata
|
|
144
167
|
: null;
|
|
145
168
|
assertNoSensitiveDispatchContent(rawMetadata === null
|
|
146
|
-
?
|
|
169
|
+
? boundedInput
|
|
147
170
|
: {
|
|
148
|
-
...
|
|
171
|
+
...boundedInput,
|
|
149
172
|
event: {
|
|
150
173
|
...value.event,
|
|
151
174
|
metadata: { ...rawMetadata, entries: null },
|
|
152
175
|
},
|
|
153
176
|
});
|
|
154
|
-
const record = parseGenericDispatchRecord(value.record);
|
|
155
177
|
if (rawMetadata !== null) {
|
|
156
178
|
if ('observation' in value.event) {
|
|
157
179
|
throw new Error('A runtime observation event carries either observation or metadata, not both.');
|
|
@@ -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;AAkB9B,OAAO,EAUL,KAAK,uBAAuB,EAY7B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,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;AAkB9B,OAAO,EAUL,KAAK,uBAAuB,EAY7B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAoCzB,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAiC5C,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;AAm4FD,wBAAgB,mCAAmC,CACjD,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,OAAO,CA0GT"}
|
|
@@ -12,7 +12,9 @@ import { getOwnKey, setOwnKey } from '../../../config/own-keys.js';
|
|
|
12
12
|
import { resolveEffectiveConfig, } from '../../../config/resolve.js';
|
|
13
13
|
import { resolveProjectRoot } from '../../../fs/paths.js';
|
|
14
14
|
import TOML from '@iarna/toml';
|
|
15
|
-
import { getCeilingAdapter, isDirectDispatchRoleName,
|
|
15
|
+
import { getCeilingAdapter, isDirectDispatchRoleName, } from '../../../providers/ceiling/registry.js';
|
|
16
|
+
import { claudeTargetRank, CLAUDE_EFFORT_ORDER, validateClaudeDispatchCapability, validateClaudeDispatchTarget, } from '../../../providers/claude/targets.js';
|
|
17
|
+
import { SUPPORTED_CODEX_ROLE_TARGETS } from '../../../providers/codex/codec/shared.js';
|
|
16
18
|
import { buildDispatchReport, formatDispatchReport, } from '../../../providers/identity/dispatch-report.js';
|
|
17
19
|
import { classifyModelFamily, } from '../../../providers/identity/family.js';
|
|
18
20
|
import { formatDispatchStamp, } from '../../../providers/identity/stamp.js';
|
|
@@ -21,6 +23,11 @@ import YAML from 'yaml';
|
|
|
21
23
|
const CODEX_VALUES = [
|
|
22
24
|
...VALID_CODEX_DISPATCH_CEILINGS,
|
|
23
25
|
];
|
|
26
|
+
// Catalogue order is low to high within each model; the scalar ceiling
|
|
27
|
+
// remains separately capped by CODEX_VALUES.
|
|
28
|
+
const CODEX_CANDIDATE_EFFORTS = [
|
|
29
|
+
...new Set(SUPPORTED_CODEX_ROLE_TARGETS.map((target) => target.effort)),
|
|
30
|
+
];
|
|
24
31
|
const CLAUDE_VALUES = [
|
|
25
32
|
...VALID_CLAUDE_DISPATCH_CEILINGS,
|
|
26
33
|
];
|
|
@@ -124,6 +131,9 @@ function validManagedPolicyList() {
|
|
|
124
131
|
return managedDispatchPolicyValueList(', ');
|
|
125
132
|
}
|
|
126
133
|
function validProviderValueList(provider) {
|
|
134
|
+
if (provider === 'codex') {
|
|
135
|
+
return CODEX_VALUES.join(', ');
|
|
136
|
+
}
|
|
127
137
|
return providerValueOrder(provider)?.join(', ') ?? 'none';
|
|
128
138
|
}
|
|
129
139
|
function compiledPolicyValueForProvider(provider, compiled) {
|
|
@@ -259,6 +269,39 @@ function routeTargetFromObject(provider, target, routeIndex, routeLength) {
|
|
|
259
269
|
routeLength,
|
|
260
270
|
};
|
|
261
271
|
}
|
|
272
|
+
function resolveClaudeTargetCapability(target, env) {
|
|
273
|
+
if (!target ||
|
|
274
|
+
target.harness !== 'claude' ||
|
|
275
|
+
!target.model ||
|
|
276
|
+
!target.effort) {
|
|
277
|
+
return target;
|
|
278
|
+
}
|
|
279
|
+
const validation = validateClaudeDispatchCapability({
|
|
280
|
+
model: target.model,
|
|
281
|
+
effort: target.effort,
|
|
282
|
+
...(target.capabilityEvidence
|
|
283
|
+
? { capabilityEvidence: target.capabilityEvidence }
|
|
284
|
+
: {}),
|
|
285
|
+
}, env);
|
|
286
|
+
if (!validation.valid || !validation.capabilityEvidence) {
|
|
287
|
+
throw new Error(validation.reason ??
|
|
288
|
+
'Claude effort target has no established model capability.');
|
|
289
|
+
}
|
|
290
|
+
return { ...target, capabilityEvidence: validation.capabilityEvidence };
|
|
291
|
+
}
|
|
292
|
+
function resolveClaudePolicyCapabilities(policy, env) {
|
|
293
|
+
if (!policy)
|
|
294
|
+
return policy;
|
|
295
|
+
return {
|
|
296
|
+
...policy,
|
|
297
|
+
target: resolveClaudeTargetCapability(policy.target, env) ?? null,
|
|
298
|
+
...(policy.ceilingTarget !== undefined
|
|
299
|
+
? {
|
|
300
|
+
ceilingTarget: resolveClaudeTargetCapability(policy.ceilingTarget, env) ?? null,
|
|
301
|
+
}
|
|
302
|
+
: {}),
|
|
303
|
+
};
|
|
304
|
+
}
|
|
262
305
|
function resolveRouteMatrixCell(provider, route, escalationLevel, cellSource) {
|
|
263
306
|
const routeIndex = Math.min(escalationLevel, route.length - 1);
|
|
264
307
|
const entry = route[routeIndex];
|
|
@@ -319,6 +362,8 @@ function resolveProviderCellFromValue(provider, providerValue, tier, cellSource,
|
|
|
319
362
|
};
|
|
320
363
|
}
|
|
321
364
|
if (isWorkflowDispatchCandidateLadder(cell)) {
|
|
365
|
+
if (provider === 'claude')
|
|
366
|
+
assertCandidateOrder(provider, tier, cell);
|
|
322
367
|
const ceiling = cell.candidates.at(-1);
|
|
323
368
|
if (ceiling === undefined) {
|
|
324
369
|
return null;
|
|
@@ -417,7 +462,7 @@ function candidatePrimaryTarget(provider, tier, candidate) {
|
|
|
417
462
|
if (targetAdapter.selectionAxis === 'model-effort' &&
|
|
418
463
|
(!target.model ||
|
|
419
464
|
!target.effort ||
|
|
420
|
-
!
|
|
465
|
+
!CODEX_CANDIDATE_EFFORTS.includes(target.effort))) {
|
|
421
466
|
throw new Error(`Malformed ${provider} candidate ordering in ${tier}: Codex candidates require a model and supported effort.`);
|
|
422
467
|
}
|
|
423
468
|
if ((targetAdapter.selectionAxis === 'model' ||
|
|
@@ -425,6 +470,15 @@ function candidatePrimaryTarget(provider, tier, candidate) {
|
|
|
425
470
|
!target.model) {
|
|
426
471
|
throw new Error(`Malformed ${provider} candidate ordering in ${tier}: model-argument candidates require a model.`);
|
|
427
472
|
}
|
|
473
|
+
if (target.harness === 'claude' && target.model) {
|
|
474
|
+
const validation = validateClaudeDispatchTarget({
|
|
475
|
+
model: target.model,
|
|
476
|
+
...(target.effort ? { effort: target.effort } : {}),
|
|
477
|
+
});
|
|
478
|
+
if (!validation.valid) {
|
|
479
|
+
throw new Error(`Malformed ${provider} candidate ordering in ${tier}: ${validation.reason}`);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
428
482
|
return target;
|
|
429
483
|
}
|
|
430
484
|
function candidateTargetKey(target) {
|
|
@@ -450,17 +504,18 @@ function assertCandidateOrder(provider, tier, ladder) {
|
|
|
450
504
|
}
|
|
451
505
|
seen.add(key);
|
|
452
506
|
if (target.harness === 'claude' && target.model) {
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
}
|
|
507
|
+
const [modelRank, effortRank] = claudeTargetRank({
|
|
508
|
+
model: target.model,
|
|
509
|
+
...(target.effort ? { effort: target.effort } : {}),
|
|
510
|
+
});
|
|
511
|
+
const rank = modelRank * CLAUDE_EFFORT_ORDER.length + effortRank;
|
|
457
512
|
if (previousClaudeRank !== null && rank < previousClaudeRank) {
|
|
458
513
|
throw new Error(`Malformed ${provider} candidate ordering in ${tier}: Claude candidates must be nondecreasing.`);
|
|
459
514
|
}
|
|
460
515
|
previousClaudeRank = rank;
|
|
461
516
|
}
|
|
462
517
|
if (target.harness === 'codex' && target.model && target.effort) {
|
|
463
|
-
const rank =
|
|
518
|
+
const rank = CODEX_CANDIDATE_EFFORTS.indexOf(target.effort);
|
|
464
519
|
const previousRank = codexRanksByModel.get(target.model);
|
|
465
520
|
if (previousRank !== undefined && rank < previousRank) {
|
|
466
521
|
throw new Error(`Malformed ${provider} candidate ordering in ${tier}: Codex efforts for ${target.model} must be nondecreasing.`);
|
|
@@ -478,16 +533,26 @@ function assertTierCeilingsNondecreasing(provider, previous, current, tier) {
|
|
|
478
533
|
if (current.harness === 'claude' &&
|
|
479
534
|
previous.model &&
|
|
480
535
|
current.model &&
|
|
481
|
-
|
|
482
|
-
|
|
536
|
+
(() => {
|
|
537
|
+
const [previousModel, previousEffort] = claudeTargetRank({
|
|
538
|
+
model: previous.model,
|
|
539
|
+
...(previous.effort ? { effort: previous.effort } : {}),
|
|
540
|
+
});
|
|
541
|
+
const [currentModel, currentEffort] = claudeTargetRank({
|
|
542
|
+
model: current.model,
|
|
543
|
+
...(current.effort ? { effort: current.effort } : {}),
|
|
544
|
+
});
|
|
545
|
+
return (currentModel < previousModel ||
|
|
546
|
+
(currentModel === previousModel && currentEffort < previousEffort));
|
|
547
|
+
})()) {
|
|
483
548
|
throw new Error(`Malformed ${provider} candidate ordering in ${tier}: named tier ceilings must be nondecreasing.`);
|
|
484
549
|
}
|
|
485
550
|
if (current.harness === 'codex' &&
|
|
486
551
|
previous.model === current.model &&
|
|
487
552
|
previous.effort &&
|
|
488
553
|
current.effort &&
|
|
489
|
-
|
|
490
|
-
|
|
554
|
+
CODEX_CANDIDATE_EFFORTS.indexOf(current.effort) <
|
|
555
|
+
CODEX_CANDIDATE_EFFORTS.indexOf(previous.effort)) {
|
|
491
556
|
throw new Error(`Malformed ${provider} candidate ordering in ${tier}: named tier ceilings must be nondecreasing.`);
|
|
492
557
|
}
|
|
493
558
|
}
|
|
@@ -495,10 +560,11 @@ function requestedCandidateMatches(provider, requested, target) {
|
|
|
495
560
|
if (target.harness !== provider || target.model !== requested.model) {
|
|
496
561
|
return false;
|
|
497
562
|
}
|
|
498
|
-
return provider !== 'codex'
|
|
563
|
+
return ((provider !== 'codex' && provider !== 'claude') ||
|
|
564
|
+
target.effort === requested.effort);
|
|
499
565
|
}
|
|
500
566
|
function formatRequestedCandidate(provider, requested) {
|
|
501
|
-
return provider === 'codex'
|
|
567
|
+
return provider === 'codex' || requested.effort !== undefined
|
|
502
568
|
? `${requested.model}/${requested.effort}`
|
|
503
569
|
: requested.model;
|
|
504
570
|
}
|
|
@@ -867,7 +933,7 @@ function normalizeRole(value) {
|
|
|
867
933
|
}
|
|
868
934
|
function providerValueOrder(provider) {
|
|
869
935
|
if (provider === 'codex') {
|
|
870
|
-
return
|
|
936
|
+
return CODEX_CANDIDATE_EFFORTS;
|
|
871
937
|
}
|
|
872
938
|
if (provider === 'claude') {
|
|
873
939
|
return CLAUDE_VALUES;
|
|
@@ -887,7 +953,7 @@ function normalizePreferredValue(provider, value) {
|
|
|
887
953
|
return null;
|
|
888
954
|
}
|
|
889
955
|
if (!isValidProviderValue(provider, normalized)) {
|
|
890
|
-
const validValues = order.join(', ');
|
|
956
|
+
const validValues = (provider === 'codex' ? CODEX_VALUES : order).join(', ');
|
|
891
957
|
throw new Error(`Invalid preferred dispatch value "${normalized}" for ${provider}. Valid values: ${validValues}.`);
|
|
892
958
|
}
|
|
893
959
|
return normalized;
|
|
@@ -927,17 +993,23 @@ function normalizeRequestedCandidate(provider, role, options) {
|
|
|
927
993
|
if (!effort) {
|
|
928
994
|
throw new Error('--candidate-effort is required for an exact Codex candidate.');
|
|
929
995
|
}
|
|
930
|
-
if (!
|
|
931
|
-
throw new Error(`Invalid Codex candidate effort "${effort}". Valid values: ${
|
|
996
|
+
if (!CODEX_CANDIDATE_EFFORTS.includes(effort)) {
|
|
997
|
+
throw new Error(`Invalid Codex candidate effort "${effort}". Valid values: ${CODEX_CANDIDATE_EFFORTS.join(', ')}.`);
|
|
932
998
|
}
|
|
933
999
|
return { model, effort };
|
|
934
1000
|
}
|
|
935
|
-
if (
|
|
936
|
-
|
|
1001
|
+
if (provider === 'claude') {
|
|
1002
|
+
const validation = validateClaudeDispatchTarget({
|
|
1003
|
+
model,
|
|
1004
|
+
...(effort ? { effort } : {}),
|
|
1005
|
+
});
|
|
1006
|
+
if (!validation.valid) {
|
|
1007
|
+
throw new Error(validation.reason);
|
|
1008
|
+
}
|
|
1009
|
+
return effort ? { model, effort } : { model };
|
|
937
1010
|
}
|
|
938
|
-
if (
|
|
939
|
-
|
|
940
|
-
throw new Error(`Invalid Claude candidate model "${model}". Valid values: ${CLAUDE_VALUES.join(', ')}.`);
|
|
1011
|
+
if (effort) {
|
|
1012
|
+
throw new Error(`--candidate-effort is only valid for Codex or Claude; ${provider} candidates use --candidate-model only.`);
|
|
941
1013
|
}
|
|
942
1014
|
return { model };
|
|
943
1015
|
}
|
|
@@ -965,12 +1037,12 @@ function normalizeClassification(provider, role, options) {
|
|
|
965
1037
|
throw new Error(`Invalid task class "${taskClassValue}". Valid values: ${TASK_CLASSES.join(', ')}.`);
|
|
966
1038
|
}
|
|
967
1039
|
const taskEffort = options.taskEffort?.trim() ?? '';
|
|
968
|
-
if (hasTaskEffort && provider !== 'codex') {
|
|
969
|
-
throw new Error(`--task-effort is only valid for Codex; received ${provider}.`);
|
|
1040
|
+
if (hasTaskEffort && provider !== 'codex' && provider !== 'claude') {
|
|
1041
|
+
throw new Error(`--task-effort is only valid for Codex or Claude; received ${provider}.`);
|
|
970
1042
|
}
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
throw new Error(`Invalid Codex task effort "${taskEffort}". Valid values: ${
|
|
1043
|
+
const validTaskEfforts = provider === 'claude' ? CLAUDE_EFFORT_ORDER : CODEX_CANDIDATE_EFFORTS;
|
|
1044
|
+
if (hasTaskEffort && !validTaskEfforts.includes(taskEffort)) {
|
|
1045
|
+
throw new Error(`Invalid ${provider === 'claude' ? 'Claude' : 'Codex'} task effort "${taskEffort}". Valid values: ${validTaskEfforts.join(', ')}.`);
|
|
974
1046
|
}
|
|
975
1047
|
return {
|
|
976
1048
|
taskClass: hasTaskClass ? taskClassValue : null,
|
|
@@ -1153,7 +1225,7 @@ function codexEffortAxis(selection, dispatchArgs) {
|
|
|
1153
1225
|
* the enforcement mode, mechanism, dispatch args, and verify-on-upgrade flag.
|
|
1154
1226
|
* Mode is computed here at call time — it is never read from persisted state.
|
|
1155
1227
|
*/
|
|
1156
|
-
function buildProviderResolution(provider, policy, role, orchestratorTier, preferredValue) {
|
|
1228
|
+
function buildProviderResolution(provider, policy, role, orchestratorTier, preferredValue, env) {
|
|
1157
1229
|
const adapter = getCeilingAdapter(provider);
|
|
1158
1230
|
if (policy === null) {
|
|
1159
1231
|
return {
|
|
@@ -1193,6 +1265,7 @@ function buildProviderResolution(provider, policy, role, orchestratorTier, prefe
|
|
|
1193
1265
|
? adapter.compileToDispatchArgs(dispatchValue, role, {
|
|
1194
1266
|
orchestratorTier,
|
|
1195
1267
|
target: selection.target,
|
|
1268
|
+
env,
|
|
1196
1269
|
})
|
|
1197
1270
|
: null;
|
|
1198
1271
|
let mode;
|
|
@@ -1208,12 +1281,16 @@ function buildProviderResolution(provider, policy, role, orchestratorTier, prefe
|
|
|
1208
1281
|
return {
|
|
1209
1282
|
value: policy.value,
|
|
1210
1283
|
mode,
|
|
1211
|
-
mechanism:
|
|
1284
|
+
mechanism: hasVariantDispatchArgs(dispatchArgs)
|
|
1285
|
+
? 'pinned-variant'
|
|
1286
|
+
: adapter.mechanism,
|
|
1212
1287
|
dispatchArgs,
|
|
1213
1288
|
modelAxis: modelAxis(provider, selection, dispatchArgs),
|
|
1214
1289
|
effortAxis: provider === 'codex'
|
|
1215
1290
|
? codexEffortAxis(selection, dispatchArgs)
|
|
1216
|
-
: '
|
|
1291
|
+
: provider === 'claude' && selection.target?.effort
|
|
1292
|
+
? `selected:${selection.target.effort}`
|
|
1293
|
+
: 'not-applicable',
|
|
1217
1294
|
verifyOnDispatch: dispatchValue && !isCrossHarness
|
|
1218
1295
|
? adapter.verifyOnDispatch(dispatchValue, {
|
|
1219
1296
|
orchestratorTier,
|
|
@@ -1385,11 +1462,11 @@ async function resolveDispatchCeiling(context, dependencies, options) {
|
|
|
1385
1462
|
const escalationLevel = normalizeEscalationLevel(options.escalationLevel);
|
|
1386
1463
|
const policyResolution = readResolvedConfigCeiling(provider, resolvedConfig) ??
|
|
1387
1464
|
(await resolveProjectStateCeiling(provider, projectPath, dependencies));
|
|
1388
|
-
const resolvedValue = await resolveCeilingValue(provider, resolvedConfig, projectPath, dependencies, escalationLevel, role, preferredValue, requestedCandidate, ceilingTier);
|
|
1465
|
+
const resolvedValue = resolveClaudePolicyCapabilities(await resolveCeilingValue(provider, resolvedConfig, projectPath, dependencies, escalationLevel, role, preferredValue, requestedCandidate, ceilingTier), dependencies.processEnv);
|
|
1389
1466
|
for (const warning of resolvedValue?.warnings ?? []) {
|
|
1390
1467
|
context.logger.warn(warning);
|
|
1391
1468
|
}
|
|
1392
|
-
const providerResolution = buildProviderResolution(provider, resolvedValue, role, orchestratorTier, preferredValue);
|
|
1469
|
+
const providerResolution = buildProviderResolution(provider, resolvedValue, role, orchestratorTier, preferredValue, dependencies.processEnv);
|
|
1393
1470
|
const providers = {
|
|
1394
1471
|
[provider]: providerResolution,
|
|
1395
1472
|
};
|
|
@@ -1714,7 +1791,7 @@ function writeHumanResolution(context, resolution) {
|
|
|
1714
1791
|
}
|
|
1715
1792
|
}
|
|
1716
1793
|
else {
|
|
1717
|
-
context.logger.info(
|
|
1794
|
+
context.logger.info(`Effort axis: ${providerResolution?.effortAxis ?? 'not-applicable'}`);
|
|
1718
1795
|
if (providerResolution?.selection.selectionMode === 'inherit-default') {
|
|
1719
1796
|
context.logger.info('Note: OAT will not select a Claude model; Task dispatch inherits host/provider behavior.');
|
|
1720
1797
|
}
|
|
@@ -1910,9 +1987,9 @@ export function createProjectDispatchCeilingCommand(overrides = {}) {
|
|
|
1910
1987
|
.option('--preferred <value>', 'Legacy preferred implementer/fix value before applying the resolved policy')
|
|
1911
1988
|
.addOption(new Option('--ceiling-tier <tier>', 'Invocation-only named maximum tier; never persists configuration or project state').choices([...VALID_DISPATCH_MATRIX_TIERS]))
|
|
1912
1989
|
.option('--candidate-model <model>', 'Exact configured implementer candidate model beneath the named ceiling')
|
|
1913
|
-
.option('--candidate-effort <effort>', 'Exact configured Codex candidate effort paired with --candidate-model')
|
|
1990
|
+
.option('--candidate-effort <effort>', 'Exact configured Codex or Claude candidate effort paired with --candidate-model')
|
|
1914
1991
|
.option('--task-class <class>', `Provider-neutral task classification provenance: ${TASK_CLASSES.join(', ')}`)
|
|
1915
|
-
.option('--task-effort <effort>', 'Codex
|
|
1992
|
+
.option('--task-effort <effort>', 'Codex or Claude task effort classification provenance; does not select a candidate')
|
|
1916
1993
|
.option('--escalation-level <level>', 'Ordered route entry to select; 0 is the floor and higher values advance through escalation targets')
|
|
1917
1994
|
.option('--project-path <path>', 'Read project-state policy from an explicit project path')
|
|
1918
1995
|
.option('--preflight', 'Treat unresolved non-interactive resolution as an implementation block')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch-matrix.d.ts","sourceRoot":"","sources":["../../src/config/dispatch-matrix.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dispatch-matrix.d.ts","sourceRoot":"","sources":["../../src/config/dispatch-matrix.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { validateClaudeDispatchTarget } from '../providers/claude/targets.js';
|
|
1
2
|
export const VALID_DISPATCH_MATRIX_TIERS = ['economy', 'balanced', 'high', 'frontier'];
|
|
2
3
|
const VALID_CODEX_PROVIDER_SCALARS = new Set([
|
|
3
4
|
'low',
|
|
@@ -205,6 +206,18 @@ export function isCodexMaterializedRouteTarget(provider, target) {
|
|
|
205
206
|
return (target.harness ?? provider) === 'codex';
|
|
206
207
|
}
|
|
207
208
|
export function validateDispatchRouteTarget(provider, target) {
|
|
209
|
+
if ((target.harness ?? provider) === 'claude') {
|
|
210
|
+
if (!target.model) {
|
|
211
|
+
return {
|
|
212
|
+
valid: false,
|
|
213
|
+
reason: 'Claude dispatch targets must provide a model.',
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
return validateClaudeDispatchTarget({
|
|
217
|
+
model: target.model,
|
|
218
|
+
...(target.effort ? { effort: target.effort } : {}),
|
|
219
|
+
});
|
|
220
|
+
}
|
|
208
221
|
if (!isCodexMaterializedRouteTarget(provider, target)) {
|
|
209
222
|
return { valid: true };
|
|
210
223
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ClaudeCapabilityEvidence } from '../claude/targets.js';
|
|
1
2
|
/**
|
|
2
3
|
* Provider ceiling adapter registry.
|
|
3
4
|
*
|
|
@@ -9,8 +10,9 @@
|
|
|
9
10
|
* to produce concrete dispatch args — skills never re-implement this logic.
|
|
10
11
|
*
|
|
11
12
|
* Codex enforces via sync-time materialized role variants selected from matrix
|
|
12
|
-
* model+effort targets. Claude
|
|
13
|
-
*
|
|
13
|
+
* model+effort targets. Claude effort routes use materialized model-and-effort
|
|
14
|
+
* variants, while legacy model-only routes keep the per-call Task `model`
|
|
15
|
+
* argument. Every other provider is advisory by default.
|
|
14
16
|
*/
|
|
15
17
|
export type EnforcementMechanism = 'pinned-variant' | 'model-arg' | 'none';
|
|
16
18
|
export type ProviderSelectionAxis = 'model' | 'model-effort' | 'tier' | 'none';
|
|
@@ -18,9 +20,12 @@ export type CeilingRole = 'implementer' | 'reviewer';
|
|
|
18
20
|
export interface CeilingCompileContext {
|
|
19
21
|
/** The orchestrator's own tier, used to detect above-orchestrator upgrades. */
|
|
20
22
|
orchestratorTier?: string;
|
|
23
|
+
/** Provider environment used by the resolver's capability derivation. */
|
|
24
|
+
env?: NodeJS.ProcessEnv;
|
|
21
25
|
target?: {
|
|
22
26
|
model?: string;
|
|
23
27
|
effort?: string;
|
|
28
|
+
capabilityEvidence?: ClaudeCapabilityEvidence;
|
|
24
29
|
} | null;
|
|
25
30
|
}
|
|
26
31
|
export type CeilingDispatchArgs = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/providers/ceiling/registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/providers/ceiling/registry.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,wBAAwB,EAE9B,MAAM,2BAA2B,CAAC;AAQnC;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,WAAW,GAAG,MAAM,CAAC;AAC3E,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC;AAE/E,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;KAC/C,GAAG,IAAI,CAAC;CACV;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GACnB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB,IAAI,CAAC;AAKT,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,oBAAoB,CAAC;IAChC,aAAa,EAAE,qBAAqB,CAAC;IACrC;;;OAGG;IACH,qBAAqB,CACnB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,qBAAqB,GACzB,mBAAmB,CAAC;IACvB;;;;OAIG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC;CACtE;AAMD,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAA4B,CAAC;AAkK5E;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,sBAAsB,CAM1E"}
|