fix: force Agent mode in Cursor protobuf when User-Agent contains Claude Code (closes #643) (#692)

This commit is contained in:
Anurag Saxena
2026-04-21 23:24:58 -04:00
committed by GitHub
parent 95841f9a48
commit 37f7e97348
3 changed files with 13 additions and 8 deletions

View File

@@ -132,7 +132,10 @@ export class CursorExecutor extends BaseExecutor {
const messages = body.messages || [];
const tools = body.tools || [];
const reasoningEffort = body.reasoning_effort || null;
return generateCursorBody(messages, model, tools, reasoningEffort);
// Detect Claude Code UA to force Agent mode (issue #643)
const ua = credentials?.rawHeaders?.["user-agent"] || "";
const forceAgentMode = ua.includes("claude-cli") || ua.includes("claude-code") || ua.includes("Claude Code");
return generateCursorBody(messages, model, tools, reasoningEffort, forceAgentMode);
}
async makeFetchRequest(url, headers, body, signal, proxyOptions = null) {

View File

@@ -169,8 +169,10 @@ function convertMessages(messages) {
export function buildCursorRequest(model, body, stream, credentials) {
const messages = convertMessages(body.messages || []);
// Strip fields irrelevant to Cursor (OpenAI/Anthropic-specific)
const { user, metadata, tool_choice, stream_options, system, ...rest } = body;
return {
...rest,
messages,

View File

@@ -447,9 +447,9 @@ export function encodeMcpTool(tool) {
// ==================== REQUEST BUILDING ====================
export function encodeRequest(messages, modelName, tools = [], reasoningEffort = null) {
export function encodeRequest(messages, modelName, tools = [], reasoningEffort = null, forceAgentMode = false) {
const hasTools = tools?.length > 0;
const isAgentic = hasTools;
const isAgentic = hasTools || forceAgentMode;
const formattedMessages = [];
const messageIds = [];
const normalizedMessages = [];
@@ -583,8 +583,8 @@ export function encodeRequest(messages, modelName, tools = [], reasoningEffort =
);
}
export function buildChatRequest(messages, modelName, tools = [], reasoningEffort = null) {
return encodeField(FIELD.REQUEST, WIRE_TYPE.LEN, encodeRequest(messages, modelName, tools, reasoningEffort));
export function buildChatRequest(messages, modelName, tools = [], reasoningEffort = null, forceAgentMode = false) {
return encodeField(FIELD.REQUEST, WIRE_TYPE.LEN, encodeRequest(messages, modelName, tools, reasoningEffort, forceAgentMode));
}
/**
@@ -646,10 +646,10 @@ export function wrapConnectRPCFrame(payload, compress = false) {
return frame;
}
export function generateCursorBody(messages, modelName, tools = [], reasoningEffort = null) {
log("BODY", `Generating: ${messages.length} msgs, model=${modelName}, tools=${tools.length}, reasoning=${reasoningEffort || "none"}`);
export function generateCursorBody(messages, modelName, tools = [], reasoningEffort = null, forceAgentMode = false) {
log("BODY", `Generating: ${messages.length} msgs, model=${modelName}, tools=${tools.length}, reasoning=${reasoningEffort || "none"}, forceAgentMode=${forceAgentMode}`);
const protobuf = buildChatRequest(messages, modelName, tools, reasoningEffort);
const protobuf = buildChatRequest(messages, modelName, tools, reasoningEffort, forceAgentMode);
const framed = wrapConnectRPCFrame(protobuf, false); // Cursor doesn't support compressed requests
log("BODY", `Protobuf=${protobuf.length}B, Framed=${framed.length}B`);