@yourgpt/llm-sdk 2.1.9 → 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.
Files changed (51) hide show
  1. package/dist/adapters/index.d.mts +38 -4
  2. package/dist/adapters/index.d.ts +38 -4
  3. package/dist/adapters/index.js +318 -8
  4. package/dist/adapters/index.mjs +318 -8
  5. package/dist/{base-iGi9Va6Z.d.ts → base-DN1EfKnE.d.mts} +2 -1
  6. package/dist/{base-D-U61JaB.d.mts → base-DuUNxtVg.d.ts} +2 -1
  7. package/dist/fallback/index.d.mts +4 -4
  8. package/dist/fallback/index.d.ts +4 -4
  9. package/dist/index.d.mts +7 -7
  10. package/dist/index.d.ts +7 -7
  11. package/dist/index.js +43 -23
  12. package/dist/index.mjs +43 -23
  13. package/dist/providers/anthropic/index.d.mts +3 -3
  14. package/dist/providers/anthropic/index.d.ts +3 -3
  15. package/dist/providers/anthropic/index.js +17 -0
  16. package/dist/providers/anthropic/index.mjs +17 -0
  17. package/dist/providers/azure/index.d.mts +3 -3
  18. package/dist/providers/azure/index.d.ts +3 -3
  19. package/dist/providers/fireworks/index.d.mts +1 -1
  20. package/dist/providers/fireworks/index.d.ts +1 -1
  21. package/dist/providers/google/index.d.mts +3 -3
  22. package/dist/providers/google/index.d.ts +3 -3
  23. package/dist/providers/google/index.js +311 -8
  24. package/dist/providers/google/index.mjs +311 -8
  25. package/dist/providers/ollama/index.d.mts +4 -4
  26. package/dist/providers/ollama/index.d.ts +4 -4
  27. package/dist/providers/openai/index.d.mts +3 -3
  28. package/dist/providers/openai/index.d.ts +3 -3
  29. package/dist/providers/openai/index.js +321 -8
  30. package/dist/providers/openai/index.mjs +321 -8
  31. package/dist/providers/openrouter/index.d.mts +7 -3
  32. package/dist/providers/openrouter/index.d.ts +7 -3
  33. package/dist/providers/openrouter/index.js +601 -11
  34. package/dist/providers/openrouter/index.mjs +601 -11
  35. package/dist/providers/togetherai/index.d.mts +3 -3
  36. package/dist/providers/togetherai/index.d.ts +3 -3
  37. package/dist/providers/togetherai/index.js +311 -8
  38. package/dist/providers/togetherai/index.mjs +311 -8
  39. package/dist/providers/xai/index.d.mts +3 -3
  40. package/dist/providers/xai/index.d.ts +3 -3
  41. package/dist/providers/xai/index.js +311 -8
  42. package/dist/providers/xai/index.mjs +311 -8
  43. package/dist/{types-D4YfrQJR.d.mts → types-BNCmlJMs.d.mts} +1 -1
  44. package/dist/{types-DRqxMIjF.d.mts → types-CMMQ8s2O.d.mts} +1 -1
  45. package/dist/{types-CR8mi9I0.d.ts → types-CMvvDo-E.d.mts} +12 -1
  46. package/dist/{types-CR8mi9I0.d.mts → types-CMvvDo-E.d.ts} +12 -1
  47. package/dist/{types-BctsnC3g.d.ts → types-DhktekQ3.d.ts} +1 -1
  48. package/dist/{types-38yolWJn.d.ts → types-Pj-vpmoT.d.ts} +1 -1
  49. package/dist/yourgpt/index.d.mts +1 -1
  50. package/dist/yourgpt/index.d.ts +1 -1
  51. package/package.json +1 -1
@@ -423,6 +423,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
423
423
  if (baseUrl.includes("generativelanguage.googleapis.com")) return "google";
424
424
  if (baseUrl.includes("x.ai")) return "xai";
425
425
  if (baseUrl.includes("azure")) return "azure";
426
+ if (baseUrl.includes("openrouter.ai")) return "openrouter";
426
427
  return "openai";
427
428
  }
428
429
  async getClient() {
@@ -522,6 +523,256 @@ var OpenAIAdapter = class _OpenAIAdapter {
522
523
  rawResponse: response
523
524
  };
524
525
  }
526
+ /**
527
+ * OpenAI reasoning models on OpenRouter (o1/o3/o4/gpt-5 family) hide their
528
+ * reasoning content on the chat-completions endpoint. To surface reasoning
529
+ * SUMMARIES (not raw CoT, which OpenAI never exposes) we have to use the
530
+ * Responses API, which streams `response.reasoning_summary_text.delta` events.
531
+ *
532
+ * Match by prefix on the OpenRouter model id. Excludes openai/gpt-4o,
533
+ * openai/gpt-4.1, openai/chatgpt-* — those continue on chat-completions.
534
+ */
535
+ isOpenAIReasoningModelOnOpenRouter(activeModel) {
536
+ if (this.provider !== "openrouter") return false;
537
+ return activeModel.startsWith("openai/o1") || activeModel.startsWith("openai/o3") || activeModel.startsWith("openai/o4") || activeModel.startsWith("openai/gpt-5");
538
+ }
539
+ /**
540
+ * Convert ActionDefinition[] (the chat-completions tool shape used by the
541
+ * adapter) to the Responses API tool shape.
542
+ */
543
+ buildResponsesToolsFromActions(actions) {
544
+ if (!actions || actions.length === 0) return void 0;
545
+ const formatted = formatTools(actions);
546
+ return formatted.map((t) => ({
547
+ type: "function",
548
+ name: t.function.name,
549
+ description: t.function.description,
550
+ parameters: t.function.parameters
551
+ }));
552
+ }
553
+ /**
554
+ * Streaming Responses API path for OpenAI reasoning models on OpenRouter.
555
+ *
556
+ * Maps Responses API SSE events back to the same StreamEvent shapes the
557
+ * chat-completions path emits, so downstream consumers (processChunk.ts,
558
+ * frontend tool handlers, plan approval, specialist delegations) see
559
+ * identical events regardless of which path produced them.
560
+ *
561
+ * response.reasoning_summary_text.delta → thinking:start (once) + thinking:delta
562
+ * response.output_text.delta → message:delta
563
+ * response.output_item.added (function_call) → action:start (queued buffer)
564
+ * response.function_call_arguments.delta → action:args (progressive)
565
+ * response.output_item.done (function_call) → final action:args + action:end
566
+ * response.completed → message:end + done(usage)
567
+ * response.error → error
568
+ */
569
+ async *streamWithResponsesAPI(request, activeModel, messageId) {
570
+ const client = await this.getClient();
571
+ const maxTokensValue = request.config?.maxTokens ?? this.config.maxTokens;
572
+ const payload = {
573
+ model: activeModel,
574
+ input: this.buildResponsesInput(request),
575
+ stream: true,
576
+ reasoning: {
577
+ effort: request.config?.reasoningEffort ?? "medium",
578
+ summary: "auto"
579
+ }
580
+ };
581
+ if (request.systemPrompt) payload.instructions = request.systemPrompt;
582
+ if (typeof maxTokensValue === "number")
583
+ payload.max_output_tokens = maxTokensValue;
584
+ const tools = this.buildResponsesToolsFromActions(request.actions);
585
+ if (tools && tools.length > 0) payload.tools = tools;
586
+ logProviderPayload(
587
+ "openai",
588
+ "responses-api request payload",
589
+ payload,
590
+ request.debug
591
+ );
592
+ let stream;
593
+ try {
594
+ stream = await client.responses.create(payload);
595
+ } catch (error) {
596
+ yield {
597
+ type: "error",
598
+ message: error instanceof Error ? error.message : "Unknown error",
599
+ code: "OPENAI_RESPONSES_ERROR"
600
+ };
601
+ return;
602
+ }
603
+ const toolBuffers = /* @__PURE__ */ new Map();
604
+ const itemIdToCallId = /* @__PURE__ */ new Map();
605
+ let usage;
606
+ let reasoningStarted = false;
607
+ let textStarted = false;
608
+ let finishEmitted = false;
609
+ const resolveCallId = (evt) => {
610
+ if (evt?.call_id) return evt.call_id;
611
+ if (evt?.item_id) return itemIdToCallId.get(evt.item_id) ?? evt.item_id;
612
+ if (evt?.item?.call_id) return evt.item.call_id;
613
+ if (evt?.item?.id) return evt.item.id;
614
+ return "";
615
+ };
616
+ try {
617
+ for await (const evt of stream) {
618
+ logProviderPayload(
619
+ "openai",
620
+ "responses-api stream chunk",
621
+ evt,
622
+ request.debug
623
+ );
624
+ if (request.signal?.aborted) break;
625
+ const t = evt?.type ?? "";
626
+ if (t === "response.reasoning_summary_text.delta") {
627
+ const delta = evt.delta ?? "";
628
+ if (!delta) continue;
629
+ if (!reasoningStarted) {
630
+ yield { type: "thinking:start" };
631
+ reasoningStarted = true;
632
+ }
633
+ yield { type: "thinking:delta", content: delta };
634
+ continue;
635
+ }
636
+ if (t === "response.reasoning_summary_text.done" || t === "response.reasoning.done") {
637
+ continue;
638
+ }
639
+ if (t === "response.output_text.delta") {
640
+ const text = evt.delta ?? "";
641
+ if (!text) continue;
642
+ if (reasoningStarted && !textStarted) {
643
+ yield { type: "thinking:end" };
644
+ textStarted = true;
645
+ }
646
+ yield { type: "message:delta", content: text };
647
+ continue;
648
+ }
649
+ if (t === "response.output_item.added") {
650
+ const item = evt.item;
651
+ if (item?.type === "function_call") {
652
+ const callId = item.call_id ?? item.id ?? "";
653
+ const itemId = item.id ?? callId;
654
+ if (callId) {
655
+ if (itemId && itemId !== callId) {
656
+ itemIdToCallId.set(itemId, callId);
657
+ }
658
+ if (!toolBuffers.has(callId)) {
659
+ toolBuffers.set(callId, {
660
+ id: callId,
661
+ name: item.name ?? "",
662
+ arguments: item.arguments ?? "",
663
+ emittedStart: false
664
+ });
665
+ }
666
+ const buf = toolBuffers.get(callId);
667
+ if (buf.name && !buf.emittedStart) {
668
+ yield { type: "action:start", id: buf.id, name: buf.name };
669
+ buf.emittedStart = true;
670
+ }
671
+ }
672
+ }
673
+ continue;
674
+ }
675
+ if (t === "response.function_call_arguments.delta") {
676
+ const callId = resolveCallId(evt);
677
+ const delta = evt.delta ?? "";
678
+ if (!callId || !delta) continue;
679
+ let buf = toolBuffers.get(callId);
680
+ if (!buf) {
681
+ buf = { id: callId, name: "", arguments: "", emittedStart: false };
682
+ toolBuffers.set(callId, buf);
683
+ }
684
+ buf.arguments += delta;
685
+ if (buf.emittedStart) {
686
+ yield {
687
+ type: "action:args",
688
+ id: buf.id,
689
+ args: buf.arguments
690
+ };
691
+ }
692
+ continue;
693
+ }
694
+ if (t === "response.output_item.done") {
695
+ const item = evt.item;
696
+ if (item?.type === "function_call") {
697
+ const callId = item.call_id ?? item.id ?? "";
698
+ const buf = toolBuffers.get(callId);
699
+ const name = buf?.name || item.name || "";
700
+ const argsStr = buf?.arguments || item.arguments || "{}";
701
+ if (callId && name) {
702
+ if (!buf?.emittedStart) {
703
+ yield { type: "action:start", id: callId, name };
704
+ }
705
+ yield {
706
+ type: "action:args",
707
+ id: callId,
708
+ args: argsStr
709
+ };
710
+ yield {
711
+ type: "action:end",
712
+ id: callId,
713
+ name
714
+ };
715
+ }
716
+ toolBuffers.delete(callId);
717
+ }
718
+ continue;
719
+ }
720
+ if (t === "response.completed") {
721
+ const u = evt.response?.usage;
722
+ if (u) {
723
+ usage = {
724
+ prompt_tokens: u.input_tokens ?? 0,
725
+ completion_tokens: u.output_tokens ?? 0,
726
+ total_tokens: u.total_tokens ?? (u.input_tokens ?? 0) + (u.output_tokens ?? 0)
727
+ };
728
+ }
729
+ for (const buf of toolBuffers.values()) {
730
+ if (!buf.id || !buf.name) continue;
731
+ if (!buf.emittedStart) {
732
+ yield { type: "action:start", id: buf.id, name: buf.name };
733
+ }
734
+ yield {
735
+ type: "action:args",
736
+ id: buf.id,
737
+ args: buf.arguments || "{}"
738
+ };
739
+ yield { type: "action:end", id: buf.id, name: buf.name };
740
+ }
741
+ toolBuffers.clear();
742
+ if (reasoningStarted && !textStarted) {
743
+ yield { type: "thinking:end" };
744
+ }
745
+ yield { type: "message:end" };
746
+ yield { type: "done", usage };
747
+ finishEmitted = true;
748
+ continue;
749
+ }
750
+ if (t === "response.error" || t === "error") {
751
+ const msg = evt.error?.message || evt.message || "Responses API error";
752
+ yield {
753
+ type: "error",
754
+ message: msg,
755
+ code: "OPENAI_RESPONSES_ERROR"
756
+ };
757
+ return;
758
+ }
759
+ }
760
+ } catch (error) {
761
+ yield {
762
+ type: "error",
763
+ message: error instanceof Error ? error.message : "Unknown error",
764
+ code: "OPENAI_RESPONSES_ERROR"
765
+ };
766
+ return;
767
+ }
768
+ if (!finishEmitted) {
769
+ if (reasoningStarted && !textStarted) {
770
+ yield { type: "thinking:end" };
771
+ }
772
+ yield { type: "message:end" };
773
+ yield { type: "done", usage };
774
+ }
775
+ }
525
776
  async completeWithResponses(request) {
526
777
  const client = await this.getClient();
527
778
  const openaiToolOptions = request.providerToolOptions?.openai;
@@ -655,16 +906,37 @@ var OpenAIAdapter = class _OpenAIAdapter {
655
906
  name: openaiToolOptions.toolChoice.name
656
907
  }
657
908
  } : openaiToolOptions?.toolChoice;
909
+ const isOpenRouter = this.provider === "openrouter";
910
+ const activeModel = request.config?.model || this.model;
911
+ const modelSlug = activeModel.replace("openai/", "");
912
+ const isOSeries = /^o[1-9]/.test(modelSlug);
913
+ const isOpenAIOnOpenRouter = isOpenRouter && activeModel.startsWith("openai/");
914
+ if (!this.config.disableThinking && this.isOpenAIReasoningModelOnOpenRouter(activeModel)) {
915
+ yield* this.streamWithResponsesAPI(request, activeModel, messageId);
916
+ return;
917
+ }
918
+ const maxTokensValue = request.config?.maxTokens ?? this.config.maxTokens;
658
919
  const payload = {
659
- model: request.config?.model || this.model,
920
+ model: activeModel,
660
921
  messages,
661
922
  tools: tools.length > 0 ? tools : void 0,
662
923
  tool_choice: tools.length > 0 ? toolChoice : void 0,
663
924
  parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
664
- temperature: request.config?.temperature ?? this.config.temperature,
665
- max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
666
925
  stream: true,
667
- stream_options: { include_usage: true }
926
+ stream_options: { include_usage: true },
927
+ // o-series: use max_completion_tokens + reasoning_effort, no temperature
928
+ // regular models: use max_tokens + temperature
929
+ ...isOSeries ? {
930
+ max_completion_tokens: maxTokensValue,
931
+ reasoning_effort: request.config?.reasoningEffort ?? "medium"
932
+ } : {
933
+ temperature: request.config?.temperature ?? this.config.temperature,
934
+ max_tokens: maxTokensValue
935
+ },
936
+ // Non-OpenAI OpenRouter models support OR's reasoning/include_reasoning params.
937
+ // When disableThinking=true we must explicitly send include_reasoning:false because
938
+ // models like Qwen3 and DeepSeek-R1 reason by default even without the reasoning param.
939
+ ...isOpenRouter && !isOpenAIOnOpenRouter ? this.config.disableThinking ? { include_reasoning: false } : { reasoning: { max_tokens: 8e3 }, include_reasoning: true } : {}
668
940
  };
669
941
  logProviderPayload("openai", "request payload", payload, request.debug);
670
942
  const stream = await client.chat.completions.create(payload);
@@ -672,6 +944,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
672
944
  const collectedCitations = [];
673
945
  let citationIndex = 0;
674
946
  let usage;
947
+ let adapterReasoningStarted = false;
675
948
  for await (const chunk of stream) {
676
949
  logProviderPayload("openai", "stream chunk", chunk, request.debug);
677
950
  if (request.signal?.aborted) {
@@ -682,6 +955,22 @@ var OpenAIAdapter = class _OpenAIAdapter {
682
955
  if (delta?.content) {
683
956
  yield { type: "message:delta", content: delta.content };
684
957
  }
958
+ if (isOpenRouter) {
959
+ const rc = delta?.reasoning_content ?? delta?.reasoning ?? null;
960
+ if (rc) {
961
+ const rcText = typeof rc === "string" ? rc : Array.isArray(rc) && rc[0]?.text ? rc[0].text : "";
962
+ if (rcText) {
963
+ if (!adapterReasoningStarted) {
964
+ yield { type: "thinking:start" };
965
+ adapterReasoningStarted = true;
966
+ }
967
+ yield { type: "thinking:delta", content: rcText };
968
+ }
969
+ } else if (adapterReasoningStarted && (delta?.content || choice?.finish_reason)) {
970
+ yield { type: "thinking:end" };
971
+ adapterReasoningStarted = false;
972
+ }
973
+ }
685
974
  const annotations = delta?.annotations;
686
975
  if (annotations && annotations.length > 0) {
687
976
  for (const annotation of annotations) {
@@ -729,6 +1018,11 @@ var OpenAIAdapter = class _OpenAIAdapter {
729
1018
  };
730
1019
  } else if (currentToolCall && toolCall.function?.arguments) {
731
1020
  currentToolCall.arguments += toolCall.function.arguments;
1021
+ yield {
1022
+ type: "action:args",
1023
+ id: currentToolCall.id,
1024
+ args: currentToolCall.arguments
1025
+ };
732
1026
  }
733
1027
  }
734
1028
  }
@@ -804,15 +1098,24 @@ var OpenAIAdapter = class _OpenAIAdapter {
804
1098
  name: openaiToolOptions.toolChoice.name
805
1099
  }
806
1100
  } : openaiToolOptions?.toolChoice;
1101
+ const activeModel2 = request.config?.model || this.model;
1102
+ const modelSlug2 = activeModel2.replace("openai/", "");
1103
+ const isOSeries2 = /^o[1-9]/.test(modelSlug2);
1104
+ const maxTokensValue2 = request.config?.maxTokens ?? this.config.maxTokens;
807
1105
  const payload = {
808
- model: request.config?.model || this.model,
1106
+ model: activeModel2,
809
1107
  messages,
810
1108
  tools: tools.length > 0 ? tools : void 0,
811
1109
  tool_choice: tools.length > 0 ? toolChoice : void 0,
812
1110
  parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
813
- temperature: request.config?.temperature ?? this.config.temperature,
814
- max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
815
- stream: false
1111
+ stream: false,
1112
+ ...isOSeries2 ? {
1113
+ max_completion_tokens: maxTokensValue2,
1114
+ reasoning_effort: request.config?.reasoningEffort ?? "medium"
1115
+ } : {
1116
+ temperature: request.config?.temperature ?? this.config.temperature,
1117
+ max_tokens: maxTokensValue2
1118
+ }
816
1119
  };
817
1120
  logProviderPayload("openai", "request payload", payload, request.debug);
818
1121
  const response = await client.chat.completions.create(payload);
@@ -1,7 +1,7 @@
1
- import { L as LanguageModel } from '../../types-CR8mi9I0.mjs';
2
- import { X as XAIProviderConfig, A as AIProvider } from '../../types-DRqxMIjF.mjs';
1
+ import { L as LanguageModel } from '../../types-CMvvDo-E.mjs';
2
+ import { X as XAIProviderConfig, A as AIProvider } from '../../types-CMMQ8s2O.mjs';
3
3
  import 'zod';
4
- import '../../base-D-U61JaB.mjs';
4
+ import '../../base-DN1EfKnE.mjs';
5
5
 
6
6
  /**
7
7
  * xAI Provider - Modern Pattern
@@ -1,7 +1,7 @@
1
- import { L as LanguageModel } from '../../types-CR8mi9I0.js';
2
- import { X as XAIProviderConfig, A as AIProvider } from '../../types-BctsnC3g.js';
1
+ import { L as LanguageModel } from '../../types-CMvvDo-E.js';
2
+ import { X as XAIProviderConfig, A as AIProvider } from '../../types-DhktekQ3.js';
3
3
  import 'zod';
4
- import '../../base-iGi9Va6Z.js';
4
+ import '../../base-DuUNxtVg.js';
5
5
 
6
6
  /**
7
7
  * xAI Provider - Modern Pattern