MCPcopy Create free account
hub / github.com/dwgx/WindsurfAPI / buildCascadeConfig

Function buildCascadeConfig

src/windsurf.js:390–621  ·  view source on GitHub ↗
(modelEnum, modelUid, { toolPreamble, forceDefault, nativeMode, nativeAllowlist, nativeEnvironment } = {})

Source from the content-addressed store, hash-verified

388}
389
390function buildCascadeConfig(modelEnum, modelUid, { toolPreamble, forceDefault, nativeMode, nativeAllowlist, nativeEnvironment } = {}) {
391 // CascadeConversationalPlannerConfig.planner_mode (field 4) uses
392 // codeium_common.ConversationalPlannerMode:
393 // 0 UNSPECIFIED 1 DEFAULT 2 READ_ONLY 3 NO_TOOL
394 // 4 EXPLORE 5 PLANNING 6 AUTO
395 //
396 // Default: NO_TOOL (3). DEFAULT keeps the IDE agent loop alive, which
397 // is exactly the behaviour the v2.0.65 native bridge wants — the planner
398 // reflexively proposes view_file / run_command / grep_search_v2 / find,
399 // and the bridge translates those proposals back into OpenAI tool_calls
400 // for the caller to execute. Without the bridge, DEFAULT mode produced:
401 // - stall_warm bursts (15–25s silent tool-execution trajectory steps)
402 // - "Cascade cannot create /tmp/windsurf-workspace/foo because it
403 // already exists" on request bursts that reuse the same filename
404 // - /tmp/windsurf-workspace path leaks inside the chat body
405 // The bridge tames these by (a) populating CascadeToolConfig.tool_allowlist
406 // so only the kinds the caller actually has are enabled, (b) injecting
407 // observation steps via additional_steps[9] so the planner doesn't
408 // re-execute server-side, (c) ALWAYS sanitising paths on the way out.
409 //
410 // When toolPreamble is provided (NO_TOOL emulation path), we inject it
411 // into the system prompt's tool_calling_section via SectionOverrideConfig
412 // (OVERRIDE mode). This is far more reliable than user-message injection
413 // because NO_TOOL mode's system prompt tells the model "you have no
414 // tools" — which overpowers anything we put in the user message. The
415 // section override replaces that section directly so the model sees our
416 // emulated tool definitions at the system-prompt level.
417 //
418 // Mode selection:
419 // nativeMode=true → DEFAULT (1) + tool_allowlist
420 // forceDefault=true (vision) → DEFAULT (1) without bridge config
421 // else → NO_TOOL (3) + tool preamble in section overrides
422 const mode = (nativeMode || forceDefault) ? 1 : 3;
423 const convParts = [writeVarintField(4, mode)];
424
425 // ── System prompt section overrides ──────────────────────────────────
426 //
427 // CascadeConversationalPlannerConfig section override fields:
428 // field 10: tool_calling_section
429 // field 12: additional_instructions_section
430 //
431 // Key insight: NO_TOOL mode (planner_mode=3) SUPPRESSES the
432 // tool_calling_section entirely — SectionOverrideConfig on field 10 is
433 // injected but never rendered to the model. Verified 2026-04-12: even
434 // with OVERRIDE mode on field 10, the model said "I don't have access
435 // to tools" and ignored the emulated definitions.
436 //
437 // We deliver tool definitions exclusively via
438 // additional_instructions_section (field 12, OVERRIDE) which IS
439 // rendered regardless of planner mode. The earlier code also wrote the
440 // same blob to field 10 as belt-and-suspenders, but with a 30+ tool
441 // Claude Code request that doubled the proto-level system payload and
442 // pushed total LS panel state past the ~30KB ceiling — directly causing
443 // the "tools work locally but not in cloud" symptom users reported.
444 // Field 10 is now intentionally left untouched.
445 if (toolPreamble) {
446 // ── Client provided OpenAI tools[] ──
447 // Primary (and only) delivery: additional_instructions_section

Callers 1

Calls 7

writeVarintFieldFunction · 0.90
getSystemPromptsFunction · 0.90
writeStringFieldFunction · 0.90
writeMessageFieldFunction · 0.90
writeBoolFieldFunction · 0.90
pushMethod · 0.80

Tested by

no test coverage detected