package integrationtools import ( "fmt" "math" "mime" "path/filepath" "regexp" "strconv" "strings" "unicode" ) var ( inlineMarkdownDataURLRe = regexp.MustCompile(`!\[[^\]]*\]\((data:[^)]+)\)`) inlineRawDataURLRe = regexp.MustCompile(`data:[^;\s]+;base64,[A-Za-z0-9+/=\r\n]+`) ) const ( largeBase64OmittedMessage = "[Tool returned a large base64-like payload; omitted from model context.]" inlineMediaOmittedMessage = "[Tool returned inline media content; omitted from model context.]" ) func sanitizeToolLLMContent(text string) string { trimmed := strings.TrimSpace(text) if trimmed == "" { return text } if inlineMarkdownDataURLRe.MatchString(trimmed) || inlineRawDataURLRe.MatchString(trimmed) { cleaned := inlineMarkdownDataURLRe.ReplaceAllString(trimmed, "") cleaned = inlineRawDataURLRe.ReplaceAllString(cleaned, "") cleaned = strings.TrimSpace(cleaned) if cleaned == "" { return inlineMediaOmittedMessage } return cleaned + "\n" + inlineMediaOmittedMessage } if looksLikeLargeBase64Payload(trimmed) { return largeBase64OmittedMessage } return text } func looksLikeLargeBase64Payload(text string) bool { trimmed := strings.TrimSpace(text) if len(trimmed) < 1024 { return false } nonSpace := 0 base64Like := 0 spaceCount := 0 for _, r := range trimmed { if unicode.IsSpace(r) { spaceCount++ continue } nonSpace++ if (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '+' || r == '/' || r == '=' { base64Like++ } } if nonSpace == 0 { return false } ratio := float64(base64Like) / float64(nonSpace) return ratio >= 0.97 && spaceCount <= len(trimmed)/128 } func extensionForMIMEType(mimeType string) string { if mimeType == "" { return ".bin" } if exts, err := mime.ExtensionsByType(mimeType); err == nil && len(exts) > 0 { return exts[0] } switch strings.ToLower(mimeType) { case "image/jpeg": return ".jpg" case "image/png": return ".png" case "image/gif": return ".gif" case "image/webp": return ".webp" case "audio/wav", "audio/x-wav": return ".wav" case "audio/mpeg": return ".mp3" case "audio/ogg": return ".ogg" case "video/mp4": return ".mp4" default: return filepath.Ext(mimeType) } } func getInt64Arg(args map[string]any, key string, defaultVal int64) (int64, error) { raw, exists := args[key] if !exists { return defaultVal, nil } switch v := raw.(type) { case float64: if v != math.Trunc(v) { return 0, fmt.Errorf("%s must be an integer, got float %v", key, v) } if v > math.MaxInt64 || v < math.MinInt64 { return 0, fmt.Errorf("%s value %v overflows int64", key, v) } return int64(v), nil case int: return int64(v), nil case int64: return v, nil case string: parsed, err := strconv.ParseInt(v, 10, 64) if err != nil { return 0, fmt.Errorf("invalid integer format for %s parameter: %w", key, err) } return parsed, nil default: return 0, fmt.Errorf("unsupported type %T for %s parameter", raw, key) } }