@triflux/core 10.43.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.
@@ -4,169 +4,23 @@
4
4
  // 산출한다. 실제 spawn 은 Phase 1 에서 이관된다 (현재는 tfx-route.sh 가 수행).
5
5
  //
6
6
  // 진입점: tfx-route.mjs → selectAdapter("codex") → plan({...}).
7
- // 출처: scripts/tfx-route.sh route_agent() L1001-L1079 case 문 미러.
7
+ // 출처: agent-route-policy.mjs 의 canonical Codex role policy.
8
8
  // timeoutSec은 lane 예상 소요 시간(advisory)이다. hard ceiling 집행은 Bash route가 소유한다.
9
9
 
10
10
  export const id = "codex";
11
11
  export const cliType = "codex";
12
12
  export const command = "codex";
13
13
 
14
- const AGENT_PROFILES = {
15
- executor: {
16
- profile: "gpt56_terra_high",
17
- timeoutSec: 1080,
18
- runMode: "fg",
19
- opusOversight: false,
20
- mcpHint: "implement",
21
- },
22
- codex: {
23
- profile: "gpt56_terra_high",
24
- timeoutSec: 1080,
25
- runMode: "fg",
26
- opusOversight: false,
27
- mcpHint: "implement",
28
- },
29
- "build-fixer": {
30
- profile: "gpt56_luna_low",
31
- timeoutSec: 540,
32
- runMode: "fg",
33
- opusOversight: false,
34
- mcpHint: "implement",
35
- },
36
- cleanup: {
37
- profile: "gpt56_terra_med",
38
- timeoutSec: 540,
39
- runMode: "fg",
40
- opusOversight: false,
41
- mcpHint: "implement",
42
- },
43
- deslop: {
44
- profile: "gpt56_terra_med",
45
- timeoutSec: 540,
46
- runMode: "fg",
47
- opusOversight: false,
48
- mcpHint: "implement",
49
- },
50
- debugger: {
51
- profile: "gpt56_sol_xhigh",
52
- timeoutSec: 900,
53
- runMode: "bg",
54
- opusOversight: false,
55
- mcpHint: "implement",
56
- },
57
- "deep-executor": {
58
- profile: "gpt56_sol_xhigh",
59
- timeoutSec: 3600,
60
- runMode: "bg",
61
- opusOversight: true,
62
- mcpHint: "implement",
63
- },
64
- architect: {
65
- profile: "gpt56_sol_xhigh",
66
- timeoutSec: 3600,
67
- runMode: "bg",
68
- opusOversight: true,
69
- mcpHint: "analyze",
70
- },
71
- critic: {
72
- profile: "gpt56_sol_xhigh",
73
- timeoutSec: 3600,
74
- runMode: "bg",
75
- opusOversight: true,
76
- mcpHint: "analyze",
77
- },
78
- planner: {
79
- profile: "gpt56_sol_xhigh",
80
- timeoutSec: 3600,
81
- runMode: "fg",
82
- opusOversight: true,
83
- mcpHint: "analyze",
84
- },
85
- analyst: {
86
- profile: "gpt56_sol_xhigh",
87
- timeoutSec: 3600,
88
- runMode: "fg",
89
- opusOversight: true,
90
- mcpHint: "analyze",
91
- },
92
- "code-reviewer": {
93
- profile: "gpt56_terra_high",
94
- timeoutSec: 1800,
95
- runMode: "bg",
96
- opusOversight: false,
97
- mcpHint: "review",
98
- subcommand: "review",
99
- },
100
- "quality-reviewer": {
101
- profile: "gpt56_terra_high",
102
- timeoutSec: 1800,
103
- runMode: "bg",
104
- opusOversight: false,
105
- mcpHint: "review",
106
- subcommand: "review",
107
- },
108
- "security-reviewer": {
109
- profile: "gpt56_sol_xhigh",
110
- timeoutSec: 1800,
111
- runMode: "bg",
112
- opusOversight: true,
113
- mcpHint: "review",
114
- subcommand: "review",
115
- },
116
- scientist: {
117
- profile: "gpt56_terra_high",
118
- timeoutSec: 1440,
119
- runMode: "bg",
120
- opusOversight: false,
121
- mcpHint: "analyze",
122
- },
123
- "document-specialist": {
124
- profile: "gpt56_terra_high",
125
- timeoutSec: 1440,
126
- runMode: "bg",
127
- opusOversight: false,
128
- mcpHint: "analyze",
129
- },
130
- "scientist-deep": {
131
- profile: "gpt56_sol_xhigh",
132
- timeoutSec: 3600,
133
- runMode: "bg",
134
- opusOversight: false,
135
- mcpHint: "analyze",
136
- },
137
- verifier: {
138
- profile: "gpt56_terra_high",
139
- timeoutSec: 1200,
140
- runMode: "fg",
141
- opusOversight: false,
142
- mcpHint: "review",
143
- subcommand: "review",
144
- },
145
- "test-engineer": {
146
- profile: "gpt56_terra_high",
147
- timeoutSec: 1200,
148
- runMode: "bg",
149
- opusOversight: false,
150
- mcpHint: "implement",
151
- },
152
- "qa-tester": {
153
- profile: "gpt56_terra_high",
154
- timeoutSec: 1200,
155
- runMode: "bg",
156
- opusOversight: false,
157
- mcpHint: "review",
158
- subcommand: "review",
159
- },
160
- spark: {
161
- profile: "gpt56_luna_low",
162
- timeoutSec: 180,
163
- runMode: "fg",
164
- opusOversight: false,
165
- mcpHint: "implement",
166
- },
167
- };
14
+ import {
15
+ CODEX_AGENT_POLICY,
16
+ resolveCodexAgentPolicy,
17
+ resolveCodexAgentProfile,
18
+ resolveNestedCodexAgentProfile,
19
+ } from "./agent-route-policy.mjs";
168
20
 
169
- const DEFAULT_PROFILE = AGENT_PROFILES.executor;
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 };
170
24
 
171
25
  export function plan({
172
26
  agent,
@@ -174,18 +28,26 @@ export function plan({
174
28
  mcpProfile = "auto",
175
29
  timeoutSec,
176
30
  contextFile,
31
+ profileOverride = "auto",
32
+ retryProfile = null,
33
+ nested = false,
177
34
  } = {}) {
178
35
  if (!agent) {
179
36
  throw new Error("[cli-codex] agent required");
180
37
  }
181
- const cfg = AGENT_PROFILES[agent] ?? DEFAULT_PROFILE;
38
+ const cfg = resolveCodexAgentPolicy(agent);
39
+ const profile = resolveCodexAgentProfile(agent, {
40
+ profileOverride,
41
+ retryProfile,
42
+ nested,
43
+ });
182
44
  const effectiveTimeoutSec =
183
45
  Number.isFinite(timeoutSec) && timeoutSec > 0 ? timeoutSec : cfg.timeoutSec;
184
46
  return {
185
47
  command,
186
48
  subcommand: cfg.subcommand ?? "exec",
187
- profile: cfg.profile,
188
- effort: cfg.profile,
49
+ profile,
50
+ effort: profile,
189
51
  timeoutMs: effectiveTimeoutSec * 1000,
190
52
  runMode: cfg.runMode,
191
53
  opusOversight: cfg.opusOversight,
@@ -196,5 +58,5 @@ export function plan({
196
58
  }
197
59
 
198
60
  export function describe() {
199
- return { id, cliType, command, agents: Object.keys(AGENT_PROFILES) };
61
+ return { id, cliType, command, agents: Object.keys(CODEX_AGENT_POLICY) };
200
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(
@@ -49,8 +60,10 @@ function readProfileScalar(raw, key) {
49
60
  * @param {{ codexHome?: string }} [opts]
50
61
  * @returns {string[]} e.g. ['model="gpt-5.6-terra"', 'model_reasoning_effort="high"']
51
62
  */
52
- export function codexProfileConfigOverrides(profileName, opts = {}) {
53
- if (typeof profileName !== "string" || !profileName) return [];
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