@zhongqian97-code/ecode 0.3.7 → 0.3.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/dist/index.js +66 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -38,7 +38,11 @@ var MODEL_CONTEXT_LIMITS = {
|
|
|
38
38
|
"claude-haiku-4-5-20251001": 2e5,
|
|
39
39
|
// DeepSeek 系列(上下文较小,截断策略需更激进)
|
|
40
40
|
"deepseek-chat": 65536,
|
|
41
|
-
"deepseek-reasoner": 65536
|
|
41
|
+
"deepseek-reasoner": 65536,
|
|
42
|
+
// MiniMax 系列(baseUrl: https://api.minimax.chat/v1)
|
|
43
|
+
"MiniMax-M2.5": 1e6,
|
|
44
|
+
"MiniMax-M2.5-highspeed": 192e3,
|
|
45
|
+
"MiniMax-Text-01": 1e6
|
|
42
46
|
};
|
|
43
47
|
var DEFAULT_CONTEXT_LIMIT = 128e3;
|
|
44
48
|
function getContextLimit(model, override) {
|
|
@@ -144,6 +148,34 @@ function createOpenAIProvider(profile) {
|
|
|
144
148
|
stream(messages, tools, signal) {
|
|
145
149
|
return {
|
|
146
150
|
[Symbol.asyncIterator]: async function* () {
|
|
151
|
+
let inThinkBlock = false;
|
|
152
|
+
function stripThinkTags(raw) {
|
|
153
|
+
let text = "";
|
|
154
|
+
let thinking = "";
|
|
155
|
+
let i = 0;
|
|
156
|
+
while (i < raw.length) {
|
|
157
|
+
if (!inThinkBlock) {
|
|
158
|
+
const start = raw.indexOf("<think>", i);
|
|
159
|
+
if (start === -1) {
|
|
160
|
+
text += raw.slice(i);
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
text += raw.slice(i, start);
|
|
164
|
+
inThinkBlock = true;
|
|
165
|
+
i = start + 7;
|
|
166
|
+
} else {
|
|
167
|
+
const end = raw.indexOf("</think>", i);
|
|
168
|
+
if (end === -1) {
|
|
169
|
+
thinking += raw.slice(i);
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
thinking += raw.slice(i, end);
|
|
173
|
+
inThinkBlock = false;
|
|
174
|
+
i = end + 8;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return { text, thinking };
|
|
178
|
+
}
|
|
147
179
|
const requestParams = {
|
|
148
180
|
model: profile.model,
|
|
149
181
|
messages,
|
|
@@ -159,6 +191,7 @@ function createOpenAIProvider(profile) {
|
|
|
159
191
|
);
|
|
160
192
|
const tcAccumulator = /* @__PURE__ */ new Map();
|
|
161
193
|
let reasoningAccumulator = "";
|
|
194
|
+
const reasoningDetailsAcc = /* @__PURE__ */ new Map();
|
|
162
195
|
for await (const chunk of response) {
|
|
163
196
|
const choice = chunk.choices[0];
|
|
164
197
|
if (!choice) continue;
|
|
@@ -166,6 +199,26 @@ function createOpenAIProvider(profile) {
|
|
|
166
199
|
if (delta.reasoning_content) {
|
|
167
200
|
reasoningAccumulator += delta.reasoning_content;
|
|
168
201
|
}
|
|
202
|
+
if (delta.reasoning_details && delta.reasoning_details.length > 0) {
|
|
203
|
+
for (const rd of delta.reasoning_details) {
|
|
204
|
+
const id = rd.id ?? "";
|
|
205
|
+
const text = rd.text ?? "";
|
|
206
|
+
if (!reasoningDetailsAcc.has(id)) {
|
|
207
|
+
reasoningDetailsAcc.set(id, {
|
|
208
|
+
type: rd.type ?? "reasoning.text",
|
|
209
|
+
id,
|
|
210
|
+
format: rd.format ?? "",
|
|
211
|
+
index: rd.index ?? 0,
|
|
212
|
+
text: ""
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
const existing = reasoningDetailsAcc.get(id);
|
|
216
|
+
existing.text += text;
|
|
217
|
+
if (!delta.reasoning_content && text) {
|
|
218
|
+
reasoningAccumulator += text;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
169
222
|
if (delta.tool_calls) {
|
|
170
223
|
for (const tc of delta.tool_calls) {
|
|
171
224
|
if (!tcAccumulator.has(tc.index)) {
|
|
@@ -181,17 +234,24 @@ function createOpenAIProvider(profile) {
|
|
|
181
234
|
existing.arguments += tc.function?.arguments ?? "";
|
|
182
235
|
}
|
|
183
236
|
}
|
|
184
|
-
const isLast = choice.finish_reason
|
|
237
|
+
const isLast = choice.finish_reason != null;
|
|
238
|
+
const raw = delta.content ?? "";
|
|
239
|
+
const { text: filteredText, thinking: thinkContent } = stripThinkTags(raw);
|
|
240
|
+
if (thinkContent) {
|
|
241
|
+
reasoningAccumulator += thinkContent;
|
|
242
|
+
}
|
|
185
243
|
if (isLast) {
|
|
186
244
|
const rawUsage = chunk.usage;
|
|
187
245
|
yield {
|
|
188
|
-
text:
|
|
246
|
+
text: filteredText,
|
|
189
247
|
done: true,
|
|
190
248
|
finishReason: choice.finish_reason,
|
|
191
249
|
// tcAccumulator 为空说明本轮没有工具调用,传 undefined 而非空数组,
|
|
192
250
|
// 让调用方用 if (chunk.toolCalls) 做简洁判断
|
|
193
251
|
toolCalls: tcAccumulator.size > 0 ? Array.from(tcAccumulator.values()) : void 0,
|
|
194
252
|
reasoning: reasoningAccumulator || void 0,
|
|
253
|
+
// reasoningDetails 仅在流中出现过结构化推理时返回(MiniMax 兼容)
|
|
254
|
+
reasoningDetails: reasoningDetailsAcc.size > 0 ? Array.from(reasoningDetailsAcc.values()) : void 0,
|
|
195
255
|
// 将 snake_case 的原始字段映射为 camelCase,对外接口保持一致
|
|
196
256
|
usage: rawUsage ? {
|
|
197
257
|
promptTokens: rawUsage.prompt_tokens,
|
|
@@ -200,9 +260,10 @@ function createOpenAIProvider(profile) {
|
|
|
200
260
|
} : void 0
|
|
201
261
|
};
|
|
202
262
|
} else {
|
|
263
|
+
const incrementalReasoning = delta.reasoning_content || thinkContent || (delta.reasoning_details && delta.reasoning_details.length > 0 ? delta.reasoning_details.map((rd) => rd.text ?? "").join("") : void 0) || void 0;
|
|
203
264
|
yield {
|
|
204
|
-
text:
|
|
205
|
-
reasoning:
|
|
265
|
+
text: filteredText,
|
|
266
|
+
reasoning: incrementalReasoning || void 0,
|
|
206
267
|
done: false
|
|
207
268
|
};
|
|
208
269
|
}
|