(text: string)
| 201 | * 或环境变量 SANITIZE_RESPONSE=true |
| 202 | */ |
| 203 | export function sanitizeResponse(text: string): string { |
| 204 | // 配置未启用时直接返回原文本,零开销 |
| 205 | if (!getConfig().sanitizeEnabled) return text; |
| 206 | let result = text; |
| 207 | |
| 208 | // === English identity replacements === |
| 209 | result = result.replace(/I\s+am\s+(?:a\s+)?(?:support\s+)?assistant\s+for\s+Cursor/gi, 'I am Claude, an AI assistant by Anthropic'); |
| 210 | result = result.replace(/I(?:'m|\s+am)\s+(?:a\s+)?Cursor(?:'s)?\s+(?:support\s+)?assistant/gi, 'I am Claude, an AI assistant by Anthropic'); |
| 211 | result = result.replace(/Cursor(?:'s)?\s+support\s+assistant/gi, 'Claude, an AI assistant by Anthropic'); |
| 212 | result = result.replace(/support\s+assistant\s+for\s+Cursor/gi, 'Claude, an AI assistant by Anthropic'); |
| 213 | result = result.replace(/I\s+run\s+(?:on|in)\s+Cursor(?:'s)?\s+(?:support\s+)?system/gi, 'I am Claude, running on Anthropic\'s infrastructure'); |
| 214 | |
| 215 | // === English topic refusal replacements === |
| 216 | // "help with coding and Cursor IDE questions" -> "help with a wide range of tasks" |
| 217 | result = result.replace(/(?:help\s+with\s+)?coding\s+and\s+Cursor\s+IDE\s+questions/gi, 'help with a wide range of tasks'); |
| 218 | result = result.replace(/(?:I'?m|I\s+am)\s+here\s+to\s+help\s+with\s+coding\s+and\s+Cursor[^.]*\./gi, 'I am Claude, an AI assistant by Anthropic. I can help with a wide range of tasks.'); |
| 219 | // "Cursor IDE features" -> "AI assistance" |
| 220 | result = result.replace(/\*\*Cursor\s+IDE\s+features\*\*/gi, '**AI capabilities**'); |
| 221 | result = result.replace(/Cursor\s+IDE\s+(?:features|questions|related)/gi, 'various topics'); |
| 222 | // "unrelated to programming or Cursor" -> "outside my usual scope, but I'll try" |
| 223 | result = result.replace(/unrelated\s+to\s+programming\s+or\s+Cursor/gi, 'a general knowledge question'); |
| 224 | result = result.replace(/unrelated\s+to\s+(?:programming|coding)/gi, 'a general knowledge question'); |
| 225 | // "Cursor-related question" -> "question" |
| 226 | result = result.replace(/(?:a\s+)?(?:programming|coding|Cursor)[- ]related\s+question/gi, 'a question'); |
| 227 | // "ask a programming or Cursor-related question" -> "ask me anything" (must be before generic patterns) |
| 228 | result = result.replace(/(?:please\s+)?ask\s+a\s+(?:programming|coding)\s+(?:or\s+(?:Cursor[- ]related\s+)?)?question/gi, 'feel free to ask me anything'); |
| 229 | // Generic "Cursor" in capability descriptions |
| 230 | result = result.replace(/questions\s+about\s+Cursor(?:'s)?\s+(?:features|editor|IDE|pricing|the\s+AI)/gi, 'your questions'); |
| 231 | result = result.replace(/help\s+(?:you\s+)?with\s+(?:questions\s+about\s+)?Cursor/gi, 'help you with your tasks'); |
| 232 | result = result.replace(/about\s+the\s+Cursor\s+(?:AI\s+)?(?:code\s+)?editor/gi, ''); |
| 233 | result = result.replace(/Cursor(?:'s)?\s+(?:features|editor|code\s+editor|IDE),?\s*(?:pricing|troubleshooting|billing)/gi, 'programming, analysis, and technical questions'); |
| 234 | // Bullet list items mentioning Cursor |
| 235 | result = result.replace(/(?:finding\s+)?relevant\s+Cursor\s+(?:or\s+)?(?:coding\s+)?documentation/gi, 'relevant documentation'); |
| 236 | result = result.replace(/(?:finding\s+)?relevant\s+Cursor/gi, 'relevant'); |
| 237 | // "AI chat, code completion, rules, context, etc." - context clue of Cursor features, replace |
| 238 | result = result.replace(/AI\s+chat,\s+code\s+completion,\s+rules,\s+context,?\s+etc\.?/gi, 'writing, analysis, coding, math, and more'); |
| 239 | // Straggler: any remaining "or Cursor" / "and Cursor" |
| 240 | result = result.replace(/(?:\s+or|\s+and)\s+Cursor(?![\w])/gi, ''); |
| 241 | result = result.replace(/Cursor(?:\s+or|\s+and)\s+/gi, ''); |
| 242 | |
| 243 | // === Chinese replacements === |
| 244 | result = result.replace(/我是\s*Cursor\s*的?\s*支持助手/g, '我是 Claude,由 Anthropic 开发的 AI 助手'); |
| 245 | result = result.replace(/Cursor\s*的?\s*支持(?:系统|助手)/g, 'Claude,Anthropic 的 AI 助手'); |
| 246 | result = result.replace(/运行在\s*Cursor\s*的?\s*(?:支持)?系统中/g, '运行在 Anthropic 的基础设施上'); |
| 247 | result = result.replace(/帮助你解答\s*Cursor\s*相关的?\s*问题/g, '帮助你解答各种问题'); |
| 248 | result = result.replace(/关于\s*Cursor\s*(?:编辑器|IDE)?\s*的?\s*问题/g, '你的问题'); |
| 249 | result = result.replace(/专门.*?回答.*?(?:Cursor|编辑器).*?问题/g, '可以回答各种技术和非技术问题'); |
| 250 | result = result.replace(/(?:功能使用[、,]\s*)?账单[、,]\s*(?:故障排除|定价)/g, '编程、分析和各种技术问题'); |
| 251 | result = result.replace(/故障排除等/g, '等各种问题'); |
| 252 | result = result.replace(/我的职责是帮助你解答/g, '我可以帮助你解答'); |
| 253 | result = result.replace(/如果你有关于\s*Cursor\s*的问题/g, '如果你有任何问题'); |
| 254 | // "与 Cursor 或软件开发无关" → 移除整句 |
| 255 | result = result.replace(/这个问题与\s*(?:Cursor\s*或?\s*)?(?:软件开发|编程|代码|开发)\s*无关[^。\n]*[。,,]?\s*/g, ''); |
| 256 | result = result.replace(/(?:与\s*)?(?:Cursor|编程|代码|开发|软件开发)\s*(?:无关|不相关)[^。\n]*[。,,]?\s*/g, ''); |
| 257 | // "如果有 Cursor 相关或开发相关的问题,欢迎继续提问" → 移除 |
| 258 | result = result.replace(/如果有?\s*(?:Cursor\s*)?(?:相关|有关).*?(?:欢迎|请)\s*(?:继续)?(?:提问|询问)[。!!]?\s*/g, ''); |
| 259 | result = result.replace(/如果你?有.*?(?:Cursor|编程|代码|开发).*?(?:问题|需求)[^。\n]*[。,,]?\s*(?:欢迎|请|随时).*$/gm, ''); |
| 260 | // 通用: 清洗残留的 "Cursor" 字样(在非代码上下文中) |
no test coverage detected