cursor-api-proxy 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -36
- package/dist/cli/accounts.d.ts +18 -0
- package/dist/cli/accounts.js +149 -0
- package/dist/cli/accounts.js.map +1 -0
- package/dist/cli/args.d.ts +14 -0
- package/dist/cli/args.js +93 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/constants.d.ts +1 -0
- package/dist/cli/constants.js +4 -0
- package/dist/cli/constants.js.map +1 -0
- package/dist/cli/login.d.ts +1 -0
- package/dist/cli/login.js +143 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/cli/reset-hwid.d.ts +24 -0
- package/dist/cli/reset-hwid.js +277 -0
- package/dist/cli/reset-hwid.js.map +1 -0
- package/dist/cli/usage.d.ts +31 -0
- package/dist/cli/usage.js +214 -0
- package/dist/cli/usage.js.map +1 -0
- package/dist/cli.d.ts +1 -4
- package/dist/cli.js +40 -35
- package/dist/cli.js.map +1 -1
- package/dist/lib/account-pool.d.ts +35 -0
- package/dist/lib/account-pool.js +143 -0
- package/dist/lib/account-pool.js.map +1 -0
- package/dist/lib/agent-cmd-args.d.ts +4 -0
- package/dist/lib/agent-cmd-args.js +8 -3
- package/dist/lib/agent-cmd-args.js.map +1 -1
- package/dist/lib/agent-runner.d.ts +2 -2
- package/dist/lib/agent-runner.js +18 -6
- package/dist/lib/agent-runner.js.map +1 -1
- package/dist/lib/anthropic.js +22 -11
- package/dist/lib/anthropic.js.map +1 -1
- package/dist/lib/config.d.ts +6 -0
- package/dist/lib/config.js +3 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/env.d.ts +9 -0
- package/dist/lib/env.js +71 -8
- package/dist/lib/env.js.map +1 -1
- package/dist/lib/handlers/anthropic-messages.js +83 -15
- package/dist/lib/handlers/anthropic-messages.js.map +1 -1
- package/dist/lib/handlers/chat-completions.js +77 -11
- package/dist/lib/handlers/chat-completions.js.map +1 -1
- package/dist/lib/handlers/models.d.ts +1 -0
- package/dist/lib/handlers/models.js +16 -6
- package/dist/lib/handlers/models.js.map +1 -1
- package/dist/lib/http.d.ts +2 -2
- package/dist/lib/http.js +7 -3
- package/dist/lib/http.js.map +1 -1
- package/dist/lib/max-mode-preflight.d.ts +1 -1
- package/dist/lib/max-mode-preflight.js +9 -3
- package/dist/lib/max-mode-preflight.js.map +1 -1
- package/dist/lib/openai.d.ts +10 -0
- package/dist/lib/openai.js +53 -1
- package/dist/lib/openai.js.map +1 -1
- package/dist/lib/process.d.ts +6 -0
- package/dist/lib/process.js +71 -9
- package/dist/lib/process.js.map +1 -1
- package/dist/lib/request-listener.js +28 -4
- package/dist/lib/request-listener.js.map +1 -1
- package/dist/lib/request-log.d.ts +3 -0
- package/dist/lib/request-log.js +37 -0
- package/dist/lib/request-log.js.map +1 -1
- package/dist/lib/sanitize.d.ts +21 -0
- package/dist/lib/sanitize.js +79 -0
- package/dist/lib/sanitize.js.map +1 -0
- package/dist/lib/server.d.ts +6 -1
- package/dist/lib/server.js +76 -0
- package/dist/lib/server.js.map +1 -1
- package/dist/lib/win-cmdline-limit.d.ts +32 -0
- package/dist/lib/win-cmdline-limit.js +92 -0
- package/dist/lib/win-cmdline-limit.js.map +1 -0
- package/package.json +5 -2
package/dist/lib/env.js
CHANGED
|
@@ -50,23 +50,76 @@ function resolveAbsolutePath(raw, cwd) {
|
|
|
50
50
|
return undefined;
|
|
51
51
|
return path.resolve(cwd, raw);
|
|
52
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Auto-discovers configuration directories located inside ~/.cursor-api-proxy/accounts/
|
|
55
|
+
*/
|
|
56
|
+
function isAuthenticatedAccountDir(dir) {
|
|
57
|
+
const configFile = path.join(dir, "cli-config.json");
|
|
58
|
+
if (!fs.existsSync(configFile))
|
|
59
|
+
return false;
|
|
60
|
+
try {
|
|
61
|
+
const config = JSON.parse(fs.readFileSync(configFile, "utf-8"));
|
|
62
|
+
return Boolean(config?.authInfo?.email);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function discoverAccountDirs(homeDir) {
|
|
69
|
+
if (!homeDir)
|
|
70
|
+
return [];
|
|
71
|
+
const accountsDir = path.join(homeDir, ".cursor-api-proxy", "accounts");
|
|
72
|
+
if (!fs.existsSync(accountsDir))
|
|
73
|
+
return [];
|
|
74
|
+
try {
|
|
75
|
+
const entries = fs.readdirSync(accountsDir, { withFileTypes: true });
|
|
76
|
+
return entries
|
|
77
|
+
.filter((e) => e.isDirectory())
|
|
78
|
+
.map((e) => path.join(accountsDir, e.name))
|
|
79
|
+
.filter(isAuthenticatedAccountDir);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
53
85
|
export function loadEnvConfig(opts = {}) {
|
|
54
86
|
const env = getEnvSource(opts.env);
|
|
55
87
|
const cwd = getCwd(opts.cwd);
|
|
56
|
-
const host = envString(env, ["CURSOR_BRIDGE_HOST"]) ??
|
|
88
|
+
const host = envString(env, ["CURSOR_BRIDGE_HOST"]) ??
|
|
89
|
+
(opts.tailscale ? "0.0.0.0" : "127.0.0.1");
|
|
57
90
|
const portValue = envNumber(env, ["CURSOR_BRIDGE_PORT"], 8765);
|
|
58
91
|
const port = Number.isFinite(portValue) && portValue > 0 ? portValue : 8765;
|
|
92
|
+
const home = envString(env, ["HOME", "USERPROFILE"]);
|
|
59
93
|
const sessionsLogPath = (() => {
|
|
60
94
|
const explicit = resolveAbsolutePath(envString(env, ["CURSOR_BRIDGE_SESSIONS_LOG"]), cwd);
|
|
61
95
|
if (explicit)
|
|
62
96
|
return explicit;
|
|
63
|
-
const home = envString(env, ["HOME", "USERPROFILE"]);
|
|
64
97
|
if (home)
|
|
65
98
|
return path.join(home, ".cursor-api-proxy", "sessions.log");
|
|
66
99
|
return path.join(cwd, "sessions.log");
|
|
67
100
|
})();
|
|
101
|
+
const force = envBool(env, ["CURSOR_BRIDGE_FORCE"], false);
|
|
102
|
+
const rawConfigDirs = envString(env, [
|
|
103
|
+
"CURSOR_CONFIG_DIRS",
|
|
104
|
+
"CURSOR_ACCOUNT_DIRS",
|
|
105
|
+
]);
|
|
106
|
+
let configDirs = rawConfigDirs
|
|
107
|
+
? rawConfigDirs
|
|
108
|
+
.split(",")
|
|
109
|
+
.map((d) => resolveAbsolutePath(d.trim(), cwd))
|
|
110
|
+
.filter((d) => d !== undefined)
|
|
111
|
+
: [];
|
|
112
|
+
if (configDirs.length === 0) {
|
|
113
|
+
configDirs = discoverAccountDirs(home);
|
|
114
|
+
}
|
|
115
|
+
const winCmdlineRaw = envNumber(env, ["CURSOR_BRIDGE_WIN_CMDLINE_MAX"], 30_000);
|
|
116
|
+
const winCmdlineMax = Math.min(32_700, Math.max(4096, Number.isFinite(winCmdlineRaw) ? winCmdlineRaw : 30_000));
|
|
68
117
|
return {
|
|
69
|
-
agentBin: envString(env, [
|
|
118
|
+
agentBin: envString(env, [
|
|
119
|
+
"CURSOR_AGENT_BIN",
|
|
120
|
+
"CURSOR_CLI_BIN",
|
|
121
|
+
"CURSOR_CLI_PATH",
|
|
122
|
+
]) ?? "agent",
|
|
70
123
|
agentNode: envString(env, ["CURSOR_AGENT_NODE"]),
|
|
71
124
|
agentScript: envString(env, ["CURSOR_AGENT_SCRIPT"]),
|
|
72
125
|
commandShell: envString(env, ["COMSPEC"]) ?? "cmd.exe",
|
|
@@ -74,10 +127,11 @@ export function loadEnvConfig(opts = {}) {
|
|
|
74
127
|
port,
|
|
75
128
|
requiredKey: envString(env, ["CURSOR_BRIDGE_API_KEY"]),
|
|
76
129
|
defaultModel: normalizeModelId(envString(env, ["CURSOR_BRIDGE_DEFAULT_MODEL"])),
|
|
77
|
-
force
|
|
130
|
+
force,
|
|
78
131
|
approveMcps: envBool(env, ["CURSOR_BRIDGE_APPROVE_MCPS"], false),
|
|
79
132
|
strictModel: envBool(env, ["CURSOR_BRIDGE_STRICT_MODEL"], true),
|
|
80
|
-
workspace: resolveAbsolutePath(envString(env, ["CURSOR_BRIDGE_WORKSPACE"]), cwd) ??
|
|
133
|
+
workspace: resolveAbsolutePath(envString(env, ["CURSOR_BRIDGE_WORKSPACE"]), cwd) ??
|
|
134
|
+
cwd,
|
|
81
135
|
timeoutMs: envNumber(env, ["CURSOR_BRIDGE_TIMEOUT_MS"], 300_000),
|
|
82
136
|
tlsCertPath: resolveAbsolutePath(envString(env, ["CURSOR_BRIDGE_TLS_CERT"]), cwd),
|
|
83
137
|
tlsKeyPath: resolveAbsolutePath(envString(env, ["CURSOR_BRIDGE_TLS_KEY"]), cwd),
|
|
@@ -85,6 +139,9 @@ export function loadEnvConfig(opts = {}) {
|
|
|
85
139
|
chatOnlyWorkspace: envBool(env, ["CURSOR_BRIDGE_CHAT_ONLY_WORKSPACE"], true),
|
|
86
140
|
verbose: envBool(env, ["CURSOR_BRIDGE_VERBOSE"], false),
|
|
87
141
|
maxMode: envBool(env, ["CURSOR_BRIDGE_MAX_MODE"], false),
|
|
142
|
+
configDirs,
|
|
143
|
+
multiPort: envBool(env, ["CURSOR_BRIDGE_MULTI_PORT"], false),
|
|
144
|
+
winCmdlineMax,
|
|
88
145
|
};
|
|
89
146
|
}
|
|
90
147
|
export function resolveAgentCommand(cmd, args, opts = {}) {
|
|
@@ -104,7 +161,9 @@ export function resolveAgentCommand(cmd, args, opts = {}) {
|
|
|
104
161
|
args: [loaded.agentScript, ...args],
|
|
105
162
|
env: { ...env, CURSOR_INVOKED_AS: "agent.cmd" },
|
|
106
163
|
agentScriptPath,
|
|
107
|
-
configDir: fs.existsSync(path.join(configDir, "cli-config.json"))
|
|
164
|
+
configDir: fs.existsSync(path.join(configDir, "cli-config.json"))
|
|
165
|
+
? configDir
|
|
166
|
+
: undefined,
|
|
108
167
|
};
|
|
109
168
|
return out;
|
|
110
169
|
}
|
|
@@ -120,10 +179,14 @@ export function resolveAgentCommand(cmd, args, opts = {}) {
|
|
|
120
179
|
args: [script, ...args],
|
|
121
180
|
env: { ...env, CURSOR_INVOKED_AS: "agent.cmd" },
|
|
122
181
|
agentScriptPath: script,
|
|
123
|
-
configDir: fs.existsSync(path.join(configDir, "cli-config.json"))
|
|
182
|
+
configDir: fs.existsSync(path.join(configDir, "cli-config.json"))
|
|
183
|
+
? configDir
|
|
184
|
+
: undefined,
|
|
124
185
|
};
|
|
125
186
|
}
|
|
126
|
-
const quotedArgs = args
|
|
187
|
+
const quotedArgs = args
|
|
188
|
+
.map((arg) => (arg.includes(" ") ? `"${arg}"` : arg))
|
|
189
|
+
.join(" ");
|
|
127
190
|
const cmdLine = `""${cmd}" ${quotedArgs}"`;
|
|
128
191
|
return {
|
|
129
192
|
command: loaded.commandShell,
|
package/dist/lib/env.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +1,33 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { buildPromptFromAnthropicMessages } from "../anthropic.js";
|
|
3
|
-
import {
|
|
3
|
+
import { buildAgentFixedArgs } from "../agent-cmd-args.js";
|
|
4
4
|
import { runAgentStream, runAgentSync } from "../agent-runner.js";
|
|
5
5
|
import { createStreamParser } from "../cli-stream-parser.js";
|
|
6
6
|
import { json, writeSseHeaders } from "../http.js";
|
|
7
7
|
import { resolveToCursorModel } from "../model-map.js";
|
|
8
|
-
import { normalizeModelId } from "../openai.js";
|
|
9
|
-
import { logAgentError, logTrafficRequest, logTrafficResponse, } from "../request-log.js";
|
|
8
|
+
import { normalizeModelId, toolsToSystemText } from "../openai.js";
|
|
9
|
+
import { logAgentError, logAccountAssigned, logAccountStats, logTrafficRequest, logTrafficResponse, } from "../request-log.js";
|
|
10
10
|
import { resolveModel } from "../resolve-model.js";
|
|
11
11
|
import { resolveWorkspace } from "../workspace.js";
|
|
12
|
+
import { sanitizeMessages, sanitizeSystem } from "../sanitize.js";
|
|
13
|
+
import { getNextAccountConfigDir, reportRequestStart, reportRequestEnd, reportRateLimit, reportRequestSuccess, reportRequestError, getAccountStats, } from "../account-pool.js";
|
|
14
|
+
import { fitPromptToWinCmdline, warnPromptTruncated, } from "../win-cmdline-limit.js";
|
|
15
|
+
function isRateLimited(stderr) {
|
|
16
|
+
return /\b429\b|rate.?limit|too many requests/i.test(stderr);
|
|
17
|
+
}
|
|
12
18
|
export async function handleAnthropicMessages(req, res, ctx, rawBody, method, pathname, remoteAddress) {
|
|
13
19
|
const { config, lastRequestedModelRef } = ctx;
|
|
14
20
|
const body = JSON.parse(rawBody || "{}");
|
|
15
21
|
const requested = normalizeModelId(body.model);
|
|
16
22
|
const model = resolveModel(requested, lastRequestedModelRef, config);
|
|
23
|
+
const cleanSystem = sanitizeSystem(body.system);
|
|
24
|
+
const cleanMessages = sanitizeMessages(body.messages ?? []);
|
|
25
|
+
// Inject Anthropic tool schemas as a system text block
|
|
26
|
+
const toolsText = toolsToSystemText(body.tools);
|
|
27
|
+
const systemWithTools = toolsText
|
|
28
|
+
? [cleanSystem, toolsText].filter(Boolean).join("\n\n")
|
|
29
|
+
: cleanSystem;
|
|
30
|
+
const prompt = buildPromptFromAnthropicMessages(cleanMessages, systemWithTools);
|
|
17
31
|
if (body.max_tokens == null || typeof body.max_tokens !== "number") {
|
|
18
32
|
json(res, 400, {
|
|
19
33
|
error: {
|
|
@@ -24,19 +38,18 @@ export async function handleAnthropicMessages(req, res, ctx, rawBody, method, pa
|
|
|
24
38
|
return;
|
|
25
39
|
}
|
|
26
40
|
const cursorModel = resolveToCursorModel(model) ?? model;
|
|
27
|
-
const prompt = buildPromptFromAnthropicMessages(body.messages, body.system);
|
|
28
41
|
const trafficMessages = [];
|
|
29
|
-
if (
|
|
30
|
-
const sys = typeof
|
|
31
|
-
?
|
|
32
|
-
:
|
|
42
|
+
if (cleanSystem) {
|
|
43
|
+
const sys = typeof cleanSystem === "string"
|
|
44
|
+
? cleanSystem
|
|
45
|
+
: cleanSystem
|
|
33
46
|
.filter((p) => p.type === "text")
|
|
34
47
|
.map((p) => p.text ?? "")
|
|
35
48
|
.join("\n");
|
|
36
49
|
if (sys.trim())
|
|
37
50
|
trafficMessages.push({ role: "system", content: sys.trim() });
|
|
38
51
|
}
|
|
39
|
-
for (const m of
|
|
52
|
+
for (const m of cleanMessages) {
|
|
40
53
|
const text = typeof m.content === "string"
|
|
41
54
|
? m.content
|
|
42
55
|
: m.content
|
|
@@ -49,10 +62,31 @@ export async function handleAnthropicMessages(req, res, ctx, rawBody, method, pa
|
|
|
49
62
|
logTrafficRequest(config.verbose, model ?? cursorModel, trafficMessages, !!body.stream);
|
|
50
63
|
const headerWs = req.headers["x-cursor-workspace"];
|
|
51
64
|
const { workspaceDir, tempDir } = resolveWorkspace(config, headerWs);
|
|
52
|
-
const
|
|
65
|
+
const fixedArgs = buildAgentFixedArgs(config, workspaceDir, cursorModel, !!body.stream);
|
|
66
|
+
const fit = fitPromptToWinCmdline(config.agentBin, fixedArgs, prompt, {
|
|
67
|
+
maxCmdline: config.winCmdlineMax,
|
|
68
|
+
platform: process.platform,
|
|
69
|
+
cwd: workspaceDir,
|
|
70
|
+
});
|
|
71
|
+
if (!fit.ok) {
|
|
72
|
+
json(res, 500, {
|
|
73
|
+
error: { type: "api_error", message: fit.error },
|
|
74
|
+
});
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (fit.truncated) {
|
|
78
|
+
warnPromptTruncated(fit.originalLength, fit.finalPromptLength);
|
|
79
|
+
}
|
|
80
|
+
const cmdArgs = fit.args;
|
|
53
81
|
const msgId = `msg_${randomUUID().replace(/-/g, "")}`;
|
|
82
|
+
const truncatedHeaders = fit.truncated
|
|
83
|
+
? { "X-Cursor-Proxy-Prompt-Truncated": "true" }
|
|
84
|
+
: undefined;
|
|
54
85
|
if (body.stream) {
|
|
55
|
-
writeSseHeaders(res);
|
|
86
|
+
writeSseHeaders(res, truncatedHeaders);
|
|
87
|
+
res.on("error", () => {
|
|
88
|
+
/* client disconnected mid-stream */
|
|
89
|
+
});
|
|
56
90
|
const writeEvent = (evt) => {
|
|
57
91
|
res.write(`data: ${JSON.stringify(evt)}\n\n`);
|
|
58
92
|
};
|
|
@@ -84,33 +118,67 @@ export async function handleAnthropicMessages(req, res, ctx, rawBody, method, pa
|
|
|
84
118
|
writeEvent({ type: "content_block_stop", index: 0 });
|
|
85
119
|
writeEvent({
|
|
86
120
|
type: "message_delta",
|
|
87
|
-
delta: { stop_reason: "end_turn" },
|
|
121
|
+
delta: { stop_reason: "end_turn", stop_sequence: null },
|
|
122
|
+
usage: { output_tokens: 0 },
|
|
88
123
|
});
|
|
89
124
|
writeEvent({ type: "message_stop" });
|
|
90
125
|
});
|
|
91
|
-
|
|
126
|
+
const configDir = getNextAccountConfigDir();
|
|
127
|
+
logAccountAssigned(configDir);
|
|
128
|
+
reportRequestStart(configDir);
|
|
129
|
+
const streamStart = Date.now();
|
|
130
|
+
const abortController = new AbortController();
|
|
131
|
+
req.once("close", () => abortController.abort());
|
|
132
|
+
runAgentStream(config, workspaceDir, cmdArgs, parseLine, tempDir, configDir, abortController.signal)
|
|
92
133
|
.then(({ code, stderr: stderrOut }) => {
|
|
134
|
+
const latencyMs = Date.now() - streamStart;
|
|
135
|
+
reportRequestEnd(configDir);
|
|
136
|
+
if (stderrOut && isRateLimited(stderrOut)) {
|
|
137
|
+
reportRateLimit(configDir, 60000);
|
|
138
|
+
}
|
|
93
139
|
if (code !== 0) {
|
|
140
|
+
reportRequestError(configDir, latencyMs);
|
|
94
141
|
logAgentError(config.sessionsLogPath, method, pathname, remoteAddress, code, stderrOut);
|
|
95
142
|
}
|
|
143
|
+
else {
|
|
144
|
+
reportRequestSuccess(configDir, latencyMs);
|
|
145
|
+
}
|
|
146
|
+
logAccountStats(config.verbose, getAccountStats());
|
|
96
147
|
res.end();
|
|
97
148
|
})
|
|
98
149
|
.catch((err) => {
|
|
150
|
+
reportRequestEnd(configDir);
|
|
151
|
+
reportRequestError(configDir, Date.now() - streamStart);
|
|
99
152
|
console.error(`[${new Date().toISOString()}] Agent stream error:`, err);
|
|
100
153
|
res.end();
|
|
101
154
|
});
|
|
102
155
|
return;
|
|
103
156
|
}
|
|
104
|
-
const
|
|
157
|
+
const configDir = getNextAccountConfigDir();
|
|
158
|
+
logAccountAssigned(configDir);
|
|
159
|
+
reportRequestStart(configDir);
|
|
160
|
+
const syncStart = Date.now();
|
|
161
|
+
const abortController = new AbortController();
|
|
162
|
+
req.once("close", () => abortController.abort());
|
|
163
|
+
const out = await runAgentSync(config, workspaceDir, cmdArgs, tempDir, configDir, abortController.signal);
|
|
164
|
+
const syncLatency = Date.now() - syncStart;
|
|
165
|
+
reportRequestEnd(configDir);
|
|
166
|
+
if (out.stderr && isRateLimited(out.stderr)) {
|
|
167
|
+
reportRateLimit(configDir, 60000);
|
|
168
|
+
}
|
|
105
169
|
if (out.code !== 0) {
|
|
170
|
+
reportRequestError(configDir, syncLatency);
|
|
171
|
+
logAccountStats(config.verbose, getAccountStats());
|
|
106
172
|
const errMsg = logAgentError(config.sessionsLogPath, method, pathname, remoteAddress, out.code, out.stderr);
|
|
107
173
|
json(res, 500, {
|
|
108
174
|
error: { type: "api_error", message: errMsg },
|
|
109
175
|
});
|
|
110
176
|
return;
|
|
111
177
|
}
|
|
178
|
+
reportRequestSuccess(configDir, syncLatency);
|
|
112
179
|
const content = out.stdout.trim();
|
|
113
180
|
logTrafficResponse(config.verbose, model ?? cursorModel, content, false);
|
|
181
|
+
logAccountStats(config.verbose, getAccountStats());
|
|
114
182
|
json(res, 200, {
|
|
115
183
|
id: msgId,
|
|
116
184
|
type: "message",
|
|
@@ -119,6 +187,6 @@ export async function handleAnthropicMessages(req, res, ctx, rawBody, method, pa
|
|
|
119
187
|
model: model ?? cursorModel,
|
|
120
188
|
stop_reason: "end_turn",
|
|
121
189
|
usage: { input_tokens: 0, output_tokens: 0 },
|
|
122
|
-
});
|
|
190
|
+
}, truncatedHeaders);
|
|
123
191
|
}
|
|
124
192
|
//# sourceMappingURL=anthropic-messages.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-messages.js","sourceRoot":"","sources":["../../../src/lib/handlers/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAIzC,OAAO,EAAE,gCAAgC,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"anthropic-messages.js","sourceRoot":"","sources":["../../../src/lib/handlers/anthropic-messages.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import { buildAgentFixedArgs } from "../agent-cmd-args.js";
|
|
3
3
|
import { runAgentStream, runAgentSync } from "../agent-runner.js";
|
|
4
4
|
import { createStreamParser } from "../cli-stream-parser.js";
|
|
5
5
|
import { json, writeSseHeaders } from "../http.js";
|
|
6
6
|
import { resolveToCursorModel } from "../model-map.js";
|
|
7
|
-
import { buildPromptFromMessages, normalizeModelId, } from "../openai.js";
|
|
8
|
-
import { logAgentError, logTrafficRequest, logTrafficResponse, } from "../request-log.js";
|
|
7
|
+
import { buildPromptFromMessages, normalizeModelId, toolsToSystemText, } from "../openai.js";
|
|
8
|
+
import { logAgentError, logAccountAssigned, logAccountStats, logTrafficRequest, logTrafficResponse, } from "../request-log.js";
|
|
9
9
|
import { resolveModel } from "../resolve-model.js";
|
|
10
10
|
import { resolveWorkspace } from "../workspace.js";
|
|
11
|
+
import { sanitizeMessages } from "../sanitize.js";
|
|
12
|
+
import { getNextAccountConfigDir, reportRequestStart, reportRequestEnd, reportRateLimit, reportRequestSuccess, reportRequestError, getAccountStats, } from "../account-pool.js";
|
|
13
|
+
import { fitPromptToWinCmdline, warnPromptTruncated, } from "../win-cmdline-limit.js";
|
|
14
|
+
function isRateLimited(stderr) {
|
|
15
|
+
return /\b429\b|rate.?limit|too many requests/i.test(stderr);
|
|
16
|
+
}
|
|
11
17
|
export async function handleChatCompletions(req, res, ctx, rawBody, method, pathname, remoteAddress) {
|
|
12
18
|
const { config, lastRequestedModelRef } = ctx;
|
|
13
19
|
const body = JSON.parse(rawBody || "{}");
|
|
14
20
|
const requested = normalizeModelId(body.model);
|
|
15
21
|
const model = resolveModel(requested, lastRequestedModelRef, config);
|
|
16
22
|
const cursorModel = resolveToCursorModel(model) ?? model;
|
|
17
|
-
const
|
|
18
|
-
|
|
23
|
+
const cleanMessages = sanitizeMessages(body.messages ?? []);
|
|
24
|
+
// Inject tool/function schemas as a system message so the model is aware of them
|
|
25
|
+
const toolsText = toolsToSystemText(body.tools, body.functions);
|
|
26
|
+
const messagesWithTools = toolsText
|
|
27
|
+
? [{ role: "system", content: toolsText }, ...cleanMessages]
|
|
28
|
+
: cleanMessages;
|
|
29
|
+
const prompt = buildPromptFromMessages(messagesWithTools);
|
|
30
|
+
const trafficMessages = cleanMessages.map((m) => {
|
|
19
31
|
const content = typeof m?.content === "string"
|
|
20
32
|
? m.content
|
|
21
33
|
: Array.isArray(m?.content)
|
|
@@ -29,11 +41,32 @@ export async function handleChatCompletions(req, res, ctx, rawBody, method, path
|
|
|
29
41
|
logTrafficRequest(config.verbose, model ?? cursorModel, trafficMessages, !!body.stream);
|
|
30
42
|
const headerWs = req.headers["x-cursor-workspace"];
|
|
31
43
|
const { workspaceDir, tempDir } = resolveWorkspace(config, headerWs);
|
|
32
|
-
const
|
|
44
|
+
const fixedArgs = buildAgentFixedArgs(config, workspaceDir, cursorModel, !!body.stream);
|
|
45
|
+
const fit = fitPromptToWinCmdline(config.agentBin, fixedArgs, prompt, {
|
|
46
|
+
maxCmdline: config.winCmdlineMax,
|
|
47
|
+
platform: process.platform,
|
|
48
|
+
cwd: workspaceDir,
|
|
49
|
+
});
|
|
50
|
+
if (!fit.ok) {
|
|
51
|
+
json(res, 500, {
|
|
52
|
+
error: { message: fit.error, code: "windows_cmdline_limit" },
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (fit.truncated) {
|
|
57
|
+
warnPromptTruncated(fit.originalLength, fit.finalPromptLength);
|
|
58
|
+
}
|
|
59
|
+
const cmdArgs = fit.args;
|
|
33
60
|
const id = `chatcmpl_${randomUUID().replace(/-/g, "")}`;
|
|
34
61
|
const created = Math.floor(Date.now() / 1000);
|
|
62
|
+
const truncatedHeaders = fit.truncated
|
|
63
|
+
? { "X-Cursor-Proxy-Prompt-Truncated": "true" }
|
|
64
|
+
: undefined;
|
|
35
65
|
if (body.stream) {
|
|
36
|
-
writeSseHeaders(res);
|
|
66
|
+
writeSseHeaders(res, truncatedHeaders);
|
|
67
|
+
res.on("error", () => {
|
|
68
|
+
/* client disconnected mid-stream */
|
|
69
|
+
});
|
|
37
70
|
let accumulated = "";
|
|
38
71
|
const parseLine = createStreamParser((text) => {
|
|
39
72
|
accumulated += text;
|
|
@@ -57,29 +90,62 @@ export async function handleChatCompletions(req, res, ctx, rawBody, method, path
|
|
|
57
90
|
})}\n\n`);
|
|
58
91
|
res.write("data: [DONE]\n\n");
|
|
59
92
|
});
|
|
60
|
-
|
|
93
|
+
const configDir = getNextAccountConfigDir();
|
|
94
|
+
logAccountAssigned(configDir);
|
|
95
|
+
reportRequestStart(configDir);
|
|
96
|
+
const streamStart = Date.now();
|
|
97
|
+
const abortController = new AbortController();
|
|
98
|
+
req.once("close", () => abortController.abort());
|
|
99
|
+
runAgentStream(config, workspaceDir, cmdArgs, parseLine, tempDir, configDir, abortController.signal)
|
|
61
100
|
.then(({ code, stderr: stderrOut }) => {
|
|
62
|
-
|
|
101
|
+
const latencyMs = Date.now() - streamStart;
|
|
102
|
+
reportRequestEnd(configDir);
|
|
103
|
+
if (stderrOut && isRateLimited(stderrOut)) {
|
|
104
|
+
reportRateLimit(configDir, 60000);
|
|
105
|
+
}
|
|
106
|
+
if (code !== 0 && !abortController.signal.aborted) {
|
|
107
|
+
reportRequestError(configDir, latencyMs);
|
|
63
108
|
logAgentError(config.sessionsLogPath, method, pathname, remoteAddress, code, stderrOut);
|
|
64
109
|
}
|
|
110
|
+
else {
|
|
111
|
+
reportRequestSuccess(configDir, latencyMs);
|
|
112
|
+
}
|
|
113
|
+
logAccountStats(config.verbose, getAccountStats());
|
|
65
114
|
res.end();
|
|
66
115
|
})
|
|
67
116
|
.catch((err) => {
|
|
117
|
+
reportRequestEnd(configDir);
|
|
118
|
+
reportRequestError(configDir, Date.now() - streamStart);
|
|
68
119
|
console.error(`[${new Date().toISOString()}] Agent stream error:`, err);
|
|
69
120
|
res.end();
|
|
70
121
|
});
|
|
71
122
|
return;
|
|
72
123
|
}
|
|
73
|
-
const
|
|
124
|
+
const configDir = getNextAccountConfigDir();
|
|
125
|
+
logAccountAssigned(configDir);
|
|
126
|
+
reportRequestStart(configDir);
|
|
127
|
+
const syncStart = Date.now();
|
|
128
|
+
const abortController = new AbortController();
|
|
129
|
+
req.once("close", () => abortController.abort());
|
|
130
|
+
const out = await runAgentSync(config, workspaceDir, cmdArgs, tempDir, configDir, abortController.signal);
|
|
131
|
+
const syncLatency = Date.now() - syncStart;
|
|
132
|
+
reportRequestEnd(configDir);
|
|
133
|
+
if (out.stderr && isRateLimited(out.stderr)) {
|
|
134
|
+
reportRateLimit(configDir, 60000);
|
|
135
|
+
}
|
|
74
136
|
if (out.code !== 0) {
|
|
137
|
+
reportRequestError(configDir, syncLatency);
|
|
138
|
+
logAccountStats(config.verbose, getAccountStats());
|
|
75
139
|
const errMsg = logAgentError(config.sessionsLogPath, method, pathname, remoteAddress, out.code, out.stderr);
|
|
76
140
|
json(res, 500, {
|
|
77
141
|
error: { message: errMsg, code: "cursor_cli_error" },
|
|
78
142
|
});
|
|
79
143
|
return;
|
|
80
144
|
}
|
|
145
|
+
reportRequestSuccess(configDir, syncLatency);
|
|
81
146
|
const content = out.stdout.trim();
|
|
82
147
|
logTrafficResponse(config.verbose, model ?? cursorModel, content, false);
|
|
148
|
+
logAccountStats(config.verbose, getAccountStats());
|
|
83
149
|
json(res, 200, {
|
|
84
150
|
id,
|
|
85
151
|
object: "chat.completion",
|
|
@@ -93,6 +159,6 @@ export async function handleChatCompletions(req, res, ctx, rawBody, method, path
|
|
|
93
159
|
},
|
|
94
160
|
],
|
|
95
161
|
usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
|
|
96
|
-
});
|
|
162
|
+
}, truncatedHeaders);
|
|
97
163
|
}
|
|
98
164
|
//# sourceMappingURL=chat-completions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-completions.js","sourceRoot":"","sources":["../../../src/lib/handlers/chat-completions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAIzC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"chat-completions.js","sourceRoot":"","sources":["../../../src/lib/handlers/chat-completions.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,13 +7,23 @@ export async function handleModels(res, opts) {
|
|
|
7
7
|
const now = Date.now();
|
|
8
8
|
if (!modelCacheRef.current ||
|
|
9
9
|
now - modelCacheRef.current.at > MODEL_CACHE_TTL_MS) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
// Deduplicate concurrent fetches — reuse a single in-flight promise
|
|
11
|
+
if (!modelCacheRef.inflight) {
|
|
12
|
+
modelCacheRef.inflight = listCursorCliModels({
|
|
13
|
+
agentBin: config.agentBin,
|
|
14
|
+
timeoutMs: 60_000,
|
|
15
|
+
}).then((models) => {
|
|
16
|
+
modelCacheRef.current = { at: Date.now(), models };
|
|
17
|
+
modelCacheRef.inflight = undefined;
|
|
18
|
+
return models;
|
|
19
|
+
}, (err) => {
|
|
20
|
+
modelCacheRef.inflight = undefined;
|
|
21
|
+
throw err;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
await modelCacheRef.inflight;
|
|
15
25
|
}
|
|
16
|
-
const models = modelCacheRef.current
|
|
26
|
+
const models = modelCacheRef.current?.models ?? [];
|
|
17
27
|
const cursorModels = models.map((m) => ({
|
|
18
28
|
id: m.id,
|
|
19
29
|
object: "model",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../src/lib/handlers/models.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAE3D,MAAM,kBAAkB,GAAG,CAAC,GAAG,MAAM,CAAC;AAStC,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAwB,EACxB,IAAsB;IAEtB,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IACE,CAAC,aAAa,CAAC,OAAO;QACtB,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,kBAAkB,EACnD,CAAC;QACD,
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../src/lib/handlers/models.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAE3D,MAAM,kBAAkB,GAAG,CAAC,GAAG,MAAM,CAAC;AAStC,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAwB,EACxB,IAAsB;IAEtB,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IACE,CAAC,aAAa,CAAC,OAAO;QACtB,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,kBAAkB,EACnD,CAAC;QACD,oEAAoE;QACpE,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC5B,aAAa,CAAC,QAAQ,GAAG,mBAAmB,CAAC;gBAC3C,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,SAAS,EAAE,MAAM;aAClB,CAAC,CAAC,IAAI,CACL,CAAC,MAAM,EAAE,EAAE;gBACT,aAAa,CAAC,OAAO,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC;gBACnD,aAAa,CAAC,QAAQ,GAAG,SAAS,CAAC;gBACnC,OAAO,MAAM,CAAC;YAChB,CAAC,EACD,CAAC,GAAG,EAAE,EAAE;gBACN,aAAa,CAAC,QAAQ,GAAG,SAAS,CAAC;gBACnC,MAAM,GAAG,CAAC;YACZ,CAAC,CACF,CAAC;QACJ,CAAC;QACD,MAAM,aAAa,CAAC,QAAQ,CAAC;IAC/B,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,MAAM,IAAI,EAAE,CAAC;IACnD,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACtC,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,MAAM,EAAE,OAAgB;QACxB,QAAQ,EAAE,QAAiB;QAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;KACb,CAAC,CAAC,CAAC;IACJ,MAAM,gBAAgB,GAAG,wBAAwB,CAC/C,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACxB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACZ,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,MAAM,EAAE,OAAgB;QACxB,QAAQ,EAAE,QAAiB;QAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;KACb,CAAC,CAAC,CAAC;IAEJ,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE;QACb,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,CAAC,GAAG,YAAY,EAAE,GAAG,gBAAgB,CAAC;KAC7C,CAAC,CAAC;AACL,CAAC"}
|
package/dist/lib/http.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as http from "node:http";
|
|
2
2
|
export declare function extractBearerToken(req: http.IncomingMessage): string | undefined;
|
|
3
|
-
export declare function json(res: http.ServerResponse, status: number, body: unknown): void;
|
|
4
|
-
export declare function writeSseHeaders(res: http.ServerResponse): void;
|
|
3
|
+
export declare function json(res: http.ServerResponse, status: number, body: unknown, extraHeaders?: http.OutgoingHttpHeaders): void;
|
|
4
|
+
export declare function writeSseHeaders(res: http.ServerResponse, extraHeaders?: http.OutgoingHttpHeaders): void;
|
|
5
5
|
export declare function readBody(req: http.IncomingMessage): Promise<string>;
|
package/dist/lib/http.js
CHANGED
|
@@ -6,12 +6,16 @@ export function extractBearerToken(req) {
|
|
|
6
6
|
const match = val.match(/^Bearer\s+(.+)$/i);
|
|
7
7
|
return match ? match[1] : undefined;
|
|
8
8
|
}
|
|
9
|
-
export function json(res, status, body) {
|
|
10
|
-
res.writeHead(status, {
|
|
9
|
+
export function json(res, status, body, extraHeaders) {
|
|
10
|
+
res.writeHead(status, {
|
|
11
|
+
...extraHeaders,
|
|
12
|
+
"Content-Type": "application/json",
|
|
13
|
+
});
|
|
11
14
|
res.end(JSON.stringify(body));
|
|
12
15
|
}
|
|
13
|
-
export function writeSseHeaders(res) {
|
|
16
|
+
export function writeSseHeaders(res, extraHeaders) {
|
|
14
17
|
res.writeHead(200, {
|
|
18
|
+
...extraHeaders,
|
|
15
19
|
"Content-Type": "text/event-stream",
|
|
16
20
|
"Cache-Control": "no-cache",
|
|
17
21
|
Connection: "keep-alive",
|