@yourgpt/llm-sdk 2.1.5 → 2.1.6

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 (41) hide show
  1. package/dist/adapters/index.d.mts +11 -37
  2. package/dist/adapters/index.d.ts +11 -37
  3. package/dist/adapters/index.js +41 -192
  4. package/dist/adapters/index.mjs +42 -192
  5. package/dist/{base-5n-UuPfS.d.mts → base-D-U61JaB.d.mts} +22 -2
  6. package/dist/{base-Di31iy_8.d.ts → base-iGi9Va6Z.d.ts} +22 -2
  7. package/dist/fallback/index.d.mts +3 -3
  8. package/dist/fallback/index.d.ts +3 -3
  9. package/dist/index.d.mts +5 -5
  10. package/dist/index.d.ts +5 -5
  11. package/dist/index.js +96 -76
  12. package/dist/index.mjs +96 -76
  13. package/dist/providers/anthropic/index.d.mts +2 -2
  14. package/dist/providers/anthropic/index.d.ts +2 -2
  15. package/dist/providers/azure/index.d.mts +2 -2
  16. package/dist/providers/azure/index.d.ts +2 -2
  17. package/dist/providers/azure/index.js +4 -2
  18. package/dist/providers/azure/index.mjs +4 -2
  19. package/dist/providers/google/index.d.mts +2 -2
  20. package/dist/providers/google/index.d.ts +2 -2
  21. package/dist/providers/google/index.js +527 -339
  22. package/dist/providers/google/index.mjs +527 -339
  23. package/dist/providers/ollama/index.d.mts +3 -3
  24. package/dist/providers/ollama/index.d.ts +3 -3
  25. package/dist/providers/openai/index.d.mts +2 -2
  26. package/dist/providers/openai/index.d.ts +2 -2
  27. package/dist/providers/openai/index.js +34 -11
  28. package/dist/providers/openai/index.mjs +34 -11
  29. package/dist/providers/openrouter/index.d.mts +2 -2
  30. package/dist/providers/openrouter/index.d.ts +2 -2
  31. package/dist/providers/openrouter/index.js +34 -11
  32. package/dist/providers/openrouter/index.mjs +34 -11
  33. package/dist/providers/xai/index.d.mts +2 -2
  34. package/dist/providers/xai/index.d.ts +2 -2
  35. package/dist/providers/xai/index.js +355 -46
  36. package/dist/providers/xai/index.mjs +355 -46
  37. package/dist/{types-CNL8ZRne.d.ts → types-38yolWJn.d.ts} +1 -1
  38. package/dist/{types-C0vLXzuw.d.ts → types-BctsnC3g.d.ts} +1 -1
  39. package/dist/{types-BQl1suAv.d.mts → types-D4YfrQJR.d.mts} +1 -1
  40. package/dist/{types-VDgiUvH2.d.mts → types-DRqxMIjF.d.mts} +1 -1
  41. package/package.json +1 -1
@@ -241,6 +241,9 @@ function generateId(prefix = "id") {
241
241
  function generateMessageId() {
242
242
  return generateId("msg");
243
243
  }
244
+ function generateToolCallId() {
245
+ return generateId("call");
246
+ }
244
247
 
245
248
  // src/adapters/base.ts
246
249
  function stringifyForDebug(value) {
@@ -309,6 +312,40 @@ function parameterToJsonSchema(param) {
309
312
  }
310
313
  return schema;
311
314
  }
315
+ function normalizeObjectJsonSchema(schema) {
316
+ if (!schema || typeof schema !== "object") {
317
+ return {
318
+ type: "object",
319
+ properties: {},
320
+ required: [],
321
+ additionalProperties: false
322
+ };
323
+ }
324
+ const normalized = { ...schema };
325
+ const type = normalized.type;
326
+ if (type === "object") {
327
+ const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
328
+ normalized.properties = Object.fromEntries(
329
+ Object.entries(properties).map(([key, value]) => [
330
+ key,
331
+ normalizeObjectJsonSchema(value)
332
+ ])
333
+ );
334
+ const propertyKeys = Object.keys(properties);
335
+ const required = Array.isArray(normalized.required) ? normalized.required.filter(
336
+ (value) => typeof value === "string"
337
+ ) : [];
338
+ normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
339
+ if (normalized.additionalProperties === void 0) {
340
+ normalized.additionalProperties = false;
341
+ }
342
+ } else if (type === "array" && normalized.items && typeof normalized.items === "object") {
343
+ normalized.items = normalizeObjectJsonSchema(
344
+ normalized.items
345
+ );
346
+ }
347
+ return normalized;
348
+ }
312
349
  function formatTools(actions) {
313
350
  return actions.map((action) => ({
314
351
  type: "function",
@@ -385,11 +422,13 @@ function formatMessagesForOpenAI(messages, systemPrompt) {
385
422
  content: messageToOpenAIContent(msg)
386
423
  });
387
424
  } else if (msg.role === "assistant") {
425
+ const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
388
426
  const assistantMsg = {
389
427
  role: "assistant",
390
- content: msg.content
428
+ // Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
429
+ content: hasToolCalls ? msg.content || null : msg.content
391
430
  };
392
- if (msg.tool_calls && msg.tool_calls.length > 0) {
431
+ if (hasToolCalls) {
393
432
  assistantMsg.tool_calls = msg.tool_calls;
394
433
  }
395
434
  formatted.push(assistantMsg);
@@ -404,29 +443,183 @@ function formatMessagesForOpenAI(messages, systemPrompt) {
404
443
  return formatted;
405
444
  }
406
445
 
407
- // src/adapters/xai.ts
408
- var XAI_BASE_URL = "https://api.x.ai/v1";
409
- var XAIAdapter = class {
446
+ // src/adapters/openai.ts
447
+ var OpenAIAdapter = class _OpenAIAdapter {
410
448
  constructor(config) {
411
- this.provider = "xai";
412
449
  this.config = config;
413
- this.model = config.model || "grok-2";
450
+ this.model = config.model || "gpt-4o";
451
+ this.provider = _OpenAIAdapter.resolveProviderName(config.baseUrl);
452
+ }
453
+ static resolveProviderName(baseUrl) {
454
+ if (!baseUrl) return "openai";
455
+ if (baseUrl.includes("generativelanguage.googleapis.com")) return "google";
456
+ if (baseUrl.includes("x.ai")) return "xai";
457
+ if (baseUrl.includes("azure")) return "azure";
458
+ return "openai";
414
459
  }
415
460
  async getClient() {
416
461
  if (!this.client) {
417
462
  const { default: OpenAI } = await import('openai');
418
463
  this.client = new OpenAI({
419
464
  apiKey: this.config.apiKey,
420
- baseURL: this.config.baseUrl || XAI_BASE_URL
465
+ baseURL: this.config.baseUrl
421
466
  });
422
467
  }
423
468
  return this.client;
424
469
  }
470
+ shouldUseResponsesApi(request) {
471
+ return request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false && Array.isArray(request.toolDefinitions) && request.toolDefinitions.length > 0;
472
+ }
473
+ buildResponsesInput(request) {
474
+ const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? request.rawMessages : formatMessagesForOpenAI(request.messages, void 0);
475
+ const input = [];
476
+ for (const message of sourceMessages) {
477
+ if (message.role === "system") {
478
+ continue;
479
+ }
480
+ if (message.role === "assistant") {
481
+ const content = typeof message.content === "string" ? message.content : Array.isArray(message.content) ? message.content : message.content ? JSON.stringify(message.content) : "";
482
+ if (content) {
483
+ input.push({
484
+ type: "message",
485
+ role: "assistant",
486
+ content
487
+ });
488
+ }
489
+ const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
490
+ for (const toolCall of toolCalls) {
491
+ input.push({
492
+ type: "function_call",
493
+ call_id: toolCall.id,
494
+ name: toolCall.function?.name,
495
+ arguments: toolCall.function?.arguments ?? "{}"
496
+ });
497
+ }
498
+ continue;
499
+ }
500
+ if (message.role === "tool") {
501
+ input.push({
502
+ type: "function_call_output",
503
+ call_id: message.tool_call_id,
504
+ output: typeof message.content === "string" ? message.content : JSON.stringify(message.content ?? null)
505
+ });
506
+ continue;
507
+ }
508
+ input.push({
509
+ type: "message",
510
+ role: message.role === "developer" ? "developer" : "user",
511
+ content: typeof message.content === "string" ? message.content : Array.isArray(message.content) ? message.content : JSON.stringify(message.content ?? "")
512
+ });
513
+ }
514
+ return input;
515
+ }
516
+ buildResponsesTools(tools) {
517
+ const nativeTools = tools.filter((tool) => tool.available !== false).map((tool) => ({
518
+ type: "function",
519
+ name: tool.name,
520
+ description: tool.description,
521
+ parameters: normalizeObjectJsonSchema(
522
+ tool.inputSchema ?? {
523
+ type: "object",
524
+ properties: {},
525
+ required: []
526
+ }
527
+ ),
528
+ strict: true,
529
+ defer_loading: tool.deferLoading === true
530
+ }));
531
+ return [{ type: "tool_search" }, ...nativeTools];
532
+ }
533
+ parseResponsesResult(response) {
534
+ const content = typeof response?.output_text === "string" ? response.output_text : "";
535
+ const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => ({
536
+ id: item.call_id ?? item.id ?? generateToolCallId(),
537
+ name: item.name,
538
+ args: (() => {
539
+ try {
540
+ return JSON.parse(item.arguments ?? "{}");
541
+ } catch {
542
+ return {};
543
+ }
544
+ })()
545
+ })) : [];
546
+ return {
547
+ content,
548
+ toolCalls,
549
+ usage: response?.usage ? {
550
+ promptTokens: response.usage.input_tokens ?? 0,
551
+ completionTokens: response.usage.output_tokens ?? 0,
552
+ totalTokens: response.usage.total_tokens ?? (response.usage.input_tokens ?? 0) + (response.usage.output_tokens ?? 0)
553
+ } : void 0,
554
+ rawResponse: response
555
+ };
556
+ }
557
+ async completeWithResponses(request) {
558
+ const client = await this.getClient();
559
+ const openaiToolOptions = request.providerToolOptions?.openai;
560
+ const payload = {
561
+ model: request.config?.model || this.model,
562
+ instructions: request.systemPrompt,
563
+ input: this.buildResponsesInput(request),
564
+ tools: this.buildResponsesTools(request.toolDefinitions ?? []),
565
+ tool_choice: openaiToolOptions?.toolChoice === "required" ? "required" : openaiToolOptions?.toolChoice === "auto" ? "auto" : void 0,
566
+ parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
567
+ temperature: request.config?.temperature ?? this.config.temperature,
568
+ max_output_tokens: request.config?.maxTokens ?? this.config.maxTokens,
569
+ stream: false
570
+ };
571
+ logProviderPayload("openai", "request payload", payload, request.debug);
572
+ const response = await client.responses.create(payload);
573
+ logProviderPayload("openai", "response payload", response, request.debug);
574
+ return this.parseResponsesResult(response);
575
+ }
425
576
  async *stream(request) {
577
+ if (this.shouldUseResponsesApi(request)) {
578
+ const messageId2 = generateMessageId();
579
+ yield { type: "message:start", id: messageId2 };
580
+ try {
581
+ const result = await this.completeWithResponses(request);
582
+ if (result.content) {
583
+ yield { type: "message:delta", content: result.content };
584
+ }
585
+ for (const toolCall of result.toolCalls) {
586
+ yield {
587
+ type: "action:start",
588
+ id: toolCall.id,
589
+ name: toolCall.name
590
+ };
591
+ yield {
592
+ type: "action:args",
593
+ id: toolCall.id,
594
+ args: JSON.stringify(toolCall.args)
595
+ };
596
+ }
597
+ yield { type: "message:end" };
598
+ yield {
599
+ type: "done",
600
+ usage: result.usage ? {
601
+ prompt_tokens: result.usage.promptTokens,
602
+ completion_tokens: result.usage.completionTokens,
603
+ total_tokens: result.usage.totalTokens
604
+ } : void 0
605
+ };
606
+ return;
607
+ } catch (error) {
608
+ yield {
609
+ type: "error",
610
+ message: error instanceof Error ? error.message : "Unknown error",
611
+ code: "OPENAI_RESPONSES_ERROR"
612
+ };
613
+ return;
614
+ }
615
+ }
426
616
  const client = await this.getClient();
427
617
  let messages;
428
618
  if (request.rawMessages && request.rawMessages.length > 0) {
429
619
  const processedMessages = request.rawMessages.map((msg) => {
620
+ if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
621
+ return { ...msg, content: null };
622
+ }
430
623
  const hasAttachments = msg.attachments && Array.isArray(msg.attachments) && msg.attachments.length > 0;
431
624
  if (hasAttachments) {
432
625
  const content = [];
@@ -435,9 +628,13 @@ var XAIAdapter = class {
435
628
  }
436
629
  for (const attachment of msg.attachments) {
437
630
  if (attachment.type === "image") {
438
- let imageUrl = attachment.data;
439
- if (!imageUrl.startsWith("data:")) {
440
- imageUrl = `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
631
+ let imageUrl;
632
+ if (attachment.url) {
633
+ imageUrl = attachment.url;
634
+ } else if (attachment.data) {
635
+ imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
636
+ } else {
637
+ continue;
441
638
  }
442
639
  content.push({
443
640
  type: "image_url",
@@ -468,30 +665,72 @@ var XAIAdapter = class {
468
665
  request.systemPrompt
469
666
  );
470
667
  }
471
- const tools = request.actions?.length ? formatTools(request.actions) : void 0;
668
+ const tools = request.actions?.length ? formatTools(request.actions) : [];
669
+ const webSearchConfig = request.webSearch ?? this.config.webSearch;
670
+ if (webSearchConfig) {
671
+ const webSearchTool = {
672
+ type: "web_search_preview"
673
+ };
674
+ const wsConfig = typeof webSearchConfig === "object" ? webSearchConfig : {};
675
+ if (wsConfig.userLocation) {
676
+ webSearchTool.search_context_size = "medium";
677
+ }
678
+ tools.push(webSearchTool);
679
+ }
472
680
  const messageId = generateMessageId();
473
681
  yield { type: "message:start", id: messageId };
474
682
  try {
683
+ const openaiToolOptions = request.providerToolOptions?.openai;
684
+ const toolChoice = openaiToolOptions?.toolChoice && typeof openaiToolOptions.toolChoice === "object" ? {
685
+ type: "function",
686
+ function: {
687
+ name: openaiToolOptions.toolChoice.name
688
+ }
689
+ } : openaiToolOptions?.toolChoice;
475
690
  const payload = {
476
691
  model: request.config?.model || this.model,
477
692
  messages,
478
- tools,
693
+ tools: tools.length > 0 ? tools : void 0,
694
+ tool_choice: tools.length > 0 ? toolChoice : void 0,
695
+ parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
479
696
  temperature: request.config?.temperature ?? this.config.temperature,
480
697
  max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
481
- stream: true
698
+ stream: true,
699
+ stream_options: { include_usage: true }
482
700
  };
483
- logProviderPayload("xai", "request payload", payload, request.debug);
701
+ logProviderPayload("openai", "request payload", payload, request.debug);
484
702
  const stream = await client.chat.completions.create(payload);
485
703
  let currentToolCall = null;
704
+ const collectedCitations = [];
705
+ let citationIndex = 0;
706
+ let usage;
486
707
  for await (const chunk of stream) {
487
- logProviderPayload("xai", "stream chunk", chunk, request.debug);
708
+ logProviderPayload("openai", "stream chunk", chunk, request.debug);
488
709
  if (request.signal?.aborted) {
489
710
  break;
490
711
  }
491
712
  const delta = chunk.choices[0]?.delta;
713
+ const choice = chunk.choices[0];
492
714
  if (delta?.content) {
493
715
  yield { type: "message:delta", content: delta.content };
494
716
  }
717
+ const annotations = delta?.annotations;
718
+ if (annotations && annotations.length > 0) {
719
+ for (const annotation of annotations) {
720
+ if (annotation.type === "url_citation" && annotation.url_citation?.url) {
721
+ citationIndex++;
722
+ const url = annotation.url_citation.url;
723
+ const domain = extractDomain(url);
724
+ collectedCitations.push({
725
+ index: citationIndex,
726
+ url,
727
+ title: annotation.url_citation.title || domain,
728
+ domain,
729
+ favicon: domain ? `https://www.google.com/s2/favicons?domain=${domain}&sz=32` : void 0
730
+ });
731
+ }
732
+ }
733
+ }
495
734
  if (delta?.tool_calls) {
496
735
  for (const toolCall of delta.tool_calls) {
497
736
  if (toolCall.id) {
@@ -502,22 +741,32 @@ var XAIAdapter = class {
502
741
  args: currentToolCall.arguments
503
742
  };
504
743
  }
744
+ const tcExtraContent = toolCall.extra_content;
505
745
  currentToolCall = {
506
746
  id: toolCall.id,
507
747
  name: toolCall.function?.name || "",
508
- arguments: toolCall.function?.arguments || ""
748
+ arguments: toolCall.function?.arguments || "",
749
+ ...tcExtraContent ? { extra_content: tcExtraContent } : {}
509
750
  };
510
751
  yield {
511
752
  type: "action:start",
512
753
  id: currentToolCall.id,
513
- name: currentToolCall.name
754
+ name: currentToolCall.name,
755
+ ...currentToolCall.extra_content ? { extra_content: currentToolCall.extra_content } : {}
514
756
  };
515
757
  } else if (currentToolCall && toolCall.function?.arguments) {
516
758
  currentToolCall.arguments += toolCall.function.arguments;
517
759
  }
518
760
  }
519
761
  }
520
- if (chunk.choices[0]?.finish_reason) {
762
+ if (chunk.usage) {
763
+ usage = {
764
+ prompt_tokens: chunk.usage.prompt_tokens,
765
+ completion_tokens: chunk.usage.completion_tokens,
766
+ total_tokens: chunk.usage.total_tokens
767
+ };
768
+ }
769
+ if (choice?.finish_reason) {
521
770
  if (currentToolCall) {
522
771
  yield {
523
772
  type: "action:args",
@@ -527,32 +776,40 @@ var XAIAdapter = class {
527
776
  }
528
777
  }
529
778
  }
779
+ if (collectedCitations.length > 0) {
780
+ const uniqueCitations = deduplicateCitations(collectedCitations);
781
+ yield { type: "citation", citations: uniqueCitations };
782
+ }
530
783
  yield { type: "message:end" };
531
- yield { type: "done" };
784
+ yield { type: "done", usage };
532
785
  } catch (error) {
533
786
  yield {
534
787
  type: "error",
535
788
  message: error instanceof Error ? error.message : "Unknown error",
536
- code: "XAI_ERROR"
789
+ code: `${this.provider.toUpperCase()}_ERROR`
537
790
  };
538
791
  }
539
792
  }
540
- /**
541
- * Non-streaming completion (optional, for debugging)
542
- */
543
793
  async complete(request) {
794
+ if (this.shouldUseResponsesApi(request)) {
795
+ return this.completeWithResponses(request);
796
+ }
544
797
  const client = await this.getClient();
545
798
  let messages;
546
799
  if (request.rawMessages && request.rawMessages.length > 0) {
547
- messages = request.rawMessages;
548
- if (request.systemPrompt) {
549
- const hasSystem = messages.some((m) => m.role === "system");
550
- if (!hasSystem) {
551
- messages = [
552
- { role: "system", content: request.systemPrompt },
553
- ...messages
554
- ];
800
+ const sanitized = request.rawMessages.map((msg) => {
801
+ if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
802
+ return { ...msg, content: null };
555
803
  }
804
+ return msg;
805
+ });
806
+ if (request.systemPrompt && !sanitized.some((message2) => message2.role === "system")) {
807
+ messages = [
808
+ { role: "system", content: request.systemPrompt },
809
+ ...sanitized
810
+ ];
811
+ } else {
812
+ messages = sanitized;
556
813
  }
557
814
  } else {
558
815
  messages = formatMessagesForOpenAI(
@@ -560,33 +817,85 @@ var XAIAdapter = class {
560
817
  request.systemPrompt
561
818
  );
562
819
  }
563
- const tools = request.actions?.length ? formatTools(request.actions) : void 0;
820
+ const tools = request.actions?.length ? formatTools(request.actions) : [];
821
+ const openaiToolOptions = request.providerToolOptions?.openai;
822
+ const toolChoice = openaiToolOptions?.toolChoice && typeof openaiToolOptions.toolChoice === "object" ? {
823
+ type: "function",
824
+ function: {
825
+ name: openaiToolOptions.toolChoice.name
826
+ }
827
+ } : openaiToolOptions?.toolChoice;
564
828
  const payload = {
565
829
  model: request.config?.model || this.model,
566
830
  messages,
567
- tools,
831
+ tools: tools.length > 0 ? tools : void 0,
832
+ tool_choice: tools.length > 0 ? toolChoice : void 0,
833
+ parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
568
834
  temperature: request.config?.temperature ?? this.config.temperature,
569
- max_tokens: request.config?.maxTokens ?? this.config.maxTokens
835
+ max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
836
+ stream: false
570
837
  };
571
- logProviderPayload("xai", "request payload", payload, request.debug);
838
+ logProviderPayload("openai", "request payload", payload, request.debug);
572
839
  const response = await client.chat.completions.create(payload);
573
- logProviderPayload("xai", "response payload", response, request.debug);
574
- const choice = response.choices[0];
840
+ logProviderPayload("openai", "response payload", response, request.debug);
841
+ const choice = response.choices?.[0];
575
842
  const message = choice?.message;
576
- const toolCalls = (message?.tool_calls || []).map((tc) => ({
577
- id: tc.id,
578
- name: tc.function.name,
579
- args: JSON.parse(tc.function.arguments || "{}")
580
- }));
581
843
  return {
582
- content: message?.content || "",
583
- toolCalls,
844
+ content: message?.content ?? "",
845
+ toolCalls: message?.tool_calls?.map((toolCall) => ({
846
+ id: toolCall.id ?? generateToolCallId(),
847
+ name: toolCall.function?.name ?? "",
848
+ args: (() => {
849
+ try {
850
+ return JSON.parse(toolCall.function?.arguments ?? "{}");
851
+ } catch {
852
+ return {};
853
+ }
854
+ })(),
855
+ ...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
856
+ })) ?? [],
857
+ usage: response.usage ? {
858
+ promptTokens: response.usage.prompt_tokens,
859
+ completionTokens: response.usage.completion_tokens,
860
+ totalTokens: response.usage.total_tokens
861
+ } : void 0,
584
862
  rawResponse: response
585
863
  };
586
864
  }
587
865
  };
866
+ function extractDomain(url) {
867
+ try {
868
+ const parsed = new URL(url);
869
+ return parsed.hostname;
870
+ } catch {
871
+ return "";
872
+ }
873
+ }
874
+ function deduplicateCitations(citations) {
875
+ const seen = /* @__PURE__ */ new Map();
876
+ let index = 0;
877
+ for (const citation of citations) {
878
+ if (!seen.has(citation.url)) {
879
+ index++;
880
+ seen.set(citation.url, { ...citation, index });
881
+ }
882
+ }
883
+ return Array.from(seen.values());
884
+ }
885
+ function createOpenAIAdapter(config) {
886
+ return new OpenAIAdapter(config);
887
+ }
888
+
889
+ // src/adapters/xai.ts
890
+ var XAI_BASE_URL = "https://api.x.ai/v1";
588
891
  function createXAIAdapter(config) {
589
- return new XAIAdapter(config);
892
+ return createOpenAIAdapter({
893
+ apiKey: config.apiKey,
894
+ model: config.model || "grok-3",
895
+ baseUrl: config.baseUrl || XAI_BASE_URL,
896
+ temperature: config.temperature,
897
+ maxTokens: config.maxTokens
898
+ });
590
899
  }
591
900
 
592
901
  // src/providers/types.ts