MCPcopy
hub / github.com/7836246/cursor2api / convertToCursorRequest

Function convertToCursorRequest

src/converter.ts:210–837  ·  view source on GitHub ↗
(req: AnthropicRequest)

Source from the content-addressed store, hash-verified

208 * 不覆盖模型身份,而是顺应它在 IDE 内的角色,让它认为自己在执行 IDE 内部的自动化任务
209 */
210export async function convertToCursorRequest(req: AnthropicRequest): Promise<CursorChatRequest> {
211 const config = getConfig();
212
213 // ★ 图片预处理:在协议转换之前,检测并处理 Anthropic 格式的 ImageBlockParam
214 await preprocessImages(req.messages);
215
216 // ★ 预估原始上下文大小,驱动动态工具结果预算
217 let estimatedContextChars = 0;
218 if (req.system) {
219 estimatedContextChars += typeof req.system === 'string' ? req.system.length : JSON.stringify(req.system).length;
220 }
221 for (const msg of req.messages ?? []) {
222 estimatedContextChars += typeof msg.content === 'string' ? msg.content.length : JSON.stringify(msg.content).length;
223 }
224 if (req.tools && req.tools.length > 0) {
225 estimatedContextChars += req.tools.length * 150; // 压缩后每个工具约 150 chars
226 }
227 setCurrentContextChars(estimatedContextChars);
228
229 const messages: CursorMessage[] = [];
230 const hasTools = req.tools && req.tools.length > 0;
231
232 // 提取系统提示词
233 let combinedSystem = '';
234 if (req.system) {
235 if (typeof req.system === 'string') combinedSystem = req.system;
236 else if (Array.isArray(req.system)) {
237 combinedSystem = req.system.filter(b => b.type === 'text').map(b => b.text).join('\n');
238 }
239 }
240
241 // ★ 计费头清除:x-anthropic-billing-header 会被模型判定为恶意伪造并触发注入警告
242 if (combinedSystem) {
243 combinedSystem = combinedSystem.replace(/^x-anthropic-billing-header[^\n]*$/gim, '');
244 // ★ Claude Code 身份声明清除:模型看到 "You are Claude Code" 会认为是 prompt injection
245 combinedSystem = combinedSystem.replace(/^You are Claude Code[^\n]*$/gim, '');
246 combinedSystem = combinedSystem.replace(/^You are Claude,\s+Anthropic's[^\n]*$/gim, '');
247 combinedSystem = combinedSystem.replace(/\n{3,}/g, '\n\n').trim();
248 }
249 // ★ Thinking 提示注入:根据是否有工具选择不同的注入位置
250 // 有工具时:放在工具指令末尾(不会被工具定义覆盖,模型更容易注意)
251 // 无工具时:放在系统提示词末尾(原有行为,已验证有效)
252 const thinkingEnabled = req.thinking?.type === 'enabled' || req.thinking?.type === 'adaptive';
253 const thinkingHint = '\n\n**IMPORTANT**: Before your response, you MUST first think through the problem step by step inside <thinking>...</thinking> tags. Your thinking process will be extracted and shown separately. After the closing </thinking> tag, provide your actual response or actions.';
254 if (thinkingEnabled && !hasTools) {
255 combinedSystem = (combinedSystem || '') + thinkingHint;
256 }
257
258 if (hasTools) {
259 const tools = req.tools!;
260 const toolChoice = req.tool_choice;
261 const toolsCfg = config.tools || { schemaMode: 'compact', descriptionMaxLength: 50 };
262 const isDisabled = toolsCfg.disabled === true;
263 const isPassthrough = toolsCfg.passthrough === true;
264
265 if (isDisabled) {
266 // ★ 禁用模式:完全不注入工具定义和 few-shot 示例
267 // 目的:最大化节省上下文空间,让模型凭训练记忆处理工具调用

Callers 11

handleOpenAIStreamFunction · 0.85
handleOpenAINonStreamFunction · 0.85
handleOpenAIResponsesFunction · 0.85
handleResponsesStreamFunction · 0.85
handleResponsesNonStreamFunction · 0.85
handleMessagesFunction · 0.85
handleDirectTextStreamFunction · 0.85
handleStreamFunction · 0.85
handleNonStreamFunction · 0.85

Calls 15

getConfigFunction · 0.90
preprocessImagesFunction · 0.85
setCurrentContextCharsFunction · 0.85
buildToolInstructionsFunction · 0.85
isCoreToolNameFunction · 0.85
getToolNamespaceFunction · 0.85
makeExampleParamsFunction · 0.85
hasToolResultBlockFunction · 0.85
extractMessageTextFunction · 0.85
generateFallbackParamsFunction · 0.85
extractToolResultNaturalFunction · 0.85
processTagsFunction · 0.85

Tested by

no test coverage detected