@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.
- package/dist/adapters/index.d.mts +11 -37
- package/dist/adapters/index.d.ts +11 -37
- package/dist/adapters/index.js +41 -192
- package/dist/adapters/index.mjs +42 -192
- package/dist/{base-5n-UuPfS.d.mts → base-D-U61JaB.d.mts} +22 -2
- package/dist/{base-Di31iy_8.d.ts → base-iGi9Va6Z.d.ts} +22 -2
- package/dist/fallback/index.d.mts +3 -3
- package/dist/fallback/index.d.ts +3 -3
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +96 -76
- package/dist/index.mjs +96 -76
- package/dist/providers/anthropic/index.d.mts +2 -2
- package/dist/providers/anthropic/index.d.ts +2 -2
- package/dist/providers/azure/index.d.mts +2 -2
- package/dist/providers/azure/index.d.ts +2 -2
- package/dist/providers/azure/index.js +4 -2
- package/dist/providers/azure/index.mjs +4 -2
- package/dist/providers/google/index.d.mts +2 -2
- package/dist/providers/google/index.d.ts +2 -2
- package/dist/providers/google/index.js +527 -339
- package/dist/providers/google/index.mjs +527 -339
- package/dist/providers/ollama/index.d.mts +3 -3
- package/dist/providers/ollama/index.d.ts +3 -3
- package/dist/providers/openai/index.d.mts +2 -2
- package/dist/providers/openai/index.d.ts +2 -2
- package/dist/providers/openai/index.js +34 -11
- package/dist/providers/openai/index.mjs +34 -11
- package/dist/providers/openrouter/index.d.mts +2 -2
- package/dist/providers/openrouter/index.d.ts +2 -2
- package/dist/providers/openrouter/index.js +34 -11
- package/dist/providers/openrouter/index.mjs +34 -11
- package/dist/providers/xai/index.d.mts +2 -2
- package/dist/providers/xai/index.d.ts +2 -2
- package/dist/providers/xai/index.js +355 -46
- package/dist/providers/xai/index.mjs +355 -46
- package/dist/{types-CNL8ZRne.d.ts → types-38yolWJn.d.ts} +1 -1
- package/dist/{types-C0vLXzuw.d.ts → types-BctsnC3g.d.ts} +1 -1
- package/dist/{types-BQl1suAv.d.mts → types-D4YfrQJR.d.mts} +1 -1
- package/dist/{types-VDgiUvH2.d.mts → types-DRqxMIjF.d.mts} +1 -1
- 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:
|
|
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 (
|
|
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/
|
|
408
|
-
var
|
|
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 || "
|
|
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
|
|
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
|
|
439
|
-
if (
|
|
440
|
-
imageUrl =
|
|
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) :
|
|
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("
|
|
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("
|
|
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.
|
|
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:
|
|
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
|
-
|
|
548
|
-
|
|
549
|
-
|
|
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) :
|
|
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("
|
|
838
|
+
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
572
839
|
const response = await client.chat.completions.create(payload);
|
|
573
|
-
logProviderPayload("
|
|
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
|
|
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
|