@yourgpt/llm-sdk 2.1.8 → 2.5.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.
@@ -23,7 +23,12 @@ function togetherai(modelId, options = {}) {
23
23
  supportsThinking: false,
24
24
  supportsPDF: false,
25
25
  maxTokens: 131072,
26
- supportedImageTypes: ["image/png", "image/jpeg", "image/gif", "image/webp"]
26
+ supportedImageTypes: [
27
+ "image/png",
28
+ "image/jpeg",
29
+ "image/gif",
30
+ "image/webp"
31
+ ]
27
32
  },
28
33
  async doGenerate(params) {
29
34
  const client2 = await getClient();
@@ -199,7 +204,727 @@ function formatMessages(messages) {
199
204
  });
200
205
  }
201
206
 
202
- exports.createTogetherAI = togetherai;
207
+ // src/core/utils.ts
208
+ function generateId(prefix = "id") {
209
+ return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
210
+ }
211
+ function generateMessageId() {
212
+ return generateId("msg");
213
+ }
214
+ function generateToolCallId() {
215
+ return generateId("call");
216
+ }
217
+
218
+ // src/adapters/base.ts
219
+ function stringifyForDebug(value) {
220
+ return JSON.stringify(
221
+ value,
222
+ (_key, currentValue) => {
223
+ if (typeof currentValue === "bigint") {
224
+ return currentValue.toString();
225
+ }
226
+ if (currentValue instanceof Error) {
227
+ return {
228
+ name: currentValue.name,
229
+ message: currentValue.message,
230
+ stack: currentValue.stack
231
+ };
232
+ }
233
+ return currentValue;
234
+ },
235
+ 2
236
+ );
237
+ }
238
+ function logProviderPayload(provider, label, payload, enabled) {
239
+ if (!enabled) {
240
+ return;
241
+ }
242
+ if (label.toLowerCase().includes("stream ")) {
243
+ return;
244
+ }
245
+ try {
246
+ console.log(
247
+ `[llm-sdk:${provider}] ${label}
248
+ ${stringifyForDebug(payload)}`
249
+ );
250
+ } catch (error) {
251
+ console.log(
252
+ `[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
253
+ error
254
+ );
255
+ }
256
+ }
257
+ function parameterToJsonSchema(param) {
258
+ const schema = {
259
+ type: param.type
260
+ };
261
+ if (param.description) {
262
+ schema.description = param.description;
263
+ }
264
+ if (param.enum) {
265
+ schema.enum = param.enum;
266
+ }
267
+ if (param.type === "array" && param.items) {
268
+ schema.items = parameterToJsonSchema(
269
+ param.items
270
+ );
271
+ }
272
+ if (param.type === "object" && param.properties) {
273
+ schema.properties = Object.fromEntries(
274
+ Object.entries(param.properties).map(([key, prop]) => [
275
+ key,
276
+ parameterToJsonSchema(
277
+ prop
278
+ )
279
+ ])
280
+ );
281
+ schema.additionalProperties = false;
282
+ }
283
+ return schema;
284
+ }
285
+ function normalizeObjectJsonSchema(schema) {
286
+ if (!schema || typeof schema !== "object") {
287
+ return {
288
+ type: "object",
289
+ properties: {},
290
+ required: [],
291
+ additionalProperties: false
292
+ };
293
+ }
294
+ const normalized = { ...schema };
295
+ const type = normalized.type;
296
+ if (type === "object") {
297
+ const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
298
+ normalized.properties = Object.fromEntries(
299
+ Object.entries(properties).map(([key, value]) => [
300
+ key,
301
+ normalizeObjectJsonSchema(value)
302
+ ])
303
+ );
304
+ const propertyKeys = Object.keys(properties);
305
+ const required = Array.isArray(normalized.required) ? normalized.required.filter(
306
+ (value) => typeof value === "string"
307
+ ) : [];
308
+ normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
309
+ if (normalized.additionalProperties === void 0) {
310
+ normalized.additionalProperties = false;
311
+ }
312
+ } else if (type === "array" && normalized.items && typeof normalized.items === "object") {
313
+ normalized.items = normalizeObjectJsonSchema(
314
+ normalized.items
315
+ );
316
+ }
317
+ return normalized;
318
+ }
319
+ function formatTools(actions) {
320
+ return actions.map((action) => ({
321
+ type: "function",
322
+ function: {
323
+ name: action.name,
324
+ description: action.description,
325
+ parameters: {
326
+ type: "object",
327
+ properties: action.parameters ? Object.fromEntries(
328
+ Object.entries(action.parameters).map(([key, param]) => [
329
+ key,
330
+ parameterToJsonSchema(param)
331
+ ])
332
+ ) : {},
333
+ required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
334
+ additionalProperties: false
335
+ }
336
+ }
337
+ }));
338
+ }
339
+ function hasImageAttachments(message) {
340
+ const attachments = message.metadata?.attachments;
341
+ return attachments?.some((a) => a.type === "image") ?? false;
342
+ }
343
+ function attachmentToOpenAIImage(attachment) {
344
+ if (attachment.type !== "image") return null;
345
+ let imageUrl;
346
+ if (attachment.url) {
347
+ imageUrl = attachment.url;
348
+ } else if (attachment.data) {
349
+ imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
350
+ } else {
351
+ return null;
352
+ }
353
+ return {
354
+ type: "image_url",
355
+ image_url: {
356
+ url: imageUrl,
357
+ detail: "auto"
358
+ }
359
+ };
360
+ }
361
+ function messageToOpenAIContent(message) {
362
+ const attachments = message.metadata?.attachments;
363
+ const content = message.content ?? "";
364
+ if (!hasImageAttachments(message)) {
365
+ return content;
366
+ }
367
+ const blocks = [];
368
+ if (content) {
369
+ blocks.push({ type: "text", text: content });
370
+ }
371
+ if (attachments) {
372
+ for (const attachment of attachments) {
373
+ const imageBlock = attachmentToOpenAIImage(attachment);
374
+ if (imageBlock) {
375
+ blocks.push(imageBlock);
376
+ }
377
+ }
378
+ }
379
+ return blocks;
380
+ }
381
+ function formatMessagesForOpenAI(messages, systemPrompt) {
382
+ const formatted = [];
383
+ if (systemPrompt) {
384
+ formatted.push({ role: "system", content: systemPrompt });
385
+ }
386
+ for (const msg of messages) {
387
+ if (msg.role === "system") {
388
+ formatted.push({ role: "system", content: msg.content ?? "" });
389
+ } else if (msg.role === "user") {
390
+ formatted.push({
391
+ role: "user",
392
+ content: messageToOpenAIContent(msg)
393
+ });
394
+ } else if (msg.role === "assistant") {
395
+ const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
396
+ const assistantMsg = {
397
+ role: "assistant",
398
+ // Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
399
+ content: hasToolCalls ? msg.content || null : msg.content
400
+ };
401
+ if (hasToolCalls) {
402
+ assistantMsg.tool_calls = msg.tool_calls;
403
+ }
404
+ formatted.push(assistantMsg);
405
+ } else if (msg.role === "tool" && msg.tool_call_id) {
406
+ formatted.push({
407
+ role: "tool",
408
+ content: msg.content ?? "",
409
+ tool_call_id: msg.tool_call_id
410
+ });
411
+ }
412
+ }
413
+ return formatted;
414
+ }
415
+
416
+ // src/adapters/openai.ts
417
+ var OpenAIAdapter = class _OpenAIAdapter {
418
+ constructor(config) {
419
+ this.config = config;
420
+ this.model = config.model || "gpt-4o";
421
+ this.provider = _OpenAIAdapter.resolveProviderName(config.baseUrl);
422
+ }
423
+ static resolveProviderName(baseUrl) {
424
+ if (!baseUrl) return "openai";
425
+ if (baseUrl.includes("generativelanguage.googleapis.com")) return "google";
426
+ if (baseUrl.includes("x.ai")) return "xai";
427
+ if (baseUrl.includes("azure")) return "azure";
428
+ return "openai";
429
+ }
430
+ async getClient() {
431
+ if (!this.client) {
432
+ const { default: OpenAI } = await import('openai');
433
+ this.client = new OpenAI({
434
+ apiKey: this.config.apiKey,
435
+ baseURL: this.config.baseUrl
436
+ });
437
+ }
438
+ return this.client;
439
+ }
440
+ shouldUseResponsesApi(request) {
441
+ return request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false && Array.isArray(request.toolDefinitions) && request.toolDefinitions.length > 0;
442
+ }
443
+ buildResponsesInput(request) {
444
+ const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? request.rawMessages : formatMessagesForOpenAI(request.messages, void 0);
445
+ const input = [];
446
+ for (const message of sourceMessages) {
447
+ if (message.role === "system") {
448
+ continue;
449
+ }
450
+ if (message.role === "assistant") {
451
+ const content = typeof message.content === "string" ? message.content : Array.isArray(message.content) ? message.content : message.content ? JSON.stringify(message.content) : "";
452
+ if (content) {
453
+ input.push({
454
+ type: "message",
455
+ role: "assistant",
456
+ content
457
+ });
458
+ }
459
+ const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
460
+ for (const toolCall of toolCalls) {
461
+ input.push({
462
+ type: "function_call",
463
+ call_id: toolCall.id,
464
+ name: toolCall.function?.name,
465
+ arguments: toolCall.function?.arguments ?? "{}"
466
+ });
467
+ }
468
+ continue;
469
+ }
470
+ if (message.role === "tool") {
471
+ input.push({
472
+ type: "function_call_output",
473
+ call_id: message.tool_call_id,
474
+ output: typeof message.content === "string" ? message.content : JSON.stringify(message.content ?? null)
475
+ });
476
+ continue;
477
+ }
478
+ input.push({
479
+ type: "message",
480
+ role: message.role === "developer" ? "developer" : "user",
481
+ content: typeof message.content === "string" ? message.content : Array.isArray(message.content) ? message.content : JSON.stringify(message.content ?? "")
482
+ });
483
+ }
484
+ return input;
485
+ }
486
+ buildResponsesTools(tools) {
487
+ const nativeTools = tools.filter((tool) => tool.available !== false).map((tool) => ({
488
+ type: "function",
489
+ name: tool.name,
490
+ description: tool.description,
491
+ parameters: normalizeObjectJsonSchema(
492
+ tool.inputSchema ?? {
493
+ type: "object",
494
+ properties: {},
495
+ required: []
496
+ }
497
+ ),
498
+ strict: true,
499
+ defer_loading: tool.deferLoading === true
500
+ }));
501
+ return [{ type: "tool_search" }, ...nativeTools];
502
+ }
503
+ parseResponsesResult(response) {
504
+ const content = typeof response?.output_text === "string" ? response.output_text : "";
505
+ const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => ({
506
+ id: item.call_id ?? item.id ?? generateToolCallId(),
507
+ name: item.name,
508
+ args: (() => {
509
+ try {
510
+ return JSON.parse(item.arguments ?? "{}");
511
+ } catch {
512
+ return {};
513
+ }
514
+ })()
515
+ })) : [];
516
+ return {
517
+ content,
518
+ toolCalls,
519
+ usage: response?.usage ? {
520
+ promptTokens: response.usage.input_tokens ?? 0,
521
+ completionTokens: response.usage.output_tokens ?? 0,
522
+ totalTokens: response.usage.total_tokens ?? (response.usage.input_tokens ?? 0) + (response.usage.output_tokens ?? 0)
523
+ } : void 0,
524
+ rawResponse: response
525
+ };
526
+ }
527
+ async completeWithResponses(request) {
528
+ const client = await this.getClient();
529
+ const openaiToolOptions = request.providerToolOptions?.openai;
530
+ const payload = {
531
+ model: request.config?.model || this.model,
532
+ instructions: request.systemPrompt,
533
+ input: this.buildResponsesInput(request),
534
+ tools: this.buildResponsesTools(request.toolDefinitions ?? []),
535
+ tool_choice: openaiToolOptions?.toolChoice === "required" ? "required" : openaiToolOptions?.toolChoice === "auto" ? "auto" : void 0,
536
+ parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
537
+ temperature: request.config?.temperature ?? this.config.temperature,
538
+ max_output_tokens: request.config?.maxTokens ?? this.config.maxTokens,
539
+ stream: false
540
+ };
541
+ logProviderPayload("openai", "request payload", payload, request.debug);
542
+ const response = await client.responses.create(payload);
543
+ logProviderPayload("openai", "response payload", response, request.debug);
544
+ return this.parseResponsesResult(response);
545
+ }
546
+ async *stream(request) {
547
+ if (this.shouldUseResponsesApi(request)) {
548
+ const messageId2 = generateMessageId();
549
+ yield { type: "message:start", id: messageId2 };
550
+ try {
551
+ const result = await this.completeWithResponses(request);
552
+ if (result.content) {
553
+ yield { type: "message:delta", content: result.content };
554
+ }
555
+ for (const toolCall of result.toolCalls) {
556
+ yield {
557
+ type: "action:start",
558
+ id: toolCall.id,
559
+ name: toolCall.name
560
+ };
561
+ yield {
562
+ type: "action:args",
563
+ id: toolCall.id,
564
+ args: JSON.stringify(toolCall.args)
565
+ };
566
+ }
567
+ yield { type: "message:end" };
568
+ yield {
569
+ type: "done",
570
+ usage: result.usage ? {
571
+ prompt_tokens: result.usage.promptTokens,
572
+ completion_tokens: result.usage.completionTokens,
573
+ total_tokens: result.usage.totalTokens
574
+ } : void 0
575
+ };
576
+ return;
577
+ } catch (error) {
578
+ yield {
579
+ type: "error",
580
+ message: error instanceof Error ? error.message : "Unknown error",
581
+ code: "OPENAI_RESPONSES_ERROR"
582
+ };
583
+ return;
584
+ }
585
+ }
586
+ const client = await this.getClient();
587
+ let messages;
588
+ if (request.rawMessages && request.rawMessages.length > 0) {
589
+ const processedMessages = request.rawMessages.map((msg) => {
590
+ if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
591
+ return { ...msg, content: null };
592
+ }
593
+ const hasAttachments = msg.attachments && Array.isArray(msg.attachments) && msg.attachments.length > 0;
594
+ if (hasAttachments) {
595
+ const content = [];
596
+ if (msg.content) {
597
+ content.push({ type: "text", text: msg.content });
598
+ }
599
+ for (const attachment of msg.attachments) {
600
+ if (attachment.type === "image") {
601
+ let imageUrl;
602
+ if (attachment.url) {
603
+ imageUrl = attachment.url;
604
+ } else if (attachment.data) {
605
+ imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
606
+ } else {
607
+ continue;
608
+ }
609
+ content.push({
610
+ type: "image_url",
611
+ image_url: { url: imageUrl, detail: "auto" }
612
+ });
613
+ }
614
+ }
615
+ return { ...msg, content, attachments: void 0 };
616
+ }
617
+ return msg;
618
+ });
619
+ if (request.systemPrompt) {
620
+ const hasSystem = processedMessages.some((m) => m.role === "system");
621
+ if (!hasSystem) {
622
+ messages = [
623
+ { role: "system", content: request.systemPrompt },
624
+ ...processedMessages
625
+ ];
626
+ } else {
627
+ messages = processedMessages;
628
+ }
629
+ } else {
630
+ messages = processedMessages;
631
+ }
632
+ } else {
633
+ messages = formatMessagesForOpenAI(
634
+ request.messages,
635
+ request.systemPrompt
636
+ );
637
+ }
638
+ const tools = request.actions?.length ? formatTools(request.actions) : [];
639
+ const webSearchConfig = request.webSearch ?? this.config.webSearch;
640
+ if (webSearchConfig) {
641
+ const webSearchTool = {
642
+ type: "web_search_preview"
643
+ };
644
+ const wsConfig = typeof webSearchConfig === "object" ? webSearchConfig : {};
645
+ if (wsConfig.userLocation) {
646
+ webSearchTool.search_context_size = "medium";
647
+ }
648
+ tools.push(webSearchTool);
649
+ }
650
+ const messageId = generateMessageId();
651
+ yield { type: "message:start", id: messageId };
652
+ try {
653
+ const openaiToolOptions = request.providerToolOptions?.openai;
654
+ const toolChoice = openaiToolOptions?.toolChoice && typeof openaiToolOptions.toolChoice === "object" ? {
655
+ type: "function",
656
+ function: {
657
+ name: openaiToolOptions.toolChoice.name
658
+ }
659
+ } : openaiToolOptions?.toolChoice;
660
+ const payload = {
661
+ model: request.config?.model || this.model,
662
+ messages,
663
+ tools: tools.length > 0 ? tools : void 0,
664
+ tool_choice: tools.length > 0 ? toolChoice : void 0,
665
+ parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
666
+ temperature: request.config?.temperature ?? this.config.temperature,
667
+ max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
668
+ stream: true,
669
+ stream_options: { include_usage: true }
670
+ };
671
+ logProviderPayload("openai", "request payload", payload, request.debug);
672
+ const stream = await client.chat.completions.create(payload);
673
+ let currentToolCall = null;
674
+ const collectedCitations = [];
675
+ let citationIndex = 0;
676
+ let usage;
677
+ for await (const chunk of stream) {
678
+ logProviderPayload("openai", "stream chunk", chunk, request.debug);
679
+ if (request.signal?.aborted) {
680
+ break;
681
+ }
682
+ const delta = chunk.choices[0]?.delta;
683
+ const choice = chunk.choices[0];
684
+ if (delta?.content) {
685
+ yield { type: "message:delta", content: delta.content };
686
+ }
687
+ const annotations = delta?.annotations;
688
+ if (annotations && annotations.length > 0) {
689
+ for (const annotation of annotations) {
690
+ if (annotation.type === "url_citation" && annotation.url_citation?.url) {
691
+ citationIndex++;
692
+ const url = annotation.url_citation.url;
693
+ const domain = extractDomain(url);
694
+ collectedCitations.push({
695
+ index: citationIndex,
696
+ url,
697
+ title: annotation.url_citation.title || domain,
698
+ domain,
699
+ favicon: domain ? `https://www.google.com/s2/favicons?domain=${domain}&sz=32` : void 0
700
+ });
701
+ }
702
+ }
703
+ }
704
+ if (delta?.tool_calls) {
705
+ for (const toolCall of delta.tool_calls) {
706
+ if (toolCall.id) {
707
+ if (currentToolCall) {
708
+ yield {
709
+ type: "action:args",
710
+ id: currentToolCall.id,
711
+ args: currentToolCall.arguments
712
+ };
713
+ yield {
714
+ type: "action:end",
715
+ id: currentToolCall.id,
716
+ name: currentToolCall.name
717
+ };
718
+ }
719
+ const tcExtraContent = toolCall.extra_content;
720
+ currentToolCall = {
721
+ id: toolCall.id,
722
+ name: toolCall.function?.name || "",
723
+ arguments: toolCall.function?.arguments || "",
724
+ ...tcExtraContent ? { extra_content: tcExtraContent } : {}
725
+ };
726
+ yield {
727
+ type: "action:start",
728
+ id: currentToolCall.id,
729
+ name: currentToolCall.name,
730
+ ...currentToolCall.extra_content ? { extra_content: currentToolCall.extra_content } : {}
731
+ };
732
+ } else if (currentToolCall && toolCall.function?.arguments) {
733
+ currentToolCall.arguments += toolCall.function.arguments;
734
+ }
735
+ }
736
+ }
737
+ if (chunk.usage) {
738
+ usage = {
739
+ prompt_tokens: chunk.usage.prompt_tokens,
740
+ completion_tokens: chunk.usage.completion_tokens,
741
+ total_tokens: chunk.usage.total_tokens
742
+ };
743
+ }
744
+ if (choice?.finish_reason) {
745
+ if (currentToolCall) {
746
+ yield {
747
+ type: "action:args",
748
+ id: currentToolCall.id,
749
+ args: currentToolCall.arguments
750
+ };
751
+ yield {
752
+ type: "action:end",
753
+ id: currentToolCall.id,
754
+ name: currentToolCall.name
755
+ };
756
+ currentToolCall = null;
757
+ }
758
+ }
759
+ }
760
+ if (collectedCitations.length > 0) {
761
+ const uniqueCitations = deduplicateCitations(collectedCitations);
762
+ yield { type: "citation", citations: uniqueCitations };
763
+ }
764
+ yield { type: "message:end" };
765
+ yield { type: "done", usage };
766
+ } catch (error) {
767
+ yield {
768
+ type: "error",
769
+ message: error instanceof Error ? error.message : "Unknown error",
770
+ code: `${this.provider.toUpperCase()}_ERROR`
771
+ };
772
+ }
773
+ }
774
+ async complete(request) {
775
+ if (this.shouldUseResponsesApi(request)) {
776
+ return this.completeWithResponses(request);
777
+ }
778
+ const client = await this.getClient();
779
+ let messages;
780
+ if (request.rawMessages && request.rawMessages.length > 0) {
781
+ const sanitized = request.rawMessages.map((msg) => {
782
+ if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
783
+ return { ...msg, content: null };
784
+ }
785
+ return msg;
786
+ });
787
+ if (request.systemPrompt && !sanitized.some((message2) => message2.role === "system")) {
788
+ messages = [
789
+ { role: "system", content: request.systemPrompt },
790
+ ...sanitized
791
+ ];
792
+ } else {
793
+ messages = sanitized;
794
+ }
795
+ } else {
796
+ messages = formatMessagesForOpenAI(
797
+ request.messages,
798
+ request.systemPrompt
799
+ );
800
+ }
801
+ const tools = request.actions?.length ? formatTools(request.actions) : [];
802
+ const openaiToolOptions = request.providerToolOptions?.openai;
803
+ const toolChoice = openaiToolOptions?.toolChoice && typeof openaiToolOptions.toolChoice === "object" ? {
804
+ type: "function",
805
+ function: {
806
+ name: openaiToolOptions.toolChoice.name
807
+ }
808
+ } : openaiToolOptions?.toolChoice;
809
+ const payload = {
810
+ model: request.config?.model || this.model,
811
+ messages,
812
+ tools: tools.length > 0 ? tools : void 0,
813
+ tool_choice: tools.length > 0 ? toolChoice : void 0,
814
+ parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
815
+ temperature: request.config?.temperature ?? this.config.temperature,
816
+ max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
817
+ stream: false
818
+ };
819
+ logProviderPayload("openai", "request payload", payload, request.debug);
820
+ const response = await client.chat.completions.create(payload);
821
+ logProviderPayload("openai", "response payload", response, request.debug);
822
+ const choice = response.choices?.[0];
823
+ const message = choice?.message;
824
+ return {
825
+ content: message?.content ?? "",
826
+ toolCalls: message?.tool_calls?.map((toolCall) => ({
827
+ id: toolCall.id ?? generateToolCallId(),
828
+ name: toolCall.function?.name ?? "",
829
+ args: (() => {
830
+ try {
831
+ return JSON.parse(toolCall.function?.arguments ?? "{}");
832
+ } catch {
833
+ return {};
834
+ }
835
+ })(),
836
+ ...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
837
+ })) ?? [],
838
+ usage: response.usage ? {
839
+ promptTokens: response.usage.prompt_tokens,
840
+ completionTokens: response.usage.completion_tokens,
841
+ totalTokens: response.usage.total_tokens
842
+ } : void 0,
843
+ rawResponse: response
844
+ };
845
+ }
846
+ };
847
+ function extractDomain(url) {
848
+ try {
849
+ const parsed = new URL(url);
850
+ return parsed.hostname;
851
+ } catch {
852
+ return "";
853
+ }
854
+ }
855
+ function deduplicateCitations(citations) {
856
+ const seen = /* @__PURE__ */ new Map();
857
+ let index = 0;
858
+ for (const citation of citations) {
859
+ if (!seen.has(citation.url)) {
860
+ index++;
861
+ seen.set(citation.url, { ...citation, index });
862
+ }
863
+ }
864
+ return Array.from(seen.values());
865
+ }
866
+ function createOpenAIAdapter(config) {
867
+ return new OpenAIAdapter(config);
868
+ }
869
+
870
+ // src/providers/types.ts
871
+ function createCallableProvider(providerFn, properties) {
872
+ Object.defineProperty(providerFn, "name", {
873
+ value: properties.name,
874
+ writable: false,
875
+ configurable: true
876
+ });
877
+ Object.assign(providerFn, {
878
+ supportedModels: properties.supportedModels,
879
+ languageModel: providerFn,
880
+ getCapabilities: properties.getCapabilities,
881
+ embeddingModel: properties.embeddingModel
882
+ });
883
+ return providerFn;
884
+ }
885
+
886
+ // src/providers/togetherai/index.ts
887
+ var DEFAULT_CAPABILITIES = {
888
+ vision: true,
889
+ tools: true,
890
+ jsonMode: true,
891
+ maxTokens: 131072
892
+ };
893
+ function createTogetherAI(config = {}) {
894
+ const apiKey = config.apiKey ?? process.env.TOGETHER_API_KEY ?? "";
895
+ const baseUrl = config.baseUrl ?? "https://api.together.xyz/v1";
896
+ const providerFn = (modelId) => {
897
+ return createOpenAIAdapter({
898
+ apiKey,
899
+ model: modelId,
900
+ baseUrl
901
+ });
902
+ };
903
+ const getCapabilities = (_modelId) => {
904
+ return {
905
+ supportsVision: DEFAULT_CAPABILITIES.vision,
906
+ supportsTools: DEFAULT_CAPABILITIES.tools,
907
+ supportsThinking: false,
908
+ supportsStreaming: true,
909
+ supportsPDF: false,
910
+ supportsAudio: false,
911
+ supportsVideo: false,
912
+ maxTokens: DEFAULT_CAPABILITIES.maxTokens,
913
+ supportedImageTypes: ["image/png", "image/jpeg", "image/gif", "image/webp"] ,
914
+ supportsJsonMode: DEFAULT_CAPABILITIES.jsonMode,
915
+ supportsSystemMessages: true
916
+ };
917
+ };
918
+ return createCallableProvider(providerFn, {
919
+ name: "togetherai",
920
+ supportedModels: [],
921
+ getCapabilities
922
+ });
923
+ }
924
+ var createTogetherAIProvider = createTogetherAI;
925
+
926
+ exports.createTogetherAI = createTogetherAI;
927
+ exports.createTogetherAIProvider = createTogetherAIProvider;
203
928
  exports.togetherai = togetherai;
204
929
  //# sourceMappingURL=index.js.map
205
930
  //# sourceMappingURL=index.js.map