77 codexAutoStartEnabled ,
88 hasOwnProvider ,
99 isValidProviderName ,
10+ multiAgentGuidanceEnabled ,
1011 providerBaseUrlConfigError ,
1112 providerHeadersConfigError ,
1213 saveConfig ,
@@ -1105,6 +1106,7 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
11051106 stored === m . namespaced || slugEquals ( stored , m . provider , m . model )
11061107 ) ) ) ;
11071108 return jsonResponse ( {
1109+ multiAgentGuidanceEnabled : multiAgentGuidanceEnabled ( config ) ,
11081110 model : config . injectionModel ?? null ,
11091111 effort : config . injectionEffort ?? null ,
11101112 prompt : config . injectionPrompt ?? null ,
@@ -1113,34 +1115,69 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
11131115 } ) ;
11141116 }
11151117 if ( url . pathname === "/api/injection-model" && req . method === "PUT" ) {
1116- let body : { model ?: unknown ; effort ?: unknown ; prompt ?: unknown } ;
1117- try { body = await req . json ( ) ; } catch { return jsonResponse ( { error : "invalid JSON body" } , 400 ) ; }
1118+ let parsedBody : unknown ;
1119+ try { parsedBody = await req . json ( ) ; } catch {
1120+ return jsonResponse ( { error : "invalid JSON body" } , 400 ) ;
1121+ }
1122+ if ( ! parsedBody || typeof parsedBody !== "object" || Array . isArray ( parsedBody ) ) {
1123+ return jsonResponse ( { error : "body must be a JSON object" } , 400 ) ;
1124+ }
1125+ const body = parsedBody as {
1126+ multiAgentGuidanceEnabled ?: unknown ;
1127+ model ?: unknown ;
1128+ effort ?: unknown ;
1129+ prompt ?: unknown ;
1130+ } ;
11181131 const { isCodexReasoningEffort } = await import ( "../reasoning-effort" ) ;
1119- const model = typeof body . model === "string" && body . model . length > 0 ? body . model : undefined ;
1120- let effort = config . injectionEffort ;
1121- // `effort` key semantics: absent -> unchanged; null/"" -> clear; ladder value -> set;
1122- // anything else -> 400. Clearing the model always clears the effort (it is meaningless alone).
1132+
1133+ let nextEnabled = config . multiAgentGuidanceEnabled ;
1134+ let nextModel = config . injectionModel ;
1135+ let nextEffort = config . injectionEffort ;
1136+ let nextPrompt = config . injectionPrompt ;
1137+
1138+ if ( "multiAgentGuidanceEnabled" in body ) {
1139+ if ( typeof body . multiAgentGuidanceEnabled !== "boolean" ) {
1140+ return jsonResponse ( { error : "multiAgentGuidanceEnabled must be a boolean" } , 400 ) ;
1141+ }
1142+ nextEnabled = body . multiAgentGuidanceEnabled ;
1143+ }
1144+ if ( "model" in body ) {
1145+ if ( body . model === null || body . model === "" ) nextModel = undefined ;
1146+ else if ( typeof body . model === "string" && body . model . length > 0 ) nextModel = body . model ;
1147+ else return jsonResponse ( { error : "model must be a non-empty string or null" } , 400 ) ;
1148+ }
11231149 if ( "effort" in body ) {
1124- const requestedEffort = typeof body . effort === "string" && body . effort . length > 0 ? body . effort : undefined ;
1125- if ( requestedEffort !== undefined && ! isCodexReasoningEffort ( requestedEffort ) ) {
1126- return jsonResponse ( { error : `unknown reasoning effort "${ requestedEffort } "` } , 400 ) ;
1150+ if ( body . effort === null || body . effort === "" ) nextEffort = undefined ;
1151+ else if ( typeof body . effort === "string" && isCodexReasoningEffort ( body . effort ) ) {
1152+ nextEffort = body . effort ;
1153+ } else {
1154+ return jsonResponse ( { error : `unknown reasoning effort "${ String ( body . effort ) } "` } , 400 ) ;
11271155 }
1128- effort = requestedEffort ;
11291156 }
1130- if ( ! model ) effort = undefined ;
1131- if ( model ) config . injectionModel = model ;
1132- else delete config . injectionModel ;
1133- if ( effort ) config . injectionEffort = effort ;
1134- else delete config . injectionEffort ;
1135- // `prompt` key semantics mirror `effort`: absent -> unchanged; null/"" -> clear;
1136- // non-empty string -> set (custom <multi_agent_mode> body, {{model}}/{{effort}}/{{roster}} placeholders).
11371157 if ( "prompt" in body ) {
1138- if ( typeof body . prompt === "string" && body . prompt . trim ( ) . length > 0 ) config . injectionPrompt = body . prompt ;
1139- else if ( body . prompt === null || body . prompt === "" ) delete config . injectionPrompt ;
1158+ if ( typeof body . prompt === "string" && body . prompt . trim ( ) . length > 0 ) nextPrompt = body . prompt ;
1159+ else if ( body . prompt === null || body . prompt === "" ) nextPrompt = undefined ;
11401160 else return jsonResponse ( { error : "prompt must be a string or null" } , 400 ) ;
11411161 }
1162+ // Clearing the model always clears the effort (it is meaningless alone).
1163+ if ( ! nextModel ) nextEffort = undefined ;
1164+
1165+ config . multiAgentGuidanceEnabled = nextEnabled ;
1166+ if ( nextModel ) config . injectionModel = nextModel ;
1167+ else delete config . injectionModel ;
1168+ if ( nextEffort ) config . injectionEffort = nextEffort ;
1169+ else delete config . injectionEffort ;
1170+ if ( nextPrompt ) config . injectionPrompt = nextPrompt ;
1171+ else delete config . injectionPrompt ;
1172+
11421173 saveConfig ( config ) ;
1143- return jsonResponse ( { ok : true , model : config . injectionModel ?? null , effort : config . injectionEffort ?? null , prompt : config . injectionPrompt ?? null } ) ;
1174+ return jsonResponse ( {
1175+ ok : true ,
1176+ multiAgentGuidanceEnabled : multiAgentGuidanceEnabled ( config ) ,
1177+ model : config . injectionModel ?? null ,
1178+ effort : config . injectionEffort ?? null ,
1179+ prompt : config . injectionPrompt ?? null ,
1180+ } ) ;
11441181 }
11451182
11461183 // Hard reasoning-effort caps (devlog/260710_subagent_effort_intercept): a global ceiling and a
0 commit comments