@kaitranntt/ccs 7.54.0-dev.1 → 7.54.0-dev.3
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 +1 -0
- package/dist/cursor/cursor-anthropic-response.d.ts +6 -0
- package/dist/cursor/cursor-anthropic-response.d.ts.map +1 -0
- package/dist/cursor/cursor-anthropic-response.js +190 -0
- package/dist/cursor/cursor-anthropic-response.js.map +1 -0
- package/dist/cursor/cursor-anthropic-translator.d.ts +11 -0
- package/dist/cursor/cursor-anthropic-translator.d.ts.map +1 -0
- package/dist/cursor/cursor-anthropic-translator.js +167 -0
- package/dist/cursor/cursor-anthropic-translator.js.map +1 -0
- package/dist/cursor/cursor-anthropic-types.d.ts +46 -0
- package/dist/cursor/cursor-anthropic-types.d.ts.map +1 -0
- package/dist/cursor/cursor-anthropic-types.js +3 -0
- package/dist/cursor/cursor-anthropic-types.js.map +1 -0
- package/dist/cursor/cursor-daemon-entry.d.ts.map +1 -1
- package/dist/cursor/cursor-daemon-entry.js +53 -24
- package/dist/cursor/cursor-daemon-entry.js.map +1 -1
- package/dist/cursor/cursor-models.d.ts.map +1 -1
- package/dist/cursor/cursor-models.js +36 -2
- package/dist/cursor/cursor-models.js.map +1 -1
- package/dist/glmt/sse-parser.d.ts +2 -0
- package/dist/glmt/sse-parser.d.ts.map +1 -1
- package/dist/glmt/sse-parser.js +4 -0
- package/dist/glmt/sse-parser.js.map +1 -1
- package/dist/shared/provider-preset-catalog.d.ts +1 -1
- package/dist/shared/provider-preset-catalog.d.ts.map +1 -1
- package/dist/shared/provider-preset-catalog.js +15 -0
- package/dist/shared/provider-preset-catalog.js.map +1 -1
- package/dist/ui/assets/{accounts-CZEg1_PX.js → accounts-CrNRfOOP.js} +1 -1
- package/dist/ui/assets/{alert-dialog-DhwS38kc.js → alert-dialog-0GYXcDLu.js} +1 -1
- package/dist/ui/assets/{api-sWNND4wP.js → api-Du9rjWhx.js} +1 -1
- package/dist/ui/assets/{auth-section-nJIpOcnm.js → auth-section-DMcsqZyo.js} +1 -1
- package/dist/ui/assets/{backups-section-D3A6hmrU.js → backups-section-Bu4mUdGV.js} +1 -1
- package/dist/ui/assets/{checkbox-CZrxD1iS.js → checkbox-DiyJL_k4.js} +1 -1
- package/dist/ui/assets/{claude-extension-BjInaILv.js → claude-extension-CUlLIos9.js} +1 -1
- package/dist/ui/assets/{cliproxy-BGiSCGkl.js → cliproxy-DS95Joc9.js} +1 -1
- package/dist/ui/assets/{cliproxy-control-panel-CKO2Sn9B.js → cliproxy-control-panel-BNUMUGIt.js} +1 -1
- package/dist/ui/assets/{confirm-dialog-DTKxwrat.js → confirm-dialog-DTWvVQlx.js} +1 -1
- package/dist/ui/assets/{copilot-CuRngdBg.js → copilot-p2K9Y5LR.js} +1 -1
- package/dist/ui/assets/{cursor-Dxo0uIiU.js → cursor-5SbcR5sW.js} +1 -1
- package/dist/ui/assets/{droid-Cl8QsJJL.js → droid-DxdiLHHD.js} +1 -1
- package/dist/ui/assets/{globalenv-section-C3dxxoD9.js → globalenv-section-B9l_4XUg.js} +1 -1
- package/dist/ui/assets/{health-BUifaDU7.js → health-DDs2IlMm.js} +1 -1
- package/dist/ui/assets/{index-CYo-E5rU.js → index-Cy76XBS9.js} +1 -1
- package/dist/ui/assets/{index-xayyyR26.js → index-D3yHEBlf.js} +1 -1
- package/dist/ui/assets/{index-Cw9Urr0S.js → index-JgHDFSHt.js} +3 -3
- package/dist/ui/assets/{index-CPdceT1C.js → index-X7b7NDPo.js} +1 -1
- package/dist/ui/assets/{index-BOsbrhaa.js → index-awSrtRcI.js} +1 -1
- package/dist/ui/assets/{proxy-status-widget-D94htBPb.js → proxy-status-widget-DEkHz7X-.js} +1 -1
- package/dist/ui/assets/{separator-3fBbTn-V.js → separator-BFr5KvfF.js} +1 -1
- package/dist/ui/assets/{shared-q_FNNbjD.js → shared-BwP9MOQi.js} +1 -1
- package/dist/ui/assets/{switch-5N8qBdBr.js → switch-w7IoOY5x.js} +1 -1
- package/dist/ui/assets/{updates-CubQ54J0.js → updates--SN_PZnJ.js} +1 -1
- package/dist/ui/icons/novita.svg +9 -0
- package/dist/ui/index.html +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -110,6 +110,7 @@ The dashboard provides visual management for all account types:
|
|
|
110
110
|
| **Azure Foundry** | API Key | `ccs foundry` | Claude via Microsoft Azure |
|
|
111
111
|
| **Minimax** | API Key | `ccs mm` | M2 series, 1M context |
|
|
112
112
|
| **DeepSeek** | API Key | `ccs deepseek` | V3.2 and R1 reasoning |
|
|
113
|
+
| **Novita AI** | API Key | `ccs api create --preset novita` | Anthropic-compatible Novita endpoint for Claude Code |
|
|
113
114
|
| **Qwen (OAuth)** | OAuth | `ccs qwen` | Qwen Code via CLIProxy |
|
|
114
115
|
| **Qwen API** | API Key | `ccs api create --preset qwen` | DashScope Anthropic-compatible API |
|
|
115
116
|
| **Alibaba Coding Plan** | API Key | `ccs api create --preset alibaba-coding-plan` | Model Studio Coding Plan endpoint |
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
type ResponseHeaders = Headers | Record<string, string> | Array<[string, string]>;
|
|
3
|
+
export declare function createAnthropicErrorResponse(status: number, type: string, message: string, headers?: ResponseHeaders): Response;
|
|
4
|
+
export declare function createAnthropicProxyResponse(response: Response): Promise<Response>;
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=cursor-anthropic-response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-anthropic-response.d.ts","sourceRoot":"","sources":["../../src/cursor/cursor-anthropic-response.ts"],"names":[],"mappings":";AAOA,KAAK,eAAe,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAoClF,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,eAAe,GACxB,QAAQ,CASV;AAmLD,wBAAsB,4BAA4B,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAYxF"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAnthropicProxyResponse = exports.createAnthropicErrorResponse = void 0;
|
|
4
|
+
const delta_accumulator_1 = require("../glmt/delta-accumulator");
|
|
5
|
+
const glmt_transformer_1 = require("../glmt/glmt-transformer");
|
|
6
|
+
const sse_parser_1 = require("../glmt/sse-parser");
|
|
7
|
+
const JSON_TRANSLATION_ERROR_MESSAGE = 'Failed to translate Cursor JSON response';
|
|
8
|
+
const STREAM_TRANSLATION_ERROR_MESSAGE = 'Failed to translate Cursor SSE response';
|
|
9
|
+
function createAnthropicErrorPayload(type, message) {
|
|
10
|
+
return {
|
|
11
|
+
type: 'error',
|
|
12
|
+
error: {
|
|
13
|
+
type,
|
|
14
|
+
message,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function formatErrorForLog(error) {
|
|
19
|
+
if (error instanceof Error) {
|
|
20
|
+
return error.message;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
return JSON.stringify(error);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return String(error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function logTranslationError(context, error) {
|
|
30
|
+
console.error(`[cursor-anthropic-response] ${context}: ${formatErrorForLog(error)}`);
|
|
31
|
+
}
|
|
32
|
+
function createAnthropicErrorResponse(status, type, message, headers) {
|
|
33
|
+
const responseHeaders = new Headers(headers);
|
|
34
|
+
responseHeaders.set('Content-Type', 'application/json');
|
|
35
|
+
responseHeaders.delete('Content-Length');
|
|
36
|
+
return new Response(JSON.stringify(createAnthropicErrorPayload(type, message)), {
|
|
37
|
+
status,
|
|
38
|
+
headers: responseHeaders,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
exports.createAnthropicErrorResponse = createAnthropicErrorResponse;
|
|
42
|
+
function formatSseEvent(event, data) {
|
|
43
|
+
return `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
|
|
44
|
+
}
|
|
45
|
+
function hasTranslatableChoices(value) {
|
|
46
|
+
if (typeof value !== 'object' || value === null) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
const { choices } = value;
|
|
50
|
+
if (!Array.isArray(choices) || choices.length === 0) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const firstChoice = choices[0];
|
|
54
|
+
if (typeof firstChoice !== 'object' || firstChoice === null) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const message = firstChoice.message;
|
|
58
|
+
return typeof message === 'object' && message !== null;
|
|
59
|
+
}
|
|
60
|
+
function isSyntheticTransformationFallback(value) {
|
|
61
|
+
return (typeof value === 'object' &&
|
|
62
|
+
value !== null &&
|
|
63
|
+
typeof value.id === 'string' &&
|
|
64
|
+
value.id.startsWith('msg_error_'));
|
|
65
|
+
}
|
|
66
|
+
async function createAnthropicErrorProxyResponse(response) {
|
|
67
|
+
const headers = new Headers(response.headers);
|
|
68
|
+
headers.delete('Content-Type');
|
|
69
|
+
headers.delete('Content-Length');
|
|
70
|
+
let type = response.status === 401
|
|
71
|
+
? 'authentication_error'
|
|
72
|
+
: response.status === 429
|
|
73
|
+
? 'rate_limit_error'
|
|
74
|
+
: response.status >= 400 && response.status < 500
|
|
75
|
+
? 'invalid_request_error'
|
|
76
|
+
: 'api_error';
|
|
77
|
+
let message = `Cursor request failed with status ${response.status}`;
|
|
78
|
+
try {
|
|
79
|
+
const contentType = (response.headers.get('content-type') || '').toLowerCase();
|
|
80
|
+
if (contentType.includes('application/json')) {
|
|
81
|
+
const payload = (await response.json());
|
|
82
|
+
if (typeof payload?.error?.type === 'string' && payload.error.type.trim().length > 0) {
|
|
83
|
+
type = payload.error.type;
|
|
84
|
+
}
|
|
85
|
+
if (typeof payload?.error?.message === 'string' && payload.error.message.trim().length > 0) {
|
|
86
|
+
message = payload.error.message;
|
|
87
|
+
}
|
|
88
|
+
else if (typeof payload?.message === 'string' && payload.message.trim().length > 0) {
|
|
89
|
+
message = payload.message;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const text = (await response.text()).trim();
|
|
94
|
+
if (text.length > 0) {
|
|
95
|
+
message = text;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
logTranslationError('Failed to parse Cursor error response', error);
|
|
101
|
+
}
|
|
102
|
+
return createAnthropicErrorResponse(response.status, type, message, headers);
|
|
103
|
+
}
|
|
104
|
+
async function createAnthropicJsonResponse(response) {
|
|
105
|
+
try {
|
|
106
|
+
const openAiResponse = await response.json();
|
|
107
|
+
if (!hasTranslatableChoices(openAiResponse)) {
|
|
108
|
+
return createAnthropicErrorResponse(502, 'api_error', JSON_TRANSLATION_ERROR_MESSAGE);
|
|
109
|
+
}
|
|
110
|
+
const anthropicResponse = new glmt_transformer_1.GlmtTransformer().transformResponse(openAiResponse);
|
|
111
|
+
if (isSyntheticTransformationFallback(anthropicResponse)) {
|
|
112
|
+
logTranslationError('Cursor JSON translation produced synthetic fallback response', anthropicResponse);
|
|
113
|
+
return createAnthropicErrorResponse(502, 'api_error', JSON_TRANSLATION_ERROR_MESSAGE);
|
|
114
|
+
}
|
|
115
|
+
return new Response(JSON.stringify(anthropicResponse), {
|
|
116
|
+
status: response.status,
|
|
117
|
+
headers: { 'Content-Type': 'application/json' },
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
logTranslationError('Cursor JSON translation failed', error);
|
|
122
|
+
return createAnthropicErrorResponse(502, 'api_error', JSON_TRANSLATION_ERROR_MESSAGE);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function createAnthropicStreamingResponse(response) {
|
|
126
|
+
const body = response.body;
|
|
127
|
+
if (!body) {
|
|
128
|
+
return createAnthropicErrorResponse(502, 'api_error', 'Cursor stream ended before a response body was available');
|
|
129
|
+
}
|
|
130
|
+
const parser = new sse_parser_1.SSEParser({ throwOnMalformedJson: true });
|
|
131
|
+
const transformer = new glmt_transformer_1.GlmtTransformer();
|
|
132
|
+
const accumulator = new delta_accumulator_1.DeltaAccumulator({});
|
|
133
|
+
const encoder = new TextEncoder();
|
|
134
|
+
const readable = new ReadableStream({
|
|
135
|
+
async start(controller) {
|
|
136
|
+
const reader = body.getReader();
|
|
137
|
+
try {
|
|
138
|
+
while (true) {
|
|
139
|
+
const { done, value } = await reader.read();
|
|
140
|
+
if (done) {
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
if (!value) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
const events = parser.parse(Buffer.from(value));
|
|
147
|
+
events.forEach((event) => {
|
|
148
|
+
const anthropicEvents = transformer.transformDelta(event, accumulator);
|
|
149
|
+
anthropicEvents.forEach((anthropicEvent) => {
|
|
150
|
+
controller.enqueue(encoder.encode(formatSseEvent(anthropicEvent.event, anthropicEvent.data)));
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
if (!accumulator.isFinalized() && accumulator.isMessageStarted()) {
|
|
155
|
+
transformer.finalizeDelta(accumulator).forEach((anthropicEvent) => {
|
|
156
|
+
controller.enqueue(encoder.encode(formatSseEvent(anthropicEvent.event, anthropicEvent.data)));
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
logTranslationError('Cursor SSE translation failed', error);
|
|
162
|
+
controller.enqueue(encoder.encode(formatSseEvent('error', createAnthropicErrorPayload('api_error', STREAM_TRANSLATION_ERROR_MESSAGE))));
|
|
163
|
+
}
|
|
164
|
+
finally {
|
|
165
|
+
reader.releaseLock();
|
|
166
|
+
controller.close();
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
return new Response(readable, {
|
|
171
|
+
status: response.status,
|
|
172
|
+
headers: {
|
|
173
|
+
'Content-Type': 'text/event-stream',
|
|
174
|
+
'Cache-Control': 'no-cache',
|
|
175
|
+
Connection: 'keep-alive',
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
async function createAnthropicProxyResponse(response) {
|
|
180
|
+
if (!response.ok) {
|
|
181
|
+
return createAnthropicErrorProxyResponse(response);
|
|
182
|
+
}
|
|
183
|
+
const contentType = (response.headers.get('content-type') || '').toLowerCase();
|
|
184
|
+
const isEventStream = contentType === 'text/event-stream' || contentType.startsWith('text/event-stream;');
|
|
185
|
+
return isEventStream
|
|
186
|
+
? createAnthropicStreamingResponse(response)
|
|
187
|
+
: createAnthropicJsonResponse(response);
|
|
188
|
+
}
|
|
189
|
+
exports.createAnthropicProxyResponse = createAnthropicProxyResponse;
|
|
190
|
+
//# sourceMappingURL=cursor-anthropic-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-anthropic-response.js","sourceRoot":"","sources":["../../src/cursor/cursor-anthropic-response.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CursorTool } from './cursor-protobuf-schema';
|
|
2
|
+
import type { CursorOpenAIMessage } from './cursor-anthropic-types';
|
|
3
|
+
export interface TranslatedAnthropicRequest {
|
|
4
|
+
model?: string;
|
|
5
|
+
stream: boolean;
|
|
6
|
+
reasoning_effort?: string;
|
|
7
|
+
tools?: CursorTool[];
|
|
8
|
+
messages: CursorOpenAIMessage[];
|
|
9
|
+
}
|
|
10
|
+
export declare function translateAnthropicRequest(raw: unknown): TranslatedAnthropicRequest;
|
|
11
|
+
//# sourceMappingURL=cursor-anthropic-translator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-anthropic-translator.d.ts","sourceRoot":"","sources":["../../src/cursor/cursor-anthropic-translator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAGV,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,0BAA0B;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AA0ED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG,0BAA0B,CAgIlF"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.translateAnthropicRequest = void 0;
|
|
4
|
+
const TOOL_RESULT_SERIALIZATION_FALLBACK = '[unserializable content]';
|
|
5
|
+
const TOOL_USE_ARGUMENTS_FALLBACK = '{}';
|
|
6
|
+
function assertObject(value, label) {
|
|
7
|
+
if (typeof value !== 'object' || value === null) {
|
|
8
|
+
throw new Error(`${label} must be an object`);
|
|
9
|
+
}
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
function safeJsonStringify(value, fallback) {
|
|
13
|
+
try {
|
|
14
|
+
const serialized = JSON.stringify(value);
|
|
15
|
+
return typeof serialized === 'string' ? serialized : fallback;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return fallback;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function createFallbackToolId(messageIndex, blockIndex) {
|
|
22
|
+
return `toolu_ccs_fallback_${messageIndex}_${blockIndex}`;
|
|
23
|
+
}
|
|
24
|
+
function flattenTextContent(content, label) {
|
|
25
|
+
if (typeof content === 'string') {
|
|
26
|
+
return content;
|
|
27
|
+
}
|
|
28
|
+
if (!Array.isArray(content)) {
|
|
29
|
+
throw new Error(`${label} must be a string or content block array`);
|
|
30
|
+
}
|
|
31
|
+
return content
|
|
32
|
+
.map((block, index) => {
|
|
33
|
+
const parsed = assertObject(block, `${label}[${index}]`);
|
|
34
|
+
if (parsed.type !== 'text') {
|
|
35
|
+
throw new Error(`${label}[${index}].type "${String(parsed.type)}" is not supported`);
|
|
36
|
+
}
|
|
37
|
+
return typeof parsed.text === 'string' ? parsed.text : '';
|
|
38
|
+
})
|
|
39
|
+
.join('\n');
|
|
40
|
+
}
|
|
41
|
+
function toToolResultContent(content, label) {
|
|
42
|
+
if (content === undefined) {
|
|
43
|
+
return '';
|
|
44
|
+
}
|
|
45
|
+
if (typeof content === 'string') {
|
|
46
|
+
return content;
|
|
47
|
+
}
|
|
48
|
+
if (Array.isArray(content)) {
|
|
49
|
+
return flattenTextContent(content, label);
|
|
50
|
+
}
|
|
51
|
+
return safeJsonStringify(content, TOOL_RESULT_SERIALIZATION_FALLBACK);
|
|
52
|
+
}
|
|
53
|
+
function mapThinkingToReasoningEffort(thinking) {
|
|
54
|
+
if (!thinking) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
if (thinking.type === 'disabled') {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
if (thinking.type !== 'enabled') {
|
|
61
|
+
throw new Error('thinking.type must be "enabled" or "disabled"');
|
|
62
|
+
}
|
|
63
|
+
return typeof thinking.budget_tokens === 'number' && thinking.budget_tokens >= 8192
|
|
64
|
+
? 'high'
|
|
65
|
+
: 'medium';
|
|
66
|
+
}
|
|
67
|
+
function translateAnthropicRequest(raw) {
|
|
68
|
+
const request = assertObject(raw, 'request');
|
|
69
|
+
const translatedMessages = [];
|
|
70
|
+
if (request.system !== undefined) {
|
|
71
|
+
translatedMessages.push({
|
|
72
|
+
role: 'system',
|
|
73
|
+
content: flattenTextContent(request.system, 'system'),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (!Array.isArray(request.messages)) {
|
|
77
|
+
throw new Error('messages must be an array');
|
|
78
|
+
}
|
|
79
|
+
request.messages.forEach((message, messageIndex) => {
|
|
80
|
+
const role = message.role;
|
|
81
|
+
if (role !== 'user' && role !== 'assistant') {
|
|
82
|
+
throw new Error(`messages[${messageIndex}].role must be "user" or "assistant"`);
|
|
83
|
+
}
|
|
84
|
+
const content = message.content;
|
|
85
|
+
if (typeof content === 'string') {
|
|
86
|
+
translatedMessages.push({ role, content });
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (!Array.isArray(content)) {
|
|
90
|
+
throw new Error(`messages[${messageIndex}].content must be a string or array`);
|
|
91
|
+
}
|
|
92
|
+
const textParts = [];
|
|
93
|
+
const toolCalls = [];
|
|
94
|
+
let sawToolResult = false;
|
|
95
|
+
content.forEach((block, blockIndex) => {
|
|
96
|
+
const parsed = assertObject(block, `messages[${messageIndex}].content[${blockIndex}]`);
|
|
97
|
+
if (parsed.type === 'text') {
|
|
98
|
+
textParts.push(typeof parsed.text === 'string' ? parsed.text : '');
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (parsed.type === 'tool_use') {
|
|
102
|
+
if (role !== 'assistant') {
|
|
103
|
+
throw new Error(`messages[${messageIndex}].content[${blockIndex}] tool_use requires assistant role`);
|
|
104
|
+
}
|
|
105
|
+
toolCalls.push({
|
|
106
|
+
id: typeof parsed.id === 'string' && parsed.id.length > 0
|
|
107
|
+
? parsed.id
|
|
108
|
+
: createFallbackToolId(messageIndex, blockIndex),
|
|
109
|
+
type: 'function',
|
|
110
|
+
function: {
|
|
111
|
+
name: typeof parsed.name === 'string' ? parsed.name : 'tool',
|
|
112
|
+
arguments: safeJsonStringify(parsed.input ?? {}, TOOL_USE_ARGUMENTS_FALLBACK),
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (parsed.type === 'tool_result') {
|
|
118
|
+
if (role !== 'user') {
|
|
119
|
+
throw new Error(`messages[${messageIndex}].content[${blockIndex}] tool_result requires user role`);
|
|
120
|
+
}
|
|
121
|
+
if (typeof parsed.tool_use_id !== 'string' || parsed.tool_use_id.trim().length === 0) {
|
|
122
|
+
throw new Error(`messages[${messageIndex}].content[${blockIndex}].tool_use_id must be a non-empty string`);
|
|
123
|
+
}
|
|
124
|
+
sawToolResult = true;
|
|
125
|
+
if (textParts.length > 0) {
|
|
126
|
+
translatedMessages.push({
|
|
127
|
+
role,
|
|
128
|
+
content: textParts.join('\n'),
|
|
129
|
+
});
|
|
130
|
+
textParts.length = 0;
|
|
131
|
+
}
|
|
132
|
+
translatedMessages.push({
|
|
133
|
+
role: 'tool',
|
|
134
|
+
tool_call_id: parsed.tool_use_id,
|
|
135
|
+
content: toToolResultContent(parsed.content, `messages[${messageIndex}].content[${blockIndex}].content`),
|
|
136
|
+
});
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
throw new Error(`messages[${messageIndex}].content[${blockIndex}].type "${String(parsed.type)}" is not supported`);
|
|
140
|
+
});
|
|
141
|
+
if (role === 'assistant') {
|
|
142
|
+
translatedMessages.push({
|
|
143
|
+
role,
|
|
144
|
+
content: textParts.join('\n'),
|
|
145
|
+
tool_calls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
146
|
+
});
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (textParts.length > 0 || !sawToolResult) {
|
|
150
|
+
translatedMessages.push({
|
|
151
|
+
role,
|
|
152
|
+
content: textParts.join('\n'),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
return {
|
|
157
|
+
model: typeof request.model === 'string' && request.model.trim().length > 0
|
|
158
|
+
? request.model
|
|
159
|
+
: undefined,
|
|
160
|
+
stream: request.stream === true,
|
|
161
|
+
reasoning_effort: mapThinkingToReasoningEffort(request.thinking),
|
|
162
|
+
tools: Array.isArray(request.tools) ? request.tools : undefined,
|
|
163
|
+
messages: translatedMessages,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
exports.translateAnthropicRequest = translateAnthropicRequest;
|
|
167
|
+
//# sourceMappingURL=cursor-anthropic-translator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-anthropic-translator.js","sourceRoot":"","sources":["../../src/cursor/cursor-anthropic-translator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { CursorTool } from './cursor-protobuf-schema';
|
|
2
|
+
export interface CursorOpenAIMessage {
|
|
3
|
+
role: string;
|
|
4
|
+
content: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
tool_call_id?: string;
|
|
7
|
+
tool_calls?: Array<{
|
|
8
|
+
id: string;
|
|
9
|
+
type: string;
|
|
10
|
+
function: {
|
|
11
|
+
name: string;
|
|
12
|
+
arguments: string;
|
|
13
|
+
};
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
export interface AnthropicTextBlock {
|
|
17
|
+
type: 'text';
|
|
18
|
+
text?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface AnthropicToolUseBlock {
|
|
21
|
+
type: 'tool_use';
|
|
22
|
+
id?: string;
|
|
23
|
+
name?: string;
|
|
24
|
+
input?: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
export interface AnthropicToolResultBlock {
|
|
27
|
+
type: 'tool_result';
|
|
28
|
+
tool_use_id?: string;
|
|
29
|
+
content?: unknown;
|
|
30
|
+
}
|
|
31
|
+
export type AnthropicContentBlock = AnthropicTextBlock | AnthropicToolUseBlock | AnthropicToolResultBlock;
|
|
32
|
+
export interface CursorAnthropicRequest {
|
|
33
|
+
model?: string;
|
|
34
|
+
messages?: Array<{
|
|
35
|
+
role?: string;
|
|
36
|
+
content?: string | AnthropicContentBlock[];
|
|
37
|
+
}>;
|
|
38
|
+
system?: string | AnthropicTextBlock[];
|
|
39
|
+
stream?: boolean;
|
|
40
|
+
tools?: CursorTool[];
|
|
41
|
+
thinking?: {
|
|
42
|
+
type?: string;
|
|
43
|
+
budget_tokens?: number;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=cursor-anthropic-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-anthropic-types.d.ts","sourceRoot":"","sources":["../../src/cursor/cursor-anthropic-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,KAAK,CAAC;QACjB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC;KAC/C,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,qBAAqB,GAC7B,kBAAkB,GAClB,qBAAqB,GACrB,wBAAwB,CAAC;AAE7B,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,GAAG,qBAAqB,EAAE,CAAA;KAAE,CAAC,CAAC;IAChF,MAAM,CAAC,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-anthropic-types.js","sourceRoot":"","sources":["../../src/cursor/cursor-anthropic-types.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor-daemon-entry.d.ts","sourceRoot":"","sources":["../../src/cursor/cursor-daemon-entry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"cursor-daemon-entry.d.ts","sourceRoot":"","sources":["../../src/cursor/cursor-daemon-entry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAY7B,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AA4KD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC,MAAM,CAoKlF"}
|
|
@@ -32,6 +32,8 @@ exports.startCursorDaemonServer = void 0;
|
|
|
32
32
|
const http = __importStar(require("http"));
|
|
33
33
|
const stream_1 = require("stream");
|
|
34
34
|
const cursor_executor_1 = require("./cursor-executor");
|
|
35
|
+
const cursor_anthropic_response_1 = require("./cursor-anthropic-response");
|
|
36
|
+
const cursor_anthropic_translator_1 = require("./cursor-anthropic-translator");
|
|
35
37
|
const cursor_auth_1 = require("./cursor-auth");
|
|
36
38
|
const cursor_models_1 = require("./cursor-models");
|
|
37
39
|
const MAX_BODY_SIZE = 10 * 1024 * 1024; // 10MB
|
|
@@ -155,9 +157,11 @@ function parseArgs(argv) {
|
|
|
155
157
|
function startCursorDaemonServer(options) {
|
|
156
158
|
const executor = new cursor_executor_1.CursorExecutor();
|
|
157
159
|
const server = http.createServer(async (req, res) => {
|
|
160
|
+
const method = req.method || 'GET';
|
|
161
|
+
const requestUrl = req.url || '/';
|
|
162
|
+
const isOpenAiRoute = method === 'POST' && requestUrl === '/v1/chat/completions';
|
|
163
|
+
const isAnthropicRoute = method === 'POST' && requestUrl === '/v1/messages';
|
|
158
164
|
try {
|
|
159
|
-
const method = req.method || 'GET';
|
|
160
|
-
const requestUrl = req.url || '/';
|
|
161
165
|
if (method === 'GET' && requestUrl === '/health') {
|
|
162
166
|
writeJson(res, 200, { ok: true, service: 'cursor-daemon' });
|
|
163
167
|
return;
|
|
@@ -182,33 +186,49 @@ function startCursorDaemonServer(options) {
|
|
|
182
186
|
writeJson(res, 200, { object: 'list', data });
|
|
183
187
|
return;
|
|
184
188
|
}
|
|
185
|
-
if (
|
|
189
|
+
if (!isOpenAiRoute && !isAnthropicRoute) {
|
|
186
190
|
writeJson(res, 404, { error: 'Not found' });
|
|
187
191
|
return;
|
|
188
192
|
}
|
|
189
|
-
const
|
|
190
|
-
const
|
|
193
|
+
const rawBody = await readJsonBody(req);
|
|
194
|
+
const anthropicBody = isAnthropicRoute ? (0, cursor_anthropic_translator_1.translateAnthropicRequest)(rawBody) : undefined;
|
|
195
|
+
const parsedBody = anthropicBody ?? (rawBody || {});
|
|
196
|
+
const messages = anthropicBody
|
|
197
|
+
? anthropicBody.messages
|
|
198
|
+
: normalizeMessages(parsedBody.messages);
|
|
191
199
|
const requestedModel = typeof parsedBody.model === 'string' && parsedBody.model.trim().length > 0
|
|
192
200
|
? parsedBody.model.trim()
|
|
193
201
|
: undefined;
|
|
194
202
|
const stream = parsedBody.stream === true;
|
|
195
203
|
const authStatus = (0, cursor_auth_1.checkAuthStatus)();
|
|
196
204
|
if (!authStatus.authenticated || !authStatus.credentials) {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
205
|
+
const message = 'Cursor credentials not found. Run `ccs cursor auth` first.';
|
|
206
|
+
if (isAnthropicRoute) {
|
|
207
|
+
await pipeWebResponseToNode((0, cursor_anthropic_response_1.createAnthropicErrorResponse)(401, 'authentication_error', message), res);
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
writeJson(res, 401, {
|
|
211
|
+
error: {
|
|
212
|
+
type: 'authentication_error',
|
|
213
|
+
message,
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
}
|
|
203
217
|
return;
|
|
204
218
|
}
|
|
205
219
|
if (authStatus.expired) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
220
|
+
const message = 'Cursor credentials expired. Run `ccs cursor auth` again.';
|
|
221
|
+
if (isAnthropicRoute) {
|
|
222
|
+
await pipeWebResponseToNode((0, cursor_anthropic_response_1.createAnthropicErrorResponse)(401, 'authentication_error', message), res);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
writeJson(res, 401, {
|
|
226
|
+
error: {
|
|
227
|
+
type: 'authentication_error',
|
|
228
|
+
message,
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
}
|
|
212
232
|
return;
|
|
213
233
|
}
|
|
214
234
|
const daemonCredentials = {
|
|
@@ -247,17 +267,26 @@ function startCursorDaemonServer(options) {
|
|
|
247
267
|
: undefined,
|
|
248
268
|
},
|
|
249
269
|
});
|
|
250
|
-
|
|
270
|
+
const outgoingResponse = isAnthropicRoute
|
|
271
|
+
? await (0, cursor_anthropic_response_1.createAnthropicProxyResponse)(result.response)
|
|
272
|
+
: result.response;
|
|
273
|
+
await pipeWebResponseToNode(outgoingResponse, res);
|
|
251
274
|
}
|
|
252
275
|
catch (error) {
|
|
253
276
|
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
254
277
|
const isPayloadTooLarge = message.includes('Request body too large');
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
278
|
+
const status = isPayloadTooLarge ? 413 : 400;
|
|
279
|
+
if (isAnthropicRoute) {
|
|
280
|
+
await pipeWebResponseToNode((0, cursor_anthropic_response_1.createAnthropicErrorResponse)(status, 'invalid_request_error', message), res);
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
writeJson(res, status, {
|
|
284
|
+
error: {
|
|
285
|
+
type: 'invalid_request_error',
|
|
286
|
+
message,
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
}
|
|
261
290
|
}
|
|
262
291
|
});
|
|
263
292
|
server.listen(options.port, '127.0.0.1');
|