@triflux/remote 10.41.1 → 10.43.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/cto/hygiene-actions.mjs +355 -0
- package/cto/hygiene.mjs +79 -9
- package/cto/steward.mjs +362 -0
- package/hub/log-retention.mjs +726 -0
- package/hub/pipe.mjs +5 -1
- package/hub/public/tray.html +50 -53
- package/hub/schema.sql +149 -0
- package/hub/server.mjs +44 -22
- package/hub/store.mjs +37 -19
- package/hub/team/claude-daemon-control.mjs +33 -12
- package/hub/team/cli/commands/start/parse-args.mjs +2 -2
- package/hub/team/headless.mjs +275 -24
- package/hub/team/intervention.mjs +530 -0
- package/hub/team/retry-state-machine.mjs +6 -2
- package/hub/team/swarm-hypervisor.mjs +19 -2
- package/hub/team/swarm-locks.mjs +17 -1
- package/hub/team/uds-orchestrator.mjs +62 -9
- package/hub/tools.mjs +5 -7
- package/hub/workers/codex-app-server-worker.mjs +54 -5
- package/hub/workers/codex-mcp.mjs +1 -1
- package/hub/workers/delegator-mcp.mjs +18 -18
- package/package.json +1 -1
- package/scripts/lib/cli-agy.mjs +1 -0
- package/scripts/lib/cli-claude.mjs +1 -0
- package/scripts/lib/cli-codex.mjs +22 -21
- package/scripts/lib/codex-profile-config.mjs +2 -2
|
@@ -6,6 +6,11 @@ import { tmpdir } from "node:os";
|
|
|
6
6
|
import { join as pathJoin } from "node:path";
|
|
7
7
|
|
|
8
8
|
import { execute as defaultExecuteCodex } from "@triflux/core/hub/codex-adapter.mjs";
|
|
9
|
+
import {
|
|
10
|
+
createActivityLifecycle,
|
|
11
|
+
isActivityLifecycleEnabled,
|
|
12
|
+
resolveHardCeilingMs,
|
|
13
|
+
} from "@triflux/core/hub/lib/worker-lifecycle.mjs";
|
|
9
14
|
import { JsonRpcWsUdsClient } from "../workers/lib/jsonrpc-ws-uds.mjs";
|
|
10
15
|
import {
|
|
11
16
|
buildClaudePromptDispatchPayload,
|
|
@@ -141,8 +146,11 @@ export async function runUdsOrchestration({ mode, task, claude, codex } = {}) {
|
|
|
141
146
|
throw new Error(`Unsupported UDS orchestration mode: ${selectedMode}`);
|
|
142
147
|
}
|
|
143
148
|
|
|
144
|
-
function scanMessage(message, marker, state) {
|
|
149
|
+
function scanMessage(message, marker, state, onActivity = () => {}) {
|
|
145
150
|
const scan = (text) => {
|
|
151
|
+
// Only stream/snapshot content advances liveness. "state" heartbeats do
|
|
152
|
+
// not keep an otherwise silent turn alive forever.
|
|
153
|
+
onActivity();
|
|
146
154
|
state.streamBytes += Buffer.byteLength(text);
|
|
147
155
|
state.stream.push(text);
|
|
148
156
|
if (/⏺/.test(stripAnsi(text))) state.assistantStarted = true;
|
|
@@ -167,7 +175,10 @@ export function subscribeClaudeUntilMarker(
|
|
|
167
175
|
controlSock,
|
|
168
176
|
short,
|
|
169
177
|
marker,
|
|
170
|
-
{
|
|
178
|
+
{
|
|
179
|
+
timeoutMs = DEFAULT_TIMEOUT_MS,
|
|
180
|
+
maxTurnMs = Math.min(resolveHardCeilingMs(), 15 * 60_000),
|
|
181
|
+
} = {},
|
|
171
182
|
) {
|
|
172
183
|
return new Promise((resolve) => {
|
|
173
184
|
const socket = net.connect(controlSock);
|
|
@@ -185,7 +196,23 @@ export function subscribeClaudeUntilMarker(
|
|
|
185
196
|
stream: [],
|
|
186
197
|
assistantStarted: false,
|
|
187
198
|
};
|
|
188
|
-
const
|
|
199
|
+
const activityEnabled = isActivityLifecycleEnabled();
|
|
200
|
+
const lifecycle = createActivityLifecycle({
|
|
201
|
+
enabled: activityEnabled,
|
|
202
|
+
interventionMs: timeoutMs,
|
|
203
|
+
hardCeilingMs: maxTurnMs,
|
|
204
|
+
});
|
|
205
|
+
let timer = null;
|
|
206
|
+
|
|
207
|
+
const armTimer = () => {
|
|
208
|
+
timer = setTimeout(async () => {
|
|
209
|
+
if (!activityEnabled) return finish({ timedOut: true });
|
|
210
|
+
const reason = await lifecycle.check();
|
|
211
|
+
if (reason) return finish({ timedOut: true, timeoutReason: reason });
|
|
212
|
+
armTimer();
|
|
213
|
+
}, timeoutMs);
|
|
214
|
+
};
|
|
215
|
+
armTimer();
|
|
189
216
|
|
|
190
217
|
function finish(extra = {}) {
|
|
191
218
|
if (finished) return;
|
|
@@ -209,7 +236,9 @@ export function subscribeClaudeUntilMarker(
|
|
|
209
236
|
data = data.slice(index + 1);
|
|
210
237
|
if (!line) continue;
|
|
211
238
|
try {
|
|
212
|
-
scanMessage(JSON.parse(line), marker, state)
|
|
239
|
+
scanMessage(JSON.parse(line), marker, state, () =>
|
|
240
|
+
lifecycle.observe(),
|
|
241
|
+
);
|
|
213
242
|
} catch (_error) {
|
|
214
243
|
state.messageCount += 1;
|
|
215
244
|
}
|
|
@@ -263,6 +292,7 @@ export function createClaudeUdsEndpoint({
|
|
|
263
292
|
daemonPaths = deriveClaudeDaemonPaths(),
|
|
264
293
|
cwd = process.cwd(),
|
|
265
294
|
timeoutMs = DEFAULT_TIMEOUT_MS,
|
|
295
|
+
maxTurnMs = Math.min(resolveHardCeilingMs(), 15 * 60_000),
|
|
266
296
|
markerFactory = () =>
|
|
267
297
|
`TFX_UDS_ORCH_DONE_${crypto.randomBytes(6).toString("hex")}`,
|
|
268
298
|
shortFactory,
|
|
@@ -299,7 +329,7 @@ export function createClaudeUdsEndpoint({
|
|
|
299
329
|
sock,
|
|
300
330
|
payload.short,
|
|
301
331
|
marker,
|
|
302
|
-
{ timeoutMs },
|
|
332
|
+
{ timeoutMs, maxTurnMs },
|
|
303
333
|
);
|
|
304
334
|
await teardownDaemonJob({
|
|
305
335
|
controlSock: sock,
|
|
@@ -441,6 +471,7 @@ export function createCodexAppServerUdsEndpoint({
|
|
|
441
471
|
cwd = process.cwd(),
|
|
442
472
|
model,
|
|
443
473
|
timeoutMs = DEFAULT_CODEX_APP_SERVER_UDS_TIMEOUT_MS,
|
|
474
|
+
maxTurnMs = Math.min(resolveHardCeilingMs(), 15 * 60_000),
|
|
444
475
|
bootstrapTimeoutMs = DEFAULT_CODEX_APP_SERVER_UDS_BOOTSTRAP_MS,
|
|
445
476
|
clientFactory = (opts) => new JsonRpcWsUdsClient(opts),
|
|
446
477
|
spawnFn = spawn,
|
|
@@ -536,10 +567,12 @@ export function createCodexAppServerUdsEndpoint({
|
|
|
536
567
|
let offDelta = () => {};
|
|
537
568
|
let offError = () => {};
|
|
538
569
|
let offDone = () => {};
|
|
570
|
+
let offActivity = () => {};
|
|
539
571
|
const cleanup = () => {
|
|
540
572
|
offDelta();
|
|
541
573
|
offError();
|
|
542
574
|
offDone();
|
|
575
|
+
offActivity();
|
|
543
576
|
};
|
|
544
577
|
const completion = new Promise((resolve) => {
|
|
545
578
|
offDelta = client.onNotification(
|
|
@@ -566,12 +599,32 @@ export function createCodexAppServerUdsEndpoint({
|
|
|
566
599
|
{ threadId, input: [{ type: "text", text: prompt }] },
|
|
567
600
|
timeoutMs,
|
|
568
601
|
);
|
|
602
|
+
const activityEnabled = isActivityLifecycleEnabled();
|
|
603
|
+
const lifecycle = createActivityLifecycle({
|
|
604
|
+
enabled: activityEnabled,
|
|
605
|
+
interventionMs: timeoutMs,
|
|
606
|
+
hardCeilingMs: maxTurnMs,
|
|
607
|
+
});
|
|
608
|
+
offActivity = client.onNotification("*", () => lifecycle.observe());
|
|
569
609
|
let timeoutHandle = null;
|
|
570
610
|
const timeoutPromise = new Promise((resolve) => {
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
611
|
+
const arm = () => {
|
|
612
|
+
timeoutHandle = setTimeout(async () => {
|
|
613
|
+
if (!activityEnabled) {
|
|
614
|
+
cleanup();
|
|
615
|
+
resolve({ status: "timeout" });
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
const reason = await lifecycle.check();
|
|
619
|
+
if (reason) {
|
|
620
|
+
cleanup();
|
|
621
|
+
resolve({ status: "timeout", reason });
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
arm();
|
|
625
|
+
}, timeoutMs);
|
|
626
|
+
};
|
|
627
|
+
arm();
|
|
575
628
|
});
|
|
576
629
|
let settled;
|
|
577
630
|
try {
|
package/hub/tools.mjs
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from "@triflux/core/hub/pipeline/state.mjs";
|
|
11
11
|
import { sendInputToConductorSession } from "./team/conductor-registry.mjs";
|
|
12
12
|
import { getTeamBridge } from "@triflux/core/hub/team-bridge.mjs";
|
|
13
|
+
import { DEFAULT_ASSIGN_TIMEOUT_MS, DEFAULT_ASSIGN_TTL_MS, DEFAULT_HANDOFF_TTL_MS } from "@triflux/core/hub/lib/timeout-defaults.mjs";
|
|
13
14
|
|
|
14
15
|
const TEAM_BRIDGE_NOT_REGISTERED = "bridge_not_registered";
|
|
15
16
|
|
|
@@ -155,10 +156,7 @@ export function createTools(store, router, hitl, pipe = null) {
|
|
|
155
156
|
},
|
|
156
157
|
},
|
|
157
158
|
},
|
|
158
|
-
handler: wrap("REGISTER_FAILED", (args) =>
|
|
159
|
-
const data = router.registerAgent(args);
|
|
160
|
-
return { ok: true, data };
|
|
161
|
-
}),
|
|
159
|
+
handler: wrap("REGISTER_FAILED", (args) => router.registerAgent(args)),
|
|
162
160
|
},
|
|
163
161
|
|
|
164
162
|
// ── 2. status ──
|
|
@@ -362,7 +360,7 @@ export function createTools(store, router, hitl, pipe = null) {
|
|
|
362
360
|
type: "integer",
|
|
363
361
|
minimum: 1000,
|
|
364
362
|
maximum: 86400000,
|
|
365
|
-
default:
|
|
363
|
+
default: DEFAULT_HANDOFF_TTL_MS,
|
|
366
364
|
},
|
|
367
365
|
trace_id: { type: "string" },
|
|
368
366
|
correlation_id: { type: "string" },
|
|
@@ -399,13 +397,13 @@ export function createTools(store, router, hitl, pipe = null) {
|
|
|
399
397
|
type: "integer",
|
|
400
398
|
minimum: 1000,
|
|
401
399
|
maximum: 86400000,
|
|
402
|
-
default:
|
|
400
|
+
default: DEFAULT_ASSIGN_TTL_MS,
|
|
403
401
|
},
|
|
404
402
|
timeout_ms: {
|
|
405
403
|
type: "integer",
|
|
406
404
|
minimum: 1000,
|
|
407
405
|
maximum: 86400000,
|
|
408
|
-
default:
|
|
406
|
+
default: DEFAULT_ASSIGN_TIMEOUT_MS,
|
|
409
407
|
},
|
|
410
408
|
max_retries: { type: "integer", minimum: 0, maximum: 20, default: 0 },
|
|
411
409
|
trace_id: { type: "string" },
|
|
@@ -12,6 +12,12 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
12
12
|
import { isAbsolute } from "node:path";
|
|
13
13
|
import process from "node:process";
|
|
14
14
|
|
|
15
|
+
import {
|
|
16
|
+
createActivityLifecycle,
|
|
17
|
+
isActivityLifecycleEnabled,
|
|
18
|
+
resolveHardCeilingMs,
|
|
19
|
+
resolveStallInterventionMs,
|
|
20
|
+
} from "@triflux/core/hub/lib/worker-lifecycle.mjs";
|
|
15
21
|
import {
|
|
16
22
|
JsonRpcProtocolError,
|
|
17
23
|
JsonRpcStdioClient,
|
|
@@ -25,6 +31,7 @@ export const CODEX_APP_SERVER_TRANSPORT_EXIT_CODE = 70;
|
|
|
25
31
|
export const CODEX_APP_SERVER_TIMEOUT_EXIT_CODE = 124;
|
|
26
32
|
|
|
27
33
|
export const DEFAULT_CODEX_APP_SERVER_BOOTSTRAP_TIMEOUT_MS = 10_000;
|
|
34
|
+
// Legacy wall-clock default retained for TFX_ACTIVITY_LIFECYCLE=0 compatibility.
|
|
28
35
|
export const DEFAULT_CODEX_APP_SERVER_EXECUTION_TIMEOUT_MS = 10 * 60 * 1000;
|
|
29
36
|
export const DEFAULT_UNKNOWN_METHOD_WARN_THRESHOLD = 5;
|
|
30
37
|
/**
|
|
@@ -327,6 +334,7 @@ export class CodexAppServerWorker {
|
|
|
327
334
|
* @param {number} [options.unknownMethodWarnThreshold]
|
|
328
335
|
* @param {(method: string) => void} [options.onUnknownMethod]
|
|
329
336
|
* @param {(label: string, payload: object) => void} [options.warn]
|
|
337
|
+
* @param {(context: object) => Promise<boolean|string>|boolean|string} [options.interveneFn]
|
|
330
338
|
*/
|
|
331
339
|
constructor(options = {}) {
|
|
332
340
|
this.command = options.command || process.env.CODEX_BIN || "codex";
|
|
@@ -370,6 +378,8 @@ export class CodexAppServerWorker {
|
|
|
370
378
|
typeof options.onUnknownMethod === "function"
|
|
371
379
|
? options.onUnknownMethod
|
|
372
380
|
: null;
|
|
381
|
+
this._interveneFn =
|
|
382
|
+
typeof options.interveneFn === "function" ? options.interveneFn : null;
|
|
373
383
|
|
|
374
384
|
/** @type {import('node:child_process').ChildProcess | null} */
|
|
375
385
|
this.child = null;
|
|
@@ -643,6 +653,8 @@ export class CodexAppServerWorker {
|
|
|
643
653
|
}
|
|
644
654
|
|
|
645
655
|
const outputParts = [];
|
|
656
|
+
let lastActivityAt = Date.now();
|
|
657
|
+
let activityLifecycle = null;
|
|
646
658
|
const unknownMethodsThisTurn = new Set();
|
|
647
659
|
let threadId =
|
|
648
660
|
typeof opts.threadId === "string" && opts.threadId ? opts.threadId : null;
|
|
@@ -714,6 +726,10 @@ export class CodexAppServerWorker {
|
|
|
714
726
|
};
|
|
715
727
|
|
|
716
728
|
const handleNotification = (method, params) => {
|
|
729
|
+
// Any notification, including unknown and opt-out methods, proves the
|
|
730
|
+
// transport is live. Content filtering below remains unchanged.
|
|
731
|
+
lastActivityAt = Date.now();
|
|
732
|
+
activityLifecycle?.observe();
|
|
717
733
|
// AC5 defense: opt-out should already be filtered server-side.
|
|
718
734
|
if (OPT_OUT_METHODS.includes(method)) return;
|
|
719
735
|
|
|
@@ -854,16 +870,40 @@ export class CodexAppServerWorker {
|
|
|
854
870
|
};
|
|
855
871
|
}
|
|
856
872
|
|
|
857
|
-
//
|
|
873
|
+
// In activity mode timeoutMs is the inactivity window. Notifications
|
|
874
|
+
// re-arm the lifecycle; hardCeilingMs remains the leak-prevention bound.
|
|
875
|
+
const activityEnabled = isActivityLifecycleEnabled();
|
|
858
876
|
const timeoutMs = Number.isFinite(opts.timeoutMs)
|
|
859
877
|
? opts.timeoutMs
|
|
860
|
-
:
|
|
878
|
+
: activityEnabled
|
|
879
|
+
? resolveStallInterventionMs()
|
|
880
|
+
: DEFAULT_CODEX_APP_SERVER_EXECUTION_TIMEOUT_MS;
|
|
881
|
+
const hardCeilingMs = Number.isFinite(opts.hardCeilingMs)
|
|
882
|
+
? opts.hardCeilingMs
|
|
883
|
+
: resolveHardCeilingMs();
|
|
861
884
|
// Capture current child so a stale timer (post-result) cannot SIGTERM a
|
|
862
885
|
// later reused worker's child process.
|
|
863
886
|
const capturedChild = this.child;
|
|
887
|
+
activityLifecycle = createActivityLifecycle({
|
|
888
|
+
enabled: activityEnabled,
|
|
889
|
+
interventionMs: timeoutMs,
|
|
890
|
+
hardCeilingMs,
|
|
891
|
+
onIntervene: async (context) => {
|
|
892
|
+
if (this._interveneFn) {
|
|
893
|
+
const result = await this._interveneFn({
|
|
894
|
+
threadId,
|
|
895
|
+
client,
|
|
896
|
+
lastActivityAt,
|
|
897
|
+
...context,
|
|
898
|
+
});
|
|
899
|
+
return result === true || result === "resolved";
|
|
900
|
+
}
|
|
901
|
+
return false;
|
|
902
|
+
},
|
|
903
|
+
});
|
|
864
904
|
const timeoutPromise = new Promise((resolve) => {
|
|
865
|
-
|
|
866
|
-
this._warn("execution timeout", { timeoutMs });
|
|
905
|
+
const fire = (reason) => {
|
|
906
|
+
this._warn("execution timeout", { timeoutMs, reason });
|
|
867
907
|
try {
|
|
868
908
|
capturedChild?.kill?.("SIGTERM");
|
|
869
909
|
} catch {}
|
|
@@ -878,7 +918,16 @@ export class CodexAppServerWorker {
|
|
|
878
918
|
),
|
|
879
919
|
raw: null,
|
|
880
920
|
});
|
|
881
|
-
}
|
|
921
|
+
};
|
|
922
|
+
const arm = () => {
|
|
923
|
+
timer = setTimeout(async () => {
|
|
924
|
+
if (!activityEnabled) return fire("timeout");
|
|
925
|
+
const reason = await activityLifecycle.check({ threadId, client });
|
|
926
|
+
if (reason) return fire(reason);
|
|
927
|
+
arm();
|
|
928
|
+
}, timeoutMs);
|
|
929
|
+
};
|
|
930
|
+
arm();
|
|
882
931
|
});
|
|
883
932
|
|
|
884
933
|
const result = await Promise.race([resultPromise, timeoutPromise]);
|
|
@@ -119,7 +119,7 @@ function readTomlScalar(raw, key) {
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
/**
|
|
122
|
-
* Resolve a Codex effort profile name (e.g. "
|
|
122
|
+
* Resolve a Codex effort profile name (e.g. "gpt56_terra_high") to its concrete
|
|
123
123
|
* `model` + reasoning effort. SSOT = the per-profile file written by
|
|
124
124
|
* `tfx setup` at `~/.codex/<profile>.config.toml`. Falls back to deriving the
|
|
125
125
|
* effort from the `<...>_<effort>` naming convention when the file is absent.
|
|
@@ -64,24 +64,24 @@ const AGENT_TIMEOUT_SEC = Object.freeze({
|
|
|
64
64
|
});
|
|
65
65
|
|
|
66
66
|
const CODEX_PROFILE_BY_AGENT = Object.freeze({
|
|
67
|
-
executor: "
|
|
68
|
-
"build-fixer": "
|
|
69
|
-
debugger: "
|
|
70
|
-
"deep-executor": "
|
|
71
|
-
architect: "
|
|
72
|
-
planner: "
|
|
73
|
-
critic: "
|
|
74
|
-
analyst: "
|
|
75
|
-
"code-reviewer": "
|
|
76
|
-
"security-reviewer": "
|
|
77
|
-
"quality-reviewer": "
|
|
78
|
-
scientist: "
|
|
79
|
-
"scientist-deep": "
|
|
80
|
-
"document-specialist": "
|
|
81
|
-
verifier: "
|
|
82
|
-
designer: "
|
|
83
|
-
writer: "
|
|
84
|
-
spark: "
|
|
67
|
+
executor: "gpt56_terra_high",
|
|
68
|
+
"build-fixer": "gpt56_luna_low",
|
|
69
|
+
debugger: "gpt56_sol_xhigh",
|
|
70
|
+
"deep-executor": "gpt56_sol_xhigh",
|
|
71
|
+
architect: "gpt56_sol_xhigh",
|
|
72
|
+
planner: "gpt56_sol_xhigh",
|
|
73
|
+
critic: "gpt56_sol_xhigh",
|
|
74
|
+
analyst: "gpt56_sol_xhigh",
|
|
75
|
+
"code-reviewer": "gpt56_terra_high",
|
|
76
|
+
"security-reviewer": "gpt56_sol_xhigh",
|
|
77
|
+
"quality-reviewer": "gpt56_terra_high",
|
|
78
|
+
scientist: "gpt56_terra_high",
|
|
79
|
+
"scientist-deep": "gpt56_sol_xhigh",
|
|
80
|
+
"document-specialist": "gpt56_terra_high",
|
|
81
|
+
verifier: "gpt56_terra_high",
|
|
82
|
+
designer: "gpt56_sol_xhigh",
|
|
83
|
+
writer: "gpt56_luna_low",
|
|
84
|
+
spark: "gpt56_luna_low",
|
|
85
85
|
});
|
|
86
86
|
|
|
87
87
|
const REVIEW_INSTRUCTION_BY_AGENT = Object.freeze({
|
package/package.json
CHANGED
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";
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
//
|
|
6
6
|
// 진입점: tfx-route.mjs → selectAdapter("codex") → plan({...}).
|
|
7
7
|
// 출처: scripts/tfx-route.sh route_agent() L1001-L1079 case 문 미러.
|
|
8
|
+
// timeoutSec은 lane 예상 소요 시간(advisory)이다. hard ceiling 집행은 Bash route가 소유한다.
|
|
8
9
|
|
|
9
10
|
export const id = "codex";
|
|
10
11
|
export const cliType = "codex";
|
|
@@ -12,84 +13,84 @@ export const command = "codex";
|
|
|
12
13
|
|
|
13
14
|
const AGENT_PROFILES = {
|
|
14
15
|
executor: {
|
|
15
|
-
profile: "
|
|
16
|
+
profile: "gpt56_terra_high",
|
|
16
17
|
timeoutSec: 1080,
|
|
17
18
|
runMode: "fg",
|
|
18
19
|
opusOversight: false,
|
|
19
20
|
mcpHint: "implement",
|
|
20
21
|
},
|
|
21
22
|
codex: {
|
|
22
|
-
profile: "
|
|
23
|
+
profile: "gpt56_terra_high",
|
|
23
24
|
timeoutSec: 1080,
|
|
24
25
|
runMode: "fg",
|
|
25
26
|
opusOversight: false,
|
|
26
27
|
mcpHint: "implement",
|
|
27
28
|
},
|
|
28
29
|
"build-fixer": {
|
|
29
|
-
profile: "
|
|
30
|
+
profile: "gpt56_luna_low",
|
|
30
31
|
timeoutSec: 540,
|
|
31
32
|
runMode: "fg",
|
|
32
33
|
opusOversight: false,
|
|
33
34
|
mcpHint: "implement",
|
|
34
35
|
},
|
|
35
36
|
cleanup: {
|
|
36
|
-
profile: "
|
|
37
|
+
profile: "gpt56_terra_med",
|
|
37
38
|
timeoutSec: 540,
|
|
38
39
|
runMode: "fg",
|
|
39
40
|
opusOversight: false,
|
|
40
41
|
mcpHint: "implement",
|
|
41
42
|
},
|
|
42
43
|
deslop: {
|
|
43
|
-
profile: "
|
|
44
|
+
profile: "gpt56_terra_med",
|
|
44
45
|
timeoutSec: 540,
|
|
45
46
|
runMode: "fg",
|
|
46
47
|
opusOversight: false,
|
|
47
48
|
mcpHint: "implement",
|
|
48
49
|
},
|
|
49
50
|
debugger: {
|
|
50
|
-
profile: "
|
|
51
|
+
profile: "gpt56_sol_xhigh",
|
|
51
52
|
timeoutSec: 900,
|
|
52
53
|
runMode: "bg",
|
|
53
54
|
opusOversight: false,
|
|
54
55
|
mcpHint: "implement",
|
|
55
56
|
},
|
|
56
57
|
"deep-executor": {
|
|
57
|
-
profile: "
|
|
58
|
+
profile: "gpt56_sol_xhigh",
|
|
58
59
|
timeoutSec: 3600,
|
|
59
60
|
runMode: "bg",
|
|
60
61
|
opusOversight: true,
|
|
61
62
|
mcpHint: "implement",
|
|
62
63
|
},
|
|
63
64
|
architect: {
|
|
64
|
-
profile: "
|
|
65
|
+
profile: "gpt56_sol_xhigh",
|
|
65
66
|
timeoutSec: 3600,
|
|
66
67
|
runMode: "bg",
|
|
67
68
|
opusOversight: true,
|
|
68
69
|
mcpHint: "analyze",
|
|
69
70
|
},
|
|
70
71
|
critic: {
|
|
71
|
-
profile: "
|
|
72
|
+
profile: "gpt56_sol_xhigh",
|
|
72
73
|
timeoutSec: 3600,
|
|
73
74
|
runMode: "bg",
|
|
74
75
|
opusOversight: true,
|
|
75
76
|
mcpHint: "analyze",
|
|
76
77
|
},
|
|
77
78
|
planner: {
|
|
78
|
-
profile: "
|
|
79
|
+
profile: "gpt56_sol_xhigh",
|
|
79
80
|
timeoutSec: 3600,
|
|
80
81
|
runMode: "fg",
|
|
81
82
|
opusOversight: true,
|
|
82
83
|
mcpHint: "analyze",
|
|
83
84
|
},
|
|
84
85
|
analyst: {
|
|
85
|
-
profile: "
|
|
86
|
+
profile: "gpt56_sol_xhigh",
|
|
86
87
|
timeoutSec: 3600,
|
|
87
88
|
runMode: "fg",
|
|
88
89
|
opusOversight: true,
|
|
89
90
|
mcpHint: "analyze",
|
|
90
91
|
},
|
|
91
92
|
"code-reviewer": {
|
|
92
|
-
profile: "
|
|
93
|
+
profile: "gpt56_terra_high",
|
|
93
94
|
timeoutSec: 1800,
|
|
94
95
|
runMode: "bg",
|
|
95
96
|
opusOversight: false,
|
|
@@ -97,7 +98,7 @@ const AGENT_PROFILES = {
|
|
|
97
98
|
subcommand: "review",
|
|
98
99
|
},
|
|
99
100
|
"quality-reviewer": {
|
|
100
|
-
profile: "
|
|
101
|
+
profile: "gpt56_terra_high",
|
|
101
102
|
timeoutSec: 1800,
|
|
102
103
|
runMode: "bg",
|
|
103
104
|
opusOversight: false,
|
|
@@ -105,7 +106,7 @@ const AGENT_PROFILES = {
|
|
|
105
106
|
subcommand: "review",
|
|
106
107
|
},
|
|
107
108
|
"security-reviewer": {
|
|
108
|
-
profile: "
|
|
109
|
+
profile: "gpt56_sol_xhigh",
|
|
109
110
|
timeoutSec: 1800,
|
|
110
111
|
runMode: "bg",
|
|
111
112
|
opusOversight: true,
|
|
@@ -113,28 +114,28 @@ const AGENT_PROFILES = {
|
|
|
113
114
|
subcommand: "review",
|
|
114
115
|
},
|
|
115
116
|
scientist: {
|
|
116
|
-
profile: "
|
|
117
|
+
profile: "gpt56_terra_high",
|
|
117
118
|
timeoutSec: 1440,
|
|
118
119
|
runMode: "bg",
|
|
119
120
|
opusOversight: false,
|
|
120
121
|
mcpHint: "analyze",
|
|
121
122
|
},
|
|
122
123
|
"document-specialist": {
|
|
123
|
-
profile: "
|
|
124
|
+
profile: "gpt56_terra_high",
|
|
124
125
|
timeoutSec: 1440,
|
|
125
126
|
runMode: "bg",
|
|
126
127
|
opusOversight: false,
|
|
127
128
|
mcpHint: "analyze",
|
|
128
129
|
},
|
|
129
130
|
"scientist-deep": {
|
|
130
|
-
profile: "
|
|
131
|
+
profile: "gpt56_sol_xhigh",
|
|
131
132
|
timeoutSec: 3600,
|
|
132
133
|
runMode: "bg",
|
|
133
134
|
opusOversight: false,
|
|
134
135
|
mcpHint: "analyze",
|
|
135
136
|
},
|
|
136
137
|
verifier: {
|
|
137
|
-
profile: "
|
|
138
|
+
profile: "gpt56_terra_high",
|
|
138
139
|
timeoutSec: 1200,
|
|
139
140
|
runMode: "fg",
|
|
140
141
|
opusOversight: false,
|
|
@@ -142,14 +143,14 @@ const AGENT_PROFILES = {
|
|
|
142
143
|
subcommand: "review",
|
|
143
144
|
},
|
|
144
145
|
"test-engineer": {
|
|
145
|
-
profile: "
|
|
146
|
+
profile: "gpt56_terra_high",
|
|
146
147
|
timeoutSec: 1200,
|
|
147
148
|
runMode: "bg",
|
|
148
149
|
opusOversight: false,
|
|
149
150
|
mcpHint: "implement",
|
|
150
151
|
},
|
|
151
152
|
"qa-tester": {
|
|
152
|
-
profile: "
|
|
153
|
+
profile: "gpt56_terra_high",
|
|
153
154
|
timeoutSec: 1200,
|
|
154
155
|
runMode: "bg",
|
|
155
156
|
opusOversight: false,
|
|
@@ -157,7 +158,7 @@ const AGENT_PROFILES = {
|
|
|
157
158
|
subcommand: "review",
|
|
158
159
|
},
|
|
159
160
|
spark: {
|
|
160
|
-
profile: "
|
|
161
|
+
profile: "gpt56_luna_low",
|
|
161
162
|
timeoutSec: 180,
|
|
162
163
|
runMode: "fg",
|
|
163
164
|
opusOversight: false,
|
|
@@ -29,7 +29,7 @@ function readProfileScalar(raw, key) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* Resolve a Codex effort profile name (e.g. "
|
|
32
|
+
* Resolve a Codex effort profile name (e.g. "gpt56_terra_high") to the `-c key=value`
|
|
33
33
|
* config overrides that `codex exec` accepts, so the headless CLI lanes can
|
|
34
34
|
* select a profile WITHOUT `codex exec --profile <name>`. codex 0.134+ rejects
|
|
35
35
|
* `--profile X` whenever config.toml still contains an inline `[profiles.X]`
|
|
@@ -47,7 +47,7 @@ function readProfileScalar(raw, key) {
|
|
|
47
47
|
*
|
|
48
48
|
* @param {string} profileName
|
|
49
49
|
* @param {{ codexHome?: string }} [opts]
|
|
50
|
-
* @returns {string[]} e.g. ['model="gpt-5.
|
|
50
|
+
* @returns {string[]} e.g. ['model="gpt-5.6-terra"', 'model_reasoning_effort="high"']
|
|
51
51
|
*/
|
|
52
52
|
export function codexProfileConfigOverrides(profileName, opts = {}) {
|
|
53
53
|
if (typeof profileName !== "string" || !profileName) return [];
|