@hileeon/mcc 0.1.8 → 0.1.9
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 +226 -127
- package/dist/accounts/store.d.ts +1 -0
- package/dist/accounts/store.d.ts.map +1 -1
- package/dist/accounts/store.js.map +1 -1
- package/dist/commands/launch.d.ts +9 -0
- package/dist/commands/launch.d.ts.map +1 -0
- package/dist/commands/launch.js +158 -0
- package/dist/commands/launch.js.map +1 -0
- package/dist/commands/mcp.d.ts +9 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +112 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/profile.d.ts +8 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +125 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/core/model-router.d.ts.map +1 -1
- package/dist/core/model-router.js +5 -2
- package/dist/core/model-router.js.map +1 -1
- package/dist/{dashboard-server.d.ts → dashboard/server.d.ts} +1 -1
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/{dashboard-server.js → dashboard/server.js} +169 -51
- package/dist/dashboard/server.js.map +1 -0
- package/dist/mcc.d.ts +4 -2
- package/dist/mcc.d.ts.map +1 -1
- package/dist/mcc.js +121 -408
- package/dist/mcc.js.map +1 -1
- package/dist/mcp/mcp-config.d.ts +17 -1
- package/dist/mcp/mcp-config.d.ts.map +1 -1
- package/dist/mcp/mcp-config.js +50 -17
- package/dist/mcp/mcp-config.js.map +1 -1
- package/dist/proxy/proxy-daemon.d.ts.map +1 -1
- package/dist/proxy/proxy-daemon.js +17 -2
- package/dist/proxy/proxy-daemon.js.map +1 -1
- package/dist/proxy/proxy-entry.js +5 -3
- package/dist/proxy/proxy-entry.js.map +1 -1
- package/dist/proxy/proxy-server.d.ts.map +1 -1
- package/dist/proxy/proxy-server.js +32 -6
- package/dist/proxy/proxy-server.js.map +1 -1
- package/dist/shared/config.d.ts +15 -0
- package/dist/shared/config.d.ts.map +1 -0
- package/dist/shared/config.js +79 -0
- package/dist/shared/config.js.map +1 -0
- package/dist/shared/logger.d.ts +23 -18
- package/dist/shared/logger.d.ts.map +1 -1
- package/dist/shared/logger.js +17 -178
- package/dist/shared/logger.js.map +1 -1
- package/dist/shared/provider-preset-catalog.d.ts +6 -2
- package/dist/shared/provider-preset-catalog.d.ts.map +1 -1
- package/dist/shared/provider-preset-catalog.js +47 -26
- package/dist/shared/provider-preset-catalog.js.map +1 -1
- package/dist/ui/assets/index-ClqmrjNk.js +40 -0
- package/dist/ui/assets/index-CwMwQ-Z4.css +1 -0
- package/dist/ui/index.html +21 -13
- package/dist/update.d.ts +31 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/update.js +196 -0
- package/dist/update.js.map +1 -0
- package/lib/mcp/mcc-image-analysis-server.cjs +454 -454
- package/lib/mcp/mcc-websearch-server.cjs +339 -339
- package/lib/mcp-hooks/image-analysis-runtime.cjs +510 -510
- package/lib/mcp-hooks/image-analyzer-transformer.cjs +526 -526
- package/lib/mcp-hooks/websearch-transformer.cjs +1597 -1421
- package/lib/proxy/config/config-loader-facade.js +24 -24
- package/lib/proxy/glmt/delta-accumulator.js +362 -362
- package/lib/proxy/glmt/glmt-transformer.js +203 -203
- package/lib/proxy/glmt/index.js +40 -40
- package/lib/proxy/glmt/locale-enforcer.js +68 -68
- package/lib/proxy/glmt/pipeline/content-transformer.js +161 -161
- package/lib/proxy/glmt/pipeline/index.js +19 -19
- package/lib/proxy/glmt/pipeline/request-transformer.js +115 -115
- package/lib/proxy/glmt/pipeline/response-builder.js +204 -204
- package/lib/proxy/glmt/pipeline/stream-parser.js +233 -233
- package/lib/proxy/glmt/pipeline/tool-call-handler.js +77 -77
- package/lib/proxy/glmt/pipeline/types.js +5 -5
- package/lib/proxy/glmt/reasoning-enforcer.js +150 -150
- package/lib/proxy/glmt/sse-parser.js +101 -101
- package/lib/proxy/services/logging.js +13 -13
- package/lib/proxy/transformers/request-transformer.js +471 -471
- package/lib/proxy/transformers/sse-stream-transformer.js +198 -198
- package/lib/shared/logger.cjs +156 -138
- package/package.json +58 -41
- package/dist/dashboard-server.d.ts.map +0 -1
- package/dist/dashboard-server.js.map +0 -1
- package/dist/ui/assets/index-B16lhKZ6.js +0 -40
- package/dist/ui/assets/index-jEfiB6-h.css +0 -1
|
@@ -1,162 +1,162 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* ContentTransformer - Handle message sanitization and content transformations
|
|
4
|
-
*
|
|
5
|
-
* Responsibilities:
|
|
6
|
-
* - Sanitize messages for OpenAI API compatibility
|
|
7
|
-
* - Extract thinking control tags from messages
|
|
8
|
-
* - Detect think keywords in user prompts
|
|
9
|
-
* - Transform tools between Anthropic and OpenAI formats
|
|
10
|
-
*/
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.ContentTransformer = void 0;
|
|
13
|
-
class ContentTransformer {
|
|
14
|
-
constructor(defaultThinking = true) {
|
|
15
|
-
this.defaultThinking = defaultThinking;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Sanitize messages for OpenAI API compatibility
|
|
19
|
-
*/
|
|
20
|
-
sanitizeMessages(messages) {
|
|
21
|
-
const result = [];
|
|
22
|
-
for (const msg of messages) {
|
|
23
|
-
// If content is a string, add as-is
|
|
24
|
-
if (typeof msg.content === 'string') {
|
|
25
|
-
result.push(msg);
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
// If content is an array, process blocks
|
|
29
|
-
if (Array.isArray(msg.content)) {
|
|
30
|
-
// Separate tool_result blocks from other content
|
|
31
|
-
const toolResults = msg.content.filter((block) => block.type === 'tool_result');
|
|
32
|
-
const textBlocks = msg.content.filter((block) => block.type === 'text');
|
|
33
|
-
// CRITICAL: Tool messages must come BEFORE user text in OpenAI API
|
|
34
|
-
for (const toolResult of toolResults) {
|
|
35
|
-
result.push({
|
|
36
|
-
role: 'tool',
|
|
37
|
-
content: typeof toolResult.content === 'string'
|
|
38
|
-
? toolResult.content
|
|
39
|
-
: JSON.stringify(toolResult.content),
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
// Add text content as user/assistant message AFTER tool messages
|
|
43
|
-
if (textBlocks.length > 0) {
|
|
44
|
-
const textContent = textBlocks.length === 1
|
|
45
|
-
? textBlocks[0].text || ''
|
|
46
|
-
: textBlocks.map((b) => b.text || '').join('\n');
|
|
47
|
-
result.push({
|
|
48
|
-
role: msg.role,
|
|
49
|
-
content: textContent,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
// If no content at all, add empty message
|
|
53
|
-
if (textBlocks.length === 0 && toolResults.length === 0) {
|
|
54
|
-
result.push({
|
|
55
|
-
role: msg.role,
|
|
56
|
-
content: '',
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
// Fallback: return message as-is
|
|
62
|
-
result.push(msg);
|
|
63
|
-
}
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Transform Anthropic tools to OpenAI tools format
|
|
68
|
-
*/
|
|
69
|
-
transformTools(anthropicTools) {
|
|
70
|
-
return anthropicTools.map((tool) => ({
|
|
71
|
-
type: 'function',
|
|
72
|
-
function: {
|
|
73
|
-
name: tool.name,
|
|
74
|
-
description: tool.description,
|
|
75
|
-
parameters: tool.input_schema || {},
|
|
76
|
-
},
|
|
77
|
-
}));
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Check if messages contain thinking control tags
|
|
81
|
-
*/
|
|
82
|
-
hasThinkingTags(messages) {
|
|
83
|
-
for (const msg of messages) {
|
|
84
|
-
if (msg.role !== 'user')
|
|
85
|
-
continue;
|
|
86
|
-
const content = msg.content;
|
|
87
|
-
if (typeof content !== 'string')
|
|
88
|
-
continue;
|
|
89
|
-
// Check for control tags
|
|
90
|
-
if (/<Thinking:(On|Off)>/i.test(content) || /<Effort:(Low|Medium|High)>/i.test(content)) {
|
|
91
|
-
return true;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Extract thinking control tags from user messages
|
|
98
|
-
*/
|
|
99
|
-
extractThinkingControl(messages) {
|
|
100
|
-
const config = {
|
|
101
|
-
thinking: this.defaultThinking,
|
|
102
|
-
effort: 'medium',
|
|
103
|
-
};
|
|
104
|
-
// Scan user messages for control tags
|
|
105
|
-
for (const msg of messages) {
|
|
106
|
-
if (msg.role !== 'user')
|
|
107
|
-
continue;
|
|
108
|
-
const content = msg.content;
|
|
109
|
-
if (typeof content !== 'string')
|
|
110
|
-
continue;
|
|
111
|
-
// Check for <Thinking:On|Off>
|
|
112
|
-
const thinkingMatch = content.match(/<Thinking:(On|Off)>/i);
|
|
113
|
-
if (thinkingMatch) {
|
|
114
|
-
config.thinking = thinkingMatch[1].toLowerCase() === 'on';
|
|
115
|
-
}
|
|
116
|
-
// Check for <Effort:Low|Medium|High>
|
|
117
|
-
const effortMatch = content.match(/<Effort:(Low|Medium|High)>/i);
|
|
118
|
-
if (effortMatch) {
|
|
119
|
-
config.effort = effortMatch[1].toLowerCase();
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return config;
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Detect Anthropic-style "think" keywords in user prompts
|
|
126
|
-
*/
|
|
127
|
-
detectThinkKeywords(messages) {
|
|
128
|
-
if (!messages || messages.length === 0)
|
|
129
|
-
return null;
|
|
130
|
-
// Extract text from user messages
|
|
131
|
-
const text = messages
|
|
132
|
-
.filter((m) => m.role === 'user')
|
|
133
|
-
.map((m) => {
|
|
134
|
-
if (typeof m.content === 'string')
|
|
135
|
-
return m.content;
|
|
136
|
-
if (Array.isArray(m.content)) {
|
|
137
|
-
return m.content
|
|
138
|
-
.filter((block) => block.type === 'text')
|
|
139
|
-
.map((block) => block.text || '')
|
|
140
|
-
.join(' ');
|
|
141
|
-
}
|
|
142
|
-
return '';
|
|
143
|
-
})
|
|
144
|
-
.join(' ');
|
|
145
|
-
// Priority: ultrathink > think harder > think hard > think
|
|
146
|
-
if (/\bultrathink\b/i.test(text)) {
|
|
147
|
-
return { thinking: true, effort: 'max', keyword: 'ultrathink' };
|
|
148
|
-
}
|
|
149
|
-
if (/\bthink\s+harder\b/i.test(text)) {
|
|
150
|
-
return { thinking: true, effort: 'high', keyword: 'think harder' };
|
|
151
|
-
}
|
|
152
|
-
if (/\bthink\s+hard\b/i.test(text)) {
|
|
153
|
-
return { thinking: true, effort: 'medium', keyword: 'think hard' };
|
|
154
|
-
}
|
|
155
|
-
if (/\bthink\b/i.test(text)) {
|
|
156
|
-
return { thinking: true, effort: 'low', keyword: 'think' };
|
|
157
|
-
}
|
|
158
|
-
return null; // No keywords detected
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
exports.ContentTransformer = ContentTransformer;
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ContentTransformer - Handle message sanitization and content transformations
|
|
4
|
+
*
|
|
5
|
+
* Responsibilities:
|
|
6
|
+
* - Sanitize messages for OpenAI API compatibility
|
|
7
|
+
* - Extract thinking control tags from messages
|
|
8
|
+
* - Detect think keywords in user prompts
|
|
9
|
+
* - Transform tools between Anthropic and OpenAI formats
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ContentTransformer = void 0;
|
|
13
|
+
class ContentTransformer {
|
|
14
|
+
constructor(defaultThinking = true) {
|
|
15
|
+
this.defaultThinking = defaultThinking;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Sanitize messages for OpenAI API compatibility
|
|
19
|
+
*/
|
|
20
|
+
sanitizeMessages(messages) {
|
|
21
|
+
const result = [];
|
|
22
|
+
for (const msg of messages) {
|
|
23
|
+
// If content is a string, add as-is
|
|
24
|
+
if (typeof msg.content === 'string') {
|
|
25
|
+
result.push(msg);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
// If content is an array, process blocks
|
|
29
|
+
if (Array.isArray(msg.content)) {
|
|
30
|
+
// Separate tool_result blocks from other content
|
|
31
|
+
const toolResults = msg.content.filter((block) => block.type === 'tool_result');
|
|
32
|
+
const textBlocks = msg.content.filter((block) => block.type === 'text');
|
|
33
|
+
// CRITICAL: Tool messages must come BEFORE user text in OpenAI API
|
|
34
|
+
for (const toolResult of toolResults) {
|
|
35
|
+
result.push({
|
|
36
|
+
role: 'tool',
|
|
37
|
+
content: typeof toolResult.content === 'string'
|
|
38
|
+
? toolResult.content
|
|
39
|
+
: JSON.stringify(toolResult.content),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// Add text content as user/assistant message AFTER tool messages
|
|
43
|
+
if (textBlocks.length > 0) {
|
|
44
|
+
const textContent = textBlocks.length === 1
|
|
45
|
+
? textBlocks[0].text || ''
|
|
46
|
+
: textBlocks.map((b) => b.text || '').join('\n');
|
|
47
|
+
result.push({
|
|
48
|
+
role: msg.role,
|
|
49
|
+
content: textContent,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// If no content at all, add empty message
|
|
53
|
+
if (textBlocks.length === 0 && toolResults.length === 0) {
|
|
54
|
+
result.push({
|
|
55
|
+
role: msg.role,
|
|
56
|
+
content: '',
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
// Fallback: return message as-is
|
|
62
|
+
result.push(msg);
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Transform Anthropic tools to OpenAI tools format
|
|
68
|
+
*/
|
|
69
|
+
transformTools(anthropicTools) {
|
|
70
|
+
return anthropicTools.map((tool) => ({
|
|
71
|
+
type: 'function',
|
|
72
|
+
function: {
|
|
73
|
+
name: tool.name,
|
|
74
|
+
description: tool.description,
|
|
75
|
+
parameters: tool.input_schema || {},
|
|
76
|
+
},
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if messages contain thinking control tags
|
|
81
|
+
*/
|
|
82
|
+
hasThinkingTags(messages) {
|
|
83
|
+
for (const msg of messages) {
|
|
84
|
+
if (msg.role !== 'user')
|
|
85
|
+
continue;
|
|
86
|
+
const content = msg.content;
|
|
87
|
+
if (typeof content !== 'string')
|
|
88
|
+
continue;
|
|
89
|
+
// Check for control tags
|
|
90
|
+
if (/<Thinking:(On|Off)>/i.test(content) || /<Effort:(Low|Medium|High)>/i.test(content)) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Extract thinking control tags from user messages
|
|
98
|
+
*/
|
|
99
|
+
extractThinkingControl(messages) {
|
|
100
|
+
const config = {
|
|
101
|
+
thinking: this.defaultThinking,
|
|
102
|
+
effort: 'medium',
|
|
103
|
+
};
|
|
104
|
+
// Scan user messages for control tags
|
|
105
|
+
for (const msg of messages) {
|
|
106
|
+
if (msg.role !== 'user')
|
|
107
|
+
continue;
|
|
108
|
+
const content = msg.content;
|
|
109
|
+
if (typeof content !== 'string')
|
|
110
|
+
continue;
|
|
111
|
+
// Check for <Thinking:On|Off>
|
|
112
|
+
const thinkingMatch = content.match(/<Thinking:(On|Off)>/i);
|
|
113
|
+
if (thinkingMatch) {
|
|
114
|
+
config.thinking = thinkingMatch[1].toLowerCase() === 'on';
|
|
115
|
+
}
|
|
116
|
+
// Check for <Effort:Low|Medium|High>
|
|
117
|
+
const effortMatch = content.match(/<Effort:(Low|Medium|High)>/i);
|
|
118
|
+
if (effortMatch) {
|
|
119
|
+
config.effort = effortMatch[1].toLowerCase();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return config;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Detect Anthropic-style "think" keywords in user prompts
|
|
126
|
+
*/
|
|
127
|
+
detectThinkKeywords(messages) {
|
|
128
|
+
if (!messages || messages.length === 0)
|
|
129
|
+
return null;
|
|
130
|
+
// Extract text from user messages
|
|
131
|
+
const text = messages
|
|
132
|
+
.filter((m) => m.role === 'user')
|
|
133
|
+
.map((m) => {
|
|
134
|
+
if (typeof m.content === 'string')
|
|
135
|
+
return m.content;
|
|
136
|
+
if (Array.isArray(m.content)) {
|
|
137
|
+
return m.content
|
|
138
|
+
.filter((block) => block.type === 'text')
|
|
139
|
+
.map((block) => block.text || '')
|
|
140
|
+
.join(' ');
|
|
141
|
+
}
|
|
142
|
+
return '';
|
|
143
|
+
})
|
|
144
|
+
.join(' ');
|
|
145
|
+
// Priority: ultrathink > think harder > think hard > think
|
|
146
|
+
if (/\bultrathink\b/i.test(text)) {
|
|
147
|
+
return { thinking: true, effort: 'max', keyword: 'ultrathink' };
|
|
148
|
+
}
|
|
149
|
+
if (/\bthink\s+harder\b/i.test(text)) {
|
|
150
|
+
return { thinking: true, effort: 'high', keyword: 'think harder' };
|
|
151
|
+
}
|
|
152
|
+
if (/\bthink\s+hard\b/i.test(text)) {
|
|
153
|
+
return { thinking: true, effort: 'medium', keyword: 'think hard' };
|
|
154
|
+
}
|
|
155
|
+
if (/\bthink\b/i.test(text)) {
|
|
156
|
+
return { thinking: true, effort: 'low', keyword: 'think' };
|
|
157
|
+
}
|
|
158
|
+
return null; // No keywords detected
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
exports.ContentTransformer = ContentTransformer;
|
|
162
162
|
//# sourceMappingURL=content-transformer.js.map
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Pipeline Module Exports
|
|
4
|
-
*
|
|
5
|
-
* Barrel file for the GLMT transformation pipeline
|
|
6
|
-
*/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.RequestTransformer = exports.StreamParser = exports.ResponseBuilder = exports.ToolCallHandler = exports.ContentTransformer = void 0;
|
|
9
|
-
// Pipeline components
|
|
10
|
-
var content_transformer_1 = require("./content-transformer");
|
|
11
|
-
Object.defineProperty(exports, "ContentTransformer", { enumerable: true, get: function () { return content_transformer_1.ContentTransformer; } });
|
|
12
|
-
var tool_call_handler_1 = require("./tool-call-handler");
|
|
13
|
-
Object.defineProperty(exports, "ToolCallHandler", { enumerable: true, get: function () { return tool_call_handler_1.ToolCallHandler; } });
|
|
14
|
-
var response_builder_1 = require("./response-builder");
|
|
15
|
-
Object.defineProperty(exports, "ResponseBuilder", { enumerable: true, get: function () { return response_builder_1.ResponseBuilder; } });
|
|
16
|
-
var stream_parser_1 = require("./stream-parser");
|
|
17
|
-
Object.defineProperty(exports, "StreamParser", { enumerable: true, get: function () { return stream_parser_1.StreamParser; } });
|
|
18
|
-
var request_transformer_1 = require("./request-transformer");
|
|
19
|
-
Object.defineProperty(exports, "RequestTransformer", { enumerable: true, get: function () { return request_transformer_1.RequestTransformer; } });
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pipeline Module Exports
|
|
4
|
+
*
|
|
5
|
+
* Barrel file for the GLMT transformation pipeline
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.RequestTransformer = exports.StreamParser = exports.ResponseBuilder = exports.ToolCallHandler = exports.ContentTransformer = void 0;
|
|
9
|
+
// Pipeline components
|
|
10
|
+
var content_transformer_1 = require("./content-transformer");
|
|
11
|
+
Object.defineProperty(exports, "ContentTransformer", { enumerable: true, get: function () { return content_transformer_1.ContentTransformer; } });
|
|
12
|
+
var tool_call_handler_1 = require("./tool-call-handler");
|
|
13
|
+
Object.defineProperty(exports, "ToolCallHandler", { enumerable: true, get: function () { return tool_call_handler_1.ToolCallHandler; } });
|
|
14
|
+
var response_builder_1 = require("./response-builder");
|
|
15
|
+
Object.defineProperty(exports, "ResponseBuilder", { enumerable: true, get: function () { return response_builder_1.ResponseBuilder; } });
|
|
16
|
+
var stream_parser_1 = require("./stream-parser");
|
|
17
|
+
Object.defineProperty(exports, "StreamParser", { enumerable: true, get: function () { return stream_parser_1.StreamParser; } });
|
|
18
|
+
var request_transformer_1 = require("./request-transformer");
|
|
19
|
+
Object.defineProperty(exports, "RequestTransformer", { enumerable: true, get: function () { return request_transformer_1.RequestTransformer; } });
|
|
20
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,116 +1,116 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* RequestTransformer - Handle Anthropic → OpenAI request transformation
|
|
4
|
-
*
|
|
5
|
-
* Responsibilities:
|
|
6
|
-
* - Transform Anthropic request format to OpenAI format
|
|
7
|
-
* - Inject locale and reasoning instructions
|
|
8
|
-
* - Map models and configure parameters
|
|
9
|
-
*/
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.RequestTransformer = void 0;
|
|
12
|
-
const locale_enforcer_1 = require("../locale-enforcer");
|
|
13
|
-
const reasoning_enforcer_1 = require("../reasoning-enforcer");
|
|
14
|
-
const content_transformer_1 = require("./content-transformer");
|
|
15
|
-
class RequestTransformer {
|
|
16
|
-
constructor(config = {}) {
|
|
17
|
-
const defaultThinking = config.defaultThinking ?? true;
|
|
18
|
-
this.log = config.log || (() => { });
|
|
19
|
-
this.localeEnforcer = new locale_enforcer_1.LocaleEnforcer();
|
|
20
|
-
this.reasoningEnforcer = new reasoning_enforcer_1.ReasoningEnforcer({
|
|
21
|
-
enabled: config.explicitReasoning ?? true,
|
|
22
|
-
});
|
|
23
|
-
this.contentTransformer = new content_transformer_1.ContentTransformer(defaultThinking);
|
|
24
|
-
this.modelMaxTokens = {
|
|
25
|
-
'GLM-4.6': 128000,
|
|
26
|
-
'GLM-4.5': 96000,
|
|
27
|
-
'GLM-4.5-air': 16000,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Transform Anthropic request to OpenAI format
|
|
32
|
-
*/
|
|
33
|
-
transform(anthropicRequest) {
|
|
34
|
-
try {
|
|
35
|
-
const messages = anthropicRequest.messages || [];
|
|
36
|
-
// 1. Extract thinking control from messages
|
|
37
|
-
const thinkingConfig = this.contentTransformer.extractThinkingControl(messages);
|
|
38
|
-
const hasControlTags = this.contentTransformer.hasThinkingTags(messages);
|
|
39
|
-
// 2. Detect "think" keywords in user prompts
|
|
40
|
-
const keywordConfig = this.contentTransformer.detectThinkKeywords(messages);
|
|
41
|
-
if (keywordConfig && !anthropicRequest.thinking && !hasControlTags) {
|
|
42
|
-
thinkingConfig.thinking = keywordConfig.thinking;
|
|
43
|
-
thinkingConfig.effort = keywordConfig.effort;
|
|
44
|
-
this.log(`Detected think keyword: ${keywordConfig.keyword}, effort=${keywordConfig.effort}`);
|
|
45
|
-
}
|
|
46
|
-
// 3. Check anthropicRequest.thinking parameter (takes precedence)
|
|
47
|
-
if (anthropicRequest.thinking) {
|
|
48
|
-
if (anthropicRequest.thinking.type === 'enabled') {
|
|
49
|
-
thinkingConfig.thinking = true;
|
|
50
|
-
this.log('Claude CLI explicitly enabled thinking');
|
|
51
|
-
}
|
|
52
|
-
else if (anthropicRequest.thinking.type === 'disabled') {
|
|
53
|
-
thinkingConfig.thinking = false;
|
|
54
|
-
this.log('Claude CLI explicitly disabled thinking');
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
this.log(`Final thinking control: ${JSON.stringify(thinkingConfig)}`);
|
|
58
|
-
// 4. Map model
|
|
59
|
-
const glmModel = this.mapModel(anthropicRequest.model);
|
|
60
|
-
// 5. Inject locale instruction
|
|
61
|
-
const messagesWithLocale = this.localeEnforcer.injectInstruction(messages);
|
|
62
|
-
// 6. Inject reasoning instruction
|
|
63
|
-
const messagesWithReasoning = this.reasoningEnforcer.injectInstruction(messagesWithLocale, thinkingConfig);
|
|
64
|
-
// 7. Build OpenAI request
|
|
65
|
-
const openaiRequest = {
|
|
66
|
-
model: glmModel,
|
|
67
|
-
messages: this.contentTransformer.sanitizeMessages(messagesWithReasoning),
|
|
68
|
-
max_tokens: this.getMaxTokens(glmModel),
|
|
69
|
-
stream: anthropicRequest.stream ?? false,
|
|
70
|
-
};
|
|
71
|
-
// 8. Transform tools if present
|
|
72
|
-
if (anthropicRequest.tools && anthropicRequest.tools.length > 0) {
|
|
73
|
-
openaiRequest.tools = this.contentTransformer.transformTools(anthropicRequest.tools);
|
|
74
|
-
openaiRequest.tool_choice = 'auto';
|
|
75
|
-
this.log(`Transformed ${anthropicRequest.tools.length} tools for OpenAI format`);
|
|
76
|
-
}
|
|
77
|
-
// 9. Preserve optional parameters
|
|
78
|
-
if (anthropicRequest.temperature !== undefined) {
|
|
79
|
-
openaiRequest.temperature = anthropicRequest.temperature;
|
|
80
|
-
}
|
|
81
|
-
if (anthropicRequest.top_p !== undefined) {
|
|
82
|
-
openaiRequest.top_p = anthropicRequest.top_p;
|
|
83
|
-
}
|
|
84
|
-
if (anthropicRequest.stream !== undefined) {
|
|
85
|
-
openaiRequest.stream = anthropicRequest.stream;
|
|
86
|
-
}
|
|
87
|
-
// 10. Inject reasoning parameters
|
|
88
|
-
this.injectReasoningParams(openaiRequest, thinkingConfig);
|
|
89
|
-
return { openaiRequest, thinkingConfig };
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
const err = error;
|
|
93
|
-
console.error('[RequestTransformer] Transformation error:', err);
|
|
94
|
-
return {
|
|
95
|
-
openaiRequest: anthropicRequest,
|
|
96
|
-
thinkingConfig: { thinking: false, effort: 'medium' },
|
|
97
|
-
error: err.message,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
injectReasoningParams(openaiRequest, thinkingConfig) {
|
|
102
|
-
openaiRequest.do_sample = true;
|
|
103
|
-
if (thinkingConfig.thinking) {
|
|
104
|
-
openaiRequest.reasoning = true;
|
|
105
|
-
openaiRequest.reasoning_effort = thinkingConfig.effort;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
mapModel(_anthropicModel) {
|
|
109
|
-
return 'GLM-4.6';
|
|
110
|
-
}
|
|
111
|
-
getMaxTokens(model) {
|
|
112
|
-
return this.modelMaxTokens[model] || 128000;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
exports.RequestTransformer = RequestTransformer;
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RequestTransformer - Handle Anthropic → OpenAI request transformation
|
|
4
|
+
*
|
|
5
|
+
* Responsibilities:
|
|
6
|
+
* - Transform Anthropic request format to OpenAI format
|
|
7
|
+
* - Inject locale and reasoning instructions
|
|
8
|
+
* - Map models and configure parameters
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.RequestTransformer = void 0;
|
|
12
|
+
const locale_enforcer_1 = require("../locale-enforcer");
|
|
13
|
+
const reasoning_enforcer_1 = require("../reasoning-enforcer");
|
|
14
|
+
const content_transformer_1 = require("./content-transformer");
|
|
15
|
+
class RequestTransformer {
|
|
16
|
+
constructor(config = {}) {
|
|
17
|
+
const defaultThinking = config.defaultThinking ?? true;
|
|
18
|
+
this.log = config.log || (() => { });
|
|
19
|
+
this.localeEnforcer = new locale_enforcer_1.LocaleEnforcer();
|
|
20
|
+
this.reasoningEnforcer = new reasoning_enforcer_1.ReasoningEnforcer({
|
|
21
|
+
enabled: config.explicitReasoning ?? true,
|
|
22
|
+
});
|
|
23
|
+
this.contentTransformer = new content_transformer_1.ContentTransformer(defaultThinking);
|
|
24
|
+
this.modelMaxTokens = {
|
|
25
|
+
'GLM-4.6': 128000,
|
|
26
|
+
'GLM-4.5': 96000,
|
|
27
|
+
'GLM-4.5-air': 16000,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Transform Anthropic request to OpenAI format
|
|
32
|
+
*/
|
|
33
|
+
transform(anthropicRequest) {
|
|
34
|
+
try {
|
|
35
|
+
const messages = anthropicRequest.messages || [];
|
|
36
|
+
// 1. Extract thinking control from messages
|
|
37
|
+
const thinkingConfig = this.contentTransformer.extractThinkingControl(messages);
|
|
38
|
+
const hasControlTags = this.contentTransformer.hasThinkingTags(messages);
|
|
39
|
+
// 2. Detect "think" keywords in user prompts
|
|
40
|
+
const keywordConfig = this.contentTransformer.detectThinkKeywords(messages);
|
|
41
|
+
if (keywordConfig && !anthropicRequest.thinking && !hasControlTags) {
|
|
42
|
+
thinkingConfig.thinking = keywordConfig.thinking;
|
|
43
|
+
thinkingConfig.effort = keywordConfig.effort;
|
|
44
|
+
this.log(`Detected think keyword: ${keywordConfig.keyword}, effort=${keywordConfig.effort}`);
|
|
45
|
+
}
|
|
46
|
+
// 3. Check anthropicRequest.thinking parameter (takes precedence)
|
|
47
|
+
if (anthropicRequest.thinking) {
|
|
48
|
+
if (anthropicRequest.thinking.type === 'enabled') {
|
|
49
|
+
thinkingConfig.thinking = true;
|
|
50
|
+
this.log('Claude CLI explicitly enabled thinking');
|
|
51
|
+
}
|
|
52
|
+
else if (anthropicRequest.thinking.type === 'disabled') {
|
|
53
|
+
thinkingConfig.thinking = false;
|
|
54
|
+
this.log('Claude CLI explicitly disabled thinking');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
this.log(`Final thinking control: ${JSON.stringify(thinkingConfig)}`);
|
|
58
|
+
// 4. Map model
|
|
59
|
+
const glmModel = this.mapModel(anthropicRequest.model);
|
|
60
|
+
// 5. Inject locale instruction
|
|
61
|
+
const messagesWithLocale = this.localeEnforcer.injectInstruction(messages);
|
|
62
|
+
// 6. Inject reasoning instruction
|
|
63
|
+
const messagesWithReasoning = this.reasoningEnforcer.injectInstruction(messagesWithLocale, thinkingConfig);
|
|
64
|
+
// 7. Build OpenAI request
|
|
65
|
+
const openaiRequest = {
|
|
66
|
+
model: glmModel,
|
|
67
|
+
messages: this.contentTransformer.sanitizeMessages(messagesWithReasoning),
|
|
68
|
+
max_tokens: this.getMaxTokens(glmModel),
|
|
69
|
+
stream: anthropicRequest.stream ?? false,
|
|
70
|
+
};
|
|
71
|
+
// 8. Transform tools if present
|
|
72
|
+
if (anthropicRequest.tools && anthropicRequest.tools.length > 0) {
|
|
73
|
+
openaiRequest.tools = this.contentTransformer.transformTools(anthropicRequest.tools);
|
|
74
|
+
openaiRequest.tool_choice = 'auto';
|
|
75
|
+
this.log(`Transformed ${anthropicRequest.tools.length} tools for OpenAI format`);
|
|
76
|
+
}
|
|
77
|
+
// 9. Preserve optional parameters
|
|
78
|
+
if (anthropicRequest.temperature !== undefined) {
|
|
79
|
+
openaiRequest.temperature = anthropicRequest.temperature;
|
|
80
|
+
}
|
|
81
|
+
if (anthropicRequest.top_p !== undefined) {
|
|
82
|
+
openaiRequest.top_p = anthropicRequest.top_p;
|
|
83
|
+
}
|
|
84
|
+
if (anthropicRequest.stream !== undefined) {
|
|
85
|
+
openaiRequest.stream = anthropicRequest.stream;
|
|
86
|
+
}
|
|
87
|
+
// 10. Inject reasoning parameters
|
|
88
|
+
this.injectReasoningParams(openaiRequest, thinkingConfig);
|
|
89
|
+
return { openaiRequest, thinkingConfig };
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
const err = error;
|
|
93
|
+
console.error('[RequestTransformer] Transformation error:', err);
|
|
94
|
+
return {
|
|
95
|
+
openaiRequest: anthropicRequest,
|
|
96
|
+
thinkingConfig: { thinking: false, effort: 'medium' },
|
|
97
|
+
error: err.message,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
injectReasoningParams(openaiRequest, thinkingConfig) {
|
|
102
|
+
openaiRequest.do_sample = true;
|
|
103
|
+
if (thinkingConfig.thinking) {
|
|
104
|
+
openaiRequest.reasoning = true;
|
|
105
|
+
openaiRequest.reasoning_effort = thinkingConfig.effort;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
mapModel(_anthropicModel) {
|
|
109
|
+
return 'GLM-4.6';
|
|
110
|
+
}
|
|
111
|
+
getMaxTokens(model) {
|
|
112
|
+
return this.modelMaxTokens[model] || 128000;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.RequestTransformer = RequestTransformer;
|
|
116
116
|
//# sourceMappingURL=request-transformer.js.map
|