mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-08-18 03:57:06 +08:00
395 lines
11 KiB
Go
395 lines
11 KiB
Go
package forwarder
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
const (
|
|
projectedReplayKiB = 1024
|
|
|
|
projectedReadReplayLimit = 64 * projectedReplayKiB
|
|
projectedShellReplayLimit = 128 * projectedReplayKiB
|
|
projectedShellStreamLimit = 16 * projectedReplayKiB
|
|
projectedShellInterleavedLimit = 32 * projectedReplayKiB
|
|
projectedGrepReplayLimit = 32 * projectedReplayKiB
|
|
projectedEditReplayLimit = 32 * projectedReplayKiB
|
|
projectedPatchEditReplayLimit = 4 * projectedReplayKiB
|
|
projectedWebFetchReplayLimit = 32 * projectedReplayKiB
|
|
projectedWebSearchReplayLimit = 16 * projectedReplayKiB
|
|
projectedMcpReplayLimit = 32 * projectedReplayKiB
|
|
)
|
|
|
|
func limitProjectedToolResultReplay(toolName string, content string, resultText string, fromStoredToolCall bool, historical bool) string {
|
|
if compacted, ok := compactProjectedGenerateImageResultReplay(toolName, content, resultText); ok {
|
|
return compacted
|
|
}
|
|
if historical {
|
|
if compacted, ok := compactHistoricalEditErrorReplay(toolName, content); ok {
|
|
content = compacted
|
|
fromStoredToolCall = false
|
|
}
|
|
}
|
|
if compacted, ok := compactProjectedEditToolResultReplay(toolName, content); ok {
|
|
content = compacted
|
|
fromStoredToolCall = false
|
|
}
|
|
if compacted, ok := compactProjectedShellToolResultReplay(toolName, content); ok {
|
|
content = compacted
|
|
fromStoredToolCall = false
|
|
}
|
|
limit, ok := projectedToolReplayLimit(toolName)
|
|
if !ok {
|
|
return strings.TrimSpace(content)
|
|
}
|
|
content = strings.TrimSpace(content)
|
|
if len(content) <= limit {
|
|
return content
|
|
}
|
|
if fromStoredToolCall {
|
|
fallback := strings.TrimSpace(resultText)
|
|
notice := fmt.Sprintf("[tool result replay truncated: stored ToolCall result exceeded %d bytes]", limit)
|
|
if fallback == "" {
|
|
fallback = notice
|
|
} else {
|
|
fallback += "\n\n" + notice
|
|
}
|
|
return truncateProjectedReplayText(toolName, fallback, limit)
|
|
}
|
|
return truncateProjectedReplayText(toolName, content, limit)
|
|
}
|
|
|
|
func projectedToolReplayLimit(toolName string) (int, bool) {
|
|
switch strings.TrimSpace(toolName) {
|
|
case "GenerateImage":
|
|
return projectedWebSearchReplayLimit, true
|
|
case "Read":
|
|
return projectedReadReplayLimit, true
|
|
case "Shell":
|
|
return projectedShellReplayLimit, true
|
|
case "Grep":
|
|
return projectedGrepReplayLimit, true
|
|
case "PatchEdit", "PatchEditLines", "PatchEditSpan":
|
|
return projectedPatchEditReplayLimit, true
|
|
case "Edit", "Write":
|
|
return projectedEditReplayLimit, true
|
|
case "WebFetch":
|
|
return projectedWebFetchReplayLimit, true
|
|
case "WebSearch":
|
|
return projectedWebSearchReplayLimit, true
|
|
case "CallMcpTool", "FetchMcpResource", "ListMcpResources":
|
|
return projectedMcpReplayLimit, true
|
|
default:
|
|
return 0, false
|
|
}
|
|
}
|
|
|
|
func compactProjectedGenerateImageResultReplay(toolName string, content string, resultText string) (string, bool) {
|
|
if strings.TrimSpace(toolName) != "GenerateImage" {
|
|
return "", false
|
|
}
|
|
fallback := strings.TrimSpace(resultText)
|
|
trimmed := strings.TrimSpace(content)
|
|
if trimmed == "" || trimmed == "{}" || trimmed == "null" {
|
|
if fallback == "" {
|
|
return "", false
|
|
}
|
|
return fallback, true
|
|
}
|
|
var payload any
|
|
if err := json.Unmarshal([]byte(trimmed), &payload); err != nil {
|
|
if fallback == "" {
|
|
return truncateProjectedReplayText("GenerateImage", trimmed, projectedWebSearchReplayLimit), true
|
|
}
|
|
return fallback, true
|
|
}
|
|
if compactGenerateImagePayload(payload) {
|
|
encoded, err := json.Marshal(payload)
|
|
if err == nil {
|
|
return string(encoded), true
|
|
}
|
|
}
|
|
if fallback != "" {
|
|
return fallback, true
|
|
}
|
|
return trimmed, true
|
|
}
|
|
|
|
func compactGenerateImagePayload(value any) bool {
|
|
changed := false
|
|
switch item := value.(type) {
|
|
case map[string]any:
|
|
for key, child := range item {
|
|
if text, ok := child.(string); ok {
|
|
switch key {
|
|
case "image_data", "imageData":
|
|
item[key] = fmt.Sprintf("[base64 image data omitted from replay; bytes=%d]", len(strings.TrimSpace(text)))
|
|
changed = true
|
|
continue
|
|
}
|
|
}
|
|
if compactGenerateImagePayload(child) {
|
|
changed = true
|
|
}
|
|
}
|
|
case []any:
|
|
for _, child := range item {
|
|
if compactGenerateImagePayload(child) {
|
|
changed = true
|
|
}
|
|
}
|
|
}
|
|
return changed
|
|
}
|
|
|
|
func patchEditReplayLimit(toolName string) int {
|
|
switch strings.TrimSpace(toolName) {
|
|
case "PatchEdit", "PatchEditLines", "PatchEditSpan":
|
|
return projectedPatchEditReplayLimit
|
|
default:
|
|
return projectedEditReplayLimit
|
|
}
|
|
}
|
|
|
|
func compactProjectedShellToolResultReplay(toolName string, content string) (string, bool) {
|
|
if strings.TrimSpace(toolName) != "Shell" {
|
|
return "", false
|
|
}
|
|
trimmed := strings.TrimSpace(content)
|
|
if trimmed == "" || trimmed == "{}" || trimmed == "null" {
|
|
return "", false
|
|
}
|
|
var payload any
|
|
if err := json.Unmarshal([]byte(trimmed), &payload); err != nil {
|
|
return "", false
|
|
}
|
|
if !compactProjectedShellFields(payload) {
|
|
return "", false
|
|
}
|
|
encoded, err := json.Marshal(payload)
|
|
if err != nil {
|
|
return "", false
|
|
}
|
|
return string(encoded), true
|
|
}
|
|
|
|
func compactProjectedShellFields(value any) bool {
|
|
changed := false
|
|
switch item := value.(type) {
|
|
case map[string]any:
|
|
for key, child := range item {
|
|
if text, ok := child.(string); ok {
|
|
switch key {
|
|
case "stdout", "stderr":
|
|
next := truncateProjectedReplayTextMiddle("Shell "+key, text, projectedShellStreamLimit)
|
|
if next != text {
|
|
item[key] = next
|
|
changed = true
|
|
}
|
|
continue
|
|
case "interleaved_output", "interleavedOutput":
|
|
next := truncateProjectedReplayTextMiddle("Shell interleaved output", text, projectedShellInterleavedLimit)
|
|
if next != text {
|
|
item[key] = next
|
|
changed = true
|
|
}
|
|
continue
|
|
}
|
|
}
|
|
if compactProjectedShellFields(child) {
|
|
changed = true
|
|
}
|
|
}
|
|
case []any:
|
|
for _, child := range item {
|
|
if compactProjectedShellFields(child) {
|
|
changed = true
|
|
}
|
|
}
|
|
}
|
|
return changed
|
|
}
|
|
|
|
func compactProjectedEditToolResultReplay(toolName string, content string) (string, bool) {
|
|
switch strings.TrimSpace(toolName) {
|
|
case "PatchEdit", "PatchEditLines", "PatchEditSpan", "Edit", "Write":
|
|
default:
|
|
return "", false
|
|
}
|
|
trimmed := strings.TrimSpace(content)
|
|
if trimmed == "" || trimmed == "{}" || trimmed == "null" {
|
|
return "", false
|
|
}
|
|
var payload map[string]any
|
|
if err := json.Unmarshal([]byte(trimmed), &payload); err != nil {
|
|
return "", false
|
|
}
|
|
success, ok := payload["success"].(map[string]any)
|
|
if !ok {
|
|
return "", false
|
|
}
|
|
diffString := firstJSONText(success, "diff_string", "diffString")
|
|
beforeContent := ""
|
|
afterContent := ""
|
|
if diffString == "" {
|
|
beforeContent = firstJSONText(success, "before_full_file_content", "beforeFullFileContent")
|
|
afterContent = firstJSONText(success, "after_full_file_content", "afterFullFileContent")
|
|
if beforeContent != "" {
|
|
diffString, _, _ = computeEditDiff(beforeContent, afterContent)
|
|
}
|
|
}
|
|
if diffString != "" {
|
|
diffString = truncateProjectedReplayText(firstNonEmpty(strings.TrimSpace(toolName), "PatchEdit"), diffString, patchEditReplayLimit(toolName))
|
|
encoded, err := json.Marshal(map[string]any{
|
|
"success": map[string]any{
|
|
"diff_string": diffString,
|
|
},
|
|
})
|
|
if err != nil {
|
|
return "", false
|
|
}
|
|
return string(encoded), true
|
|
}
|
|
if afterContent != "" {
|
|
afterContent = truncateProjectedReplayText(firstNonEmpty(strings.TrimSpace(toolName), "Write"), afterContent, patchEditReplayLimit(toolName))
|
|
encoded, err := json.Marshal(map[string]any{
|
|
"success": map[string]any{
|
|
"after_full_file_content": afterContent,
|
|
},
|
|
})
|
|
if err != nil {
|
|
return "", false
|
|
}
|
|
return string(encoded), true
|
|
}
|
|
return "", false
|
|
}
|
|
|
|
func compactHistoricalEditErrorReplay(toolName string, content string) (string, bool) {
|
|
switch strings.TrimSpace(toolName) {
|
|
case "PatchEdit", "PatchEditLines", "PatchEditSpan", "Edit", "Write":
|
|
default:
|
|
return "", false
|
|
}
|
|
trimmed := strings.TrimSpace(content)
|
|
if trimmed == "" {
|
|
return "", false
|
|
}
|
|
var payload map[string]any
|
|
if err := json.Unmarshal([]byte(trimmed), &payload); err != nil {
|
|
return "", false
|
|
}
|
|
errorPayload, ok := payload["error"].(map[string]any)
|
|
if !ok {
|
|
return "", false
|
|
}
|
|
if firstJSONText(errorPayload, "error", "modelVisibleError") == "" {
|
|
return "", false
|
|
}
|
|
encoded, err := json.Marshal(map[string]any{
|
|
"error": map[string]any{
|
|
"error": "historical edit error omitted from replay; re-read the file before editing",
|
|
},
|
|
})
|
|
if err != nil {
|
|
return "", false
|
|
}
|
|
return string(encoded), true
|
|
}
|
|
|
|
func firstJSONText(payload map[string]any, keys ...string) string {
|
|
for _, key := range keys {
|
|
if value, ok := payload[key].(string); ok {
|
|
return value
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func truncateProjectedReplayText(toolName string, text string, limit int) string {
|
|
if limit <= 0 || len(text) <= limit {
|
|
return strings.TrimSpace(text)
|
|
}
|
|
original := len(text)
|
|
notice := fmt.Sprintf("\n\n[truncated: %s result exceeded %d bytes; showing %d of %d bytes]", toolName, limit, limit, original)
|
|
for {
|
|
keep := limit - len(notice)
|
|
if keep <= 0 {
|
|
return truncateProjectedUTF8(text, limit)
|
|
}
|
|
kept := truncateProjectedUTF8(text, keep)
|
|
nextNotice := fmt.Sprintf("\n\n[truncated: %s result exceeded %d bytes; showing %d of %d bytes]", toolName, limit, len(kept), original)
|
|
output := strings.TrimRight(kept, "\n") + nextNotice
|
|
if len(output) <= limit || nextNotice == notice {
|
|
return output
|
|
}
|
|
notice = nextNotice
|
|
}
|
|
}
|
|
|
|
func truncateProjectedReplayTextMiddle(toolName string, text string, limit int) string {
|
|
if limit <= 0 {
|
|
return ""
|
|
}
|
|
if len(text) <= limit {
|
|
return text
|
|
}
|
|
original := len(text)
|
|
notice := fmt.Sprintf("\n\n[truncated: %s result exceeded %d bytes; omitted middle; showing %d of %d bytes]\n\n", toolName, limit, limit, original)
|
|
for {
|
|
keep := limit - len(notice)
|
|
if keep <= 0 {
|
|
return truncateProjectedUTF8(text, limit)
|
|
}
|
|
headLimit := keep / 2
|
|
tailLimit := keep - headLimit
|
|
head := truncateProjectedUTF8(text, headLimit)
|
|
tail := truncateProjectedUTF8Suffix(text, tailLimit)
|
|
kept := len(head) + len(tail)
|
|
nextNotice := fmt.Sprintf("\n\n[truncated: %s result exceeded %d bytes; omitted middle; showing %d of %d bytes]\n\n", toolName, limit, kept, original)
|
|
output := head + nextNotice + tail
|
|
if len(output) <= limit || nextNotice == notice {
|
|
return output
|
|
}
|
|
notice = nextNotice
|
|
}
|
|
}
|
|
|
|
func truncateProjectedUTF8(text string, limit int) string {
|
|
if limit <= 0 {
|
|
return ""
|
|
}
|
|
if len(text) <= limit {
|
|
return text
|
|
}
|
|
if limit > len(text) {
|
|
limit = len(text)
|
|
}
|
|
truncated := text[:limit]
|
|
for !utf8.ValidString(truncated) && len(truncated) > 0 {
|
|
truncated = truncated[:len(truncated)-1]
|
|
}
|
|
return truncated
|
|
}
|
|
|
|
func truncateProjectedUTF8Suffix(text string, limit int) string {
|
|
if limit <= 0 {
|
|
return ""
|
|
}
|
|
if len(text) <= limit {
|
|
return text
|
|
}
|
|
start := len(text) - limit
|
|
if start < 0 {
|
|
start = 0
|
|
}
|
|
suffix := text[start:]
|
|
for !utf8.ValidString(suffix) && start < len(text) {
|
|
start++
|
|
suffix = text[start:]
|
|
}
|
|
return suffix
|
|
}
|