@kaitranntt/ccs 7.71.0-dev.7 → 7.71.0-dev.8
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 +34 -0
- package/dist/ccs.js +31 -0
- package/dist/ccs.js.map +1 -1
- package/dist/commands/command-catalog.d.ts +1 -0
- package/dist/commands/command-catalog.d.ts.map +1 -1
- package/dist/commands/command-catalog.js +8 -1
- package/dist/commands/command-catalog.js.map +1 -1
- package/dist/commands/completion-backend.d.ts.map +1 -1
- package/dist/commands/completion-backend.js +4 -0
- package/dist/commands/completion-backend.js.map +1 -1
- package/dist/commands/help-command.d.ts.map +1 -1
- package/dist/commands/help-command.js +2 -0
- package/dist/commands/help-command.js.map +1 -1
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +3 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/proxy-command.d.ts +2 -0
- package/dist/commands/proxy-command.d.ts.map +1 -0
- package/dist/commands/proxy-command.js +156 -0
- package/dist/commands/proxy-command.js.map +1 -0
- package/dist/commands/root-command-router.d.ts.map +1 -1
- package/dist/commands/root-command-router.js +7 -0
- package/dist/commands/root-command-router.js.map +1 -1
- package/dist/config/reserved-names.d.ts +1 -1
- package/dist/config/reserved-names.d.ts.map +1 -1
- package/dist/config/reserved-names.js +1 -0
- package/dist/config/reserved-names.js.map +1 -1
- package/dist/config/unified-config-loader.d.ts.map +1 -1
- package/dist/config/unified-config-loader.js +19 -0
- package/dist/config/unified-config-loader.js.map +1 -1
- package/dist/config/unified-config-types.d.ts +14 -0
- package/dist/config/unified-config-types.d.ts.map +1 -1
- package/dist/config/unified-config-types.js +11 -1
- package/dist/config/unified-config-types.js.map +1 -1
- package/dist/cursor/cursor-anthropic-response.d.ts +1 -6
- package/dist/cursor/cursor-anthropic-response.d.ts.map +1 -1
- package/dist/cursor/cursor-anthropic-response.js +3 -186
- package/dist/cursor/cursor-anthropic-response.js.map +1 -1
- package/dist/glmt/sse-parser.d.ts.map +1 -1
- package/dist/glmt/sse-parser.js +46 -41
- package/dist/glmt/sse-parser.js.map +1 -1
- package/dist/proxy/index.d.ts +8 -0
- package/dist/proxy/index.d.ts.map +1 -0
- package/dist/proxy/index.js +24 -0
- package/dist/proxy/index.js.map +1 -0
- package/dist/proxy/profile-router.d.ts +28 -0
- package/dist/proxy/profile-router.d.ts.map +1 -0
- package/dist/proxy/profile-router.js +43 -0
- package/dist/proxy/profile-router.js.map +1 -0
- package/dist/proxy/proxy-daemon-entry.d.ts +2 -0
- package/dist/proxy/proxy-daemon-entry.d.ts.map +1 -0
- package/dist/proxy/proxy-daemon-entry.js +68 -0
- package/dist/proxy/proxy-daemon-entry.js.map +1 -0
- package/dist/proxy/proxy-daemon-paths.d.ts +6 -0
- package/dist/proxy/proxy-daemon-paths.d.ts.map +1 -0
- package/dist/proxy/proxy-daemon-paths.js +43 -0
- package/dist/proxy/proxy-daemon-paths.js.map +1 -0
- package/dist/proxy/proxy-daemon-state.d.ts +18 -0
- package/dist/proxy/proxy-daemon-state.d.ts.map +1 -0
- package/dist/proxy/proxy-daemon-state.js +92 -0
- package/dist/proxy/proxy-daemon-state.js.map +1 -0
- package/dist/proxy/proxy-daemon.d.ts +26 -0
- package/dist/proxy/proxy-daemon.d.ts.map +1 -0
- package/dist/proxy/proxy-daemon.js +350 -0
- package/dist/proxy/proxy-daemon.js.map +1 -0
- package/dist/proxy/proxy-env.d.ts +3 -0
- package/dist/proxy/proxy-env.d.ts.map +1 -0
- package/dist/proxy/proxy-env.js +26 -0
- package/dist/proxy/proxy-env.js.map +1 -0
- package/dist/proxy/request-router.d.ts +12 -0
- package/dist/proxy/request-router.d.ts.map +1 -0
- package/dist/proxy/request-router.js +163 -0
- package/dist/proxy/request-router.js.map +1 -0
- package/dist/proxy/routing-config.d.ts +10 -0
- package/dist/proxy/routing-config.d.ts.map +1 -0
- package/dist/proxy/routing-config.js +79 -0
- package/dist/proxy/routing-config.js.map +1 -0
- package/dist/proxy/server/http-helpers.d.ts +8 -0
- package/dist/proxy/server/http-helpers.d.ts.map +1 -0
- package/dist/proxy/server/http-helpers.js +73 -0
- package/dist/proxy/server/http-helpers.js.map +1 -0
- package/dist/proxy/server/messages-route.d.ts +12 -0
- package/dist/proxy/server/messages-route.d.ts.map +1 -0
- package/dist/proxy/server/messages-route.js +208 -0
- package/dist/proxy/server/messages-route.js.map +1 -0
- package/dist/proxy/server/proxy-server.d.ts +12 -0
- package/dist/proxy/server/proxy-server.d.ts.map +1 -0
- package/dist/proxy/server/proxy-server.js +110 -0
- package/dist/proxy/server/proxy-server.js.map +1 -0
- package/dist/proxy/transformers/request-transformer.d.ts +52 -0
- package/dist/proxy/transformers/request-transformer.d.ts.map +1 -0
- package/dist/proxy/transformers/request-transformer.js +254 -0
- package/dist/proxy/transformers/request-transformer.js.map +1 -0
- package/dist/proxy/transformers/sse-stream-transformer.d.ts +11 -0
- package/dist/proxy/transformers/sse-stream-transformer.d.ts.map +1 -0
- package/dist/proxy/transformers/sse-stream-transformer.js +199 -0
- package/dist/proxy/transformers/sse-stream-transformer.js.map +1 -0
- package/dist/proxy/upstream-url.d.ts +3 -0
- package/dist/proxy/upstream-url.d.ts.map +1 -0
- package/dist/proxy/upstream-url.js +35 -0
- package/dist/proxy/upstream-url.js.map +1 -0
- package/dist/targets/droid-provider.d.ts.map +1 -1
- package/dist/targets/droid-provider.js +2 -0
- package/dist/targets/droid-provider.js.map +1 -1
- package/dist/types/config.d.ts +13 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/web-server/routes/config-routes.d.ts.map +1 -1
- package/dist/web-server/routes/config-routes.js +3 -0
- package/dist/web-server/routes/config-routes.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.startOpenAICompatProxyServer = void 0;
|
|
27
|
+
const http = __importStar(require("http"));
|
|
28
|
+
const undici_1 = require("undici");
|
|
29
|
+
const proxy_daemon_paths_1 = require("../proxy-daemon-paths");
|
|
30
|
+
const logging_1 = require("../../services/logging");
|
|
31
|
+
const messages_route_1 = require("./messages-route");
|
|
32
|
+
const http_helpers_1 = require("./http-helpers");
|
|
33
|
+
function startOpenAICompatProxyServer(options) {
|
|
34
|
+
const host = options.host?.trim() || '127.0.0.1';
|
|
35
|
+
const logger = (0, logging_1.createLogger)('proxy:openai-compat', {
|
|
36
|
+
profileName: options.profile.profileName,
|
|
37
|
+
host,
|
|
38
|
+
port: options.port,
|
|
39
|
+
});
|
|
40
|
+
const insecureDispatcher = options.insecure
|
|
41
|
+
? new undici_1.Agent({ connect: { rejectUnauthorized: false } })
|
|
42
|
+
: undefined;
|
|
43
|
+
const server = http.createServer(async (req, res) => {
|
|
44
|
+
const method = req.method || 'GET';
|
|
45
|
+
const requestUrl = req.url || '/';
|
|
46
|
+
const parsedUrl = new URL(requestUrl, 'http://127.0.0.1');
|
|
47
|
+
const pathname = parsedUrl.pathname.length > 1 ? parsedUrl.pathname.replace(/\/+$/, '') : parsedUrl.pathname;
|
|
48
|
+
if (method === 'GET' && pathname === '/health') {
|
|
49
|
+
(0, http_helpers_1.writeJson)(res, 200, {
|
|
50
|
+
ok: true,
|
|
51
|
+
service: proxy_daemon_paths_1.OPENAI_COMPAT_PROXY_SERVICE_NAME,
|
|
52
|
+
host,
|
|
53
|
+
profile: options.profile.profileName,
|
|
54
|
+
port: options.port,
|
|
55
|
+
});
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (method === 'GET' && pathname === '/') {
|
|
59
|
+
(0, http_helpers_1.writeJson)(res, 200, {
|
|
60
|
+
ok: true,
|
|
61
|
+
service: proxy_daemon_paths_1.OPENAI_COMPAT_PROXY_SERVICE_NAME,
|
|
62
|
+
bind: {
|
|
63
|
+
host,
|
|
64
|
+
port: options.port,
|
|
65
|
+
},
|
|
66
|
+
profile: {
|
|
67
|
+
name: options.profile.profileName,
|
|
68
|
+
provider: options.profile.provider,
|
|
69
|
+
model: options.profile.model || null,
|
|
70
|
+
},
|
|
71
|
+
endpoints: ['/health', '/v1/messages', '/v1/models'],
|
|
72
|
+
});
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (method === 'GET' && pathname === '/v1/models') {
|
|
76
|
+
if (!(0, messages_route_1.validateIncomingProxyAuth)(req.headers, options.authToken)) {
|
|
77
|
+
(0, http_helpers_1.writeJson)(res, 401, {
|
|
78
|
+
type: 'error',
|
|
79
|
+
error: {
|
|
80
|
+
type: 'authentication_error',
|
|
81
|
+
message: 'Missing or invalid local proxy token',
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
(0, messages_route_1.handleProxyModelsRequest)(res, options.profile);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (method === 'POST' && pathname === '/v1/messages') {
|
|
90
|
+
await (0, messages_route_1.handleProxyMessagesRequest)(req, res, options.profile, options.authToken, insecureDispatcher);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
logger.warn('http.not_found', 'Rejected unknown proxy route', {
|
|
94
|
+
method,
|
|
95
|
+
pathname,
|
|
96
|
+
});
|
|
97
|
+
(0, http_helpers_1.writeJson)(res, 404, { error: 'Not found' });
|
|
98
|
+
});
|
|
99
|
+
logger.info('server.start', 'OpenAI-compatible proxy server listening', {
|
|
100
|
+
baseUrl: `http://${host}:${options.port}`,
|
|
101
|
+
});
|
|
102
|
+
server.on('close', () => {
|
|
103
|
+
logger.info('server.stop', 'OpenAI-compatible proxy server stopped');
|
|
104
|
+
void insecureDispatcher?.close();
|
|
105
|
+
});
|
|
106
|
+
server.listen(options.port, host);
|
|
107
|
+
return server;
|
|
108
|
+
}
|
|
109
|
+
exports.startOpenAICompatProxyServer = startOpenAICompatProxyServer;
|
|
110
|
+
//# sourceMappingURL=proxy-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-server.js","sourceRoot":"","sources":["../../../src/proxy/server/proxy-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
interface OpenAITextPart {
|
|
2
|
+
type: 'text';
|
|
3
|
+
text: string;
|
|
4
|
+
}
|
|
5
|
+
interface OpenAIImagePart {
|
|
6
|
+
type: 'image_url';
|
|
7
|
+
image_url: {
|
|
8
|
+
url: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
type OpenAIContentPart = OpenAITextPart | OpenAIImagePart;
|
|
12
|
+
interface OpenAIMessage {
|
|
13
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
14
|
+
content: string | OpenAIContentPart[] | null;
|
|
15
|
+
tool_call_id?: string;
|
|
16
|
+
tool_calls?: Array<{
|
|
17
|
+
id: string;
|
|
18
|
+
type: 'function';
|
|
19
|
+
function: {
|
|
20
|
+
name: string;
|
|
21
|
+
arguments: string;
|
|
22
|
+
};
|
|
23
|
+
}>;
|
|
24
|
+
}
|
|
25
|
+
export interface ProxyOpenAIRequest {
|
|
26
|
+
model?: string;
|
|
27
|
+
stream: boolean;
|
|
28
|
+
reasoning_effort?: string;
|
|
29
|
+
reasoning?: {
|
|
30
|
+
enabled: boolean;
|
|
31
|
+
effort: string;
|
|
32
|
+
};
|
|
33
|
+
tools?: Array<{
|
|
34
|
+
type: 'function';
|
|
35
|
+
function: {
|
|
36
|
+
name: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
parameters: Record<string, unknown>;
|
|
39
|
+
};
|
|
40
|
+
}>;
|
|
41
|
+
messages: OpenAIMessage[];
|
|
42
|
+
max_tokens?: number;
|
|
43
|
+
temperature?: number;
|
|
44
|
+
top_p?: number;
|
|
45
|
+
stop?: string[];
|
|
46
|
+
metadata?: Record<string, unknown>;
|
|
47
|
+
}
|
|
48
|
+
export declare class ProxyRequestTransformer {
|
|
49
|
+
transform(raw: unknown): ProxyOpenAIRequest;
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=request-transformer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-transformer.d.ts","sourceRoot":"","sources":["../../../src/proxy/transformers/request-transformer.ts"],"names":[],"mappings":"AA0DA,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE;QACT,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAED,KAAK,iBAAiB,GAAG,cAAc,GAAG,eAAe,CAAC;AAE1D,UAAU,aAAa;IACrB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,GAAG,iBAAiB,EAAE,GAAG,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,KAAK,CAAC;QACjB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,UAAU,CAAC;QACjB,QAAQ,EAAE;YACR,IAAI,EAAE,MAAM,CAAC;YACb,SAAS,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE;QACV,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,KAAK,CAAC,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,UAAU,CAAC;QACjB,QAAQ,EAAE;YACR,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,CAAC,EAAE,MAAM,CAAC;YACrB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SACrC,CAAC;KACH,CAAC,CAAC;IACH,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAiSD,qBAAa,uBAAuB;IAClC,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,kBAAkB;CA4B5C"}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProxyRequestTransformer = 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 asNumber(value) {
|
|
13
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
14
|
+
}
|
|
15
|
+
function asStringArray(value) {
|
|
16
|
+
if (!Array.isArray(value)) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
const result = value.filter((entry) => typeof entry === 'string' && entry.length > 0);
|
|
20
|
+
return result.length > 0 ? result : undefined;
|
|
21
|
+
}
|
|
22
|
+
function asMetadata(value) {
|
|
23
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
24
|
+
? value
|
|
25
|
+
: undefined;
|
|
26
|
+
}
|
|
27
|
+
function safeJsonStringify(value, fallback) {
|
|
28
|
+
try {
|
|
29
|
+
const serialized = JSON.stringify(value);
|
|
30
|
+
return typeof serialized === 'string' ? serialized : fallback;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return fallback;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function flattenTextContent(content, label) {
|
|
37
|
+
if (typeof content === 'string') {
|
|
38
|
+
return content;
|
|
39
|
+
}
|
|
40
|
+
if (!Array.isArray(content)) {
|
|
41
|
+
throw new Error(`${label} must be a string or content block array`);
|
|
42
|
+
}
|
|
43
|
+
return content
|
|
44
|
+
.map((block, index) => {
|
|
45
|
+
const parsed = assertObject(block, `${label}[${index}]`);
|
|
46
|
+
if (parsed.type !== 'text') {
|
|
47
|
+
throw new Error(`${label}[${index}].type "${String(parsed.type)}" is not supported`);
|
|
48
|
+
}
|
|
49
|
+
return typeof parsed.text === 'string' ? parsed.text : '';
|
|
50
|
+
})
|
|
51
|
+
.join('\n');
|
|
52
|
+
}
|
|
53
|
+
function toToolResultContent(content, label) {
|
|
54
|
+
if (content === undefined) {
|
|
55
|
+
return '';
|
|
56
|
+
}
|
|
57
|
+
if (typeof content === 'string') {
|
|
58
|
+
return content;
|
|
59
|
+
}
|
|
60
|
+
if (Array.isArray(content)) {
|
|
61
|
+
return flattenTextContent(content, label);
|
|
62
|
+
}
|
|
63
|
+
return safeJsonStringify(content, TOOL_RESULT_SERIALIZATION_FALLBACK);
|
|
64
|
+
}
|
|
65
|
+
function createFallbackToolId(messageIndex, blockIndex) {
|
|
66
|
+
return `toolu_proxy_fallback_${messageIndex}_${blockIndex}`;
|
|
67
|
+
}
|
|
68
|
+
function toImagePart(block, label) {
|
|
69
|
+
const source = block.source;
|
|
70
|
+
if (!source || source.type !== 'base64' || !source.media_type || !source.data) {
|
|
71
|
+
throw new Error(`${label}.source must be a base64 image payload`);
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
type: 'image_url',
|
|
75
|
+
image_url: {
|
|
76
|
+
url: `data:${source.media_type};base64,${source.data}`,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function isImageBlock(block) {
|
|
81
|
+
return block.type === 'image';
|
|
82
|
+
}
|
|
83
|
+
function isToolUseBlock(block) {
|
|
84
|
+
return block.type === 'tool_use';
|
|
85
|
+
}
|
|
86
|
+
function isToolResultBlock(block) {
|
|
87
|
+
return block.type === 'tool_result';
|
|
88
|
+
}
|
|
89
|
+
function flushUserContent(messages, parts) {
|
|
90
|
+
if (parts.length === 0) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const onlyText = parts.every((part) => part.type === 'text');
|
|
94
|
+
messages.push({
|
|
95
|
+
role: 'user',
|
|
96
|
+
content: onlyText ? parts.map((part) => part.text).join('\n') : [...parts],
|
|
97
|
+
});
|
|
98
|
+
parts.length = 0;
|
|
99
|
+
}
|
|
100
|
+
function transformTools(value) {
|
|
101
|
+
if (!Array.isArray(value)) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
const tools = value
|
|
105
|
+
.filter((entry) => typeof entry === 'object' && entry !== null)
|
|
106
|
+
.map((entry) => ({
|
|
107
|
+
type: 'function',
|
|
108
|
+
function: {
|
|
109
|
+
name: typeof entry.name === 'string' ? entry.name : 'tool',
|
|
110
|
+
...(typeof entry.description === 'string' ? { description: entry.description } : {}),
|
|
111
|
+
parameters: typeof entry.input_schema === 'object' && entry.input_schema !== null
|
|
112
|
+
? entry.input_schema
|
|
113
|
+
: { type: 'object', properties: {} },
|
|
114
|
+
},
|
|
115
|
+
}));
|
|
116
|
+
return tools.length > 0 ? tools : undefined;
|
|
117
|
+
}
|
|
118
|
+
function mapThinkingToReasoning(thinking) {
|
|
119
|
+
if (!thinking || thinking.type === 'disabled') {
|
|
120
|
+
return {};
|
|
121
|
+
}
|
|
122
|
+
if (thinking.type !== 'enabled') {
|
|
123
|
+
throw new Error('thinking.type must be "enabled" or "disabled"');
|
|
124
|
+
}
|
|
125
|
+
const effort = typeof thinking.budget_tokens === 'number' && thinking.budget_tokens >= 8192
|
|
126
|
+
? 'high'
|
|
127
|
+
: 'medium';
|
|
128
|
+
return {
|
|
129
|
+
reasoning_effort: effort,
|
|
130
|
+
reasoning: {
|
|
131
|
+
enabled: true,
|
|
132
|
+
effort,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function transformMessages(messagesValue) {
|
|
137
|
+
if (!Array.isArray(messagesValue)) {
|
|
138
|
+
throw new Error('messages must be an array');
|
|
139
|
+
}
|
|
140
|
+
const translatedMessages = [];
|
|
141
|
+
messagesValue.forEach((message, messageIndex) => {
|
|
142
|
+
const parsedMessage = assertObject(message, `messages[${messageIndex}]`);
|
|
143
|
+
const role = parsedMessage.role;
|
|
144
|
+
if (role !== 'user' && role !== 'assistant') {
|
|
145
|
+
throw new Error(`messages[${messageIndex}].role must be "user" or "assistant"`);
|
|
146
|
+
}
|
|
147
|
+
const content = parsedMessage.content;
|
|
148
|
+
if (typeof content === 'string') {
|
|
149
|
+
translatedMessages.push({ role, content });
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (!Array.isArray(content)) {
|
|
153
|
+
throw new Error(`messages[${messageIndex}].content must be a string or array`);
|
|
154
|
+
}
|
|
155
|
+
const userParts = [];
|
|
156
|
+
const assistantTextParts = [];
|
|
157
|
+
const toolCalls = [];
|
|
158
|
+
let sawToolResult = false;
|
|
159
|
+
content.forEach((block, blockIndex) => {
|
|
160
|
+
const parsed = assertObject(block, `messages[${messageIndex}].content[${blockIndex}]`);
|
|
161
|
+
if (parsed.type === 'text') {
|
|
162
|
+
const text = typeof parsed.text === 'string' ? parsed.text : '';
|
|
163
|
+
if (role === 'user') {
|
|
164
|
+
userParts.push({ type: 'text', text });
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
assistantTextParts.push(text);
|
|
168
|
+
}
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (isImageBlock(parsed)) {
|
|
172
|
+
if (role !== 'user') {
|
|
173
|
+
throw new Error(`messages[${messageIndex}].content[${blockIndex}] image requires user role`);
|
|
174
|
+
}
|
|
175
|
+
userParts.push(toImagePart(parsed, `messages[${messageIndex}].content[${blockIndex}]`));
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (isToolUseBlock(parsed)) {
|
|
179
|
+
if (role !== 'assistant') {
|
|
180
|
+
throw new Error(`messages[${messageIndex}].content[${blockIndex}] tool_use requires assistant role`);
|
|
181
|
+
}
|
|
182
|
+
toolCalls.push({
|
|
183
|
+
id: typeof parsed.id === 'string' && parsed.id.length > 0
|
|
184
|
+
? parsed.id
|
|
185
|
+
: createFallbackToolId(messageIndex, blockIndex),
|
|
186
|
+
type: 'function',
|
|
187
|
+
function: {
|
|
188
|
+
name: typeof parsed.name === 'string' ? parsed.name : 'tool',
|
|
189
|
+
arguments: safeJsonStringify(parsed.input ?? {}, TOOL_USE_ARGUMENTS_FALLBACK),
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (isToolResultBlock(parsed)) {
|
|
195
|
+
if (role !== 'user') {
|
|
196
|
+
throw new Error(`messages[${messageIndex}].content[${blockIndex}] tool_result requires user role`);
|
|
197
|
+
}
|
|
198
|
+
if (typeof parsed.tool_use_id !== 'string' || parsed.tool_use_id.trim().length === 0) {
|
|
199
|
+
throw new Error(`messages[${messageIndex}].content[${blockIndex}].tool_use_id must be a non-empty string`);
|
|
200
|
+
}
|
|
201
|
+
sawToolResult = true;
|
|
202
|
+
flushUserContent(translatedMessages, userParts);
|
|
203
|
+
translatedMessages.push({
|
|
204
|
+
role: 'tool',
|
|
205
|
+
tool_call_id: parsed.tool_use_id,
|
|
206
|
+
content: toToolResultContent(parsed.content, `messages[${messageIndex}].content[${blockIndex}].content`),
|
|
207
|
+
});
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
throw new Error(`messages[${messageIndex}].content[${blockIndex}].type "${String(parsed.type)}" is not supported`);
|
|
211
|
+
});
|
|
212
|
+
if (role === 'assistant') {
|
|
213
|
+
translatedMessages.push({
|
|
214
|
+
role: 'assistant',
|
|
215
|
+
content: assistantTextParts.join('\n'),
|
|
216
|
+
tool_calls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
217
|
+
});
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (userParts.length > 0 || !sawToolResult) {
|
|
221
|
+
flushUserContent(translatedMessages, userParts);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
return translatedMessages;
|
|
225
|
+
}
|
|
226
|
+
class ProxyRequestTransformer {
|
|
227
|
+
transform(raw) {
|
|
228
|
+
const source = assertObject(raw || {}, 'request');
|
|
229
|
+
const messages = transformMessages(source.messages);
|
|
230
|
+
const system = source.system;
|
|
231
|
+
const allMessages = system !== undefined
|
|
232
|
+
? [
|
|
233
|
+
{ role: 'system', content: flattenTextContent(system, 'system') },
|
|
234
|
+
...messages,
|
|
235
|
+
]
|
|
236
|
+
: messages;
|
|
237
|
+
return {
|
|
238
|
+
model: typeof source.model === 'string' && source.model.trim().length > 0
|
|
239
|
+
? source.model.trim()
|
|
240
|
+
: undefined,
|
|
241
|
+
stream: source.stream === true,
|
|
242
|
+
messages: allMessages,
|
|
243
|
+
max_tokens: asNumber(source.max_tokens),
|
|
244
|
+
temperature: asNumber(source.temperature),
|
|
245
|
+
top_p: asNumber(source.top_p),
|
|
246
|
+
stop: asStringArray(source.stop_sequences),
|
|
247
|
+
metadata: asMetadata(source.metadata),
|
|
248
|
+
tools: transformTools(source.tools),
|
|
249
|
+
...mapThinkingToReasoning(source.thinking),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
exports.ProxyRequestTransformer = ProxyRequestTransformer;
|
|
254
|
+
//# sourceMappingURL=request-transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-transformer.js","sourceRoot":"","sources":["../../../src/proxy/transformers/request-transformer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="bun-types" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
type ResponseHeaders = Headers | Record<string, string> | Array<[string, string]>;
|
|
4
|
+
export declare function createAnthropicErrorResponse(status: number, type: string, message: string, headers?: ResponseHeaders): Response;
|
|
5
|
+
export declare function createAnthropicProxyResponse(response: Response): Promise<Response>;
|
|
6
|
+
export declare class ProxySseStreamTransformer {
|
|
7
|
+
transform(response: Response): Promise<Response>;
|
|
8
|
+
error(status: number, type: string, message: string): Response;
|
|
9
|
+
}
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=sse-stream-transformer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse-stream-transformer.d.ts","sourceRoot":"","sources":["../../../src/proxy/transformers/sse-stream-transformer.ts"],"names":[],"mappings":";;AAQA,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;AAED,qBAAa,yBAAyB;IAC9B,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAItD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ;CAG/D"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProxySseStreamTransformer = 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 OpenAI-compatible JSON response';
|
|
8
|
+
const STREAM_TRANSLATION_ERROR_MESSAGE = 'Failed to translate OpenAI-compatible 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(`[proxy-sse-transformer] ${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 = `Upstream 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 upstream 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('OpenAI-compatible 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('OpenAI-compatible 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', 'Upstream 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
|
+
for (const event of events) {
|
|
148
|
+
const anthropicEvents = transformer.transformDelta(event, accumulator);
|
|
149
|
+
for (const anthropicEvent of anthropicEvents) {
|
|
150
|
+
controller.enqueue(encoder.encode(formatSseEvent(anthropicEvent.event, anthropicEvent.data)));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (!accumulator.isFinalized() && accumulator.isMessageStarted()) {
|
|
155
|
+
for (const anthropicEvent of transformer.finalizeDelta(accumulator)) {
|
|
156
|
+
controller.enqueue(encoder.encode(formatSseEvent(anthropicEvent.event, anthropicEvent.data)));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
logTranslationError('OpenAI-compatible 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
|
+
class ProxySseStreamTransformer {
|
|
191
|
+
async transform(response) {
|
|
192
|
+
return createAnthropicProxyResponse(response);
|
|
193
|
+
}
|
|
194
|
+
error(status, type, message) {
|
|
195
|
+
return createAnthropicErrorResponse(status, type, message);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
exports.ProxySseStreamTransformer = ProxySseStreamTransformer;
|
|
199
|
+
//# sourceMappingURL=sse-stream-transformer.js.map
|