@yansigit/opencodex 2.36.1-dev.20260829.39 → 2.36.1-dev.20260829.47
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/gui/dist/assets/{ApiKeys-BDLkAqHs.js → ApiKeys-DAuYQsGJ.js} +1 -1
- package/gui/dist/assets/{Claude-CbTHl2B0.js → Claude-bN_80RT8.js} +1 -1
- package/gui/dist/assets/{CodexSet-BWMY8up4.js → CodexSet-D3dWX_ay.js} +1 -1
- package/gui/dist/assets/{FileIntegrationPage-BFywFnu_.js → FileIntegrationPage-BGyzkPs2.js} +1 -1
- package/gui/dist/assets/{Grok-D7_rD_UK.js → Grok-CuaKd1TT.js} +1 -1
- package/gui/dist/assets/{Integrations-BM5cNRt8.js → Integrations-C7NGQoxR.js} +2 -2
- package/gui/dist/assets/{IntegrationsOverview-DUL8qhww.js → IntegrationsOverview-DjVorYO5.js} +1 -1
- package/gui/dist/assets/{Logs-BG9kIs3A.js → Logs-B21a-9xe.js} +1 -1
- package/gui/dist/assets/{Models-BJWzO0Kh.js → Models-CN7Q3kuK.js} +1 -1
- package/gui/dist/assets/{NumberStepper-K9tocDBx.js → NumberStepper-BWg90tEs.js} +1 -1
- package/gui/dist/assets/{Providers-BLweq_Hw.js → Providers-CP_i-7LS.js} +1 -1
- package/gui/dist/assets/{RestoreDialog-D9aPE4O0.js → RestoreDialog-3M0NqCiD.js} +1 -1
- package/gui/dist/assets/{Startup-CkcpO3Jv.js → Startup-BVPFoP2s.js} +1 -1
- package/gui/dist/assets/{Storage-YIqUviJJ.js → Storage-BdsG9ypz.js} +1 -1
- package/gui/dist/assets/{Subagents-C1AfLEl9.js → Subagents-CguR_bGQ.js} +1 -1
- package/gui/dist/assets/{Usage-BerHlEN0.js → Usage-C0kKi9_H.js} +1 -1
- package/gui/dist/assets/{data-surface-DCct07RT.js → data-surface-BCycbObp.js} +1 -1
- package/gui/dist/assets/{index-Bs27ITj_.js → index-CU1jE0st.js} +2 -2
- package/gui/dist/assets/{model-display-KCeq505s.js → model-display-D2elXkuE.js} +1 -1
- package/gui/dist/assets/{provider-payload-DHs_ctdK.js → provider-payload-DfkXWE7v.js} +1 -1
- package/gui/dist/index.html +1 -1
- package/package.json +1 -1
- package/src/adapters/openai-responses.ts +9 -5
- package/src/cli/agent.ts +19 -2
- package/src/cli/registry.ts +1 -1
- package/src/codex/catalog.ts +1 -1
- package/src/codex/inject.ts +2 -0
- package/src/codex/subagent-defaults.ts +1 -8
- package/src/codex/subagent-model-authority.ts +189 -0
- package/src/generated/compatibility-version.json +14 -10
- package/src/server/management/agent-settings-routes.ts +12 -0
- package/src/server/responses/collaboration.ts +1 -1
- package/src/server/responses/core.ts +11 -13
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import type { OcxConfig } from "../types";
|
|
2
|
+
import { isEligibleV2SubagentEntry, readCatalog, readCodexCatalogPath } from "./catalog";
|
|
3
|
+
import { catalogEntryEfforts } from "./catalog/effort";
|
|
4
|
+
import type { RawEntry } from "./catalog/parsing";
|
|
5
|
+
import { resolveNativeDefaultState, type NativeDefaultState } from "./subagent-defaults";
|
|
6
|
+
|
|
7
|
+
export const SUBAGENT_MODEL_AUTHORITY_VERSION = 1 as const;
|
|
8
|
+
|
|
9
|
+
export interface SubagentModelAuthorityInput {
|
|
10
|
+
schemaVersion: typeof SUBAGENT_MODEL_AUTHORITY_VERSION;
|
|
11
|
+
role: string;
|
|
12
|
+
agentType: string;
|
|
13
|
+
typedDispatchRequired?: boolean;
|
|
14
|
+
requestedModel?: string;
|
|
15
|
+
requestedEffort?: string;
|
|
16
|
+
spawnAgent: {
|
|
17
|
+
surface: "v1" | "v2";
|
|
18
|
+
supportsAgentType: boolean;
|
|
19
|
+
supportsModel: boolean;
|
|
20
|
+
supportsEffort: boolean;
|
|
21
|
+
supportsForkTurns: boolean;
|
|
22
|
+
};
|
|
23
|
+
confirmation?: { decision: "approve" | "decline" };
|
|
24
|
+
interactive?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SubagentModelAuthorityHost {
|
|
28
|
+
catalogState: "fresh" | "stale" | "not_running" | "unknown";
|
|
29
|
+
nativeDefaultState: NativeDefaultState;
|
|
30
|
+
preferredModel: string | null;
|
|
31
|
+
preferredEffort: string | null;
|
|
32
|
+
executableModels: Array<{ model: string; efforts: string[] }>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type SubagentModelAuthorityResult = {
|
|
36
|
+
schemaVersion: typeof SUBAGENT_MODEL_AUTHORITY_VERSION;
|
|
37
|
+
decision: "forward" | "omit" | "confirm" | "blocked";
|
|
38
|
+
requestClassification: "inherit" | "preferred" | "exception";
|
|
39
|
+
reason: string;
|
|
40
|
+
spawn?: {
|
|
41
|
+
agent_type?: string;
|
|
42
|
+
model?: string;
|
|
43
|
+
reasoning_effort?: string;
|
|
44
|
+
fork_turns?: "none";
|
|
45
|
+
};
|
|
46
|
+
confirmation?: {
|
|
47
|
+
role: string;
|
|
48
|
+
preferredModel: string | null;
|
|
49
|
+
requestedModel: string;
|
|
50
|
+
scope: "single spawn";
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export function parseSubagentModelAuthorityInput(value: unknown): SubagentModelAuthorityInput | null {
|
|
55
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
56
|
+
const input = value as Record<string, unknown>;
|
|
57
|
+
const spawn = input.spawnAgent;
|
|
58
|
+
if (!spawn || typeof spawn !== "object" || Array.isArray(spawn)) return null;
|
|
59
|
+
const tool = spawn as Record<string, unknown>;
|
|
60
|
+
if (input.schemaVersion !== SUBAGENT_MODEL_AUTHORITY_VERSION
|
|
61
|
+
|| typeof input.role !== "string"
|
|
62
|
+
|| typeof input.agentType !== "string"
|
|
63
|
+
|| (input.typedDispatchRequired !== undefined && typeof input.typedDispatchRequired !== "boolean")
|
|
64
|
+
|| (input.requestedModel !== undefined && typeof input.requestedModel !== "string")
|
|
65
|
+
|| (input.requestedEffort !== undefined && typeof input.requestedEffort !== "string")
|
|
66
|
+
|| (input.interactive !== undefined && typeof input.interactive !== "boolean")
|
|
67
|
+
|| (tool.surface !== "v1" && tool.surface !== "v2")
|
|
68
|
+
|| ["supportsAgentType", "supportsModel", "supportsEffort", "supportsForkTurns"]
|
|
69
|
+
.some(key => typeof tool[key] !== "boolean")) return null;
|
|
70
|
+
if (input.confirmation !== undefined) {
|
|
71
|
+
if (!input.confirmation || typeof input.confirmation !== "object" || Array.isArray(input.confirmation)) return null;
|
|
72
|
+
const decision = (input.confirmation as Record<string, unknown>).decision;
|
|
73
|
+
if (decision !== "approve" && decision !== "decline") return null;
|
|
74
|
+
}
|
|
75
|
+
return value as SubagentModelAuthorityInput;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function result(
|
|
79
|
+
decision: SubagentModelAuthorityResult["decision"],
|
|
80
|
+
requestClassification: SubagentModelAuthorityResult["requestClassification"],
|
|
81
|
+
reason: string,
|
|
82
|
+
extra: Pick<SubagentModelAuthorityResult, "spawn" | "confirmation"> = {},
|
|
83
|
+
): SubagentModelAuthorityResult {
|
|
84
|
+
return { schemaVersion: SUBAGENT_MODEL_AUTHORITY_VERSION, decision, requestClassification, reason, ...extra };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function resolveSubagentModelAuthority(
|
|
88
|
+
input: SubagentModelAuthorityInput,
|
|
89
|
+
host: SubagentModelAuthorityHost,
|
|
90
|
+
): SubagentModelAuthorityResult {
|
|
91
|
+
const requestedModel = input.requestedModel?.trim() || undefined;
|
|
92
|
+
const preferredModel = host.preferredModel?.trim() || undefined;
|
|
93
|
+
const classification = requestedModel === undefined
|
|
94
|
+
? "inherit"
|
|
95
|
+
: requestedModel === preferredModel ? "preferred" : "exception";
|
|
96
|
+
if (input.schemaVersion !== SUBAGENT_MODEL_AUTHORITY_VERSION) {
|
|
97
|
+
return result("blocked", classification, "unsupported authority schema version");
|
|
98
|
+
}
|
|
99
|
+
if (!input.role.trim() || !input.agentType.trim()) {
|
|
100
|
+
return result("blocked", classification, "role and agentType must be non-empty");
|
|
101
|
+
}
|
|
102
|
+
if (input.typedDispatchRequired && !input.spawnAgent.supportsAgentType) {
|
|
103
|
+
return result("blocked", classification, "spawn_agent does not support required agent_type dispatch");
|
|
104
|
+
}
|
|
105
|
+
if (host.catalogState === "stale" || host.catalogState === "unknown") {
|
|
106
|
+
return result("blocked", classification, "OpenCodex model authority is not current; sync or restart Codex and retry");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const chosenModel = requestedModel ?? preferredModel;
|
|
110
|
+
const executable = chosenModel
|
|
111
|
+
? host.executableModels.find(candidate => candidate.model === chosenModel)
|
|
112
|
+
: undefined;
|
|
113
|
+
if (chosenModel && !executable) {
|
|
114
|
+
return result("blocked", classification, `model ${JSON.stringify(chosenModel)} is not executable on this collaboration surface`);
|
|
115
|
+
}
|
|
116
|
+
if (chosenModel && !input.spawnAgent.supportsModel) {
|
|
117
|
+
return result("blocked", classification, "spawn_agent does not support model overrides");
|
|
118
|
+
}
|
|
119
|
+
const effort = input.requestedEffort?.trim() || (requestedModel ? undefined : host.preferredEffort?.trim()) || undefined;
|
|
120
|
+
if (effort && !input.spawnAgent.supportsEffort) {
|
|
121
|
+
return result("blocked", classification, "spawn_agent does not support reasoning_effort overrides");
|
|
122
|
+
}
|
|
123
|
+
if (effort && executable && !executable.efforts.includes(effort)) {
|
|
124
|
+
return result("blocked", classification, `reasoning effort ${JSON.stringify(effort)} is unavailable for ${JSON.stringify(chosenModel)}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (classification === "exception") {
|
|
128
|
+
if (input.confirmation?.decision === "decline") {
|
|
129
|
+
return result("blocked", classification, "single-spawn model exception was declined");
|
|
130
|
+
}
|
|
131
|
+
if (input.confirmation?.decision !== "approve") {
|
|
132
|
+
if (input.interactive === false) {
|
|
133
|
+
return result("blocked", classification, "single-spawn model exception requires interactive confirmation");
|
|
134
|
+
}
|
|
135
|
+
return result("confirm", classification, "confirm this model exception for one spawn", {
|
|
136
|
+
confirmation: {
|
|
137
|
+
role: input.role,
|
|
138
|
+
preferredModel: preferredModel ?? null,
|
|
139
|
+
requestedModel: requestedModel!,
|
|
140
|
+
scope: "single spawn",
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (!chosenModel) {
|
|
147
|
+
return host.nativeDefaultState === "active"
|
|
148
|
+
? result("omit", classification, "native OpenCodex defaults are active")
|
|
149
|
+
: result("blocked", classification, `native OpenCodex defaults are ${host.nativeDefaultState}`);
|
|
150
|
+
}
|
|
151
|
+
const spawn: NonNullable<SubagentModelAuthorityResult["spawn"]> = {
|
|
152
|
+
...(input.spawnAgent.supportsAgentType ? { agent_type: input.agentType } : {}),
|
|
153
|
+
model: chosenModel,
|
|
154
|
+
...(effort ? { reasoning_effort: effort } : {}),
|
|
155
|
+
...((input.spawnAgent.supportsForkTurns && (chosenModel || effort)) ? { fork_turns: "none" as const } : {}),
|
|
156
|
+
};
|
|
157
|
+
return result("forward", classification, classification === "exception"
|
|
158
|
+
? "single-spawn model exception approved"
|
|
159
|
+
: "OpenCodex preferred model is executable", { spawn });
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function executableModels(entries: readonly RawEntry[], surface: "v1" | "v2"): SubagentModelAuthorityHost["executableModels"] {
|
|
163
|
+
const seen = new Set<string>();
|
|
164
|
+
return entries.flatMap(entry => {
|
|
165
|
+
const model = typeof entry.slug === "string" ? entry.slug.trim() : "";
|
|
166
|
+
if (!model || seen.has(model) || entry.visibility !== "list" || (surface === "v2" && !isEligibleV2SubagentEntry(entry))) return [];
|
|
167
|
+
seen.add(model);
|
|
168
|
+
return [{ model, efforts: catalogEntryEfforts(entry) }];
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export async function resolveOpenCodexSubagentModelAuthority(
|
|
173
|
+
input: SubagentModelAuthorityInput,
|
|
174
|
+
config: OcxConfig,
|
|
175
|
+
): Promise<SubagentModelAuthorityResult> {
|
|
176
|
+
const { collectCodexAppServerCatalogStateForRequest } = await import("./app-server-processes");
|
|
177
|
+
const catalogState = await collectCodexAppServerCatalogStateForRequest();
|
|
178
|
+
const models = executableModels(readCatalog(readCodexCatalogPath())?.models ?? [], input.spawnAgent.surface);
|
|
179
|
+
const configured = config.injectionModel?.trim() || null;
|
|
180
|
+
const exact = configured ? models.find(candidate => candidate.model === configured)?.model ?? null : null;
|
|
181
|
+
const host: SubagentModelAuthorityHost = {
|
|
182
|
+
catalogState: catalogState.state,
|
|
183
|
+
nativeDefaultState: await resolveNativeDefaultState(config),
|
|
184
|
+
preferredModel: exact,
|
|
185
|
+
preferredEffort: config.injectionEffort?.trim() || null,
|
|
186
|
+
executableModels: models,
|
|
187
|
+
};
|
|
188
|
+
return resolveSubagentModelAuthority(input, host);
|
|
189
|
+
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"path": "package.json",
|
|
13
|
-
"sha256": "
|
|
13
|
+
"sha256": "f144c82b1b83fe866cfa13a56819ec264953f5e228c08bf2df632f903a4be07d"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"path": "scripts/model-metadata.source.json",
|
|
@@ -338,7 +338,7 @@
|
|
|
338
338
|
},
|
|
339
339
|
{
|
|
340
340
|
"path": "src/adapters/openai-responses.ts",
|
|
341
|
-
"sha256": "
|
|
341
|
+
"sha256": "5357d3b799bacbed86917ca68031c3625686ccd32659d7a9bc8167edb0955c57"
|
|
342
342
|
},
|
|
343
343
|
{
|
|
344
344
|
"path": "src/adapters/registry.ts",
|
|
@@ -486,7 +486,7 @@
|
|
|
486
486
|
},
|
|
487
487
|
{
|
|
488
488
|
"path": "src/cli/agent.ts",
|
|
489
|
-
"sha256": "
|
|
489
|
+
"sha256": "3caa13112d1023cafefc56addb66d7e36fcb05b1b71a29caf675a7893d69d574"
|
|
490
490
|
},
|
|
491
491
|
{
|
|
492
492
|
"path": "src/cli/alias.ts",
|
|
@@ -614,7 +614,7 @@
|
|
|
614
614
|
},
|
|
615
615
|
{
|
|
616
616
|
"path": "src/cli/registry.ts",
|
|
617
|
-
"sha256": "
|
|
617
|
+
"sha256": "66f2c0dad2451db553e7e0ae7905c78c3261e8ce2d76684d358a7148ab1582c9"
|
|
618
618
|
},
|
|
619
619
|
{
|
|
620
620
|
"path": "src/cli/replit-gateway-key-input.ts",
|
|
@@ -766,7 +766,7 @@
|
|
|
766
766
|
},
|
|
767
767
|
{
|
|
768
768
|
"path": "src/codex/catalog.ts",
|
|
769
|
-
"sha256": "
|
|
769
|
+
"sha256": "9e7af66b04e8718f4b7bf822994941a06b4135253a98668963e77bd88c9c3076"
|
|
770
770
|
},
|
|
771
771
|
{
|
|
772
772
|
"path": "src/codex/catalog/account-models.ts",
|
|
@@ -898,7 +898,7 @@
|
|
|
898
898
|
},
|
|
899
899
|
{
|
|
900
900
|
"path": "src/codex/inject.ts",
|
|
901
|
-
"sha256": "
|
|
901
|
+
"sha256": "22fe9dc3b8fe3994b921ad619807b899e609834ea69e47c5b9494075327341a2"
|
|
902
902
|
},
|
|
903
903
|
{
|
|
904
904
|
"path": "src/codex/injected-marker.ts",
|
|
@@ -1098,7 +1098,11 @@
|
|
|
1098
1098
|
},
|
|
1099
1099
|
{
|
|
1100
1100
|
"path": "src/codex/subagent-defaults.ts",
|
|
1101
|
-
"sha256": "
|
|
1101
|
+
"sha256": "c2683dd65ab7565c703e6637c5aa6c22c6a937d264e369efabb3eddabe7ba88a"
|
|
1102
|
+
},
|
|
1103
|
+
{
|
|
1104
|
+
"path": "src/codex/subagent-model-authority.ts",
|
|
1105
|
+
"sha256": "09928c56938d711365c324653e5870fc9f7aad021abae20e7d7a7ad870e52053"
|
|
1102
1106
|
},
|
|
1103
1107
|
{
|
|
1104
1108
|
"path": "src/codex/subagent-model-fallback.ts",
|
|
@@ -2710,7 +2714,7 @@
|
|
|
2710
2714
|
},
|
|
2711
2715
|
{
|
|
2712
2716
|
"path": "src/server/management/agent-settings-routes.ts",
|
|
2713
|
-
"sha256": "
|
|
2717
|
+
"sha256": "8046634493d0317a25b283e5ffa0007cf3a54dadcda5b6e7e7dcf83743f718bc"
|
|
2714
2718
|
},
|
|
2715
2719
|
{
|
|
2716
2720
|
"path": "src/server/management/api-access.ts",
|
|
@@ -2934,7 +2938,7 @@
|
|
|
2934
2938
|
},
|
|
2935
2939
|
{
|
|
2936
2940
|
"path": "src/server/responses/collaboration.ts",
|
|
2937
|
-
"sha256": "
|
|
2941
|
+
"sha256": "614afac38832befe772e6b59f6dedd3dfd44546a8f48ea2660fdcb0f9f1c089f"
|
|
2938
2942
|
},
|
|
2939
2943
|
{
|
|
2940
2944
|
"path": "src/server/responses/combo-stream-preflight.ts",
|
|
@@ -2946,7 +2950,7 @@
|
|
|
2946
2950
|
},
|
|
2947
2951
|
{
|
|
2948
2952
|
"path": "src/server/responses/core.ts",
|
|
2949
|
-
"sha256": "
|
|
2953
|
+
"sha256": "f5e37d03f10f99d7000421ef0ec8b0d63d064c67afe87eb24631e502f50fe62f"
|
|
2950
2954
|
},
|
|
2951
2955
|
{
|
|
2952
2956
|
"path": "src/server/responses/empty-completion-guard.ts",
|
|
@@ -792,6 +792,18 @@ export async function handleAgentSettingsRoutes(ctx: ManagementContext): Promise
|
|
|
792
792
|
// dynamically injected into the v1 proactive prompt, plus an optional reasoning
|
|
793
793
|
// effort the prompt tells the agent to pass to spawn_agent. GET returns the current
|
|
794
794
|
// picks + available models/efforts; PUT sets or clears them.
|
|
795
|
+
if (url.pathname === "/api/subagent-model-authority" && req.method === "POST") {
|
|
796
|
+
let body: unknown;
|
|
797
|
+
try { body = await readManagementJsonBody(req); } catch (error) {
|
|
798
|
+
rethrowManagementBodyTooLarge(error);
|
|
799
|
+
return jsonResponse({ error: "invalid JSON body" }, 400);
|
|
800
|
+
}
|
|
801
|
+
const { parseSubagentModelAuthorityInput, resolveOpenCodexSubagentModelAuthority } = await import("../../codex/subagent-model-authority");
|
|
802
|
+
const input = parseSubagentModelAuthorityInput(body);
|
|
803
|
+
if (!input) return jsonResponse({ error: "invalid subagent model authority input" }, 400);
|
|
804
|
+
return jsonResponse(await resolveOpenCodexSubagentModelAuthority(input, config));
|
|
805
|
+
}
|
|
806
|
+
|
|
795
807
|
if (url.pathname === "/api/injection-model" && req.method === "GET") {
|
|
796
808
|
const models = await fetchAllModels(config);
|
|
797
809
|
const disabled = new Set(config.disabledModels ?? []);
|
|
@@ -447,7 +447,7 @@ export async function multiAgentGuidanceText(
|
|
|
447
447
|
preferredText = ` Preferred sub-agent: model "${preferred.model}"`
|
|
448
448
|
+ (injectionEffort ? `, reasoning_effort "${injectionEffort}"` : "")
|
|
449
449
|
+ `; nativeDefaultState: ${nativeDefaultState}.`
|
|
450
|
-
+ " — use it unless the user names another.";
|
|
450
|
+
+ " — use it unless the user names another. Confirm a different listed model for one spawn only; do not persist the exception.";
|
|
451
451
|
}
|
|
452
452
|
const specialist = (catalog: string): string =>
|
|
453
453
|
catalog ? ` When spawning, use a named specialist: ${catalog}.` : "";
|
|
@@ -3502,19 +3502,17 @@ async function handleResponsesInner(
|
|
|
3502
3502
|
}
|
|
3503
3503
|
throw error;
|
|
3504
3504
|
}
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
) routedCustomToolRepairNames.add(name);
|
|
3517
|
-
}
|
|
3505
|
+
for (const name of request.convertedRoutedCustomToolNames ?? []) {
|
|
3506
|
+
if (
|
|
3507
|
+
toolBridgeMaps.freeformToolNames.has(name)
|
|
3508
|
+
|| toolBridgeMaps.toolNsMap.get(name)?.freeform === true
|
|
3509
|
+
) routedCustomToolNames.add(name);
|
|
3510
|
+
}
|
|
3511
|
+
for (const name of request.routedCustomToolRepairNames ?? []) {
|
|
3512
|
+
if (
|
|
3513
|
+
toolBridgeMaps.freeformToolNames.has(name)
|
|
3514
|
+
|| toolBridgeMaps.toolNsMap.get(name)?.freeform === true
|
|
3515
|
+
) routedCustomToolRepairNames.add(name);
|
|
3518
3516
|
}
|
|
3519
3517
|
for (const name of request.convertedRoutedToolSearchNames ?? []) {
|
|
3520
3518
|
// The adapter already keeps this set empty when tool_choice forbids the private search.
|