@vincemakes/kiso-provider-openai 0.1.2 → 0.1.4
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 +30 -17
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -294,30 +294,43 @@ function toOpenAIMessages(messages, systemPrompt) {
|
|
|
294
294
|
if (systemPrompt !== undefined) {
|
|
295
295
|
out.push({ role: "system", content: systemPrompt });
|
|
296
296
|
}
|
|
297
|
-
|
|
297
|
+
// 自举 P1/P2: thinking mode is detected by the presence of ANY
|
|
298
|
+
// reasoning in the projection (real OpenAI never emits thinking events,
|
|
299
|
+
// so its requests never see the field). In thinking mode, ONLY the
|
|
300
|
+
// CURRENT turn's assistant messages (after the last user message) carry
|
|
301
|
+
// reasoning_content — their own, or "" when the step produced no
|
|
302
|
+
// thinking (the field must still be present, or DeepSeek 400s); OLD
|
|
303
|
+
// turns' CoT is never echoed (DeepSeek does not need it, and echoing
|
|
304
|
+
// it is token waste).
|
|
305
|
+
const thinkingMode = messages.some((m) => m.role === "assistant" && m.reasoning !== undefined);
|
|
306
|
+
let lastUser = -1;
|
|
307
|
+
for (const [i, m] of messages.entries()) {
|
|
308
|
+
if (m.role === "user")
|
|
309
|
+
lastUser = i;
|
|
310
|
+
}
|
|
311
|
+
for (const [i, msg] of messages.entries()) {
|
|
298
312
|
if (msg.role === "user") {
|
|
299
313
|
out.push({ role: "user", content: toOpenAIContent(msg.content) });
|
|
300
314
|
}
|
|
301
315
|
else if (msg.role === "assistant") {
|
|
316
|
+
// OpenAI-compat APIs reject an EMPTY tool_calls array with 400
|
|
317
|
+
// ("expected an array with minimum length 1") — when the turn
|
|
318
|
+
// made no tool calls, the field is omitted entirely.
|
|
319
|
+
const toolCalls = msg.blocks
|
|
320
|
+
.filter((b) => b.type === "tool_use")
|
|
321
|
+
.map((b) => {
|
|
322
|
+
const t = b;
|
|
323
|
+
return {
|
|
324
|
+
id: t.callId,
|
|
325
|
+
type: "function",
|
|
326
|
+
function: { name: t.name, arguments: JSON.stringify(t.input) },
|
|
327
|
+
};
|
|
328
|
+
});
|
|
302
329
|
out.push({
|
|
303
330
|
role: "assistant",
|
|
304
331
|
content: msg.blocks.filter((b) => b.type === "text").map((b) => b.text).join(""),
|
|
305
|
-
tool_calls:
|
|
306
|
-
|
|
307
|
-
.map((b) => {
|
|
308
|
-
const t = b;
|
|
309
|
-
return {
|
|
310
|
-
id: t.callId,
|
|
311
|
-
type: "function",
|
|
312
|
-
function: { name: t.name, arguments: JSON.stringify(t.input) },
|
|
313
|
-
};
|
|
314
|
-
}),
|
|
315
|
-
// 自举 P1: DeepSeek's thinking mode REQUIRES the turn's
|
|
316
|
-
// reasoning back on follow-up requests (else 400) — the
|
|
317
|
-
// projection derived it from the thinking events; the compat
|
|
318
|
-
// wire field is reasoning_content. Real OpenAI never emits
|
|
319
|
-
// thinking events, so it never sees this field.
|
|
320
|
-
...(msg.reasoning !== undefined ? { reasoning_content: msg.reasoning } : {}),
|
|
332
|
+
...(toolCalls.length ? { tool_calls: toolCalls } : {}),
|
|
333
|
+
...(thinkingMode && i > lastUser ? { reasoning_content: msg.reasoning ?? "" } : {}),
|
|
321
334
|
});
|
|
322
335
|
}
|
|
323
336
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-provider-openai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "kiso OpenAI-compatible adapter \u2014 OpenAI + the compat family (GLM, Kimi, DeepSeek, OpenRouter) via base_url swap, reasoning dialects digested.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"test": "vitest run"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@vincemakes/kiso-core": "0.1.
|
|
24
|
+
"@vincemakes/kiso-core": "0.1.4",
|
|
25
25
|
"openai": "^7.3.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|