@yourgpt/llm-sdk 2.1.8 → 2.1.10-alpha.0
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/adapters/index.d.mts +38 -4
- package/dist/adapters/index.d.ts +38 -4
- package/dist/adapters/index.js +318 -8
- package/dist/adapters/index.mjs +318 -8
- package/dist/{base-iGi9Va6Z.d.ts → base-DN1EfKnE.d.mts} +2 -1
- package/dist/{base-D-U61JaB.d.mts → base-DuUNxtVg.d.ts} +2 -1
- package/dist/fallback/index.d.mts +4 -4
- package/dist/fallback/index.d.ts +4 -4
- package/dist/index.d.mts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +43 -23
- package/dist/index.mjs +43 -23
- package/dist/providers/anthropic/index.d.mts +3 -3
- package/dist/providers/anthropic/index.d.ts +3 -3
- package/dist/providers/anthropic/index.js +17 -0
- package/dist/providers/anthropic/index.mjs +17 -0
- package/dist/providers/azure/index.d.mts +3 -3
- package/dist/providers/azure/index.d.ts +3 -3
- package/dist/providers/fireworks/index.d.mts +1 -1
- package/dist/providers/fireworks/index.d.ts +1 -1
- package/dist/providers/google/index.d.mts +3 -3
- package/dist/providers/google/index.d.ts +3 -3
- package/dist/providers/google/index.js +311 -8
- package/dist/providers/google/index.mjs +311 -8
- package/dist/providers/ollama/index.d.mts +4 -4
- package/dist/providers/ollama/index.d.ts +4 -4
- package/dist/providers/openai/index.d.mts +3 -3
- package/dist/providers/openai/index.d.ts +3 -3
- package/dist/providers/openai/index.js +321 -8
- package/dist/providers/openai/index.mjs +321 -8
- package/dist/providers/openrouter/index.d.mts +7 -3
- package/dist/providers/openrouter/index.d.ts +7 -3
- package/dist/providers/openrouter/index.js +601 -11
- package/dist/providers/openrouter/index.mjs +601 -11
- package/dist/providers/togetherai/index.d.mts +61 -2
- package/dist/providers/togetherai/index.d.ts +61 -2
- package/dist/providers/togetherai/index.js +1030 -2
- package/dist/providers/togetherai/index.mjs +1029 -2
- package/dist/providers/xai/index.d.mts +3 -3
- package/dist/providers/xai/index.d.ts +3 -3
- package/dist/providers/xai/index.js +311 -8
- package/dist/providers/xai/index.mjs +311 -8
- package/dist/{types-D4YfrQJR.d.mts → types-BNCmlJMs.d.mts} +1 -1
- package/dist/{types-DRqxMIjF.d.mts → types-CMMQ8s2O.d.mts} +1 -1
- package/dist/{types-CR8mi9I0.d.ts → types-CMvvDo-E.d.mts} +12 -1
- package/dist/{types-CR8mi9I0.d.mts → types-CMvvDo-E.d.ts} +12 -1
- package/dist/{types-BctsnC3g.d.ts → types-DhktekQ3.d.ts} +1 -1
- package/dist/{types-38yolWJn.d.ts → types-Pj-vpmoT.d.ts} +1 -1
- package/dist/yourgpt/index.d.mts +1 -1
- package/dist/yourgpt/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -297,6 +297,20 @@ async function streamText(params) {
|
|
|
297
297
|
fullText += chunk.text;
|
|
298
298
|
yield { type: "text-delta", text: chunk.text };
|
|
299
299
|
break;
|
|
300
|
+
case "tool-call-start":
|
|
301
|
+
yield {
|
|
302
|
+
type: "tool-call-start",
|
|
303
|
+
toolCallId: chunk.toolCallId,
|
|
304
|
+
toolName: chunk.toolName
|
|
305
|
+
};
|
|
306
|
+
break;
|
|
307
|
+
case "tool-call-delta":
|
|
308
|
+
yield {
|
|
309
|
+
type: "tool-call-delta",
|
|
310
|
+
toolCallId: chunk.toolCallId,
|
|
311
|
+
argsText: chunk.argsText
|
|
312
|
+
};
|
|
313
|
+
break;
|
|
300
314
|
case "tool-call":
|
|
301
315
|
toolCalls.push(chunk.toolCall);
|
|
302
316
|
yield {
|
|
@@ -1595,7 +1609,7 @@ var Runtime = class {
|
|
|
1595
1609
|
const completionRequest = {
|
|
1596
1610
|
messages,
|
|
1597
1611
|
actions: allActions.length > 0 ? allActions : void 0,
|
|
1598
|
-
systemPrompt:
|
|
1612
|
+
systemPrompt: this.config.systemPrompt ?? request.systemPrompt,
|
|
1599
1613
|
config: request.config,
|
|
1600
1614
|
signal,
|
|
1601
1615
|
webSearch: this.getWebSearchConfig(),
|
|
@@ -2159,7 +2173,7 @@ var Runtime = class {
|
|
|
2159
2173
|
}
|
|
2160
2174
|
}
|
|
2161
2175
|
}
|
|
2162
|
-
const systemPrompt =
|
|
2176
|
+
const systemPrompt = this.config.systemPrompt ?? request.systemPrompt ?? "";
|
|
2163
2177
|
let accumulatedText = "";
|
|
2164
2178
|
const toolCalls = [];
|
|
2165
2179
|
let currentToolCall = null;
|
|
@@ -2206,38 +2220,44 @@ var Runtime = class {
|
|
|
2206
2220
|
break;
|
|
2207
2221
|
case "action:args":
|
|
2208
2222
|
if (currentToolCall) {
|
|
2223
|
+
currentToolCall.args = event.args || currentToolCall.args;
|
|
2209
2224
|
try {
|
|
2210
|
-
const parsedArgs = JSON.parse(
|
|
2225
|
+
const parsedArgs = JSON.parse(currentToolCall.args || "{}");
|
|
2226
|
+
const existingIdx = toolCalls.findIndex(
|
|
2227
|
+
(t) => t.id === currentToolCall.id
|
|
2228
|
+
);
|
|
2229
|
+
const entry = {
|
|
2230
|
+
id: currentToolCall.id,
|
|
2231
|
+
name: currentToolCall.name,
|
|
2232
|
+
args: parsedArgs,
|
|
2233
|
+
...currentToolCall.extra_content ? { extra_content: currentToolCall.extra_content } : {}
|
|
2234
|
+
};
|
|
2235
|
+
if (existingIdx >= 0) {
|
|
2236
|
+
toolCalls[existingIdx] = entry;
|
|
2237
|
+
} else {
|
|
2238
|
+
toolCalls.push(entry);
|
|
2239
|
+
}
|
|
2211
2240
|
if (debug) {
|
|
2212
2241
|
console.log(
|
|
2213
2242
|
`[Copilot SDK] Tool args for ${currentToolCall.name}:`,
|
|
2214
2243
|
parsedArgs
|
|
2215
2244
|
);
|
|
2216
2245
|
}
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
event.args,
|
|
2227
|
-
e
|
|
2228
|
-
);
|
|
2229
|
-
toolCalls.push({
|
|
2230
|
-
id: currentToolCall.id,
|
|
2231
|
-
name: currentToolCall.name,
|
|
2232
|
-
args: {},
|
|
2233
|
-
...currentToolCall.extra_content ? { extra_content: currentToolCall.extra_content } : {}
|
|
2234
|
-
});
|
|
2246
|
+
} catch {
|
|
2247
|
+
if (!toolCalls.find((t) => t.id === currentToolCall.id)) {
|
|
2248
|
+
toolCalls.push({
|
|
2249
|
+
id: currentToolCall.id,
|
|
2250
|
+
name: currentToolCall.name,
|
|
2251
|
+
args: {},
|
|
2252
|
+
...currentToolCall.extra_content ? { extra_content: currentToolCall.extra_content } : {}
|
|
2253
|
+
});
|
|
2254
|
+
}
|
|
2235
2255
|
}
|
|
2236
|
-
currentToolCall = null;
|
|
2237
2256
|
}
|
|
2238
2257
|
yield event;
|
|
2239
2258
|
break;
|
|
2240
2259
|
case "action:end": {
|
|
2260
|
+
currentToolCall = null;
|
|
2241
2261
|
const toolName = event.name;
|
|
2242
2262
|
const tool2 = toolName ? selectedToolMap.get(toolName) : void 0;
|
|
2243
2263
|
if (tool2?.location === "server" && tool2.handler) {
|
|
@@ -2447,7 +2467,7 @@ var Runtime = class {
|
|
|
2447
2467
|
const allTools = this.collectToolsForRequest(request);
|
|
2448
2468
|
const nativeToolSearch = this.resolveNativeToolSearchForRequest(request);
|
|
2449
2469
|
let toolSearchState = _toolSearchState;
|
|
2450
|
-
const systemPrompt =
|
|
2470
|
+
const systemPrompt = this.config.systemPrompt ?? request.systemPrompt ?? "";
|
|
2451
2471
|
let iteration = 0;
|
|
2452
2472
|
let conversationMessages = request.messages;
|
|
2453
2473
|
while (iteration < maxIterations) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { a as AnthropicProviderConfig, A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-CMvvDo-E.mjs';
|
|
2
|
+
import { a as AnthropicProviderConfig, A as AIProvider } from '../../types-CMMQ8s2O.mjs';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../../base-
|
|
4
|
+
import '../../base-DN1EfKnE.mjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Anthropic Provider - Modern Pattern
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { a as AnthropicProviderConfig, A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-CMvvDo-E.js';
|
|
2
|
+
import { a as AnthropicProviderConfig, A as AIProvider } from '../../types-DhktekQ3.js';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../../base-
|
|
4
|
+
import '../../base-DuUNxtVg.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Anthropic Provider - Modern Pattern
|
|
@@ -197,6 +197,11 @@ function anthropic(modelId, options = {}) {
|
|
|
197
197
|
name: event.content_block.name,
|
|
198
198
|
input: ""
|
|
199
199
|
};
|
|
200
|
+
yield {
|
|
201
|
+
type: "tool-call-start",
|
|
202
|
+
toolCallId: event.content_block.id,
|
|
203
|
+
toolName: event.content_block.name
|
|
204
|
+
};
|
|
200
205
|
}
|
|
201
206
|
break;
|
|
202
207
|
case "content_block_delta":
|
|
@@ -204,6 +209,11 @@ function anthropic(modelId, options = {}) {
|
|
|
204
209
|
yield { type: "text-delta", text: event.delta.text };
|
|
205
210
|
} else if (event.delta?.type === "input_json_delta" && currentToolUse) {
|
|
206
211
|
currentToolUse.input += event.delta.partial_json;
|
|
212
|
+
yield {
|
|
213
|
+
type: "tool-call-delta",
|
|
214
|
+
toolCallId: currentToolUse.id,
|
|
215
|
+
argsText: currentToolUse.input
|
|
216
|
+
};
|
|
207
217
|
}
|
|
208
218
|
break;
|
|
209
219
|
case "content_block_stop":
|
|
@@ -1007,6 +1017,13 @@ var AnthropicAdapter = class {
|
|
|
1007
1017
|
yield { type: "thinking:delta", content: event.delta.thinking };
|
|
1008
1018
|
} else if (event.delta.type === "input_json_delta" && currentToolUse) {
|
|
1009
1019
|
currentToolUse.input += event.delta.partial_json;
|
|
1020
|
+
if (currentToolUse.name !== "web_search") {
|
|
1021
|
+
yield {
|
|
1022
|
+
type: "action:args",
|
|
1023
|
+
id: currentToolUse.id,
|
|
1024
|
+
args: currentToolUse.input
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1010
1027
|
}
|
|
1011
1028
|
break;
|
|
1012
1029
|
case "content_block_stop":
|
|
@@ -195,6 +195,11 @@ function anthropic(modelId, options = {}) {
|
|
|
195
195
|
name: event.content_block.name,
|
|
196
196
|
input: ""
|
|
197
197
|
};
|
|
198
|
+
yield {
|
|
199
|
+
type: "tool-call-start",
|
|
200
|
+
toolCallId: event.content_block.id,
|
|
201
|
+
toolName: event.content_block.name
|
|
202
|
+
};
|
|
198
203
|
}
|
|
199
204
|
break;
|
|
200
205
|
case "content_block_delta":
|
|
@@ -202,6 +207,11 @@ function anthropic(modelId, options = {}) {
|
|
|
202
207
|
yield { type: "text-delta", text: event.delta.text };
|
|
203
208
|
} else if (event.delta?.type === "input_json_delta" && currentToolUse) {
|
|
204
209
|
currentToolUse.input += event.delta.partial_json;
|
|
210
|
+
yield {
|
|
211
|
+
type: "tool-call-delta",
|
|
212
|
+
toolCallId: currentToolUse.id,
|
|
213
|
+
argsText: currentToolUse.input
|
|
214
|
+
};
|
|
205
215
|
}
|
|
206
216
|
break;
|
|
207
217
|
case "content_block_stop":
|
|
@@ -1005,6 +1015,13 @@ var AnthropicAdapter = class {
|
|
|
1005
1015
|
yield { type: "thinking:delta", content: event.delta.thinking };
|
|
1006
1016
|
} else if (event.delta.type === "input_json_delta" && currentToolUse) {
|
|
1007
1017
|
currentToolUse.input += event.delta.partial_json;
|
|
1018
|
+
if (currentToolUse.name !== "web_search") {
|
|
1019
|
+
yield {
|
|
1020
|
+
type: "action:args",
|
|
1021
|
+
id: currentToolUse.id,
|
|
1022
|
+
args: currentToolUse.input
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1008
1025
|
}
|
|
1009
1026
|
break;
|
|
1010
1027
|
case "content_block_stop":
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { b as AzureProviderConfig, A as AIProvider } from '../../types-
|
|
2
|
-
import '../../base-
|
|
3
|
-
import '../../types-
|
|
1
|
+
import { b as AzureProviderConfig, A as AIProvider } from '../../types-CMMQ8s2O.mjs';
|
|
2
|
+
import '../../base-DN1EfKnE.mjs';
|
|
3
|
+
import '../../types-CMvvDo-E.mjs';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { b as AzureProviderConfig, A as AIProvider } from '../../types-
|
|
2
|
-
import '../../base-
|
|
3
|
-
import '../../types-
|
|
1
|
+
import { b as AzureProviderConfig, A as AIProvider } from '../../types-DhktekQ3.js';
|
|
2
|
+
import '../../base-DuUNxtVg.js';
|
|
3
|
+
import '../../types-CMvvDo-E.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { G as GoogleProviderConfig, A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-CMvvDo-E.mjs';
|
|
2
|
+
import { G as GoogleProviderConfig, A as AIProvider } from '../../types-CMMQ8s2O.mjs';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../../base-
|
|
4
|
+
import '../../base-DN1EfKnE.mjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Google Provider - OpenAI-Compatible
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { G as GoogleProviderConfig, A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-CMvvDo-E.js';
|
|
2
|
+
import { G as GoogleProviderConfig, A as AIProvider } from '../../types-DhktekQ3.js';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../../base-
|
|
4
|
+
import '../../base-DuUNxtVg.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Google Provider - OpenAI-Compatible
|
|
@@ -506,6 +506,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
506
506
|
if (baseUrl.includes("generativelanguage.googleapis.com")) return "google";
|
|
507
507
|
if (baseUrl.includes("x.ai")) return "xai";
|
|
508
508
|
if (baseUrl.includes("azure")) return "azure";
|
|
509
|
+
if (baseUrl.includes("openrouter.ai")) return "openrouter";
|
|
509
510
|
return "openai";
|
|
510
511
|
}
|
|
511
512
|
async getClient() {
|
|
@@ -605,6 +606,256 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
605
606
|
rawResponse: response
|
|
606
607
|
};
|
|
607
608
|
}
|
|
609
|
+
/**
|
|
610
|
+
* OpenAI reasoning models on OpenRouter (o1/o3/o4/gpt-5 family) hide their
|
|
611
|
+
* reasoning content on the chat-completions endpoint. To surface reasoning
|
|
612
|
+
* SUMMARIES (not raw CoT, which OpenAI never exposes) we have to use the
|
|
613
|
+
* Responses API, which streams `response.reasoning_summary_text.delta` events.
|
|
614
|
+
*
|
|
615
|
+
* Match by prefix on the OpenRouter model id. Excludes openai/gpt-4o,
|
|
616
|
+
* openai/gpt-4.1, openai/chatgpt-* — those continue on chat-completions.
|
|
617
|
+
*/
|
|
618
|
+
isOpenAIReasoningModelOnOpenRouter(activeModel) {
|
|
619
|
+
if (this.provider !== "openrouter") return false;
|
|
620
|
+
return activeModel.startsWith("openai/o1") || activeModel.startsWith("openai/o3") || activeModel.startsWith("openai/o4") || activeModel.startsWith("openai/gpt-5");
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Convert ActionDefinition[] (the chat-completions tool shape used by the
|
|
624
|
+
* adapter) to the Responses API tool shape.
|
|
625
|
+
*/
|
|
626
|
+
buildResponsesToolsFromActions(actions) {
|
|
627
|
+
if (!actions || actions.length === 0) return void 0;
|
|
628
|
+
const formatted = formatTools(actions);
|
|
629
|
+
return formatted.map((t) => ({
|
|
630
|
+
type: "function",
|
|
631
|
+
name: t.function.name,
|
|
632
|
+
description: t.function.description,
|
|
633
|
+
parameters: t.function.parameters
|
|
634
|
+
}));
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Streaming Responses API path for OpenAI reasoning models on OpenRouter.
|
|
638
|
+
*
|
|
639
|
+
* Maps Responses API SSE events back to the same StreamEvent shapes the
|
|
640
|
+
* chat-completions path emits, so downstream consumers (processChunk.ts,
|
|
641
|
+
* frontend tool handlers, plan approval, specialist delegations) see
|
|
642
|
+
* identical events regardless of which path produced them.
|
|
643
|
+
*
|
|
644
|
+
* response.reasoning_summary_text.delta → thinking:start (once) + thinking:delta
|
|
645
|
+
* response.output_text.delta → message:delta
|
|
646
|
+
* response.output_item.added (function_call) → action:start (queued buffer)
|
|
647
|
+
* response.function_call_arguments.delta → action:args (progressive)
|
|
648
|
+
* response.output_item.done (function_call) → final action:args + action:end
|
|
649
|
+
* response.completed → message:end + done(usage)
|
|
650
|
+
* response.error → error
|
|
651
|
+
*/
|
|
652
|
+
async *streamWithResponsesAPI(request, activeModel, messageId) {
|
|
653
|
+
const client = await this.getClient();
|
|
654
|
+
const maxTokensValue = request.config?.maxTokens ?? this.config.maxTokens;
|
|
655
|
+
const payload = {
|
|
656
|
+
model: activeModel,
|
|
657
|
+
input: this.buildResponsesInput(request),
|
|
658
|
+
stream: true,
|
|
659
|
+
reasoning: {
|
|
660
|
+
effort: request.config?.reasoningEffort ?? "medium",
|
|
661
|
+
summary: "auto"
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
if (request.systemPrompt) payload.instructions = request.systemPrompt;
|
|
665
|
+
if (typeof maxTokensValue === "number")
|
|
666
|
+
payload.max_output_tokens = maxTokensValue;
|
|
667
|
+
const tools = this.buildResponsesToolsFromActions(request.actions);
|
|
668
|
+
if (tools && tools.length > 0) payload.tools = tools;
|
|
669
|
+
logProviderPayload(
|
|
670
|
+
"openai",
|
|
671
|
+
"responses-api request payload",
|
|
672
|
+
payload,
|
|
673
|
+
request.debug
|
|
674
|
+
);
|
|
675
|
+
let stream;
|
|
676
|
+
try {
|
|
677
|
+
stream = await client.responses.create(payload);
|
|
678
|
+
} catch (error) {
|
|
679
|
+
yield {
|
|
680
|
+
type: "error",
|
|
681
|
+
message: error instanceof Error ? error.message : "Unknown error",
|
|
682
|
+
code: "OPENAI_RESPONSES_ERROR"
|
|
683
|
+
};
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
const toolBuffers = /* @__PURE__ */ new Map();
|
|
687
|
+
const itemIdToCallId = /* @__PURE__ */ new Map();
|
|
688
|
+
let usage;
|
|
689
|
+
let reasoningStarted = false;
|
|
690
|
+
let textStarted = false;
|
|
691
|
+
let finishEmitted = false;
|
|
692
|
+
const resolveCallId = (evt) => {
|
|
693
|
+
if (evt?.call_id) return evt.call_id;
|
|
694
|
+
if (evt?.item_id) return itemIdToCallId.get(evt.item_id) ?? evt.item_id;
|
|
695
|
+
if (evt?.item?.call_id) return evt.item.call_id;
|
|
696
|
+
if (evt?.item?.id) return evt.item.id;
|
|
697
|
+
return "";
|
|
698
|
+
};
|
|
699
|
+
try {
|
|
700
|
+
for await (const evt of stream) {
|
|
701
|
+
logProviderPayload(
|
|
702
|
+
"openai",
|
|
703
|
+
"responses-api stream chunk",
|
|
704
|
+
evt,
|
|
705
|
+
request.debug
|
|
706
|
+
);
|
|
707
|
+
if (request.signal?.aborted) break;
|
|
708
|
+
const t = evt?.type ?? "";
|
|
709
|
+
if (t === "response.reasoning_summary_text.delta") {
|
|
710
|
+
const delta = evt.delta ?? "";
|
|
711
|
+
if (!delta) continue;
|
|
712
|
+
if (!reasoningStarted) {
|
|
713
|
+
yield { type: "thinking:start" };
|
|
714
|
+
reasoningStarted = true;
|
|
715
|
+
}
|
|
716
|
+
yield { type: "thinking:delta", content: delta };
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
if (t === "response.reasoning_summary_text.done" || t === "response.reasoning.done") {
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
if (t === "response.output_text.delta") {
|
|
723
|
+
const text = evt.delta ?? "";
|
|
724
|
+
if (!text) continue;
|
|
725
|
+
if (reasoningStarted && !textStarted) {
|
|
726
|
+
yield { type: "thinking:end" };
|
|
727
|
+
textStarted = true;
|
|
728
|
+
}
|
|
729
|
+
yield { type: "message:delta", content: text };
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
if (t === "response.output_item.added") {
|
|
733
|
+
const item = evt.item;
|
|
734
|
+
if (item?.type === "function_call") {
|
|
735
|
+
const callId = item.call_id ?? item.id ?? "";
|
|
736
|
+
const itemId = item.id ?? callId;
|
|
737
|
+
if (callId) {
|
|
738
|
+
if (itemId && itemId !== callId) {
|
|
739
|
+
itemIdToCallId.set(itemId, callId);
|
|
740
|
+
}
|
|
741
|
+
if (!toolBuffers.has(callId)) {
|
|
742
|
+
toolBuffers.set(callId, {
|
|
743
|
+
id: callId,
|
|
744
|
+
name: item.name ?? "",
|
|
745
|
+
arguments: item.arguments ?? "",
|
|
746
|
+
emittedStart: false
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
const buf = toolBuffers.get(callId);
|
|
750
|
+
if (buf.name && !buf.emittedStart) {
|
|
751
|
+
yield { type: "action:start", id: buf.id, name: buf.name };
|
|
752
|
+
buf.emittedStart = true;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
continue;
|
|
757
|
+
}
|
|
758
|
+
if (t === "response.function_call_arguments.delta") {
|
|
759
|
+
const callId = resolveCallId(evt);
|
|
760
|
+
const delta = evt.delta ?? "";
|
|
761
|
+
if (!callId || !delta) continue;
|
|
762
|
+
let buf = toolBuffers.get(callId);
|
|
763
|
+
if (!buf) {
|
|
764
|
+
buf = { id: callId, name: "", arguments: "", emittedStart: false };
|
|
765
|
+
toolBuffers.set(callId, buf);
|
|
766
|
+
}
|
|
767
|
+
buf.arguments += delta;
|
|
768
|
+
if (buf.emittedStart) {
|
|
769
|
+
yield {
|
|
770
|
+
type: "action:args",
|
|
771
|
+
id: buf.id,
|
|
772
|
+
args: buf.arguments
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
continue;
|
|
776
|
+
}
|
|
777
|
+
if (t === "response.output_item.done") {
|
|
778
|
+
const item = evt.item;
|
|
779
|
+
if (item?.type === "function_call") {
|
|
780
|
+
const callId = item.call_id ?? item.id ?? "";
|
|
781
|
+
const buf = toolBuffers.get(callId);
|
|
782
|
+
const name = buf?.name || item.name || "";
|
|
783
|
+
const argsStr = buf?.arguments || item.arguments || "{}";
|
|
784
|
+
if (callId && name) {
|
|
785
|
+
if (!buf?.emittedStart) {
|
|
786
|
+
yield { type: "action:start", id: callId, name };
|
|
787
|
+
}
|
|
788
|
+
yield {
|
|
789
|
+
type: "action:args",
|
|
790
|
+
id: callId,
|
|
791
|
+
args: argsStr
|
|
792
|
+
};
|
|
793
|
+
yield {
|
|
794
|
+
type: "action:end",
|
|
795
|
+
id: callId,
|
|
796
|
+
name
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
toolBuffers.delete(callId);
|
|
800
|
+
}
|
|
801
|
+
continue;
|
|
802
|
+
}
|
|
803
|
+
if (t === "response.completed") {
|
|
804
|
+
const u = evt.response?.usage;
|
|
805
|
+
if (u) {
|
|
806
|
+
usage = {
|
|
807
|
+
prompt_tokens: u.input_tokens ?? 0,
|
|
808
|
+
completion_tokens: u.output_tokens ?? 0,
|
|
809
|
+
total_tokens: u.total_tokens ?? (u.input_tokens ?? 0) + (u.output_tokens ?? 0)
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
for (const buf of toolBuffers.values()) {
|
|
813
|
+
if (!buf.id || !buf.name) continue;
|
|
814
|
+
if (!buf.emittedStart) {
|
|
815
|
+
yield { type: "action:start", id: buf.id, name: buf.name };
|
|
816
|
+
}
|
|
817
|
+
yield {
|
|
818
|
+
type: "action:args",
|
|
819
|
+
id: buf.id,
|
|
820
|
+
args: buf.arguments || "{}"
|
|
821
|
+
};
|
|
822
|
+
yield { type: "action:end", id: buf.id, name: buf.name };
|
|
823
|
+
}
|
|
824
|
+
toolBuffers.clear();
|
|
825
|
+
if (reasoningStarted && !textStarted) {
|
|
826
|
+
yield { type: "thinking:end" };
|
|
827
|
+
}
|
|
828
|
+
yield { type: "message:end" };
|
|
829
|
+
yield { type: "done", usage };
|
|
830
|
+
finishEmitted = true;
|
|
831
|
+
continue;
|
|
832
|
+
}
|
|
833
|
+
if (t === "response.error" || t === "error") {
|
|
834
|
+
const msg = evt.error?.message || evt.message || "Responses API error";
|
|
835
|
+
yield {
|
|
836
|
+
type: "error",
|
|
837
|
+
message: msg,
|
|
838
|
+
code: "OPENAI_RESPONSES_ERROR"
|
|
839
|
+
};
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
} catch (error) {
|
|
844
|
+
yield {
|
|
845
|
+
type: "error",
|
|
846
|
+
message: error instanceof Error ? error.message : "Unknown error",
|
|
847
|
+
code: "OPENAI_RESPONSES_ERROR"
|
|
848
|
+
};
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
if (!finishEmitted) {
|
|
852
|
+
if (reasoningStarted && !textStarted) {
|
|
853
|
+
yield { type: "thinking:end" };
|
|
854
|
+
}
|
|
855
|
+
yield { type: "message:end" };
|
|
856
|
+
yield { type: "done", usage };
|
|
857
|
+
}
|
|
858
|
+
}
|
|
608
859
|
async completeWithResponses(request) {
|
|
609
860
|
const client = await this.getClient();
|
|
610
861
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
@@ -738,16 +989,37 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
738
989
|
name: openaiToolOptions.toolChoice.name
|
|
739
990
|
}
|
|
740
991
|
} : openaiToolOptions?.toolChoice;
|
|
992
|
+
const isOpenRouter = this.provider === "openrouter";
|
|
993
|
+
const activeModel = request.config?.model || this.model;
|
|
994
|
+
const modelSlug = activeModel.replace("openai/", "");
|
|
995
|
+
const isOSeries = /^o[1-9]/.test(modelSlug);
|
|
996
|
+
const isOpenAIOnOpenRouter = isOpenRouter && activeModel.startsWith("openai/");
|
|
997
|
+
if (!this.config.disableThinking && this.isOpenAIReasoningModelOnOpenRouter(activeModel)) {
|
|
998
|
+
yield* this.streamWithResponsesAPI(request, activeModel, messageId);
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
const maxTokensValue = request.config?.maxTokens ?? this.config.maxTokens;
|
|
741
1002
|
const payload = {
|
|
742
|
-
model:
|
|
1003
|
+
model: activeModel,
|
|
743
1004
|
messages,
|
|
744
1005
|
tools: tools.length > 0 ? tools : void 0,
|
|
745
1006
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
746
1007
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
747
|
-
temperature: request.config?.temperature ?? this.config.temperature,
|
|
748
|
-
max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
|
|
749
1008
|
stream: true,
|
|
750
|
-
stream_options: { include_usage: true }
|
|
1009
|
+
stream_options: { include_usage: true },
|
|
1010
|
+
// o-series: use max_completion_tokens + reasoning_effort, no temperature
|
|
1011
|
+
// regular models: use max_tokens + temperature
|
|
1012
|
+
...isOSeries ? {
|
|
1013
|
+
max_completion_tokens: maxTokensValue,
|
|
1014
|
+
reasoning_effort: request.config?.reasoningEffort ?? "medium"
|
|
1015
|
+
} : {
|
|
1016
|
+
temperature: request.config?.temperature ?? this.config.temperature,
|
|
1017
|
+
max_tokens: maxTokensValue
|
|
1018
|
+
},
|
|
1019
|
+
// Non-OpenAI OpenRouter models support OR's reasoning/include_reasoning params.
|
|
1020
|
+
// When disableThinking=true we must explicitly send include_reasoning:false because
|
|
1021
|
+
// models like Qwen3 and DeepSeek-R1 reason by default even without the reasoning param.
|
|
1022
|
+
...isOpenRouter && !isOpenAIOnOpenRouter ? this.config.disableThinking ? { include_reasoning: false } : { reasoning: { max_tokens: 8e3 }, include_reasoning: true } : {}
|
|
751
1023
|
};
|
|
752
1024
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
753
1025
|
const stream = await client.chat.completions.create(payload);
|
|
@@ -755,6 +1027,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
755
1027
|
const collectedCitations = [];
|
|
756
1028
|
let citationIndex = 0;
|
|
757
1029
|
let usage;
|
|
1030
|
+
let adapterReasoningStarted = false;
|
|
758
1031
|
for await (const chunk of stream) {
|
|
759
1032
|
logProviderPayload("openai", "stream chunk", chunk, request.debug);
|
|
760
1033
|
if (request.signal?.aborted) {
|
|
@@ -765,6 +1038,22 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
765
1038
|
if (delta?.content) {
|
|
766
1039
|
yield { type: "message:delta", content: delta.content };
|
|
767
1040
|
}
|
|
1041
|
+
if (isOpenRouter) {
|
|
1042
|
+
const rc = delta?.reasoning_content ?? delta?.reasoning ?? null;
|
|
1043
|
+
if (rc) {
|
|
1044
|
+
const rcText = typeof rc === "string" ? rc : Array.isArray(rc) && rc[0]?.text ? rc[0].text : "";
|
|
1045
|
+
if (rcText) {
|
|
1046
|
+
if (!adapterReasoningStarted) {
|
|
1047
|
+
yield { type: "thinking:start" };
|
|
1048
|
+
adapterReasoningStarted = true;
|
|
1049
|
+
}
|
|
1050
|
+
yield { type: "thinking:delta", content: rcText };
|
|
1051
|
+
}
|
|
1052
|
+
} else if (adapterReasoningStarted && (delta?.content || choice?.finish_reason)) {
|
|
1053
|
+
yield { type: "thinking:end" };
|
|
1054
|
+
adapterReasoningStarted = false;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
768
1057
|
const annotations = delta?.annotations;
|
|
769
1058
|
if (annotations && annotations.length > 0) {
|
|
770
1059
|
for (const annotation of annotations) {
|
|
@@ -812,6 +1101,11 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
812
1101
|
};
|
|
813
1102
|
} else if (currentToolCall && toolCall.function?.arguments) {
|
|
814
1103
|
currentToolCall.arguments += toolCall.function.arguments;
|
|
1104
|
+
yield {
|
|
1105
|
+
type: "action:args",
|
|
1106
|
+
id: currentToolCall.id,
|
|
1107
|
+
args: currentToolCall.arguments
|
|
1108
|
+
};
|
|
815
1109
|
}
|
|
816
1110
|
}
|
|
817
1111
|
}
|
|
@@ -887,15 +1181,24 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
887
1181
|
name: openaiToolOptions.toolChoice.name
|
|
888
1182
|
}
|
|
889
1183
|
} : openaiToolOptions?.toolChoice;
|
|
1184
|
+
const activeModel2 = request.config?.model || this.model;
|
|
1185
|
+
const modelSlug2 = activeModel2.replace("openai/", "");
|
|
1186
|
+
const isOSeries2 = /^o[1-9]/.test(modelSlug2);
|
|
1187
|
+
const maxTokensValue2 = request.config?.maxTokens ?? this.config.maxTokens;
|
|
890
1188
|
const payload = {
|
|
891
|
-
model:
|
|
1189
|
+
model: activeModel2,
|
|
892
1190
|
messages,
|
|
893
1191
|
tools: tools.length > 0 ? tools : void 0,
|
|
894
1192
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
895
1193
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
1194
|
+
stream: false,
|
|
1195
|
+
...isOSeries2 ? {
|
|
1196
|
+
max_completion_tokens: maxTokensValue2,
|
|
1197
|
+
reasoning_effort: request.config?.reasoningEffort ?? "medium"
|
|
1198
|
+
} : {
|
|
1199
|
+
temperature: request.config?.temperature ?? this.config.temperature,
|
|
1200
|
+
max_tokens: maxTokensValue2
|
|
1201
|
+
}
|
|
899
1202
|
};
|
|
900
1203
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
901
1204
|
const response = await client.chat.completions.create(payload);
|