@yourgpt/llm-sdk 2.5.1-beta.2 → 2.5.1-beta.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.
@@ -1,4 +1,70 @@
1
1
  // src/adapters/base.ts
2
+ function stringifyForDebug(value) {
3
+ return JSON.stringify(
4
+ value,
5
+ (_key, currentValue) => {
6
+ if (typeof currentValue === "bigint") {
7
+ return currentValue.toString();
8
+ }
9
+ if (currentValue instanceof Error) {
10
+ return {
11
+ name: currentValue.name,
12
+ message: currentValue.message,
13
+ stack: currentValue.stack
14
+ };
15
+ }
16
+ return currentValue;
17
+ },
18
+ 2
19
+ );
20
+ }
21
+ function logProviderPayload(provider, label, payload, enabled) {
22
+ if (!enabled) {
23
+ return;
24
+ }
25
+ if (label.toLowerCase().includes("stream ")) {
26
+ return;
27
+ }
28
+ try {
29
+ console.log(
30
+ `[llm-sdk:${provider}] ${label}
31
+ ${stringifyForDebug(payload)}`
32
+ );
33
+ } catch (error) {
34
+ console.log(
35
+ `[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
36
+ error
37
+ );
38
+ }
39
+ }
40
+ function parameterToJsonSchema(param) {
41
+ const schema = {
42
+ type: param.type
43
+ };
44
+ if (param.description) {
45
+ schema.description = param.description;
46
+ }
47
+ if (param.enum) {
48
+ schema.enum = param.enum;
49
+ }
50
+ if (param.type === "array" && param.items) {
51
+ schema.items = parameterToJsonSchema(
52
+ param.items
53
+ );
54
+ }
55
+ if (param.type === "object" && param.properties) {
56
+ schema.properties = Object.fromEntries(
57
+ Object.entries(param.properties).map(([key, prop]) => [
58
+ key,
59
+ parameterToJsonSchema(
60
+ prop
61
+ )
62
+ ])
63
+ );
64
+ schema.additionalProperties = false;
65
+ }
66
+ return schema;
67
+ }
2
68
  function normalizeObjectJsonSchema(schema) {
3
69
  if (!schema || typeof schema !== "object") {
4
70
  return {
@@ -33,6 +99,16 @@ function normalizeObjectJsonSchema(schema) {
33
99
  }
34
100
  return normalized;
35
101
  }
102
+ function isOpenAIReasoningModel(modelId) {
103
+ if (!modelId) return false;
104
+ return /^(o1|o3|o4|gpt-5)/i.test(modelId);
105
+ }
106
+ function buildOpenAITokenParams(modelId, maxTokens, temperature) {
107
+ if (isOpenAIReasoningModel(modelId)) {
108
+ return { max_completion_tokens: maxTokens };
109
+ }
110
+ return { max_tokens: maxTokens, temperature };
111
+ }
36
112
  function toOpenAIResponseFormat(rf) {
37
113
  if (!rf) return void 0;
38
114
  if (rf.type === "json_object") return { type: "json_object" };
@@ -46,6 +122,111 @@ function toOpenAIResponseFormat(rf) {
46
122
  }
47
123
  };
48
124
  }
125
+ function toOpenAIResponsesTextFormat(rf) {
126
+ if (!rf || rf.type !== "json_schema") return void 0;
127
+ return {
128
+ type: "json_schema",
129
+ name: rf.json_schema.name,
130
+ schema: normalizeObjectJsonSchema(rf.json_schema.schema),
131
+ strict: rf.json_schema.strict ?? true
132
+ };
133
+ }
134
+ function formatTools(actions) {
135
+ return actions.map((action) => ({
136
+ type: "function",
137
+ function: {
138
+ name: action.name,
139
+ description: action.description,
140
+ parameters: {
141
+ type: "object",
142
+ properties: action.parameters ? Object.fromEntries(
143
+ Object.entries(action.parameters).map(([key, param]) => [
144
+ key,
145
+ parameterToJsonSchema(param)
146
+ ])
147
+ ) : {},
148
+ required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
149
+ additionalProperties: false
150
+ }
151
+ }
152
+ }));
153
+ }
154
+ function hasImageAttachments(message) {
155
+ const attachments = message.metadata?.attachments;
156
+ return attachments?.some((a) => a.type === "image") ?? false;
157
+ }
158
+ function attachmentToOpenAIImage(attachment) {
159
+ if (attachment.type !== "image") return null;
160
+ let imageUrl;
161
+ if (attachment.url) {
162
+ imageUrl = attachment.url;
163
+ } else if (attachment.data) {
164
+ imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
165
+ } else {
166
+ return null;
167
+ }
168
+ return {
169
+ type: "image_url",
170
+ image_url: {
171
+ url: imageUrl,
172
+ detail: "auto"
173
+ }
174
+ };
175
+ }
176
+ function messageToOpenAIContent(message) {
177
+ const attachments = message.metadata?.attachments;
178
+ const content = message.content ?? "";
179
+ if (!hasImageAttachments(message)) {
180
+ return content;
181
+ }
182
+ const blocks = [];
183
+ if (content) {
184
+ blocks.push({ type: "text", text: content });
185
+ }
186
+ if (attachments) {
187
+ for (const attachment of attachments) {
188
+ const imageBlock = attachmentToOpenAIImage(attachment);
189
+ if (imageBlock) {
190
+ blocks.push(imageBlock);
191
+ }
192
+ }
193
+ }
194
+ return blocks;
195
+ }
196
+ function formatMessagesForOpenAI(messages, systemPrompt) {
197
+ const formatted = [];
198
+ if (systemPrompt) {
199
+ formatted.push({ role: "system", content: systemPrompt });
200
+ }
201
+ for (const msg of messages) {
202
+ if (msg.role === "system") {
203
+ formatted.push({ role: "system", content: msg.content ?? "" });
204
+ } else if (msg.role === "user") {
205
+ formatted.push({
206
+ role: "user",
207
+ content: messageToOpenAIContent(msg)
208
+ });
209
+ } else if (msg.role === "assistant") {
210
+ const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
211
+ const assistantMsg = {
212
+ role: "assistant",
213
+ // Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
214
+ content: hasToolCalls ? msg.content || null : msg.content
215
+ };
216
+ if (hasToolCalls) {
217
+ assistantMsg.tool_calls = msg.tool_calls;
218
+ }
219
+ formatted.push(assistantMsg);
220
+ } else if (msg.role === "tool" && msg.tool_call_id) {
221
+ formatted.push({
222
+ role: "tool",
223
+ content: msg.content ?? "",
224
+ tool_call_id: msg.tool_call_id
225
+ });
226
+ }
227
+ }
228
+ return formatted;
229
+ }
49
230
 
50
231
  // src/providers/fireworks/provider.ts
51
232
  function fireworks(modelId, options = {}) {
@@ -254,6 +435,542 @@ function formatMessages(messages) {
254
435
  });
255
436
  }
256
437
 
257
- export { fireworks as createFireworks, fireworks };
438
+ // src/core/utils.ts
439
+ function generateId(prefix = "id") {
440
+ return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
441
+ }
442
+ function generateMessageId() {
443
+ return generateId("msg");
444
+ }
445
+ function generateToolCallId() {
446
+ return generateId("call");
447
+ }
448
+
449
+ // src/adapters/openai.ts
450
+ var OpenAIAdapter = class _OpenAIAdapter {
451
+ constructor(config) {
452
+ this.config = config;
453
+ this.model = config.model || "gpt-4o";
454
+ this.provider = _OpenAIAdapter.resolveProviderName(config.baseUrl);
455
+ }
456
+ static resolveProviderName(baseUrl) {
457
+ if (!baseUrl) return "openai";
458
+ if (baseUrl.includes("generativelanguage.googleapis.com")) return "google";
459
+ if (baseUrl.includes("x.ai")) return "xai";
460
+ if (baseUrl.includes("azure")) return "azure";
461
+ if (baseUrl.includes("fireworks.ai")) return "fireworks";
462
+ return "openai";
463
+ }
464
+ async getClient() {
465
+ if (!this.client) {
466
+ const { default: OpenAI } = await import('openai');
467
+ this.client = new OpenAI({
468
+ apiKey: this.config.apiKey,
469
+ baseURL: this.config.baseUrl
470
+ });
471
+ }
472
+ return this.client;
473
+ }
474
+ shouldUseResponsesApi(request) {
475
+ return request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false && Array.isArray(request.toolDefinitions) && request.toolDefinitions.length > 0;
476
+ }
477
+ buildResponsesInput(request) {
478
+ const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? request.rawMessages : formatMessagesForOpenAI(request.messages, void 0);
479
+ const input = [];
480
+ for (const message of sourceMessages) {
481
+ if (message.role === "system") {
482
+ continue;
483
+ }
484
+ if (message.role === "assistant") {
485
+ const content = typeof message.content === "string" ? message.content : Array.isArray(message.content) ? message.content : message.content ? JSON.stringify(message.content) : "";
486
+ if (content) {
487
+ input.push({
488
+ type: "message",
489
+ role: "assistant",
490
+ content
491
+ });
492
+ }
493
+ const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
494
+ for (const toolCall of toolCalls) {
495
+ input.push({
496
+ type: "function_call",
497
+ call_id: toolCall.id,
498
+ name: toolCall.function?.name,
499
+ arguments: toolCall.function?.arguments ?? "{}"
500
+ });
501
+ }
502
+ continue;
503
+ }
504
+ if (message.role === "tool") {
505
+ input.push({
506
+ type: "function_call_output",
507
+ call_id: message.tool_call_id,
508
+ output: typeof message.content === "string" ? message.content : JSON.stringify(message.content ?? null)
509
+ });
510
+ continue;
511
+ }
512
+ input.push({
513
+ type: "message",
514
+ role: message.role === "developer" ? "developer" : "user",
515
+ content: typeof message.content === "string" ? message.content : Array.isArray(message.content) ? message.content : JSON.stringify(message.content ?? "")
516
+ });
517
+ }
518
+ return input;
519
+ }
520
+ buildResponsesTools(tools) {
521
+ const nativeTools = tools.filter((tool) => tool.available !== false).map((tool) => ({
522
+ type: "function",
523
+ name: tool.name,
524
+ description: tool.description,
525
+ parameters: normalizeObjectJsonSchema(
526
+ tool.inputSchema ?? {
527
+ type: "object",
528
+ properties: {},
529
+ required: []
530
+ }
531
+ ),
532
+ strict: true,
533
+ defer_loading: tool.deferLoading === true
534
+ }));
535
+ return [{ type: "tool_search" }, ...nativeTools];
536
+ }
537
+ parseResponsesResult(response) {
538
+ const content = typeof response?.output_text === "string" ? response.output_text : "";
539
+ const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => ({
540
+ id: item.call_id ?? item.id ?? generateToolCallId(),
541
+ name: item.name,
542
+ args: (() => {
543
+ try {
544
+ return JSON.parse(item.arguments ?? "{}");
545
+ } catch {
546
+ return {};
547
+ }
548
+ })()
549
+ })) : [];
550
+ return {
551
+ content,
552
+ toolCalls,
553
+ usage: response?.usage ? {
554
+ promptTokens: response.usage.input_tokens ?? 0,
555
+ completionTokens: response.usage.output_tokens ?? 0,
556
+ totalTokens: response.usage.total_tokens ?? (response.usage.input_tokens ?? 0) + (response.usage.output_tokens ?? 0)
557
+ } : void 0,
558
+ rawResponse: response
559
+ };
560
+ }
561
+ async completeWithResponses(request) {
562
+ const client = await this.getClient();
563
+ const openaiToolOptions = request.providerToolOptions?.openai;
564
+ const responsesTextFormat = toOpenAIResponsesTextFormat(
565
+ request.config?.responseFormat
566
+ );
567
+ const payload = {
568
+ model: request.config?.model || this.model,
569
+ instructions: request.systemPrompt,
570
+ input: this.buildResponsesInput(request),
571
+ tools: this.buildResponsesTools(request.toolDefinitions ?? []),
572
+ tool_choice: openaiToolOptions?.toolChoice === "required" ? "required" : openaiToolOptions?.toolChoice === "auto" ? "auto" : void 0,
573
+ parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
574
+ temperature: request.config?.temperature ?? this.config.temperature,
575
+ max_output_tokens: request.config?.maxTokens ?? this.config.maxTokens,
576
+ ...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
577
+ stream: false
578
+ };
579
+ logProviderPayload("openai", "request payload", payload, request.debug);
580
+ const response = await client.responses.create(payload);
581
+ logProviderPayload("openai", "response payload", response, request.debug);
582
+ return this.parseResponsesResult(response);
583
+ }
584
+ async *stream(request) {
585
+ if (this.shouldUseResponsesApi(request)) {
586
+ const messageId2 = generateMessageId();
587
+ yield { type: "message:start", id: messageId2 };
588
+ try {
589
+ const result = await this.completeWithResponses(request);
590
+ if (result.content) {
591
+ yield { type: "message:delta", content: result.content };
592
+ }
593
+ for (const toolCall of result.toolCalls) {
594
+ yield {
595
+ type: "action:start",
596
+ id: toolCall.id,
597
+ name: toolCall.name
598
+ };
599
+ yield {
600
+ type: "action:args",
601
+ id: toolCall.id,
602
+ args: JSON.stringify(toolCall.args)
603
+ };
604
+ }
605
+ yield { type: "message:end" };
606
+ yield {
607
+ type: "done",
608
+ usage: result.usage ? {
609
+ prompt_tokens: result.usage.promptTokens,
610
+ completion_tokens: result.usage.completionTokens,
611
+ total_tokens: result.usage.totalTokens
612
+ } : void 0
613
+ };
614
+ return;
615
+ } catch (error) {
616
+ yield {
617
+ type: "error",
618
+ message: error instanceof Error ? error.message : "Unknown error",
619
+ code: "OPENAI_RESPONSES_ERROR"
620
+ };
621
+ return;
622
+ }
623
+ }
624
+ const client = await this.getClient();
625
+ let messages;
626
+ if (request.rawMessages && request.rawMessages.length > 0) {
627
+ const processedMessages = request.rawMessages.map((msg) => {
628
+ if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
629
+ return { ...msg, content: null };
630
+ }
631
+ const hasAttachments = msg.attachments && Array.isArray(msg.attachments) && msg.attachments.length > 0;
632
+ if (hasAttachments) {
633
+ const content = [];
634
+ if (msg.content) {
635
+ content.push({ type: "text", text: msg.content });
636
+ }
637
+ for (const attachment of msg.attachments) {
638
+ if (attachment.type === "image") {
639
+ let imageUrl;
640
+ if (attachment.url) {
641
+ imageUrl = attachment.url;
642
+ } else if (attachment.data) {
643
+ imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
644
+ } else {
645
+ continue;
646
+ }
647
+ content.push({
648
+ type: "image_url",
649
+ image_url: { url: imageUrl, detail: "auto" }
650
+ });
651
+ }
652
+ }
653
+ return { ...msg, content, attachments: void 0 };
654
+ }
655
+ return msg;
656
+ });
657
+ if (request.systemPrompt) {
658
+ const hasSystem = processedMessages.some((m) => m.role === "system");
659
+ if (!hasSystem) {
660
+ messages = [
661
+ { role: "system", content: request.systemPrompt },
662
+ ...processedMessages
663
+ ];
664
+ } else {
665
+ messages = processedMessages;
666
+ }
667
+ } else {
668
+ messages = processedMessages;
669
+ }
670
+ } else {
671
+ messages = formatMessagesForOpenAI(
672
+ request.messages,
673
+ request.systemPrompt
674
+ );
675
+ }
676
+ const tools = request.actions?.length ? formatTools(request.actions) : [];
677
+ const webSearchConfig = request.webSearch ?? this.config.webSearch;
678
+ if (webSearchConfig) {
679
+ const webSearchTool = {
680
+ type: "web_search_preview"
681
+ };
682
+ const wsConfig = typeof webSearchConfig === "object" ? webSearchConfig : {};
683
+ if (wsConfig.userLocation) {
684
+ webSearchTool.search_context_size = "medium";
685
+ }
686
+ tools.push(webSearchTool);
687
+ }
688
+ const messageId = generateMessageId();
689
+ yield { type: "message:start", id: messageId };
690
+ try {
691
+ const openaiToolOptions = request.providerToolOptions?.openai;
692
+ const toolChoice = openaiToolOptions?.toolChoice && typeof openaiToolOptions.toolChoice === "object" ? {
693
+ type: "function",
694
+ function: {
695
+ name: openaiToolOptions.toolChoice.name
696
+ }
697
+ } : openaiToolOptions?.toolChoice;
698
+ const modelIdForPayload = request.config?.model || this.model;
699
+ const payload = {
700
+ model: modelIdForPayload,
701
+ messages,
702
+ tools: tools.length > 0 ? tools : void 0,
703
+ tool_choice: tools.length > 0 ? toolChoice : void 0,
704
+ parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
705
+ ...buildOpenAITokenParams(
706
+ modelIdForPayload,
707
+ request.config?.maxTokens ?? this.config.maxTokens,
708
+ request.config?.temperature ?? this.config.temperature
709
+ ),
710
+ response_format: toOpenAIResponseFormat(request.config?.responseFormat),
711
+ stream: true,
712
+ stream_options: { include_usage: true }
713
+ };
714
+ logProviderPayload("openai", "request payload", payload, request.debug);
715
+ const stream = await client.chat.completions.create(payload);
716
+ let currentToolCall = null;
717
+ const collectedCitations = [];
718
+ let citationIndex = 0;
719
+ let usage;
720
+ for await (const chunk of stream) {
721
+ logProviderPayload("openai", "stream chunk", chunk, request.debug);
722
+ if (request.signal?.aborted) {
723
+ break;
724
+ }
725
+ const delta = chunk.choices[0]?.delta;
726
+ const choice = chunk.choices[0];
727
+ if (delta?.content) {
728
+ yield { type: "message:delta", content: delta.content };
729
+ }
730
+ const annotations = delta?.annotations;
731
+ if (annotations && annotations.length > 0) {
732
+ for (const annotation of annotations) {
733
+ if (annotation.type === "url_citation" && annotation.url_citation?.url) {
734
+ citationIndex++;
735
+ const url = annotation.url_citation.url;
736
+ const domain = extractDomain(url);
737
+ collectedCitations.push({
738
+ index: citationIndex,
739
+ url,
740
+ title: annotation.url_citation.title || domain,
741
+ domain,
742
+ favicon: domain ? `https://www.google.com/s2/favicons?domain=${domain}&sz=32` : void 0
743
+ });
744
+ }
745
+ }
746
+ }
747
+ if (delta?.tool_calls) {
748
+ for (const toolCall of delta.tool_calls) {
749
+ if (toolCall.id) {
750
+ if (currentToolCall) {
751
+ yield {
752
+ type: "action:args",
753
+ id: currentToolCall.id,
754
+ args: currentToolCall.arguments
755
+ };
756
+ yield {
757
+ type: "action:end",
758
+ id: currentToolCall.id,
759
+ name: currentToolCall.name
760
+ };
761
+ }
762
+ const tcExtraContent = toolCall.extra_content;
763
+ currentToolCall = {
764
+ id: toolCall.id,
765
+ name: toolCall.function?.name || "",
766
+ arguments: toolCall.function?.arguments || "",
767
+ ...tcExtraContent ? { extra_content: tcExtraContent } : {}
768
+ };
769
+ yield {
770
+ type: "action:start",
771
+ id: currentToolCall.id,
772
+ name: currentToolCall.name,
773
+ ...currentToolCall.extra_content ? { extra_content: currentToolCall.extra_content } : {}
774
+ };
775
+ } else if (currentToolCall && toolCall.function?.arguments) {
776
+ currentToolCall.arguments += toolCall.function.arguments;
777
+ }
778
+ }
779
+ }
780
+ if (chunk.usage) {
781
+ usage = {
782
+ prompt_tokens: chunk.usage.prompt_tokens,
783
+ completion_tokens: chunk.usage.completion_tokens,
784
+ total_tokens: chunk.usage.total_tokens
785
+ };
786
+ }
787
+ if (choice?.finish_reason) {
788
+ if (currentToolCall) {
789
+ yield {
790
+ type: "action:args",
791
+ id: currentToolCall.id,
792
+ args: currentToolCall.arguments
793
+ };
794
+ yield {
795
+ type: "action:end",
796
+ id: currentToolCall.id,
797
+ name: currentToolCall.name
798
+ };
799
+ currentToolCall = null;
800
+ }
801
+ }
802
+ }
803
+ if (collectedCitations.length > 0) {
804
+ const uniqueCitations = deduplicateCitations(collectedCitations);
805
+ yield { type: "citation", citations: uniqueCitations };
806
+ }
807
+ yield { type: "message:end" };
808
+ yield { type: "done", usage };
809
+ } catch (error) {
810
+ yield {
811
+ type: "error",
812
+ message: error instanceof Error ? error.message : "Unknown error",
813
+ code: `${this.provider.toUpperCase()}_ERROR`
814
+ };
815
+ }
816
+ }
817
+ async complete(request) {
818
+ if (this.shouldUseResponsesApi(request)) {
819
+ return this.completeWithResponses(request);
820
+ }
821
+ const client = await this.getClient();
822
+ let messages;
823
+ if (request.rawMessages && request.rawMessages.length > 0) {
824
+ const sanitized = request.rawMessages.map((msg) => {
825
+ if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
826
+ return { ...msg, content: null };
827
+ }
828
+ return msg;
829
+ });
830
+ if (request.systemPrompt && !sanitized.some((message2) => message2.role === "system")) {
831
+ messages = [
832
+ { role: "system", content: request.systemPrompt },
833
+ ...sanitized
834
+ ];
835
+ } else {
836
+ messages = sanitized;
837
+ }
838
+ } else {
839
+ messages = formatMessagesForOpenAI(
840
+ request.messages,
841
+ request.systemPrompt
842
+ );
843
+ }
844
+ const tools = request.actions?.length ? formatTools(request.actions) : [];
845
+ const openaiToolOptions = request.providerToolOptions?.openai;
846
+ const toolChoice = openaiToolOptions?.toolChoice && typeof openaiToolOptions.toolChoice === "object" ? {
847
+ type: "function",
848
+ function: {
849
+ name: openaiToolOptions.toolChoice.name
850
+ }
851
+ } : openaiToolOptions?.toolChoice;
852
+ const modelIdForCompletePayload = request.config?.model || this.model;
853
+ const payload = {
854
+ model: modelIdForCompletePayload,
855
+ messages,
856
+ tools: tools.length > 0 ? tools : void 0,
857
+ tool_choice: tools.length > 0 ? toolChoice : void 0,
858
+ parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
859
+ ...buildOpenAITokenParams(
860
+ modelIdForCompletePayload,
861
+ request.config?.maxTokens ?? this.config.maxTokens,
862
+ request.config?.temperature ?? this.config.temperature
863
+ ),
864
+ response_format: toOpenAIResponseFormat(request.config?.responseFormat),
865
+ stream: false
866
+ };
867
+ logProviderPayload("openai", "request payload", payload, request.debug);
868
+ const response = await client.chat.completions.create(payload);
869
+ logProviderPayload("openai", "response payload", response, request.debug);
870
+ const choice = response.choices?.[0];
871
+ const message = choice?.message;
872
+ return {
873
+ content: message?.content ?? "",
874
+ toolCalls: message?.tool_calls?.map((toolCall) => ({
875
+ id: toolCall.id ?? generateToolCallId(),
876
+ name: toolCall.function?.name ?? "",
877
+ args: (() => {
878
+ try {
879
+ return JSON.parse(toolCall.function?.arguments ?? "{}");
880
+ } catch {
881
+ return {};
882
+ }
883
+ })(),
884
+ ...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
885
+ })) ?? [],
886
+ usage: response.usage ? {
887
+ promptTokens: response.usage.prompt_tokens,
888
+ completionTokens: response.usage.completion_tokens,
889
+ totalTokens: response.usage.total_tokens
890
+ } : void 0,
891
+ rawResponse: response
892
+ };
893
+ }
894
+ };
895
+ function extractDomain(url) {
896
+ try {
897
+ const parsed = new URL(url);
898
+ return parsed.hostname;
899
+ } catch {
900
+ return "";
901
+ }
902
+ }
903
+ function deduplicateCitations(citations) {
904
+ const seen = /* @__PURE__ */ new Map();
905
+ let index = 0;
906
+ for (const citation of citations) {
907
+ if (!seen.has(citation.url)) {
908
+ index++;
909
+ seen.set(citation.url, { ...citation, index });
910
+ }
911
+ }
912
+ return Array.from(seen.values());
913
+ }
914
+ function createOpenAIAdapter(config) {
915
+ return new OpenAIAdapter(config);
916
+ }
917
+
918
+ // src/providers/types.ts
919
+ function createCallableProvider(providerFn, properties) {
920
+ Object.defineProperty(providerFn, "name", {
921
+ value: properties.name,
922
+ writable: false,
923
+ configurable: true
924
+ });
925
+ Object.assign(providerFn, {
926
+ supportedModels: properties.supportedModels,
927
+ languageModel: providerFn,
928
+ getCapabilities: properties.getCapabilities,
929
+ embeddingModel: properties.embeddingModel
930
+ });
931
+ return providerFn;
932
+ }
933
+
934
+ // src/providers/fireworks/index.ts
935
+ var DEFAULT_CAPABILITIES = {
936
+ vision: false,
937
+ tools: true,
938
+ jsonMode: true,
939
+ maxTokens: 131072
940
+ };
941
+ function createFireworks(config = {}) {
942
+ const apiKey = config.apiKey ?? process.env.FIREWORKS_API_KEY ?? "";
943
+ const baseUrl = config.baseUrl ?? "https://api.fireworks.ai/inference/v1";
944
+ const providerFn = (modelId) => {
945
+ return createOpenAIAdapter({
946
+ apiKey,
947
+ model: modelId,
948
+ baseUrl
949
+ });
950
+ };
951
+ const getCapabilities = (_modelId) => {
952
+ return {
953
+ supportsVision: DEFAULT_CAPABILITIES.vision,
954
+ supportsTools: DEFAULT_CAPABILITIES.tools,
955
+ supportsThinking: false,
956
+ supportsStreaming: true,
957
+ supportsPDF: false,
958
+ supportsAudio: false,
959
+ supportsVideo: false,
960
+ maxTokens: DEFAULT_CAPABILITIES.maxTokens,
961
+ supportedImageTypes: [],
962
+ supportsJsonMode: DEFAULT_CAPABILITIES.jsonMode,
963
+ supportsSystemMessages: true
964
+ };
965
+ };
966
+ return createCallableProvider(providerFn, {
967
+ name: "fireworks",
968
+ supportedModels: [],
969
+ getCapabilities
970
+ });
971
+ }
972
+ var createFireworksProvider = createFireworks;
973
+
974
+ export { createFireworks, fireworks as createFireworksModel, createFireworksProvider, fireworks };
258
975
  //# sourceMappingURL=index.mjs.map
259
976
  //# sourceMappingURL=index.mjs.map