@bitkyc08/opencodex 2.7.2 → 2.7.4-preview.20260710
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/README.ko.md +1 -1
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/gui/dist/assets/{index-DGFbiUtS.js → index-DulXo5ZJ.js} +5 -5
- package/gui/dist/index.html +1 -1
- package/package.json +1 -1
- package/src/cli/debug.ts +19 -6
- package/src/lib/debug-settings.ts +14 -2
- package/src/server/management-api.ts +4 -3
- package/src/server/responses.ts +45 -84
package/gui/dist/index.html
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
} catch (e) {}
|
|
17
17
|
})();
|
|
18
18
|
</script>
|
|
19
|
-
<script type="module" crossorigin src="/assets/index-
|
|
19
|
+
<script type="module" crossorigin src="/assets/index-DulXo5ZJ.js"></script>
|
|
20
20
|
<link rel="stylesheet" crossorigin href="/assets/index-D7o1qwy-.css">
|
|
21
21
|
</head>
|
|
22
22
|
<body>
|
package/package.json
CHANGED
package/src/cli/debug.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { findLiveProxy, probeHostname } from "../server/proxy-liveness";
|
|
|
2
2
|
import { DEBUG_ENV, type DebugSettingsView } from "../lib/debug-settings";
|
|
3
3
|
import { runningProxyUpdateHeaders } from "../oauth/login-cli";
|
|
4
4
|
|
|
5
|
-
type DebugScope = "provider" | "usage";
|
|
5
|
+
type DebugScope = "provider" | "usage" | "injection";
|
|
6
6
|
|
|
7
7
|
async function requireLiveProxy() {
|
|
8
8
|
const live = await findLiveProxy();
|
|
@@ -50,10 +50,14 @@ function printScopeStatus(scope: DebugScope, view: DebugSettingsView): void {
|
|
|
50
50
|
console.log(`Provider debug: ${view.enabled ? "ON" : "off"}`);
|
|
51
51
|
console.log(` env=${view.env.debug ? "on" : "off"}, runtime=${view.runtimeOverride.debug === undefined ? "env/default" : view.runtimeOverride.debug ? "on" : "off"}`);
|
|
52
52
|
console.log(" Tail: ocx debug provider logs [-f]");
|
|
53
|
-
} else {
|
|
53
|
+
} else if (scope === "usage") {
|
|
54
54
|
console.log(`Usage debug: ${view.usage ? "ON" : "off"}`);
|
|
55
55
|
console.log(` env=${view.env.usage ? "on" : "off"}, runtime=${view.runtimeOverride.usage === undefined ? "env/default" : view.runtimeOverride.usage ? "on" : "off"}`);
|
|
56
56
|
console.log(" Tail: ocx debug usage logs [-f] (via running proxy API)");
|
|
57
|
+
} else {
|
|
58
|
+
console.log(`Injection debug: ${view.injection ? "ON" : "off"}`);
|
|
59
|
+
console.log(` env=${view.env.injection ? "on" : "off"}, runtime=${view.runtimeOverride.injection === undefined ? "env/default" : view.runtimeOverride.injection ? "on" : "off"}`);
|
|
60
|
+
console.log(" Lines appear on the proxy console when multi-agent guidance is injected.");
|
|
57
61
|
}
|
|
58
62
|
}
|
|
59
63
|
|
|
@@ -138,7 +142,7 @@ async function handleScopeCommand(scope: DebugScope, actionArgv: string[]): Prom
|
|
|
138
142
|
|
|
139
143
|
if (action === "on" || action === "off") {
|
|
140
144
|
const enabled = action === "on";
|
|
141
|
-
const body = scope === "provider" ? { debug: enabled } : { usage: enabled };
|
|
145
|
+
const body = scope === "provider" ? { debug: enabled } : scope === "usage" ? { usage: enabled } : { injection: enabled };
|
|
142
146
|
printScopeStatus(scope, await putDebugSettings(body));
|
|
143
147
|
console.log(`\n${scope} debug is now ${enabled ? "enabled" : "disabled"}.`);
|
|
144
148
|
return;
|
|
@@ -150,20 +154,26 @@ async function handleScopeCommand(scope: DebugScope, actionArgv: string[]): Prom
|
|
|
150
154
|
}
|
|
151
155
|
|
|
152
156
|
if (action === "reset") {
|
|
153
|
-
const resetKey = scope === "provider" ? "provider" :
|
|
157
|
+
const resetKey = scope === "provider" ? "provider" : scope;
|
|
154
158
|
printScopeStatus(scope, await putDebugSettings({ reset: resetKey }));
|
|
155
159
|
console.log(`\nRuntime override cleared for ${scope}; effective value follows env again.`);
|
|
156
160
|
return;
|
|
157
161
|
}
|
|
158
162
|
|
|
159
163
|
if (action === "logs") {
|
|
164
|
+
if (scope === "injection") {
|
|
165
|
+
console.error("Injection debug has no buffered log stream; lines print on the proxy console.");
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
160
168
|
const follow = actionArgv.slice(1).some(arg => arg === "-f" || arg === "--follow");
|
|
161
169
|
if (scope === "provider") await printProviderLogs(follow);
|
|
162
170
|
else await printUsageLogs(follow);
|
|
163
171
|
return;
|
|
164
172
|
}
|
|
165
173
|
|
|
166
|
-
console.error(
|
|
174
|
+
console.error(scope === "injection"
|
|
175
|
+
? "Usage: ocx debug injection on|off|status|reset"
|
|
176
|
+
: `Usage: ocx debug ${scope} on|off|status|reset|logs [-f]`);
|
|
167
177
|
process.exit(1);
|
|
168
178
|
}
|
|
169
179
|
|
|
@@ -172,16 +182,18 @@ function printTopLevelHelp(): void {
|
|
|
172
182
|
console.log("");
|
|
173
183
|
console.log(" ocx debug provider on|off|status|reset|logs [-f]");
|
|
174
184
|
console.log(" ocx debug usage on|off|status|reset|logs [-f]");
|
|
185
|
+
console.log(" ocx debug injection on|off|status|reset");
|
|
175
186
|
console.log("");
|
|
176
187
|
console.log("Env defaults on start:");
|
|
177
188
|
console.log(" provider → OCX_DEBUG=1 (legacy OCX_DEBUG_FRAMES still works)");
|
|
178
189
|
console.log(` usage → ${DEBUG_ENV.usage}=1`);
|
|
190
|
+
console.log(` injection→ ${DEBUG_ENV.injection}=1`);
|
|
179
191
|
}
|
|
180
192
|
|
|
181
193
|
export async function handleDebugCommand(argv: string[]): Promise<void> {
|
|
182
194
|
const sub = (argv[0] ?? "").trim().toLowerCase();
|
|
183
195
|
|
|
184
|
-
if (sub === "provider" || sub === "usage") {
|
|
196
|
+
if (sub === "provider" || sub === "usage" || sub === "injection") {
|
|
185
197
|
await handleScopeCommand(sub, argv.slice(1));
|
|
186
198
|
return;
|
|
187
199
|
}
|
|
@@ -192,6 +204,7 @@ export async function handleDebugCommand(argv: string[]): Promise<void> {
|
|
|
192
204
|
console.log("Proxy is not running — env defaults for the next start:");
|
|
193
205
|
console.log(` provider → OCX_DEBUG = ${envDebugEnabled() ? "on" : "off"}`);
|
|
194
206
|
console.log(` usage → ${DEBUG_ENV.usage} = ${process.env[DEBUG_ENV.usage] === "1" ? "on" : "off"}`);
|
|
207
|
+
console.log(` injection→ ${DEBUG_ENV.injection} = ${process.env[DEBUG_ENV.injection] === "1" ? "on" : "off"}`);
|
|
195
208
|
console.log("");
|
|
196
209
|
}
|
|
197
210
|
printTopLevelHelp();
|
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
* Runtime-controllable debug flags.
|
|
3
3
|
* Provider debug: `ocx debug provider on|off|status|reset|logs [-f]` (or OCX_DEBUG=1 on start).
|
|
4
4
|
* Usage capture: `ocx debug usage on|off|status|reset|logs [-f]` (or OPENCODEX_USAGE_DEBUG=1).
|
|
5
|
+
* Injection log: `ocx debug injection on|off|status|reset` (or OCX_INJECTION_DEBUG=1) —
|
|
6
|
+
* multi-agent guidance-injection console lines, default OFF.
|
|
5
7
|
* `/api/debug` and `ocx debug` override env defaults without restart.
|
|
6
8
|
*/
|
|
7
9
|
|
|
8
10
|
export const DEBUG_ENV = {
|
|
9
11
|
debug: "OCX_DEBUG",
|
|
10
12
|
usage: "OPENCODEX_USAGE_DEBUG",
|
|
13
|
+
injection: "OCX_INJECTION_DEBUG",
|
|
11
14
|
} as const;
|
|
12
15
|
|
|
13
16
|
/** Legacy env var that still enables provider debug logging. */
|
|
@@ -18,6 +21,7 @@ export type DebugFlag = keyof typeof DEBUG_ENV;
|
|
|
18
21
|
export interface DebugSettingsView {
|
|
19
22
|
enabled: boolean;
|
|
20
23
|
usage: boolean;
|
|
24
|
+
injection: boolean;
|
|
21
25
|
runtimeOverride: Partial<Record<DebugFlag, boolean>>;
|
|
22
26
|
env: Record<DebugFlag, boolean>;
|
|
23
27
|
}
|
|
@@ -47,20 +51,28 @@ export function isUsageDebugEnabled(): boolean {
|
|
|
47
51
|
return envFlag(DEBUG_ENV.usage);
|
|
48
52
|
}
|
|
49
53
|
|
|
54
|
+
/** Multi-agent guidance-injection log lines (default OFF; GUI checkbox / API / CLI). */
|
|
55
|
+
export function isInjectionDebugEnabled(): boolean {
|
|
56
|
+
if (runtimeOverride.injection !== undefined) return runtimeOverride.injection;
|
|
57
|
+
return envFlag(DEBUG_ENV.injection);
|
|
58
|
+
}
|
|
59
|
+
|
|
50
60
|
export function getDebugSettings(): DebugSettingsView {
|
|
51
61
|
return {
|
|
52
62
|
enabled: isDebugEnabled(),
|
|
53
63
|
usage: isUsageDebugEnabled(),
|
|
64
|
+
injection: isInjectionDebugEnabled(),
|
|
54
65
|
runtimeOverride: { ...runtimeOverride },
|
|
55
66
|
env: {
|
|
56
67
|
debug: envFlag(DEBUG_ENV.debug) || legacyDebugEnvEnabled(),
|
|
57
68
|
usage: envFlag(DEBUG_ENV.usage),
|
|
69
|
+
injection: envFlag(DEBUG_ENV.injection),
|
|
58
70
|
},
|
|
59
71
|
};
|
|
60
72
|
}
|
|
61
73
|
|
|
62
74
|
export function setDebugSettings(partial: Partial<Record<DebugFlag, boolean>>): DebugSettingsView {
|
|
63
|
-
for (const key of ["debug", "usage"] as const) {
|
|
75
|
+
for (const key of ["debug", "usage", "injection"] as const) {
|
|
64
76
|
if (partial[key] !== undefined) runtimeOverride[key] = partial[key];
|
|
65
77
|
}
|
|
66
78
|
return getDebugSettings();
|
|
@@ -72,7 +84,7 @@ export function clearDebugSetting(flag: DebugFlag): DebugSettingsView {
|
|
|
72
84
|
}
|
|
73
85
|
|
|
74
86
|
export function clearDebugSettings(): DebugSettingsView {
|
|
75
|
-
for (const key of ["debug", "usage"] as const) {
|
|
87
|
+
for (const key of ["debug", "usage", "injection"] as const) {
|
|
76
88
|
delete runtimeOverride[key];
|
|
77
89
|
}
|
|
78
90
|
return getDebugSettings();
|
|
@@ -208,19 +208,20 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
|
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
if (url.pathname === "/api/debug" && req.method === "PUT") {
|
|
211
|
-
let body: { debug?: unknown; usage?: unknown; reset?: unknown };
|
|
211
|
+
let body: { debug?: unknown; usage?: unknown; injection?: unknown; reset?: unknown };
|
|
212
212
|
try { body = await req.json(); } catch { return jsonResponse({ error: "invalid JSON body" }, 400); }
|
|
213
213
|
if (body.reset === true) return jsonResponse(clearDebugSettings());
|
|
214
214
|
if (body.reset === "debug" || body.reset === "provider") return jsonResponse(clearDebugSetting("debug"));
|
|
215
215
|
if (body.reset === "usage") return jsonResponse(clearDebugSetting("usage"));
|
|
216
|
+
if (body.reset === "injection") return jsonResponse(clearDebugSetting("injection"));
|
|
216
217
|
const partial: Partial<Record<DebugFlag, boolean>> = {};
|
|
217
|
-
for (const key of ["debug", "usage"] as const) {
|
|
218
|
+
for (const key of ["debug", "usage", "injection"] as const) {
|
|
218
219
|
if (body[key] === undefined) continue;
|
|
219
220
|
if (typeof body[key] !== "boolean") return jsonResponse({ error: `${key} must be a boolean` }, 400);
|
|
220
221
|
partial[key] = body[key];
|
|
221
222
|
}
|
|
222
223
|
if (Object.keys(partial).length === 0) {
|
|
223
|
-
return jsonResponse({ error: "provide debug/usage booleans or reset:true" }, 400);
|
|
224
|
+
return jsonResponse({ error: "provide debug/usage/injection booleans or reset:true" }, 400);
|
|
224
225
|
}
|
|
225
226
|
return jsonResponse(setDebugSettings(partial));
|
|
226
227
|
}
|
package/src/server/responses.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { buildCompactV1Output, COMPACT_PROMPT, decodeCompactionSummary, extractC
|
|
|
9
9
|
import { FORWARD_HEADERS } from "../adapters/openai-responses";
|
|
10
10
|
import { expandPreviousResponseInput, previousResponseConversationId, rememberResponseState } from "../responses/state";
|
|
11
11
|
import { routeModel } from "../router";
|
|
12
|
+
import { isInjectionDebugEnabled } from "../lib/debug-settings";
|
|
12
13
|
import { modelInList, namespacedToolName } from "../types";
|
|
13
14
|
import type { AdapterEvent, OcxConfig, OcxParsedRequest, OcxProviderConfig } from "../types";
|
|
14
15
|
import {
|
|
@@ -133,25 +134,12 @@ export function collabSurface(parsed: OcxParsedRequest): "v1" | "v2" | null {
|
|
|
133
134
|
/**
|
|
134
135
|
* Multi-agent guidance for this turn, or null when nothing applies.
|
|
135
136
|
*
|
|
136
|
-
* codex-rs only emits its Proactive delegation developer message on the
|
|
137
|
-
* so when a v1-surface turn arrives at the synthetic top tier (codex
|
|
138
|
-
* ultra -> max on the wire, so max arrival means the user picked the top
|
|
139
|
-
* proxy supplies the same one-liner, wrapped in codex's own
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* toggle.
|
|
143
|
-
*
|
|
144
|
-
* Dynamic model injection: when the user has configured a specific injectionModel,
|
|
145
|
-
* the prompt names it so the agent knows which routed model to delegate to.
|
|
146
|
-
*
|
|
147
|
-
* Effort gate relaxation: when an injectionModel is set, the prompt fires at every
|
|
148
|
-
* effort level, not just max/ultra — the user opted into delegation.
|
|
149
|
-
*
|
|
150
|
-
* Reasoning-effort injection: when an injectionEffort is configured alongside the
|
|
151
|
-
* model, the prompt also tells the agent to pass `reasoning_effort` in spawn_agent
|
|
152
|
-
* calls (codex-rs validates spawn efforts by catalog membership; unsupported rungs
|
|
153
|
-
* are clamped on the wire). An effort WITHOUT a model changes nothing — the gate
|
|
154
|
-
* and the base prompt stay exactly as before.
|
|
137
|
+
* V1 surface: codex-rs only emits its Proactive delegation developer message on the
|
|
138
|
+
* v2 surface, so when a v1-surface turn arrives at the synthetic top tier (codex
|
|
139
|
+
* converts ultra -> max on the wire, so max arrival means the user picked the top
|
|
140
|
+
* rung) the proxy supplies the same one-liner, wrapped in codex's own
|
|
141
|
+
* <multi_agent_mode> tags. That is ALL v1 gets — no model designation, no roster
|
|
142
|
+
* (kept lean by request, devlog 260710): ultra-tier injection is sufficient there.
|
|
155
143
|
*
|
|
156
144
|
* V2 surface (flat spawn_agent — sol/terra under the default mode, EVERY model when
|
|
157
145
|
* `ocx v2 mode v2` forces the pins): codex-rs already emits its own Proactive text
|
|
@@ -169,16 +157,12 @@ export function collabSurface(parsed: OcxParsedRequest): "v1" | "v2" | null {
|
|
|
169
157
|
* regardless of the flag (spawn.rs), so the prompt tells the model to pass the
|
|
170
158
|
* arguments even though the schema does not list them.
|
|
171
159
|
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
* `subagentModels` (the 5-list the catalog features for spawn_agent) are appended
|
|
179
|
-
* with the effort ladder each advertises in the injected catalog — the same list
|
|
180
|
-
* codex-rs validates spawn efforts against — so the agent can pick per-task models
|
|
181
|
-
* and honest effort rungs instead of flying blind behind the hidden schema.
|
|
160
|
+
* The v2 body is budgeted to <= 700 chars (V2_GUIDANCE_CHAR_BUDGET): rules first,
|
|
161
|
+
* then the preferred model, then the compact roster of configured `subagentModels`
|
|
162
|
+
* with the effort ladder each advertises in the injected catalog (the list codex-rs
|
|
163
|
+
* validates spawn efforts against). A user-configured `injectionPrompt` replaces the
|
|
164
|
+
* v2 body with {{model}}/{{effort}}/{{roster}} placeholder substitution (own length,
|
|
165
|
+
* user-owned); firing gates are unchanged.
|
|
182
166
|
*/
|
|
183
167
|
export async function multiAgentGuidanceText(parsed: OcxParsedRequest, injectionModel?: string, injectionEffort?: string, subagentModels?: string[], injectionPrompt?: string): Promise<string | null> {
|
|
184
168
|
const surface = collabSurface(parsed);
|
|
@@ -193,60 +177,33 @@ export async function multiAgentGuidanceText(parsed: OcxParsedRequest, injection
|
|
|
193
177
|
if (injectionPrompt) {
|
|
194
178
|
return `<multi_agent_mode>${applyInjectionPlaceholders(injectionPrompt, injectionModel, injectionEffort, roster)}</multi_agent_mode>`;
|
|
195
179
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
"
|
|
199
|
-
|
|
200
|
-
"- With fork_turns \"none\", the child receives NO parent context: write a fully self-contained task message with paths, goals, and constraints.",
|
|
201
|
-
];
|
|
180
|
+
let text = "spawn_agent also accepts hidden \"model\" and \"reasoning_effort\" string arguments "
|
|
181
|
+
+ "(not in the schema, but parsed and applied) — never claim sub-agent models cannot be selected. "
|
|
182
|
+
+ "When setting either, set fork_turns to \"none\" (or e.g. \"3\"; full-history forks reject overrides) "
|
|
183
|
+
+ "and make the message self-contained.";
|
|
202
184
|
if (injectionModel) {
|
|
203
|
-
|
|
185
|
+
text += ` Preferred sub-agent: model "${injectionModel}"`
|
|
186
|
+
+ (injectionEffort ? `, reasoning_effort "${injectionEffort}"` : "")
|
|
187
|
+
+ " — use it unless the user names another.";
|
|
204
188
|
}
|
|
205
|
-
|
|
206
|
-
|
|
189
|
+
text += roster;
|
|
190
|
+
if (text.length > V2_GUIDANCE_CHAR_BUDGET) {
|
|
191
|
+
// Roster is the only unbounded part — drop it before breaking the budget.
|
|
192
|
+
text = text.slice(0, text.length - roster.length);
|
|
207
193
|
}
|
|
208
|
-
const exampleModel = injectionModel ?? "gpt-5.6-terra";
|
|
209
|
-
const example = "## Example spawn_agent call\n"
|
|
210
|
-
+ "```json\n"
|
|
211
|
-
+ JSON.stringify({
|
|
212
|
-
task_name: "example_task",
|
|
213
|
-
message: "Self-contained task description with paths, goals, and constraints.",
|
|
214
|
-
fork_turns: "none",
|
|
215
|
-
model: exampleModel,
|
|
216
|
-
...(injectionEffort ? { reasoning_effort: injectionEffort } : {}),
|
|
217
|
-
}, null, 2)
|
|
218
|
-
+ "\n```";
|
|
219
|
-
const text = `## Sub-agent model selection rules\n${rules.join("\n")}\n\n${example}${roster}`;
|
|
220
194
|
return `<multi_agent_mode>${text}</multi_agent_mode>`;
|
|
221
195
|
}
|
|
222
196
|
|
|
223
197
|
const effort = parsed.options.reasoning;
|
|
224
|
-
//
|
|
225
|
-
//
|
|
226
|
-
if (
|
|
227
|
-
|
|
228
|
-
if (injectionPrompt) {
|
|
229
|
-
const roster = await subagentRosterText(subagentModels);
|
|
230
|
-
return `<multi_agent_mode>${applyInjectionPlaceholders(injectionPrompt, injectionModel, injectionEffort, roster)}</multi_agent_mode>`;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
let text = PROACTIVE_MULTI_AGENT_MODE_TEXT;
|
|
234
|
-
|
|
235
|
-
// Append the selected model when the user has configured a specific injection target.
|
|
236
|
-
if (injectionModel) {
|
|
237
|
-
text += `\n\nA preferred sub-agent model is configured: "${injectionModel}". `
|
|
238
|
-
+ `When delegating, call spawn_agent and set its model argument to exactly "${injectionModel}". `
|
|
239
|
-
+ "Use it for independent sub-tasks unless the user explicitly asks for another model.";
|
|
240
|
-
if (injectionEffort) {
|
|
241
|
-
text += ` A preferred sub-agent reasoning effort is also configured: "${injectionEffort}". `
|
|
242
|
-
+ `Set the reasoning_effort argument of spawn_agent to exactly "${injectionEffort}" for those sub-agents.`;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
text += await subagentRosterText(subagentModels);
|
|
247
|
-
return `<multi_agent_mode>${text}</multi_agent_mode>`;
|
|
198
|
+
// v1 keeps only the upstream-parity behavior: Proactive text at the top tier
|
|
199
|
+
// (ultra arrives as max on the wire). No designation/roster payload here.
|
|
200
|
+
if (effort !== "max" && effort !== "ultra") return null;
|
|
201
|
+
return `<multi_agent_mode>${PROACTIVE_MULTI_AGENT_MODE_TEXT}</multi_agent_mode>`;
|
|
248
202
|
}
|
|
249
203
|
|
|
204
|
+
/** Hard budget for the built-in v2 guidance body (user request: keep injection lean). */
|
|
205
|
+
export const V2_GUIDANCE_CHAR_BUDGET = 700;
|
|
206
|
+
|
|
250
207
|
/** {{model}}/{{effort}}/{{roster}} substitution for the user-configured injectionPrompt. */
|
|
251
208
|
function applyInjectionPlaceholders(prompt: string, model?: string, effort?: string, roster?: string): string {
|
|
252
209
|
return prompt
|
|
@@ -256,7 +213,7 @@ function applyInjectionPlaceholders(prompt: string, model?: string, effort?: str
|
|
|
256
213
|
}
|
|
257
214
|
|
|
258
215
|
/**
|
|
259
|
-
*
|
|
216
|
+
* Compact one-line roster of configured sub-agent models, or "" when no configured
|
|
260
217
|
* model resolves to a catalog entry. Efforts come from the injected catalog
|
|
261
218
|
* (catalogModelEfforts) so only rungs codex-rs will actually accept are advertised.
|
|
262
219
|
*/
|
|
@@ -265,13 +222,17 @@ async function subagentRosterText(subagentModels?: string[]): Promise<string> {
|
|
|
265
222
|
if (featured.length === 0) return "";
|
|
266
223
|
const { catalogModelEfforts } = await import("../codex/catalog");
|
|
267
224
|
const efforts = catalogModelEfforts(featured);
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
225
|
+
const resolved = featured.filter(id => efforts.has(id));
|
|
226
|
+
if (resolved.length === 0) return "";
|
|
227
|
+
const ladders = new Set(resolved.map(id => efforts.get(id)!.join("/")));
|
|
228
|
+
if (ladders.size === 1) {
|
|
229
|
+
// Shared ladder (the common case: the injected catalog advertises one rung set)
|
|
230
|
+
// -> state it once instead of per model, keeping the roster inside the budget.
|
|
231
|
+
const ids = resolved.map(id => `"${id}"`).join(", ");
|
|
232
|
+
return ` Available models (reasoning_effort ${[...ladders][0]}): ${ids}.`;
|
|
233
|
+
}
|
|
234
|
+
const entries = resolved.map(id => `"${id}" (${efforts.get(id)!.join("/")})`);
|
|
235
|
+
return ` Available models (valid reasoning_effort): ${entries.join(", ")}.`;
|
|
275
236
|
}
|
|
276
237
|
|
|
277
238
|
/**
|
|
@@ -503,8 +464,8 @@ export async function handleResponses(
|
|
|
503
464
|
const guidance = await multiAgentGuidanceText(parsed, config.injectionModel, config.injectionEffort, config.subagentModels, config.injectionPrompt);
|
|
504
465
|
if (guidance) {
|
|
505
466
|
injectDeveloperMessage(parsed, guidance);
|
|
506
|
-
console.log(`[opencodex] ${route.modelId}: multi-agent guidance injected (surface=${collabSurface(parsed)}, ${guidance.length} chars)`);
|
|
507
|
-
} else if (collabSurface(parsed) !== null) {
|
|
467
|
+
if (isInjectionDebugEnabled()) console.log(`[opencodex] ${route.modelId}: multi-agent guidance injected (surface=${collabSurface(parsed)}, ${guidance.length} chars)`);
|
|
468
|
+
} else if (isInjectionDebugEnabled() && collabSurface(parsed) !== null) {
|
|
508
469
|
console.log(`[opencodex] ${route.modelId}: collab surface=${collabSurface(parsed)}, guidance silent (effort=${parsed.options.reasoning ?? "unset"}, injectionModel=${config.injectionModel ?? "unset"})`);
|
|
509
470
|
}
|
|
510
471
|
}
|