@triflux/core 10.42.0 → 10.44.0
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/hooks/keyword-rules.json +139 -19
- package/hooks/pipeline-stop.mjs +1 -1
- package/hub/bridge.mjs +80 -1
- package/hub/cli-adapter-base.mjs +111 -21
- package/hub/codex-adapter.mjs +8 -1
- package/hub/dynamic-routing-engine.mjs +1 -1
- package/hub/gemini-adapter.mjs +3 -1
- package/hub/intent.mjs +24 -28
- package/hub/lib/cto-env.mjs +46 -0
- package/hub/lib/memory-store.mjs +25 -13
- package/hub/lib/timeout-defaults.mjs +45 -0
- package/hub/lib/worker-lifecycle.mjs +101 -0
- package/hub/middleware/request-logger.mjs +4 -1
- package/hub/role-contract.mjs +314 -0
- package/hub/role-control-events.mjs +113 -0
- package/hub/router.mjs +383 -29
- package/hub/team/claude-daemon-control.mjs +28 -15
- package/hub/team/intervention.mjs +530 -0
- package/hub/team/retry-state-machine.mjs +12 -3
- package/hub/team/synapse-http.mjs +149 -4
- package/hud/constants.mjs +21 -0
- package/hud/context-monitor.mjs +18 -21
- package/hud/hud-qos-status.mjs +1 -1
- package/hud/providers/codex-probe.mjs +216 -0
- package/hud/providers/codex.mjs +206 -29
- package/hud/renderers.mjs +6 -9
- package/package.json +1 -1
- package/scripts/lib/agent-route-policy.mjs +360 -0
- package/scripts/lib/cli-agy.mjs +1 -0
- package/scripts/lib/cli-claude.mjs +1 -0
- package/scripts/lib/cli-codex.mjs +23 -160
- package/scripts/lib/codex-profile-config.mjs +31 -5
- package/scripts/lib/keyword-rules.mjs +12 -0
- package/hub/log-retention.mjs +0 -726
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
// Canonical Codex role policy. Concrete model IDs stay in profile config files.
|
|
2
|
+
|
|
3
|
+
import { resolveCodexProfileConfigValues } from "./codex-profile-config.mjs";
|
|
4
|
+
|
|
5
|
+
const policy = {
|
|
6
|
+
executor: {
|
|
7
|
+
profile: "gpt56_terra_high",
|
|
8
|
+
timeoutSec: 1080,
|
|
9
|
+
runMode: "fg",
|
|
10
|
+
opusOversight: false,
|
|
11
|
+
mcpHint: "implement",
|
|
12
|
+
subcommand: "exec",
|
|
13
|
+
},
|
|
14
|
+
codex: {
|
|
15
|
+
profile: "gpt56_terra_high",
|
|
16
|
+
timeoutSec: 1080,
|
|
17
|
+
runMode: "fg",
|
|
18
|
+
opusOversight: false,
|
|
19
|
+
mcpHint: "implement",
|
|
20
|
+
subcommand: "exec",
|
|
21
|
+
},
|
|
22
|
+
"build-fixer": {
|
|
23
|
+
profile: "gpt56_luna_low",
|
|
24
|
+
timeoutSec: 540,
|
|
25
|
+
runMode: "fg",
|
|
26
|
+
opusOversight: false,
|
|
27
|
+
mcpHint: "implement",
|
|
28
|
+
subcommand: "exec",
|
|
29
|
+
},
|
|
30
|
+
cleanup: {
|
|
31
|
+
profile: "gpt56_terra_med",
|
|
32
|
+
timeoutSec: 540,
|
|
33
|
+
runMode: "fg",
|
|
34
|
+
opusOversight: false,
|
|
35
|
+
mcpHint: "implement",
|
|
36
|
+
subcommand: "exec",
|
|
37
|
+
},
|
|
38
|
+
deslop: {
|
|
39
|
+
profile: "gpt56_terra_med",
|
|
40
|
+
timeoutSec: 540,
|
|
41
|
+
runMode: "fg",
|
|
42
|
+
opusOversight: false,
|
|
43
|
+
mcpHint: "implement",
|
|
44
|
+
subcommand: "exec",
|
|
45
|
+
},
|
|
46
|
+
debugger: {
|
|
47
|
+
profile: "gpt56_sol_xhigh",
|
|
48
|
+
timeoutSec: 900,
|
|
49
|
+
runMode: "bg",
|
|
50
|
+
opusOversight: false,
|
|
51
|
+
mcpHint: "implement",
|
|
52
|
+
subcommand: "exec",
|
|
53
|
+
},
|
|
54
|
+
"deep-executor": {
|
|
55
|
+
profile: "gpt56_sol_xhigh",
|
|
56
|
+
timeoutSec: 3600,
|
|
57
|
+
runMode: "bg",
|
|
58
|
+
opusOversight: true,
|
|
59
|
+
mcpHint: "implement",
|
|
60
|
+
subcommand: "exec",
|
|
61
|
+
},
|
|
62
|
+
architect: {
|
|
63
|
+
profile: "gpt56_sol_xhigh",
|
|
64
|
+
timeoutSec: 3600,
|
|
65
|
+
runMode: "bg",
|
|
66
|
+
opusOversight: true,
|
|
67
|
+
mcpHint: "analyze",
|
|
68
|
+
subcommand: "exec",
|
|
69
|
+
},
|
|
70
|
+
critic: {
|
|
71
|
+
profile: "gpt56_sol_xhigh",
|
|
72
|
+
timeoutSec: 3600,
|
|
73
|
+
runMode: "bg",
|
|
74
|
+
opusOversight: true,
|
|
75
|
+
mcpHint: "analyze",
|
|
76
|
+
subcommand: "exec",
|
|
77
|
+
},
|
|
78
|
+
planner: {
|
|
79
|
+
profile: "gpt56_sol_xhigh",
|
|
80
|
+
timeoutSec: 3600,
|
|
81
|
+
runMode: "fg",
|
|
82
|
+
opusOversight: true,
|
|
83
|
+
mcpHint: "analyze",
|
|
84
|
+
subcommand: "exec",
|
|
85
|
+
},
|
|
86
|
+
analyst: {
|
|
87
|
+
profile: "gpt56_sol_xhigh",
|
|
88
|
+
timeoutSec: 3600,
|
|
89
|
+
runMode: "fg",
|
|
90
|
+
opusOversight: true,
|
|
91
|
+
mcpHint: "analyze",
|
|
92
|
+
subcommand: "exec",
|
|
93
|
+
},
|
|
94
|
+
"code-reviewer": {
|
|
95
|
+
profile: "gpt56_terra_high",
|
|
96
|
+
timeoutSec: 1800,
|
|
97
|
+
runMode: "bg",
|
|
98
|
+
opusOversight: false,
|
|
99
|
+
mcpHint: "review",
|
|
100
|
+
subcommand: "review",
|
|
101
|
+
},
|
|
102
|
+
"quality-reviewer": {
|
|
103
|
+
profile: "gpt56_terra_high",
|
|
104
|
+
timeoutSec: 1800,
|
|
105
|
+
runMode: "bg",
|
|
106
|
+
opusOversight: false,
|
|
107
|
+
mcpHint: "review",
|
|
108
|
+
subcommand: "review",
|
|
109
|
+
},
|
|
110
|
+
"security-reviewer": {
|
|
111
|
+
profile: "gpt56_sol_xhigh",
|
|
112
|
+
timeoutSec: 1800,
|
|
113
|
+
runMode: "bg",
|
|
114
|
+
opusOversight: true,
|
|
115
|
+
mcpHint: "review",
|
|
116
|
+
subcommand: "review",
|
|
117
|
+
},
|
|
118
|
+
scientist: {
|
|
119
|
+
profile: "gpt56_terra_high",
|
|
120
|
+
timeoutSec: 1440,
|
|
121
|
+
runMode: "bg",
|
|
122
|
+
opusOversight: false,
|
|
123
|
+
mcpHint: "analyze",
|
|
124
|
+
subcommand: "exec",
|
|
125
|
+
},
|
|
126
|
+
"document-specialist": {
|
|
127
|
+
profile: "gpt56_terra_high",
|
|
128
|
+
timeoutSec: 1440,
|
|
129
|
+
runMode: "bg",
|
|
130
|
+
opusOversight: false,
|
|
131
|
+
mcpHint: "analyze",
|
|
132
|
+
subcommand: "exec",
|
|
133
|
+
},
|
|
134
|
+
"scientist-deep": {
|
|
135
|
+
profile: "gpt56_sol_xhigh",
|
|
136
|
+
timeoutSec: 3600,
|
|
137
|
+
runMode: "bg",
|
|
138
|
+
opusOversight: false,
|
|
139
|
+
mcpHint: "analyze",
|
|
140
|
+
subcommand: "exec",
|
|
141
|
+
},
|
|
142
|
+
verifier: {
|
|
143
|
+
profile: "gpt56_terra_high",
|
|
144
|
+
timeoutSec: 1200,
|
|
145
|
+
runMode: "fg",
|
|
146
|
+
opusOversight: false,
|
|
147
|
+
mcpHint: "review",
|
|
148
|
+
subcommand: "review",
|
|
149
|
+
},
|
|
150
|
+
"test-engineer": {
|
|
151
|
+
profile: "gpt56_terra_high",
|
|
152
|
+
timeoutSec: 1200,
|
|
153
|
+
runMode: "bg",
|
|
154
|
+
opusOversight: false,
|
|
155
|
+
mcpHint: "implement",
|
|
156
|
+
subcommand: "exec",
|
|
157
|
+
},
|
|
158
|
+
"qa-tester": {
|
|
159
|
+
profile: "gpt56_terra_high",
|
|
160
|
+
timeoutSec: 1200,
|
|
161
|
+
runMode: "bg",
|
|
162
|
+
opusOversight: false,
|
|
163
|
+
mcpHint: "review",
|
|
164
|
+
subcommand: "review",
|
|
165
|
+
},
|
|
166
|
+
spark: {
|
|
167
|
+
profile: "gpt56_luna_low",
|
|
168
|
+
timeoutSec: 180,
|
|
169
|
+
runMode: "fg",
|
|
170
|
+
opusOversight: false,
|
|
171
|
+
mcpHint: "implement",
|
|
172
|
+
subcommand: "exec",
|
|
173
|
+
},
|
|
174
|
+
// These entries are only for explicit direct-Codex overrides. agent-map.json
|
|
175
|
+
// remains the provider-selection authority for their normal execution.
|
|
176
|
+
designer: {
|
|
177
|
+
profile: "gpt56_sol_xhigh",
|
|
178
|
+
timeoutSec: 900,
|
|
179
|
+
runMode: "bg",
|
|
180
|
+
opusOversight: false,
|
|
181
|
+
mcpHint: "implement",
|
|
182
|
+
subcommand: "exec",
|
|
183
|
+
},
|
|
184
|
+
writer: {
|
|
185
|
+
profile: "gpt56_luna_low",
|
|
186
|
+
timeoutSec: 900,
|
|
187
|
+
runMode: "bg",
|
|
188
|
+
opusOversight: false,
|
|
189
|
+
mcpHint: "implement",
|
|
190
|
+
subcommand: "exec",
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
function freezePolicy(entry) {
|
|
195
|
+
return Object.freeze({ ...entry });
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export const CODEX_AGENT_POLICY = Object.freeze(
|
|
199
|
+
Object.fromEntries(
|
|
200
|
+
Object.entries(policy).map(([agent, entry]) => [
|
|
201
|
+
agent,
|
|
202
|
+
freezePolicy(entry),
|
|
203
|
+
]),
|
|
204
|
+
),
|
|
205
|
+
);
|
|
206
|
+
export const DEFAULT_CODEX_AGENT = "executor";
|
|
207
|
+
|
|
208
|
+
export const CANONICAL_CODEX_PROFILE_OVERRIDES = Object.freeze(
|
|
209
|
+
new Set([
|
|
210
|
+
"gpt56_luna_low",
|
|
211
|
+
"gpt56_terra_med",
|
|
212
|
+
"gpt56_terra_high",
|
|
213
|
+
"gpt56_sol_xhigh",
|
|
214
|
+
"gpt56_sol_max",
|
|
215
|
+
"gpt56_sol_ultra",
|
|
216
|
+
]),
|
|
217
|
+
);
|
|
218
|
+
export const ULTRA_ELIGIBLE_CODEX_AGENTS = Object.freeze(
|
|
219
|
+
new Set(["deep-executor", "scientist-deep"]),
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
const NESTED_GLOBAL_PROFILE_OVERRIDES = new Set([
|
|
223
|
+
"max",
|
|
224
|
+
"ultra",
|
|
225
|
+
"gpt56_sol_max",
|
|
226
|
+
"gpt56_sol_ultra",
|
|
227
|
+
]);
|
|
228
|
+
|
|
229
|
+
export function resolveCodexAgentPolicy(agent) {
|
|
230
|
+
return freezePolicy(
|
|
231
|
+
CODEX_AGENT_POLICY[agent] ?? CODEX_AGENT_POLICY[DEFAULT_CODEX_AGENT],
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Resolves a requested Codex profile against the canonical role policy.
|
|
237
|
+
*
|
|
238
|
+
* `retryProfile` intentionally wins over `profileOverride`: retry snapshots
|
|
239
|
+
* represent an already-selected escalation step and must not be replaced by a
|
|
240
|
+
* later process-level `TFX_CODEX_PROFILE`. Ultra is reserved for an eligible
|
|
241
|
+
* top-level role; every nested/sandboxed or ineligible request is max.
|
|
242
|
+
*/
|
|
243
|
+
export function resolveCodexAgentProfile(
|
|
244
|
+
agent,
|
|
245
|
+
{
|
|
246
|
+
profileOverride = "auto",
|
|
247
|
+
retryProfile = null,
|
|
248
|
+
nested = false,
|
|
249
|
+
allowCustom = false,
|
|
250
|
+
} = {},
|
|
251
|
+
) {
|
|
252
|
+
const defaultProfile = resolveCodexAgentPolicy(agent).profile;
|
|
253
|
+
const retryRequested = String(retryProfile ?? "").trim();
|
|
254
|
+
const requested = retryRequested || String(profileOverride || "auto").trim();
|
|
255
|
+
if (!requested || requested === "auto") return defaultProfile;
|
|
256
|
+
|
|
257
|
+
const canonical =
|
|
258
|
+
requested === "max"
|
|
259
|
+
? "gpt56_sol_max"
|
|
260
|
+
: requested === "ultra"
|
|
261
|
+
? "gpt56_sol_ultra"
|
|
262
|
+
: requested;
|
|
263
|
+
if (!CANONICAL_CODEX_PROFILE_OVERRIDES.has(canonical)) {
|
|
264
|
+
if (allowCustom) return requested;
|
|
265
|
+
throw new Error(
|
|
266
|
+
`[agent-route-policy] unsupported profile override: ${requested}`,
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
if (canonical !== "gpt56_sol_ultra") return canonical;
|
|
270
|
+
return nested || !ULTRA_ELIGIBLE_CODEX_AGENTS.has(agent)
|
|
271
|
+
? "gpt56_sol_max"
|
|
272
|
+
: canonical;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Nested headless, team, worker, and delegator launches always select an
|
|
277
|
+
* explicit role profile rather than inheriting the global Codex config. A
|
|
278
|
+
* custom profile that resolves to ultra is also downgraded to max.
|
|
279
|
+
*/
|
|
280
|
+
export function resolveNestedCodexAgentProfile(
|
|
281
|
+
agent,
|
|
282
|
+
{
|
|
283
|
+
profileOverride = "auto",
|
|
284
|
+
globalProfile = "auto",
|
|
285
|
+
retryProfile = null,
|
|
286
|
+
codexHome,
|
|
287
|
+
} = {},
|
|
288
|
+
) {
|
|
289
|
+
const explicitProfile = String(profileOverride || "auto").trim();
|
|
290
|
+
const globalOverride = String(globalProfile || "auto").trim();
|
|
291
|
+
// Headless lanes must select their role policy explicitly. Only the max and
|
|
292
|
+
// ultra exception lanes may cross the process environment boundary.
|
|
293
|
+
const effectiveOverride =
|
|
294
|
+
explicitProfile !== "auto"
|
|
295
|
+
? explicitProfile
|
|
296
|
+
: NESTED_GLOBAL_PROFILE_OVERRIDES.has(globalOverride)
|
|
297
|
+
? globalOverride
|
|
298
|
+
: "auto";
|
|
299
|
+
const fallback = resolveCodexAgentProfile(agent);
|
|
300
|
+
const candidate = resolveCodexAgentProfile(agent, {
|
|
301
|
+
profileOverride: effectiveOverride,
|
|
302
|
+
retryProfile,
|
|
303
|
+
nested: true,
|
|
304
|
+
allowCustom: true,
|
|
305
|
+
});
|
|
306
|
+
const { effort } = resolveCodexProfileConfigValues(candidate, { codexHome });
|
|
307
|
+
if (!effort) return fallback;
|
|
308
|
+
return effort.toLowerCase() === "ultra" ? "gpt56_sol_max" : candidate;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export function describeCodexAgentPolicy() {
|
|
312
|
+
return {
|
|
313
|
+
defaultAgent: DEFAULT_CODEX_AGENT,
|
|
314
|
+
agents: Object.keys(CODEX_AGENT_POLICY),
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function parseCliArgs(argv) {
|
|
319
|
+
const args = [...argv];
|
|
320
|
+
let format = "json";
|
|
321
|
+
let agent = DEFAULT_CODEX_AGENT;
|
|
322
|
+
while (args.length > 0) {
|
|
323
|
+
const flag = args.shift();
|
|
324
|
+
if (flag === "--format") format = args.shift() || "";
|
|
325
|
+
else if (flag === "--agent") agent = args.shift() || "";
|
|
326
|
+
else throw new Error(`unknown argument: ${flag}`);
|
|
327
|
+
}
|
|
328
|
+
if (!new Set(["json", "tsv"]).has(format)) {
|
|
329
|
+
throw new Error(`unsupported format: ${format}`);
|
|
330
|
+
}
|
|
331
|
+
return { format, agent };
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function runCli() {
|
|
335
|
+
const { format, agent } = parseCliArgs(process.argv.slice(2));
|
|
336
|
+
const resolved = resolveCodexAgentPolicy(agent);
|
|
337
|
+
if (format === "tsv") {
|
|
338
|
+
process.stdout.write(
|
|
339
|
+
[
|
|
340
|
+
resolved.profile,
|
|
341
|
+
resolved.timeoutSec,
|
|
342
|
+
resolved.runMode,
|
|
343
|
+
resolved.opusOversight,
|
|
344
|
+
resolved.mcpHint,
|
|
345
|
+
resolved.subcommand,
|
|
346
|
+
].join("\t"),
|
|
347
|
+
);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
process.stdout.write(`${JSON.stringify(resolved)}\n`);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (import.meta.url === new URL(process.argv[1], "file:").href) {
|
|
354
|
+
try {
|
|
355
|
+
runCli();
|
|
356
|
+
} catch (error) {
|
|
357
|
+
process.stderr.write(`[agent-route-policy] ${error.message}\n`);
|
|
358
|
+
process.exitCode = 1;
|
|
359
|
+
}
|
|
360
|
+
}
|
package/scripts/lib/cli-agy.mjs
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
//
|
|
6
6
|
// 출처: scripts/tfx-route.sh route_agent() L1052-L1059, run_codex_exec() L2036-L2046.
|
|
7
7
|
// .claude/rules/tfx-update-logic.md Antigravity CLI 1.0.0 정밀 sanity matrix.
|
|
8
|
+
// timeoutSec은 lane 예상 소요 시간(advisory)이다. hard ceiling 집행은 Bash route가 소유한다.
|
|
8
9
|
|
|
9
10
|
export const id = "agy";
|
|
10
11
|
export const cliType = "antigravity";
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
//
|
|
6
6
|
// 출처: scripts/tfx-route.sh route_agent() L1062-L1063 (explore|claude),
|
|
7
7
|
// L1196-L1203 (TFX_CLI_MODE=gemini fallback), TFX_VERIFIER_OVERRIDE=claude.
|
|
8
|
+
// timeoutSec은 lane 예상 소요 시간(advisory)이다. hard ceiling 집행은 Bash route가 소유한다.
|
|
8
9
|
|
|
9
10
|
export const id = "claude";
|
|
10
11
|
export const cliType = "claude-native";
|
|
@@ -4,168 +4,23 @@
|
|
|
4
4
|
// 산출한다. 실제 spawn 은 Phase 1 에서 이관된다 (현재는 tfx-route.sh 가 수행).
|
|
5
5
|
//
|
|
6
6
|
// 진입점: tfx-route.mjs → selectAdapter("codex") → plan({...}).
|
|
7
|
-
// 출처:
|
|
7
|
+
// 출처: agent-route-policy.mjs 의 canonical Codex role policy.
|
|
8
|
+
// timeoutSec은 lane 예상 소요 시간(advisory)이다. hard ceiling 집행은 Bash route가 소유한다.
|
|
8
9
|
|
|
9
10
|
export const id = "codex";
|
|
10
11
|
export const cliType = "codex";
|
|
11
12
|
export const command = "codex";
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
mcpHint: "implement",
|
|
20
|
-
},
|
|
21
|
-
codex: {
|
|
22
|
-
profile: "gpt55_high",
|
|
23
|
-
timeoutSec: 1080,
|
|
24
|
-
runMode: "fg",
|
|
25
|
-
opusOversight: false,
|
|
26
|
-
mcpHint: "implement",
|
|
27
|
-
},
|
|
28
|
-
"build-fixer": {
|
|
29
|
-
profile: "gpt55_low",
|
|
30
|
-
timeoutSec: 540,
|
|
31
|
-
runMode: "fg",
|
|
32
|
-
opusOversight: false,
|
|
33
|
-
mcpHint: "implement",
|
|
34
|
-
},
|
|
35
|
-
cleanup: {
|
|
36
|
-
profile: "gpt55_med",
|
|
37
|
-
timeoutSec: 540,
|
|
38
|
-
runMode: "fg",
|
|
39
|
-
opusOversight: false,
|
|
40
|
-
mcpHint: "implement",
|
|
41
|
-
},
|
|
42
|
-
deslop: {
|
|
43
|
-
profile: "gpt55_med",
|
|
44
|
-
timeoutSec: 540,
|
|
45
|
-
runMode: "fg",
|
|
46
|
-
opusOversight: false,
|
|
47
|
-
mcpHint: "implement",
|
|
48
|
-
},
|
|
49
|
-
debugger: {
|
|
50
|
-
profile: "gpt55_xhigh",
|
|
51
|
-
timeoutSec: 900,
|
|
52
|
-
runMode: "bg",
|
|
53
|
-
opusOversight: false,
|
|
54
|
-
mcpHint: "implement",
|
|
55
|
-
},
|
|
56
|
-
"deep-executor": {
|
|
57
|
-
profile: "gpt55_xhigh",
|
|
58
|
-
timeoutSec: 3600,
|
|
59
|
-
runMode: "bg",
|
|
60
|
-
opusOversight: true,
|
|
61
|
-
mcpHint: "implement",
|
|
62
|
-
},
|
|
63
|
-
architect: {
|
|
64
|
-
profile: "gpt55_xhigh",
|
|
65
|
-
timeoutSec: 3600,
|
|
66
|
-
runMode: "bg",
|
|
67
|
-
opusOversight: true,
|
|
68
|
-
mcpHint: "analyze",
|
|
69
|
-
},
|
|
70
|
-
critic: {
|
|
71
|
-
profile: "gpt55_xhigh",
|
|
72
|
-
timeoutSec: 3600,
|
|
73
|
-
runMode: "bg",
|
|
74
|
-
opusOversight: true,
|
|
75
|
-
mcpHint: "analyze",
|
|
76
|
-
},
|
|
77
|
-
planner: {
|
|
78
|
-
profile: "gpt55_xhigh",
|
|
79
|
-
timeoutSec: 3600,
|
|
80
|
-
runMode: "fg",
|
|
81
|
-
opusOversight: true,
|
|
82
|
-
mcpHint: "analyze",
|
|
83
|
-
},
|
|
84
|
-
analyst: {
|
|
85
|
-
profile: "gpt55_xhigh",
|
|
86
|
-
timeoutSec: 3600,
|
|
87
|
-
runMode: "fg",
|
|
88
|
-
opusOversight: true,
|
|
89
|
-
mcpHint: "analyze",
|
|
90
|
-
},
|
|
91
|
-
"code-reviewer": {
|
|
92
|
-
profile: "gpt55_high",
|
|
93
|
-
timeoutSec: 1800,
|
|
94
|
-
runMode: "bg",
|
|
95
|
-
opusOversight: false,
|
|
96
|
-
mcpHint: "review",
|
|
97
|
-
subcommand: "review",
|
|
98
|
-
},
|
|
99
|
-
"quality-reviewer": {
|
|
100
|
-
profile: "gpt55_high",
|
|
101
|
-
timeoutSec: 1800,
|
|
102
|
-
runMode: "bg",
|
|
103
|
-
opusOversight: false,
|
|
104
|
-
mcpHint: "review",
|
|
105
|
-
subcommand: "review",
|
|
106
|
-
},
|
|
107
|
-
"security-reviewer": {
|
|
108
|
-
profile: "gpt55_xhigh",
|
|
109
|
-
timeoutSec: 1800,
|
|
110
|
-
runMode: "bg",
|
|
111
|
-
opusOversight: true,
|
|
112
|
-
mcpHint: "review",
|
|
113
|
-
subcommand: "review",
|
|
114
|
-
},
|
|
115
|
-
scientist: {
|
|
116
|
-
profile: "gpt55_high",
|
|
117
|
-
timeoutSec: 1440,
|
|
118
|
-
runMode: "bg",
|
|
119
|
-
opusOversight: false,
|
|
120
|
-
mcpHint: "analyze",
|
|
121
|
-
},
|
|
122
|
-
"document-specialist": {
|
|
123
|
-
profile: "gpt55_high",
|
|
124
|
-
timeoutSec: 1440,
|
|
125
|
-
runMode: "bg",
|
|
126
|
-
opusOversight: false,
|
|
127
|
-
mcpHint: "analyze",
|
|
128
|
-
},
|
|
129
|
-
"scientist-deep": {
|
|
130
|
-
profile: "gpt55_xhigh",
|
|
131
|
-
timeoutSec: 3600,
|
|
132
|
-
runMode: "bg",
|
|
133
|
-
opusOversight: false,
|
|
134
|
-
mcpHint: "analyze",
|
|
135
|
-
},
|
|
136
|
-
verifier: {
|
|
137
|
-
profile: "gpt55_high",
|
|
138
|
-
timeoutSec: 1200,
|
|
139
|
-
runMode: "fg",
|
|
140
|
-
opusOversight: false,
|
|
141
|
-
mcpHint: "review",
|
|
142
|
-
subcommand: "review",
|
|
143
|
-
},
|
|
144
|
-
"test-engineer": {
|
|
145
|
-
profile: "gpt55_high",
|
|
146
|
-
timeoutSec: 1200,
|
|
147
|
-
runMode: "bg",
|
|
148
|
-
opusOversight: false,
|
|
149
|
-
mcpHint: "implement",
|
|
150
|
-
},
|
|
151
|
-
"qa-tester": {
|
|
152
|
-
profile: "gpt55_high",
|
|
153
|
-
timeoutSec: 1200,
|
|
154
|
-
runMode: "bg",
|
|
155
|
-
opusOversight: false,
|
|
156
|
-
mcpHint: "review",
|
|
157
|
-
subcommand: "review",
|
|
158
|
-
},
|
|
159
|
-
spark: {
|
|
160
|
-
profile: "gpt55_low",
|
|
161
|
-
timeoutSec: 180,
|
|
162
|
-
runMode: "fg",
|
|
163
|
-
opusOversight: false,
|
|
164
|
-
mcpHint: "implement",
|
|
165
|
-
},
|
|
166
|
-
};
|
|
14
|
+
import {
|
|
15
|
+
CODEX_AGENT_POLICY,
|
|
16
|
+
resolveCodexAgentPolicy,
|
|
17
|
+
resolveCodexAgentProfile,
|
|
18
|
+
resolveNestedCodexAgentProfile,
|
|
19
|
+
} from "./agent-route-policy.mjs";
|
|
167
20
|
|
|
168
|
-
|
|
21
|
+
// Compatibility re-exports for launchers which historically imported these
|
|
22
|
+
// helpers from this adapter. The policy module owns the semantics.
|
|
23
|
+
export { resolveCodexAgentProfile, resolveNestedCodexAgentProfile };
|
|
169
24
|
|
|
170
25
|
export function plan({
|
|
171
26
|
agent,
|
|
@@ -173,18 +28,26 @@ export function plan({
|
|
|
173
28
|
mcpProfile = "auto",
|
|
174
29
|
timeoutSec,
|
|
175
30
|
contextFile,
|
|
31
|
+
profileOverride = "auto",
|
|
32
|
+
retryProfile = null,
|
|
33
|
+
nested = false,
|
|
176
34
|
} = {}) {
|
|
177
35
|
if (!agent) {
|
|
178
36
|
throw new Error("[cli-codex] agent required");
|
|
179
37
|
}
|
|
180
|
-
const cfg =
|
|
38
|
+
const cfg = resolveCodexAgentPolicy(agent);
|
|
39
|
+
const profile = resolveCodexAgentProfile(agent, {
|
|
40
|
+
profileOverride,
|
|
41
|
+
retryProfile,
|
|
42
|
+
nested,
|
|
43
|
+
});
|
|
181
44
|
const effectiveTimeoutSec =
|
|
182
45
|
Number.isFinite(timeoutSec) && timeoutSec > 0 ? timeoutSec : cfg.timeoutSec;
|
|
183
46
|
return {
|
|
184
47
|
command,
|
|
185
48
|
subcommand: cfg.subcommand ?? "exec",
|
|
186
|
-
profile
|
|
187
|
-
effort:
|
|
49
|
+
profile,
|
|
50
|
+
effort: profile,
|
|
188
51
|
timeoutMs: effectiveTimeoutSec * 1000,
|
|
189
52
|
runMode: cfg.runMode,
|
|
190
53
|
opusOversight: cfg.opusOversight,
|
|
@@ -195,5 +58,5 @@ export function plan({
|
|
|
195
58
|
}
|
|
196
59
|
|
|
197
60
|
export function describe() {
|
|
198
|
-
return { id, cliType, command, agents: Object.keys(
|
|
61
|
+
return { id, cliType, command, agents: Object.keys(CODEX_AGENT_POLICY) };
|
|
199
62
|
}
|
|
@@ -9,6 +9,8 @@ import { homedir } from "node:os";
|
|
|
9
9
|
import { dirname, join } from "node:path";
|
|
10
10
|
|
|
11
11
|
const EFFORT_BY_SUFFIX = {
|
|
12
|
+
ultra: "ultra",
|
|
13
|
+
max: "max",
|
|
12
14
|
xhigh: "xhigh",
|
|
13
15
|
high: "high",
|
|
14
16
|
med: "medium",
|
|
@@ -16,6 +18,15 @@ const EFFORT_BY_SUFFIX = {
|
|
|
16
18
|
low: "low",
|
|
17
19
|
};
|
|
18
20
|
|
|
21
|
+
const CANONICAL_PROFILE_VALUES = Object.freeze({
|
|
22
|
+
gpt56_luna_low: { model: "gpt-5.6-luna", effort: "low" },
|
|
23
|
+
gpt56_terra_med: { model: "gpt-5.6-terra", effort: "medium" },
|
|
24
|
+
gpt56_terra_high: { model: "gpt-5.6-terra", effort: "high" },
|
|
25
|
+
gpt56_sol_xhigh: { model: "gpt-5.6-sol", effort: "xhigh" },
|
|
26
|
+
gpt56_sol_max: { model: "gpt-5.6-sol", effort: "max" },
|
|
27
|
+
gpt56_sol_ultra: { model: "gpt-5.6-sol", effort: "ultra" },
|
|
28
|
+
});
|
|
29
|
+
|
|
19
30
|
function readProfileScalar(raw, key) {
|
|
20
31
|
const match = String(raw).match(
|
|
21
32
|
new RegExp(
|
|
@@ -29,7 +40,7 @@ function readProfileScalar(raw, key) {
|
|
|
29
40
|
}
|
|
30
41
|
|
|
31
42
|
/**
|
|
32
|
-
* Resolve a Codex effort profile name (e.g. "
|
|
43
|
+
* Resolve a Codex effort profile name (e.g. "gpt56_terra_high") to the `-c key=value`
|
|
33
44
|
* config overrides that `codex exec` accepts, so the headless CLI lanes can
|
|
34
45
|
* select a profile WITHOUT `codex exec --profile <name>`. codex 0.134+ rejects
|
|
35
46
|
* `--profile X` whenever config.toml still contains an inline `[profiles.X]`
|
|
@@ -47,10 +58,12 @@ function readProfileScalar(raw, key) {
|
|
|
47
58
|
*
|
|
48
59
|
* @param {string} profileName
|
|
49
60
|
* @param {{ codexHome?: string }} [opts]
|
|
50
|
-
* @returns {string[]} e.g. ['model="gpt-5.
|
|
61
|
+
* @returns {string[]} e.g. ['model="gpt-5.6-terra"', 'model_reasoning_effort="high"']
|
|
51
62
|
*/
|
|
52
|
-
export function
|
|
53
|
-
if (typeof profileName !== "string" || !profileName)
|
|
63
|
+
export function resolveCodexProfileConfigValues(profileName, opts = {}) {
|
|
64
|
+
if (typeof profileName !== "string" || !profileName) {
|
|
65
|
+
return { model: null, effort: null };
|
|
66
|
+
}
|
|
54
67
|
const codexHome =
|
|
55
68
|
opts.codexHome || process.env.CODEX_HOME || join(homedir(), ".codex");
|
|
56
69
|
let model = null;
|
|
@@ -63,9 +76,22 @@ export function codexProfileConfigOverrides(profileName, opts = {}) {
|
|
|
63
76
|
model = readProfileScalar(raw, "model");
|
|
64
77
|
effort = readProfileScalar(raw, "model_reasoning_effort");
|
|
65
78
|
} catch {
|
|
66
|
-
const suffix = /_(xhigh|high|med|medium|low)$/.exec(profileName);
|
|
79
|
+
const suffix = /_(ultra|max|xhigh|high|med|medium|low)$/.exec(profileName);
|
|
67
80
|
if (suffix) effort = EFFORT_BY_SUFFIX[suffix[1]] || null;
|
|
68
81
|
}
|
|
82
|
+
return { model, effort };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function codexProfileConfigOverrides(profileName, opts = {}) {
|
|
86
|
+
let { model, effort } = resolveCodexProfileConfigValues(profileName, opts);
|
|
87
|
+
if (opts.enforceCanonicalProfile === true) {
|
|
88
|
+
const canonical = CANONICAL_PROFILE_VALUES[profileName];
|
|
89
|
+
if (canonical) ({ model, effort } = canonical);
|
|
90
|
+
}
|
|
91
|
+
if (opts.disallowUltra === true && effort?.toLowerCase() === "ultra") {
|
|
92
|
+
model = "gpt-5.6-sol";
|
|
93
|
+
effort = "max";
|
|
94
|
+
}
|
|
69
95
|
const overrides = [];
|
|
70
96
|
if (model) overrides.push(`model="${model}"`);
|
|
71
97
|
if (effort) overrides.push(`model_reasoning_effort="${effort}"`);
|
|
@@ -26,6 +26,7 @@ function normalizeState(state) {
|
|
|
26
26
|
|
|
27
27
|
function normalizeRule(rule) {
|
|
28
28
|
if (!rule || typeof rule !== "object") return null;
|
|
29
|
+
if (rule.disabled === true) return null;
|
|
29
30
|
if (typeof rule.id !== "string" || !rule.id.trim()) return null;
|
|
30
31
|
if (!Array.isArray(rule.patterns) || rule.patterns.length === 0) return null;
|
|
31
32
|
if (typeof rule.priority !== "number" || !Number.isFinite(rule.priority))
|
|
@@ -61,6 +62,13 @@ function normalizeRule(rule) {
|
|
|
61
62
|
const state = normalizeState(rule.state);
|
|
62
63
|
if (rule.state != null && state == null) return null;
|
|
63
64
|
|
|
65
|
+
// repo_scope: path segment 화이트리스트 (빈 배열 = 전역). explicit: 종결 라우팅 마커.
|
|
66
|
+
const repoScope = Array.isArray(rule.repo_scope)
|
|
67
|
+
? rule.repo_scope
|
|
68
|
+
.filter((s) => typeof s === "string" && s.trim())
|
|
69
|
+
.map((s) => s.trim())
|
|
70
|
+
: [];
|
|
71
|
+
|
|
64
72
|
return {
|
|
65
73
|
id: rule.id.trim(),
|
|
66
74
|
patterns,
|
|
@@ -72,6 +80,8 @@ function normalizeRule(rule) {
|
|
|
72
80
|
exclusive: rule.exclusive === true,
|
|
73
81
|
state,
|
|
74
82
|
mcp_route: mcpRoute,
|
|
83
|
+
repo_scope: repoScope,
|
|
84
|
+
explicit: rule.explicit === true,
|
|
75
85
|
};
|
|
76
86
|
}
|
|
77
87
|
|
|
@@ -149,6 +159,8 @@ export function matchRules(compiledRules, cleanText) {
|
|
|
149
159
|
exclusive: rule.exclusive === true,
|
|
150
160
|
state: rule.state || null,
|
|
151
161
|
mcp_route: rule.mcp_route || null,
|
|
162
|
+
repo_scope: rule.repo_scope || [],
|
|
163
|
+
explicit: rule.explicit === true,
|
|
152
164
|
});
|
|
153
165
|
}
|
|
154
166
|
|