package winlimit import ( "cursor-api-proxy/internal/env" "runtime" ) const WinPromptOmissionPrefix = "[Earlier messages omitted: Windows command-line length limit.]\n\n" const LinuxPromptOmissionPrefix = "[Earlier messages omitted: Linux ARG_MAX command-line length limit.]\n\n" // safeLinuxArgMax returns a conservative estimate of ARG_MAX on Linux. // The actual limit is typically 2MB; we use 1.5MB to leave room for env vars. func safeLinuxArgMax() int { return 1536 * 1024 } type FitPromptResult struct { OK bool Args []string Truncated bool OriginalLength int FinalPromptLength int Error string } func estimateCmdlineLength(resolved env.AgentCommand) int { argv := append([]string{resolved.Command}, resolved.Args...) if resolved.WindowsVerbatimArguments { n := 0 for _, a := range argv { n += len(a) } if len(argv) > 1 { n += len(argv) - 1 } return n + 512 } dstLen := 0 for _, a := range argv { dstLen += len(a) } dstLen = dstLen*2 + len(argv)*2 if len(argv) > 1 { dstLen += len(argv) - 1 } return dstLen + 512 } func FitPromptToWinCmdline(agentBin string, fixedArgs []string, prompt string, maxCmdline int, cwd string) FitPromptResult { if runtime.GOOS != "windows" { return fitPromptLinux(fixedArgs, prompt) } e := env.OsEnvToMap() measured := func(p string) int { args := make([]string, len(fixedArgs)+1) copy(args, fixedArgs) args[len(fixedArgs)] = p resolved := env.ResolveAgentCommand(agentBin, args, e, cwd) return estimateCmdlineLength(resolved) } if measured("") > maxCmdline { return FitPromptResult{ OK: false, Error: "Windows command line exceeds the configured limit even without a prompt; shorten workspace path, model id, or CURSOR_BRIDGE_WIN_CMDLINE_MAX.", } } if measured(prompt) <= maxCmdline { args := make([]string, len(fixedArgs)+1) copy(args, fixedArgs) args[len(fixedArgs)] = prompt return FitPromptResult{ OK: true, Args: args, Truncated: false, OriginalLength: len(prompt), FinalPromptLength: len(prompt), } } prefix := WinPromptOmissionPrefix if measured(prefix) > maxCmdline { return FitPromptResult{ OK: false, Error: "Windows command line too long to fit even the truncation notice; shorten workspace path or flags.", } } lo, hi, best := 0, len(prompt), 0 for lo <= hi { mid := (lo + hi) / 2 var tail string if mid > 0 { tail = prompt[len(prompt)-mid:] } candidate := prefix + tail if measured(candidate) <= maxCmdline { best = mid lo = mid + 1 } else { hi = mid - 1 } } var finalPrompt string if best == 0 { finalPrompt = prefix } else { finalPrompt = prefix + prompt[len(prompt)-best:] } args := make([]string, len(fixedArgs)+1) copy(args, fixedArgs) args[len(fixedArgs)] = finalPrompt return FitPromptResult{ OK: true, Args: args, Truncated: true, OriginalLength: len(prompt), FinalPromptLength: len(finalPrompt), } } // fitPromptLinux handles Linux ARG_MAX truncation. func fitPromptLinux(fixedArgs []string, prompt string) FitPromptResult { argMax := safeLinuxArgMax() // Estimate total cmdline size: sum of all fixed args + prompt + null terminators fixedLen := 0 for _, a := range fixedArgs { fixedLen += len(a) + 1 } totalLen := fixedLen + len(prompt) + 1 if totalLen <= argMax { args := make([]string, len(fixedArgs)+1) copy(args, fixedArgs) args[len(fixedArgs)] = prompt return FitPromptResult{ OK: true, Args: args, Truncated: false, OriginalLength: len(prompt), FinalPromptLength: len(prompt), } } // Need to truncate: keep the tail of the prompt (most recent messages) prefix := LinuxPromptOmissionPrefix available := argMax - fixedLen - len(prefix) - 1 if available < 0 { available = 0 } var finalPrompt string if available <= 0 { finalPrompt = prefix } else if available >= len(prompt) { finalPrompt = prefix + prompt } else { finalPrompt = prefix + prompt[len(prompt)-available:] } args := make([]string, len(fixedArgs)+1) copy(args, fixedArgs) args[len(fixedArgs)] = finalPrompt return FitPromptResult{ OK: true, Args: args, Truncated: true, OriginalLength: len(prompt), FinalPromptLength: len(finalPrompt), } } func WarnPromptTruncated(originalLength, finalLength int) { _ = originalLength _ = finalLength }