





















@@ -188,6 +188,100 @@ describe("createCodexNativeWebSearchWrapper", () => {
188188expect(observedOptions[0]?.openclawCodeModeToolSurface).toBeUndefined();
189189expect(payloads[0]).toEqual({ model: "gpt-5.5" });
190190});
191+192+it("enforces the code-mode transport surface when the run enables it at agent scope", () => {
193+const observedOptions: Array<Record<string, unknown>> = [];
194+const payloads: Array<Record<string, unknown>> = [];
195+const baseStreamFn: StreamFn = (model, _context, options) => {
196+observedOptions.push(options as Record<string, unknown>);
197+const payload: Record<string, unknown> = {
198+model: model.id,
199+tools: [
200+{ type: "function", name: "exec" },
201+{ type: "function", name: "wait" },
202+{ type: "function", name: "read" },
203+],
204+};
205+options?.onPayload?.(payload, model);
206+payloads.push(structuredClone(payload));
207+return createAssistantMessageEventStream();
208+};
209+const wrapped = createCodexNativeWebSearchWrapper(baseStreamFn, {
210+codeModeToolSurfaceEnabled: true,
211+});
212+213+void wrapped(
214+{
215+api: "openai-codex-responses",
216+provider: "gateway",
217+id: "gpt-5.5",
218+} as Model<"openai-codex-responses">,
219+{
220+messages: [],
221+tools: [
222+{ name: "exec", description: "", parameters: {} },
223+{ name: "wait", description: "", parameters: {} },
224+],
225+},
226+{},
227+);
228+229+expect(observedOptions[0]?.openclawCodeModeToolSurface).toBe(true);
230+expect(payloads[0]?.tools).toEqual([
231+{ type: "function", name: "exec" },
232+{ type: "function", name: "wait" },
233+]);
234+});
235+236+it("keeps grouped provider tool declarations when code mode filters the payload", () => {
237+const payloads: Array<Record<string, unknown>> = [];
238+const baseStreamFn: StreamFn = (model, _context, options) => {
239+const payload: Record<string, unknown> = {
240+model: model.id,
241+tools: [
242+{
243+functionDeclarations: [
244+{ name: "exec", description: "Run code" },
245+{ name: "read", description: "Read a file" },
246+{ name: "wait", description: "Resume code" },
247+],
248+},
249+{ google_search: {} },
250+],
251+};
252+options?.onPayload?.(payload, model);
253+payloads.push(structuredClone(payload));
254+return createAssistantMessageEventStream();
255+};
256+const wrapped = createCodexNativeWebSearchWrapper(baseStreamFn, {
257+codeModeToolSurfaceEnabled: true,
258+});
259+260+void wrapped(
261+{
262+api: "google-generative-ai",
263+provider: "google",
264+id: "gemini-3.1-pro",
265+} as never,
266+{
267+messages: [],
268+tools: [
269+{ name: "exec", description: "", parameters: {} },
270+{ name: "wait", description: "", parameters: {} },
271+],
272+},
273+{},
274+);
275+276+expect(payloads[0]?.tools).toEqual([
277+{
278+functionDeclarations: [
279+{ name: "exec", description: "Run code" },
280+{ name: "wait", description: "Resume code" },
281+],
282+},
283+]);
284+});
191285});
192286193287describe("createOpenAICompletionsStrictMessageKeysWrapper", () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。