cursor-api-proxy 0.3.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.
Files changed (80) hide show
  1. package/README.md +219 -0
  2. package/dist/cli.d.ts +5 -0
  3. package/dist/cli.js +53 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/client.d.ts +95 -0
  6. package/dist/client.js +316 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/lib/agent-cmd-args.d.ts +5 -0
  9. package/dist/lib/agent-cmd-args.js +24 -0
  10. package/dist/lib/agent-cmd-args.js.map +1 -0
  11. package/dist/lib/agent-runner.d.ts +12 -0
  12. package/dist/lib/agent-runner.js +38 -0
  13. package/dist/lib/agent-runner.js.map +1 -0
  14. package/dist/lib/anthropic.d.ts +26 -0
  15. package/dist/lib/anthropic.js +59 -0
  16. package/dist/lib/anthropic.js.map +1 -0
  17. package/dist/lib/cli-stream-parser.d.ts +8 -0
  18. package/dist/lib/cli-stream-parser.js +46 -0
  19. package/dist/lib/cli-stream-parser.js.map +1 -0
  20. package/dist/lib/config.d.ts +28 -0
  21. package/dist/lib/config.js +24 -0
  22. package/dist/lib/config.js.map +1 -0
  23. package/dist/lib/cursor-cli.d.ts +9 -0
  24. package/dist/lib/cursor-cli.js +30 -0
  25. package/dist/lib/cursor-cli.js.map +1 -0
  26. package/dist/lib/cursorCli.d.ts +9 -0
  27. package/dist/lib/cursorCli.js +30 -0
  28. package/dist/lib/cursorCli.js.map +1 -0
  29. package/dist/lib/env.d.ts +41 -0
  30. package/dist/lib/env.js +138 -0
  31. package/dist/lib/env.js.map +1 -0
  32. package/dist/lib/handlers/anthropic-messages.d.ts +9 -0
  33. package/dist/lib/handlers/anthropic-messages.js +124 -0
  34. package/dist/lib/handlers/anthropic-messages.js.map +1 -0
  35. package/dist/lib/handlers/chat-completions.d.ts +9 -0
  36. package/dist/lib/handlers/chat-completions.js +98 -0
  37. package/dist/lib/handlers/chat-completions.js.map +1 -0
  38. package/dist/lib/handlers/health.d.ts +7 -0
  39. package/dist/lib/handlers/health.js +15 -0
  40. package/dist/lib/handlers/health.js.map +1 -0
  41. package/dist/lib/handlers/models.d.ts +14 -0
  42. package/dist/lib/handlers/models.js +34 -0
  43. package/dist/lib/handlers/models.js.map +1 -0
  44. package/dist/lib/http.d.ts +5 -0
  45. package/dist/lib/http.js +32 -0
  46. package/dist/lib/http.js.map +1 -0
  47. package/dist/lib/max-mode-preflight.d.ts +5 -0
  48. package/dist/lib/max-mode-preflight.js +56 -0
  49. package/dist/lib/max-mode-preflight.js.map +1 -0
  50. package/dist/lib/model-map.d.ts +17 -0
  51. package/dist/lib/model-map.js +62 -0
  52. package/dist/lib/model-map.js.map +1 -0
  53. package/dist/lib/modelMap.d.ts +17 -0
  54. package/dist/lib/modelMap.js +62 -0
  55. package/dist/lib/modelMap.js.map +1 -0
  56. package/dist/lib/openai.d.ts +7 -0
  57. package/dist/lib/openai.js +59 -0
  58. package/dist/lib/openai.js.map +1 -0
  59. package/dist/lib/process.d.ts +19 -0
  60. package/dist/lib/process.js +92 -0
  61. package/dist/lib/process.js.map +1 -0
  62. package/dist/lib/request-listener.d.ts +7 -0
  63. package/dist/lib/request-listener.js +70 -0
  64. package/dist/lib/request-listener.js.map +1 -0
  65. package/dist/lib/request-log.d.ts +13 -0
  66. package/dist/lib/request-log.js +110 -0
  67. package/dist/lib/request-log.js.map +1 -0
  68. package/dist/lib/requestLog.d.ts +2 -0
  69. package/dist/lib/requestLog.js +19 -0
  70. package/dist/lib/requestLog.js.map +1 -0
  71. package/dist/lib/resolve-model.d.ts +8 -0
  72. package/dist/lib/resolve-model.js +18 -0
  73. package/dist/lib/resolve-model.js.map +1 -0
  74. package/dist/lib/server.d.ts +8 -0
  75. package/dist/lib/server.js +35 -0
  76. package/dist/lib/server.js.map +1 -0
  77. package/dist/lib/workspace.d.ts +6 -0
  78. package/dist/lib/workspace.js +15 -0
  79. package/dist/lib/workspace.js.map +1 -0
  80. package/package.json +50 -0
@@ -0,0 +1,30 @@
1
+ import { tmpdir } from "node:os";
2
+ import { run } from "./process.js";
3
+ export function parseCursorCliModels(output) {
4
+ const lines = output.split(/\r?\n/g).map((l) => l.trim());
5
+ const models = [];
6
+ for (const line of lines) {
7
+ const match = line.match(/^([A-Za-z0-9][A-Za-z0-9._:/-]*)\s+-\s+(.*)$/);
8
+ if (!match)
9
+ continue;
10
+ const id = match[1];
11
+ const rawName = match[2];
12
+ const name = rawName.replace(/\s*\([^)]*\)\s*$/g, "").trim();
13
+ models.push({ id, name: name || id });
14
+ }
15
+ const byId = new Map();
16
+ for (const m of models)
17
+ byId.set(m.id, m);
18
+ return [...byId.values()];
19
+ }
20
+ export async function listCursorCliModels(args) {
21
+ const list = await run(args.agentBin, ["--list-models"], {
22
+ cwd: tmpdir(),
23
+ timeoutMs: args.timeoutMs,
24
+ });
25
+ if (list.code !== 0) {
26
+ throw new Error(`agent --list-models failed: ${list.stderr.trim()}`);
27
+ }
28
+ return parseCursorCliModels(list.stdout);
29
+ }
30
+ //# sourceMappingURL=cursor-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-cli.js","sourceRoot":"","sources":["../../src/lib/cursor-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAInC,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAqB,EAAE,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACxE,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7D,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,MAAM;QAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAGzC;IACC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,eAAe,CAAC,EAAE;QACvD,GAAG,EAAE,MAAM,EAAE;QACb,SAAS,EAAE,IAAI,CAAC,SAAS;KAC1B,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,9 @@
1
+ export type CursorCliModel = {
2
+ id: string;
3
+ name: string;
4
+ };
5
+ export declare function parseCursorCliModels(output: string): CursorCliModel[];
6
+ export declare function listCursorCliModels(args: {
7
+ agentBin: string;
8
+ timeoutMs: number;
9
+ }): Promise<CursorCliModel[]>;
@@ -0,0 +1,30 @@
1
+ import { tmpdir } from "node:os";
2
+ import { run } from "./process.js";
3
+ export function parseCursorCliModels(output) {
4
+ const lines = output.split(/\r?\n/g).map((l) => l.trim());
5
+ const models = [];
6
+ for (const line of lines) {
7
+ const match = line.match(/^([A-Za-z0-9][A-Za-z0-9._:/-]*)\s+-\s+(.*)$/);
8
+ if (!match)
9
+ continue;
10
+ const id = match[1];
11
+ const rawName = match[2];
12
+ const name = rawName.replace(/\s*\([^)]*\)\s*$/g, "").trim();
13
+ models.push({ id, name: name || id });
14
+ }
15
+ const byId = new Map();
16
+ for (const m of models)
17
+ byId.set(m.id, m);
18
+ return [...byId.values()];
19
+ }
20
+ export async function listCursorCliModels(args) {
21
+ const list = await run(args.agentBin, ["--list-models"], {
22
+ cwd: tmpdir(),
23
+ timeoutMs: args.timeoutMs,
24
+ });
25
+ if (list.code !== 0) {
26
+ throw new Error(`agent --list-models failed: ${list.stderr.trim()}`);
27
+ }
28
+ return parseCursorCliModels(list.stdout);
29
+ }
30
+ //# sourceMappingURL=cursorCli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursorCli.js","sourceRoot":"","sources":["../../src/lib/cursorCli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAInC,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAqB,EAAE,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACxE,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7D,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,MAAM;QAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAGzC;IACC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,eAAe,CAAC,EAAE;QACvD,GAAG,EAAE,MAAM,EAAE;QACb,SAAS,EAAE,IAAI,CAAC,SAAS;KAC1B,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,41 @@
1
+ export type EnvSource = Record<string, string | undefined>;
2
+ export type EnvOptions = {
3
+ tailscale?: boolean;
4
+ env?: EnvSource;
5
+ cwd?: string;
6
+ platform?: NodeJS.Platform;
7
+ };
8
+ export type LoadedEnv = {
9
+ agentBin: string;
10
+ agentNode?: string;
11
+ agentScript?: string;
12
+ commandShell: string;
13
+ host: string;
14
+ port: number;
15
+ requiredKey?: string;
16
+ defaultModel: string;
17
+ force: boolean;
18
+ approveMcps: boolean;
19
+ strictModel: boolean;
20
+ workspace: string;
21
+ timeoutMs: number;
22
+ tlsCertPath?: string;
23
+ tlsKeyPath?: string;
24
+ sessionsLogPath: string;
25
+ chatOnlyWorkspace: boolean;
26
+ verbose: boolean;
27
+ /** When true, set maxMode in cli-config.json before each run (larger context, more tools). */
28
+ maxMode: boolean;
29
+ };
30
+ export type AgentCommand = {
31
+ command: string;
32
+ args: string[];
33
+ env: EnvSource;
34
+ windowsVerbatimArguments?: boolean;
35
+ /** Path to agent entry script (e.g. index.js). Set when using node+script so max-mode preflight can find config. */
36
+ agentScriptPath?: string;
37
+ /** Cursor config dir (cli-config.json). Set so CLI reads the same config preflight wrote to. */
38
+ configDir?: string;
39
+ };
40
+ export declare function loadEnvConfig(opts?: EnvOptions): LoadedEnv;
41
+ export declare function resolveAgentCommand(cmd: string, args: string[], opts?: EnvOptions): AgentCommand;
@@ -0,0 +1,138 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ function getEnvSource(env) {
4
+ return env ?? process.env;
5
+ }
6
+ function getCwd(cwd) {
7
+ return cwd ?? process.cwd();
8
+ }
9
+ function firstDefined(env, names) {
10
+ for (const name of names) {
11
+ const value = env[name];
12
+ if (value != null)
13
+ return value;
14
+ }
15
+ return undefined;
16
+ }
17
+ function envString(env, names) {
18
+ const value = firstDefined(env, names);
19
+ if (value == null)
20
+ return undefined;
21
+ const trimmed = value.trim();
22
+ return trimmed ? trimmed : undefined;
23
+ }
24
+ function envBool(env, names, defaultValue) {
25
+ const raw = envString(env, names);
26
+ if (raw == null)
27
+ return defaultValue;
28
+ const value = raw.toLowerCase();
29
+ if (value === "1" || value === "true" || value === "yes" || value === "on")
30
+ return true;
31
+ if (value === "0" || value === "false" || value === "no" || value === "off")
32
+ return false;
33
+ return defaultValue;
34
+ }
35
+ function envNumber(env, names, defaultValue) {
36
+ const raw = envString(env, names);
37
+ if (raw == null)
38
+ return defaultValue;
39
+ const value = Number(raw);
40
+ return Number.isFinite(value) ? value : defaultValue;
41
+ }
42
+ function normalizeModelId(raw) {
43
+ if (!raw)
44
+ return "auto";
45
+ const parts = raw.split("/");
46
+ return parts[parts.length - 1] || "auto";
47
+ }
48
+ function resolveAbsolutePath(raw, cwd) {
49
+ if (!raw)
50
+ return undefined;
51
+ return path.resolve(cwd, raw);
52
+ }
53
+ export function loadEnvConfig(opts = {}) {
54
+ const env = getEnvSource(opts.env);
55
+ const cwd = getCwd(opts.cwd);
56
+ const host = envString(env, ["CURSOR_BRIDGE_HOST"]) ?? (opts.tailscale ? "0.0.0.0" : "127.0.0.1");
57
+ const portValue = envNumber(env, ["CURSOR_BRIDGE_PORT"], 8765);
58
+ const port = Number.isFinite(portValue) && portValue > 0 ? portValue : 8765;
59
+ const sessionsLogPath = (() => {
60
+ const explicit = resolveAbsolutePath(envString(env, ["CURSOR_BRIDGE_SESSIONS_LOG"]), cwd);
61
+ if (explicit)
62
+ return explicit;
63
+ const home = envString(env, ["HOME", "USERPROFILE"]);
64
+ if (home)
65
+ return path.join(home, ".cursor-api-proxy", "sessions.log");
66
+ return path.join(cwd, "sessions.log");
67
+ })();
68
+ return {
69
+ agentBin: envString(env, ["CURSOR_AGENT_BIN", "CURSOR_CLI_BIN", "CURSOR_CLI_PATH"]) ?? "agent",
70
+ agentNode: envString(env, ["CURSOR_AGENT_NODE"]),
71
+ agentScript: envString(env, ["CURSOR_AGENT_SCRIPT"]),
72
+ commandShell: envString(env, ["COMSPEC"]) ?? "cmd.exe",
73
+ host,
74
+ port,
75
+ requiredKey: envString(env, ["CURSOR_BRIDGE_API_KEY"]),
76
+ defaultModel: normalizeModelId(envString(env, ["CURSOR_BRIDGE_DEFAULT_MODEL"])),
77
+ force: envBool(env, ["CURSOR_BRIDGE_FORCE"], false),
78
+ approveMcps: envBool(env, ["CURSOR_BRIDGE_APPROVE_MCPS"], false),
79
+ strictModel: envBool(env, ["CURSOR_BRIDGE_STRICT_MODEL"], true),
80
+ workspace: resolveAbsolutePath(envString(env, ["CURSOR_BRIDGE_WORKSPACE"]), cwd) ?? cwd,
81
+ timeoutMs: envNumber(env, ["CURSOR_BRIDGE_TIMEOUT_MS"], 300_000),
82
+ tlsCertPath: resolveAbsolutePath(envString(env, ["CURSOR_BRIDGE_TLS_CERT"]), cwd),
83
+ tlsKeyPath: resolveAbsolutePath(envString(env, ["CURSOR_BRIDGE_TLS_KEY"]), cwd),
84
+ sessionsLogPath,
85
+ chatOnlyWorkspace: envBool(env, ["CURSOR_BRIDGE_CHAT_ONLY_WORKSPACE"], true),
86
+ verbose: envBool(env, ["CURSOR_BRIDGE_VERBOSE"], false),
87
+ maxMode: envBool(env, ["CURSOR_BRIDGE_MAX_MODE"], false),
88
+ };
89
+ }
90
+ export function resolveAgentCommand(cmd, args, opts = {}) {
91
+ const env = getEnvSource(opts.env);
92
+ const loaded = loadEnvConfig(opts);
93
+ const platform = opts.platform ?? process.platform;
94
+ const cwd = getCwd(opts.cwd);
95
+ if (platform === "win32") {
96
+ if (loaded.agentNode && loaded.agentScript) {
97
+ const agentScriptPath = path.isAbsolute(loaded.agentScript)
98
+ ? loaded.agentScript
99
+ : path.resolve(cwd, loaded.agentScript);
100
+ const agentDir = path.dirname(agentScriptPath);
101
+ const configDir = path.join(agentDir, "..", "data", "config");
102
+ const out = {
103
+ command: loaded.agentNode,
104
+ args: [loaded.agentScript, ...args],
105
+ env: { ...env, CURSOR_INVOKED_AS: "agent.cmd" },
106
+ agentScriptPath,
107
+ configDir: fs.existsSync(path.join(configDir, "cli-config.json")) ? configDir : undefined,
108
+ };
109
+ return out;
110
+ }
111
+ if (/\.cmd$/i.test(cmd)) {
112
+ const cmdResolved = path.resolve(cwd, cmd);
113
+ const dir = path.dirname(cmdResolved);
114
+ const nodeBin = path.join(dir, "node.exe");
115
+ const script = path.join(dir, "index.js");
116
+ if (fs.existsSync(nodeBin) && fs.existsSync(script)) {
117
+ const configDir = path.join(dir, "..", "data", "config");
118
+ return {
119
+ command: nodeBin,
120
+ args: [script, ...args],
121
+ env: { ...env, CURSOR_INVOKED_AS: "agent.cmd" },
122
+ agentScriptPath: script,
123
+ configDir: fs.existsSync(path.join(configDir, "cli-config.json")) ? configDir : undefined,
124
+ };
125
+ }
126
+ const quotedArgs = args.map((arg) => (arg.includes(" ") ? `"${arg}"` : arg)).join(" ");
127
+ const cmdLine = `""${cmd}" ${quotedArgs}"`;
128
+ return {
129
+ command: loaded.commandShell,
130
+ args: ["/d", "/s", "/c", cmdLine],
131
+ env,
132
+ windowsVerbatimArguments: true,
133
+ };
134
+ }
135
+ }
136
+ return { command: cmd, args, env };
137
+ }
138
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import * as http from "node:http";
2
+ import type { BridgeConfig } from "../config.js";
3
+ export type AnthropicMessagesCtx = {
4
+ config: BridgeConfig;
5
+ lastRequestedModelRef: {
6
+ current?: string;
7
+ };
8
+ };
9
+ export declare function handleAnthropicMessages(req: http.IncomingMessage, res: http.ServerResponse, ctx: AnthropicMessagesCtx, rawBody: string, method: string, pathname: string, remoteAddress: string): Promise<void>;
@@ -0,0 +1,124 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { buildPromptFromAnthropicMessages } from "../anthropic.js";
3
+ import { buildAgentCmdArgs } from "../agent-cmd-args.js";
4
+ import { runAgentStream, runAgentSync } from "../agent-runner.js";
5
+ import { createStreamParser } from "../cli-stream-parser.js";
6
+ import { json, writeSseHeaders } from "../http.js";
7
+ import { resolveToCursorModel } from "../model-map.js";
8
+ import { normalizeModelId } from "../openai.js";
9
+ import { logAgentError, logTrafficRequest, logTrafficResponse, } from "../request-log.js";
10
+ import { resolveModel } from "../resolve-model.js";
11
+ import { resolveWorkspace } from "../workspace.js";
12
+ export async function handleAnthropicMessages(req, res, ctx, rawBody, method, pathname, remoteAddress) {
13
+ const { config, lastRequestedModelRef } = ctx;
14
+ const body = JSON.parse(rawBody || "{}");
15
+ const requested = normalizeModelId(body.model);
16
+ const model = resolveModel(requested, lastRequestedModelRef, config);
17
+ if (body.max_tokens == null || typeof body.max_tokens !== "number") {
18
+ json(res, 400, {
19
+ error: {
20
+ type: "invalid_request_error",
21
+ message: "max_tokens is required",
22
+ },
23
+ });
24
+ return;
25
+ }
26
+ const cursorModel = resolveToCursorModel(model) ?? model;
27
+ const prompt = buildPromptFromAnthropicMessages(body.messages, body.system);
28
+ const trafficMessages = [];
29
+ if (body.system) {
30
+ const sys = typeof body.system === "string"
31
+ ? body.system
32
+ : body.system
33
+ .filter((p) => p.type === "text")
34
+ .map((p) => p.text ?? "")
35
+ .join("\n");
36
+ if (sys.trim())
37
+ trafficMessages.push({ role: "system", content: sys.trim() });
38
+ }
39
+ for (const m of body.messages ?? []) {
40
+ const text = typeof m.content === "string"
41
+ ? m.content
42
+ : m.content
43
+ .filter((p) => p.type === "text")
44
+ .map((p) => p.text ?? "")
45
+ .join("");
46
+ if (text)
47
+ trafficMessages.push({ role: m.role, content: text });
48
+ }
49
+ logTrafficRequest(config.verbose, model ?? cursorModel, trafficMessages, !!body.stream);
50
+ const headerWs = req.headers["x-cursor-workspace"];
51
+ const { workspaceDir, tempDir } = resolveWorkspace(config, headerWs);
52
+ const cmdArgs = buildAgentCmdArgs(config, workspaceDir, cursorModel, prompt, !!body.stream);
53
+ const msgId = `msg_${randomUUID().replace(/-/g, "")}`;
54
+ if (body.stream) {
55
+ writeSseHeaders(res);
56
+ const writeEvent = (evt) => {
57
+ res.write(`data: ${JSON.stringify(evt)}\n\n`);
58
+ };
59
+ writeEvent({
60
+ type: "message_start",
61
+ message: {
62
+ id: msgId,
63
+ type: "message",
64
+ role: "assistant",
65
+ model: model ?? cursorModel,
66
+ content: [],
67
+ },
68
+ });
69
+ writeEvent({
70
+ type: "content_block_start",
71
+ index: 0,
72
+ content_block: { type: "text", text: "" },
73
+ });
74
+ let accumulated = "";
75
+ const parseLine = createStreamParser((text) => {
76
+ accumulated += text;
77
+ writeEvent({
78
+ type: "content_block_delta",
79
+ index: 0,
80
+ delta: { type: "text_delta", text },
81
+ });
82
+ }, () => {
83
+ logTrafficResponse(config.verbose, model ?? cursorModel, accumulated, true);
84
+ writeEvent({ type: "content_block_stop", index: 0 });
85
+ writeEvent({
86
+ type: "message_delta",
87
+ delta: { stop_reason: "end_turn" },
88
+ });
89
+ writeEvent({ type: "message_stop" });
90
+ });
91
+ runAgentStream(config, workspaceDir, cmdArgs, parseLine, tempDir)
92
+ .then(({ code, stderr: stderrOut }) => {
93
+ if (code !== 0) {
94
+ logAgentError(config.sessionsLogPath, method, pathname, remoteAddress, code, stderrOut);
95
+ }
96
+ res.end();
97
+ })
98
+ .catch((err) => {
99
+ console.error(`[${new Date().toISOString()}] Agent stream error:`, err);
100
+ res.end();
101
+ });
102
+ return;
103
+ }
104
+ const out = await runAgentSync(config, workspaceDir, cmdArgs, tempDir);
105
+ if (out.code !== 0) {
106
+ const errMsg = logAgentError(config.sessionsLogPath, method, pathname, remoteAddress, out.code, out.stderr);
107
+ json(res, 500, {
108
+ error: { type: "api_error", message: errMsg },
109
+ });
110
+ return;
111
+ }
112
+ const content = out.stdout.trim();
113
+ logTrafficResponse(config.verbose, model ?? cursorModel, content, false);
114
+ json(res, 200, {
115
+ id: msgId,
116
+ type: "message",
117
+ role: "assistant",
118
+ content: [{ type: "text", text: content }],
119
+ model: model ?? cursorModel,
120
+ stop_reason: "end_turn",
121
+ usage: { input_tokens: 0, output_tokens: 0 },
122
+ });
123
+ }
124
+ //# sourceMappingURL=anthropic-messages.js.map
@@ -0,0 +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,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,kBAAkB,GAEnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAOnD,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,GAAyB,EACzB,GAAwB,EACxB,GAAyB,EACzB,OAAe,EACf,MAAc,EACd,QAAgB,EAChB,aAAqB;IAErB,MAAM,EAAE,MAAM,EAAE,qBAAqB,EAAE,GAAG,GAAG,CAAC;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI,CAA6B,CAAC;IACrE,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,EAAE,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAErE,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE;YACb,KAAK,EAAE;gBACL,IAAI,EAAE,uBAAuB;gBAC7B,OAAO,EAAE,wBAAwB;aAClC;SACF,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;IACzD,MAAM,MAAM,GAAG,gCAAgC,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5E,MAAM,eAAe,GAAqB,EAAE,CAAC;IAC7C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,GAAG,GACP,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ;YAC7B,CAAC,CAAC,IAAI,CAAC,MAAM;YACb,CAAC,CAAE,IAAI,CAAC,MAAkD;iBACrD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;iBAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;iBACxB,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,IAAI,GAAG,CAAC,IAAI,EAAE;YACZ,eAAe,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,GACR,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;YAC3B,CAAC,CAAC,CAAC,CAAC,OAAO;YACX,CAAC,CAAE,CAAC,CAAC,OAAmD;iBACnD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;iBAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;iBACxB,IAAI,CAAC,EAAE,CAAC,CAAC;QAClB,IAAI,IAAI;YAAE,eAAe,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,iBAAiB,CACf,MAAM,CAAC,OAAO,EACd,KAAK,IAAI,WAAW,EACpB,eAAe,EACf,CAAC,CAAC,IAAI,CAAC,MAAM,CACd,CAAC;IAEF,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACnD,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAErE,MAAM,OAAO,GAAG,iBAAiB,CAC/B,MAAM,EACN,YAAY,EACZ,WAAW,EACX,MAAM,EACN,CAAC,CAAC,IAAI,CAAC,MAAM,CACd,CAAC;IAEF,MAAM,KAAK,GAAG,OAAO,UAAU,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;IAEtD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,eAAe,CAAC,GAAG,CAAC,CAAC;QAErB,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,EAAE;YACjC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAChD,CAAC,CAAC;QAEF,UAAU,CAAC;YACT,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE;gBACP,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,KAAK,IAAI,WAAW;gBAC3B,OAAO,EAAE,EAAE;aACZ;SACF,CAAC,CAAC;QACH,UAAU,CAAC;YACT,IAAI,EAAE,qBAAqB;YAC3B,KAAK,EAAE,CAAC;YACR,aAAa,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;SAC1C,CAAC,CAAC;QAEH,IAAI,WAAW,GAAG,EAAE,CAAC;QACrB,MAAM,SAAS,GAAG,kBAAkB,CAClC,CAAC,IAAI,EAAE,EAAE;YACP,WAAW,IAAI,IAAI,CAAC;YACpB,UAAU,CAAC;gBACT,IAAI,EAAE,qBAAqB;gBAC3B,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE;aACpC,CAAC,CAAC;QACL,CAAC,EACD,GAAG,EAAE;YACH,kBAAkB,CAChB,MAAM,CAAC,OAAO,EACd,KAAK,IAAI,WAAW,EACpB,WAAW,EACX,IAAI,CACL,CAAC;YACF,UAAU,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YACrD,UAAU,CAAC;gBACT,IAAI,EAAE,eAAe;gBACrB,KAAK,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE;aACnC,CAAC,CAAC;YACH,UAAU,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QACvC,CAAC,CACF,CAAC;QACF,cAAc,CACZ,MAAM,EACN,YAAY,EACZ,OAAO,EACP,SAAS,EACT,OAAO,CACR;aACE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;YACpC,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,aAAa,CACX,MAAM,CAAC,eAAe,EACtB,MAAM,EACN,QAAQ,EACR,aAAa,EACb,IAAI,EACJ,SAAS,CACV,CAAC;YACJ,CAAC;YACD,GAAG,CAAC,GAAG,EAAE,CAAC;QACZ,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,uBAAuB,EAAE,GAAG,CAAC,CAAC;YACxE,GAAG,CAAC,GAAG,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;QACL,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAEvE,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,aAAa,CAC1B,MAAM,CAAC,eAAe,EACtB,MAAM,EACN,QAAQ,EACR,aAAa,EACb,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,MAAM,CACX,CAAC;QACF,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE;YACb,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE;SAC9C,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAClC,kBAAkB,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IACzE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE;QACb,EAAE,EAAE,KAAK;QACT,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC1C,KAAK,EAAE,KAAK,IAAI,WAAW;QAC3B,WAAW,EAAE,UAAU;QACvB,KAAK,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;KAC7C,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,9 @@
1
+ import * as http from "node:http";
2
+ import type { BridgeConfig } from "../config.js";
3
+ export type ChatCompletionsCtx = {
4
+ config: BridgeConfig;
5
+ lastRequestedModelRef: {
6
+ current?: string;
7
+ };
8
+ };
9
+ export declare function handleChatCompletions(req: http.IncomingMessage, res: http.ServerResponse, ctx: ChatCompletionsCtx, rawBody: string, method: string, pathname: string, remoteAddress: string): Promise<void>;
@@ -0,0 +1,98 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { buildAgentCmdArgs } from "../agent-cmd-args.js";
3
+ import { runAgentStream, runAgentSync } from "../agent-runner.js";
4
+ import { createStreamParser } from "../cli-stream-parser.js";
5
+ import { json, writeSseHeaders } from "../http.js";
6
+ import { resolveToCursorModel } from "../model-map.js";
7
+ import { buildPromptFromMessages, normalizeModelId, } from "../openai.js";
8
+ import { logAgentError, logTrafficRequest, logTrafficResponse, } from "../request-log.js";
9
+ import { resolveModel } from "../resolve-model.js";
10
+ import { resolveWorkspace } from "../workspace.js";
11
+ export async function handleChatCompletions(req, res, ctx, rawBody, method, pathname, remoteAddress) {
12
+ const { config, lastRequestedModelRef } = ctx;
13
+ const body = JSON.parse(rawBody || "{}");
14
+ const requested = normalizeModelId(body.model);
15
+ const model = resolveModel(requested, lastRequestedModelRef, config);
16
+ const cursorModel = resolveToCursorModel(model) ?? model;
17
+ const prompt = buildPromptFromMessages(body.messages ?? []);
18
+ const trafficMessages = (body.messages ?? []).map((m) => {
19
+ const content = typeof m?.content === "string"
20
+ ? m.content
21
+ : Array.isArray(m?.content)
22
+ ? m.content
23
+ .filter((p) => p.type === "text")
24
+ .map((p) => p.text ?? "")
25
+ .join("")
26
+ : "";
27
+ return { role: String(m?.role ?? "user"), content };
28
+ });
29
+ logTrafficRequest(config.verbose, model ?? cursorModel, trafficMessages, !!body.stream);
30
+ const headerWs = req.headers["x-cursor-workspace"];
31
+ const { workspaceDir, tempDir } = resolveWorkspace(config, headerWs);
32
+ const cmdArgs = buildAgentCmdArgs(config, workspaceDir, cursorModel, prompt, !!body.stream);
33
+ const id = `chatcmpl_${randomUUID().replace(/-/g, "")}`;
34
+ const created = Math.floor(Date.now() / 1000);
35
+ if (body.stream) {
36
+ writeSseHeaders(res);
37
+ let accumulated = "";
38
+ const parseLine = createStreamParser((text) => {
39
+ accumulated += text;
40
+ res.write(`data: ${JSON.stringify({
41
+ id,
42
+ object: "chat.completion.chunk",
43
+ created,
44
+ model,
45
+ choices: [
46
+ { index: 0, delta: { content: text }, finish_reason: null },
47
+ ],
48
+ })}\n\n`);
49
+ }, () => {
50
+ logTrafficResponse(config.verbose, model ?? cursorModel, accumulated, true);
51
+ res.write(`data: ${JSON.stringify({
52
+ id,
53
+ object: "chat.completion.chunk",
54
+ created,
55
+ model,
56
+ choices: [{ index: 0, delta: {}, finish_reason: "stop" }],
57
+ })}\n\n`);
58
+ res.write("data: [DONE]\n\n");
59
+ });
60
+ runAgentStream(config, workspaceDir, cmdArgs, parseLine, tempDir)
61
+ .then(({ code, stderr: stderrOut }) => {
62
+ if (code !== 0) {
63
+ logAgentError(config.sessionsLogPath, method, pathname, remoteAddress, code, stderrOut);
64
+ }
65
+ res.end();
66
+ })
67
+ .catch((err) => {
68
+ console.error(`[${new Date().toISOString()}] Agent stream error:`, err);
69
+ res.end();
70
+ });
71
+ return;
72
+ }
73
+ const out = await runAgentSync(config, workspaceDir, cmdArgs, tempDir);
74
+ if (out.code !== 0) {
75
+ const errMsg = logAgentError(config.sessionsLogPath, method, pathname, remoteAddress, out.code, out.stderr);
76
+ json(res, 500, {
77
+ error: { message: errMsg, code: "cursor_cli_error" },
78
+ });
79
+ return;
80
+ }
81
+ const content = out.stdout.trim();
82
+ logTrafficResponse(config.verbose, model ?? cursorModel, content, false);
83
+ json(res, 200, {
84
+ id,
85
+ object: "chat.completion",
86
+ created,
87
+ model,
88
+ choices: [
89
+ {
90
+ index: 0,
91
+ message: { role: "assistant", content },
92
+ finish_reason: "stop",
93
+ },
94
+ ],
95
+ usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
96
+ });
97
+ }
98
+ //# sourceMappingURL=chat-completions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-completions.js","sourceRoot":"","sources":["../../../src/lib/handlers/chat-completions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import * as http from "node:http";
2
+ import type { BridgeConfig } from "../config.js";
3
+ export type HealthHandlerOpts = {
4
+ version: string;
5
+ config: BridgeConfig;
6
+ };
7
+ export declare function handleHealth(res: http.ServerResponse, opts: HealthHandlerOpts): void;
@@ -0,0 +1,15 @@
1
+ import { json } from "../http.js";
2
+ export function handleHealth(res, opts) {
3
+ const { version, config } = opts;
4
+ json(res, 200, {
5
+ ok: true,
6
+ version,
7
+ workspace: config.workspace,
8
+ mode: config.mode,
9
+ defaultModel: config.defaultModel,
10
+ force: config.force,
11
+ approveMcps: config.approveMcps,
12
+ strictModel: config.strictModel,
13
+ });
14
+ }
15
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../../src/lib/handlers/health.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAOlC,MAAM,UAAU,YAAY,CAC1B,GAAwB,EACxB,IAAuB;IAEvB,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACjC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE;QACb,EAAE,EAAE,IAAI;QACR,OAAO;QACP,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,14 @@
1
+ import * as http from "node:http";
2
+ import type { BridgeConfig } from "../config.js";
3
+ import type { CursorCliModel } from "../cursor-cli.js";
4
+ export type ModelCache = {
5
+ at: number;
6
+ models: CursorCliModel[];
7
+ };
8
+ export type HandleModelsOpts = {
9
+ config: BridgeConfig;
10
+ modelCacheRef: {
11
+ current?: ModelCache;
12
+ };
13
+ };
14
+ export declare function handleModels(res: http.ServerResponse, opts: HandleModelsOpts): Promise<void>;
@@ -0,0 +1,34 @@
1
+ import { listCursorCliModels } from "../cursor-cli.js";
2
+ import { json } from "../http.js";
3
+ import { getAnthropicModelAliases } from "../model-map.js";
4
+ const MODEL_CACHE_TTL_MS = 5 * 60_000;
5
+ export async function handleModels(res, opts) {
6
+ const { config, modelCacheRef } = opts;
7
+ const now = Date.now();
8
+ if (!modelCacheRef.current ||
9
+ now - modelCacheRef.current.at > MODEL_CACHE_TTL_MS) {
10
+ const models = await listCursorCliModels({
11
+ agentBin: config.agentBin,
12
+ timeoutMs: 60_000,
13
+ });
14
+ modelCacheRef.current = { at: now, models };
15
+ }
16
+ const models = modelCacheRef.current.models;
17
+ const cursorModels = models.map((m) => ({
18
+ id: m.id,
19
+ object: "model",
20
+ owned_by: "cursor",
21
+ name: m.name,
22
+ }));
23
+ const anthropicAliases = getAnthropicModelAliases(models.map((m) => m.id)).map((a) => ({
24
+ id: a.id,
25
+ object: "model",
26
+ owned_by: "cursor",
27
+ name: a.name,
28
+ }));
29
+ json(res, 200, {
30
+ object: "list",
31
+ data: [...cursorModels, ...anthropicAliases],
32
+ });
33
+ }
34
+ //# sourceMappingURL=models.js.map
@@ -0,0 +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,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC;YACvC,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QACH,aAAa,CAAC,OAAO,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAC9C,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC;IAC5C,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,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAC5E,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACN,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,MAAM,EAAE,OAAgB;QACxB,QAAQ,EAAE,QAAiB;QAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;KACb,CAAC,CACH,CAAC;IAEF,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"}
@@ -0,0 +1,5 @@
1
+ import * as http from "node:http";
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;
5
+ export declare function readBody(req: http.IncomingMessage): Promise<string>;