@yourgpt/llm-sdk 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +23 -15
  2. package/dist/adapters/index.d.mts +23 -9
  3. package/dist/adapters/index.d.ts +23 -9
  4. package/dist/adapters/index.js.map +1 -1
  5. package/dist/adapters/index.mjs.map +1 -1
  6. package/dist/{base-D_FyHFKj.d.mts → base-CXNMfvXg.d.mts} +10 -2
  7. package/dist/{base-D_FyHFKj.d.ts → base-CXNMfvXg.d.ts} +10 -2
  8. package/dist/index.d.mts +33 -13
  9. package/dist/index.d.ts +33 -13
  10. package/dist/index.js +160 -177
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +160 -177
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/providers/anthropic/index.d.mts +2 -2
  15. package/dist/providers/anthropic/index.d.ts +2 -2
  16. package/dist/providers/anthropic/index.js.map +1 -1
  17. package/dist/providers/anthropic/index.mjs.map +1 -1
  18. package/dist/providers/azure/index.d.mts +2 -2
  19. package/dist/providers/azure/index.d.ts +2 -2
  20. package/dist/providers/azure/index.js.map +1 -1
  21. package/dist/providers/azure/index.mjs.map +1 -1
  22. package/dist/providers/google/index.d.mts +23 -10
  23. package/dist/providers/google/index.d.ts +23 -10
  24. package/dist/providers/google/index.js +160 -177
  25. package/dist/providers/google/index.js.map +1 -1
  26. package/dist/providers/google/index.mjs +160 -177
  27. package/dist/providers/google/index.mjs.map +1 -1
  28. package/dist/providers/ollama/index.d.mts +2 -2
  29. package/dist/providers/ollama/index.d.ts +2 -2
  30. package/dist/providers/ollama/index.js.map +1 -1
  31. package/dist/providers/ollama/index.mjs.map +1 -1
  32. package/dist/providers/openai/index.d.mts +2 -2
  33. package/dist/providers/openai/index.d.ts +2 -2
  34. package/dist/providers/openai/index.js.map +1 -1
  35. package/dist/providers/openai/index.mjs.map +1 -1
  36. package/dist/providers/xai/index.d.mts +2 -2
  37. package/dist/providers/xai/index.d.ts +2 -2
  38. package/dist/providers/xai/index.js.map +1 -1
  39. package/dist/providers/xai/index.mjs.map +1 -1
  40. package/dist/{types-BBCZ3Fxy.d.mts → types-B8rxpnYi.d.mts} +1 -1
  41. package/dist/{types-DcoCaVVC.d.ts → types-CrQftISG.d.ts} +1 -1
  42. package/package.json +3 -7
package/dist/index.mjs CHANGED
@@ -1391,6 +1391,21 @@ function formatMessagesForXAI(messages) {
1391
1391
 
1392
1392
  // src/providers/google/provider.ts
1393
1393
  var GOOGLE_MODELS = {
1394
+ // Gemini 2.5 (Experimental)
1395
+ "gemini-2.5-pro-preview-05-06": {
1396
+ vision: true,
1397
+ tools: true,
1398
+ audio: true,
1399
+ video: true,
1400
+ maxTokens: 1048576
1401
+ },
1402
+ "gemini-2.5-flash-preview-05-20": {
1403
+ vision: true,
1404
+ tools: true,
1405
+ audio: true,
1406
+ video: true,
1407
+ maxTokens: 1048576
1408
+ },
1394
1409
  // Gemini 2.0
1395
1410
  "gemini-2.0-flash": {
1396
1411
  vision: true,
@@ -1406,6 +1421,13 @@ var GOOGLE_MODELS = {
1406
1421
  video: true,
1407
1422
  maxTokens: 1048576
1408
1423
  },
1424
+ "gemini-2.0-flash-lite": {
1425
+ vision: true,
1426
+ tools: true,
1427
+ audio: false,
1428
+ video: false,
1429
+ maxTokens: 1048576
1430
+ },
1409
1431
  "gemini-2.0-flash-thinking-exp": {
1410
1432
  vision: true,
1411
1433
  tools: false,
@@ -1452,11 +1474,15 @@ var GOOGLE_MODELS = {
1452
1474
  };
1453
1475
  function google(modelId, options = {}) {
1454
1476
  const apiKey = options.apiKey ?? process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;
1477
+ const baseURL = options.baseURL ?? "https://generativelanguage.googleapis.com/v1beta/openai/";
1455
1478
  let client = null;
1456
1479
  async function getClient() {
1457
1480
  if (!client) {
1458
- const { GoogleGenerativeAI } = await import('@google/generative-ai');
1459
- client = new GoogleGenerativeAI(apiKey);
1481
+ const { default: OpenAI } = await import('openai');
1482
+ client = new OpenAI({
1483
+ apiKey,
1484
+ baseURL
1485
+ });
1460
1486
  }
1461
1487
  return client;
1462
1488
  }
@@ -1476,219 +1502,176 @@ function google(modelId, options = {}) {
1476
1502
  },
1477
1503
  async doGenerate(params) {
1478
1504
  const client2 = await getClient();
1479
- const model = client2.getGenerativeModel({
1505
+ const messages = formatMessagesForGoogle(params.messages);
1506
+ const response = await client2.chat.completions.create({
1480
1507
  model: modelId,
1481
- safetySettings: options.safetySettings
1508
+ messages,
1509
+ tools: params.tools,
1510
+ temperature: params.temperature,
1511
+ max_tokens: params.maxTokens
1482
1512
  });
1483
- const { systemInstruction, contents } = formatMessagesForGemini(
1484
- params.messages
1513
+ const choice = response.choices[0];
1514
+ const message = choice.message;
1515
+ const toolCalls = (message.tool_calls ?? []).map(
1516
+ (tc) => ({
1517
+ id: tc.id,
1518
+ name: tc.function.name,
1519
+ args: JSON.parse(tc.function.arguments || "{}")
1520
+ })
1485
1521
  );
1486
- const chat = model.startChat({
1487
- history: contents.slice(0, -1),
1488
- systemInstruction: systemInstruction ? { parts: [{ text: systemInstruction }] } : void 0,
1489
- tools: params.tools ? [{ functionDeclarations: formatToolsForGemini(params.tools) }] : void 0,
1490
- generationConfig: {
1491
- temperature: params.temperature,
1492
- maxOutputTokens: params.maxTokens
1493
- }
1494
- });
1495
- const lastMessage = contents[contents.length - 1];
1496
- const result = await chat.sendMessage(lastMessage.parts);
1497
- const response = result.response;
1498
- let text = "";
1499
- const toolCalls = [];
1500
- let toolCallIndex = 0;
1501
- const candidate = response.candidates?.[0];
1502
- if (candidate?.content?.parts) {
1503
- for (const part of candidate.content.parts) {
1504
- if ("text" in part && part.text) {
1505
- text += part.text;
1506
- }
1507
- if ("functionCall" in part && part.functionCall) {
1508
- toolCalls.push({
1509
- id: `call_${toolCallIndex++}`,
1510
- name: part.functionCall.name,
1511
- args: part.functionCall.args || {}
1512
- });
1513
- }
1514
- }
1515
- }
1516
1522
  return {
1517
- text,
1523
+ text: message.content ?? "",
1518
1524
  toolCalls,
1519
- finishReason: mapFinishReason4(candidate?.finishReason),
1525
+ finishReason: mapFinishReason4(choice.finish_reason),
1520
1526
  usage: {
1521
- promptTokens: response.usageMetadata?.promptTokenCount ?? 0,
1522
- completionTokens: response.usageMetadata?.candidatesTokenCount ?? 0,
1523
- totalTokens: response.usageMetadata?.totalTokenCount ?? 0
1527
+ promptTokens: response.usage?.prompt_tokens ?? 0,
1528
+ completionTokens: response.usage?.completion_tokens ?? 0,
1529
+ totalTokens: response.usage?.total_tokens ?? 0
1524
1530
  },
1525
1531
  rawResponse: response
1526
1532
  };
1527
1533
  },
1528
1534
  async *doStream(params) {
1529
1535
  const client2 = await getClient();
1530
- const model = client2.getGenerativeModel({
1536
+ const messages = formatMessagesForGoogle(params.messages);
1537
+ const stream = await client2.chat.completions.create({
1531
1538
  model: modelId,
1532
- safetySettings: options.safetySettings
1539
+ messages,
1540
+ tools: params.tools,
1541
+ temperature: params.temperature,
1542
+ max_tokens: params.maxTokens,
1543
+ stream: true
1533
1544
  });
1534
- const { systemInstruction, contents } = formatMessagesForGemini(
1535
- params.messages
1536
- );
1537
- const chat = model.startChat({
1538
- history: contents.slice(0, -1),
1539
- systemInstruction: systemInstruction ? { parts: [{ text: systemInstruction }] } : void 0,
1540
- tools: params.tools ? [{ functionDeclarations: formatToolsForGemini(params.tools) }] : void 0,
1541
- generationConfig: {
1542
- temperature: params.temperature,
1543
- maxOutputTokens: params.maxTokens
1545
+ let currentToolCall = null;
1546
+ let totalPromptTokens = 0;
1547
+ let totalCompletionTokens = 0;
1548
+ for await (const chunk of stream) {
1549
+ if (params.signal?.aborted) {
1550
+ yield { type: "error", error: new Error("Aborted") };
1551
+ return;
1544
1552
  }
1545
- });
1546
- const lastMessage = contents[contents.length - 1];
1547
- const result = await chat.sendMessageStream(lastMessage.parts);
1548
- let toolCallIndex = 0;
1549
- let promptTokens = 0;
1550
- let completionTokens = 0;
1551
- try {
1552
- for await (const chunk of result.stream) {
1553
- if (params.signal?.aborted) {
1554
- yield { type: "error", error: new Error("Aborted") };
1555
- return;
1556
- }
1557
- const candidate = chunk.candidates?.[0];
1558
- if (!candidate?.content?.parts) continue;
1559
- for (const part of candidate.content.parts) {
1560
- if ("text" in part && part.text) {
1561
- yield { type: "text-delta", text: part.text };
1562
- }
1563
- if ("functionCall" in part && part.functionCall) {
1564
- yield {
1565
- type: "tool-call",
1566
- toolCall: {
1567
- id: `call_${toolCallIndex++}`,
1568
- name: part.functionCall.name,
1569
- args: part.functionCall.args || {}
1570
- }
1553
+ const choice = chunk.choices[0];
1554
+ const delta = choice?.delta;
1555
+ if (delta?.content) {
1556
+ yield { type: "text-delta", text: delta.content };
1557
+ }
1558
+ if (delta?.tool_calls) {
1559
+ for (const tc of delta.tool_calls) {
1560
+ if (tc.id) {
1561
+ if (currentToolCall) {
1562
+ yield {
1563
+ type: "tool-call",
1564
+ toolCall: {
1565
+ id: currentToolCall.id,
1566
+ name: currentToolCall.name,
1567
+ args: JSON.parse(currentToolCall.arguments || "{}")
1568
+ }
1569
+ };
1570
+ }
1571
+ currentToolCall = {
1572
+ id: tc.id,
1573
+ name: tc.function?.name ?? "",
1574
+ arguments: tc.function?.arguments ?? ""
1571
1575
  };
1576
+ } else if (currentToolCall && tc.function?.arguments) {
1577
+ currentToolCall.arguments += tc.function.arguments;
1572
1578
  }
1573
1579
  }
1574
- if (chunk.usageMetadata) {
1575
- promptTokens = chunk.usageMetadata.promptTokenCount ?? 0;
1576
- completionTokens = chunk.usageMetadata.candidatesTokenCount ?? 0;
1577
- }
1578
- if (candidate.finishReason) {
1580
+ }
1581
+ if (choice?.finish_reason) {
1582
+ if (currentToolCall) {
1579
1583
  yield {
1580
- type: "finish",
1581
- finishReason: mapFinishReason4(candidate.finishReason),
1582
- usage: {
1583
- promptTokens,
1584
- completionTokens,
1585
- totalTokens: promptTokens + completionTokens
1584
+ type: "tool-call",
1585
+ toolCall: {
1586
+ id: currentToolCall.id,
1587
+ name: currentToolCall.name,
1588
+ args: JSON.parse(currentToolCall.arguments || "{}")
1586
1589
  }
1587
1590
  };
1591
+ currentToolCall = null;
1592
+ }
1593
+ if (chunk.usage) {
1594
+ totalPromptTokens = chunk.usage.prompt_tokens;
1595
+ totalCompletionTokens = chunk.usage.completion_tokens;
1588
1596
  }
1597
+ yield {
1598
+ type: "finish",
1599
+ finishReason: mapFinishReason4(choice.finish_reason),
1600
+ usage: {
1601
+ promptTokens: totalPromptTokens,
1602
+ completionTokens: totalCompletionTokens,
1603
+ totalTokens: totalPromptTokens + totalCompletionTokens
1604
+ }
1605
+ };
1589
1606
  }
1590
- } catch (error) {
1591
- yield {
1592
- type: "error",
1593
- error: error instanceof Error ? error : new Error(String(error))
1594
- };
1595
1607
  }
1596
1608
  }
1597
1609
  };
1598
1610
  }
1599
1611
  function mapFinishReason4(reason) {
1600
1612
  switch (reason) {
1601
- case "STOP":
1613
+ case "stop":
1602
1614
  return "stop";
1603
- case "MAX_TOKENS":
1615
+ case "length":
1604
1616
  return "length";
1605
- case "SAFETY":
1617
+ case "tool_calls":
1618
+ case "function_call":
1619
+ return "tool-calls";
1620
+ case "content_filter":
1606
1621
  return "content-filter";
1607
1622
  default:
1608
1623
  return "unknown";
1609
1624
  }
1610
1625
  }
1611
- function formatMessagesForGemini(messages) {
1612
- let systemInstruction = "";
1613
- const contents = [];
1614
- for (const msg of messages) {
1615
- if (msg.role === "system") {
1616
- systemInstruction += (systemInstruction ? "\n" : "") + msg.content;
1617
- continue;
1618
- }
1619
- const parts = [];
1620
- if (msg.role === "user") {
1621
- if (typeof msg.content === "string") {
1622
- parts.push({ text: msg.content });
1623
- } else {
1624
- for (const part of msg.content) {
1625
- if (part.type === "text") {
1626
- parts.push({ text: part.text });
1627
- } else if (part.type === "image") {
1628
- const imageData = typeof part.image === "string" ? part.image : Buffer.from(part.image).toString("base64");
1629
- const base64 = imageData.startsWith("data:") ? imageData.split(",")[1] : imageData;
1630
- parts.push({
1631
- inlineData: {
1632
- mimeType: part.mimeType ?? "image/png",
1633
- data: base64
1634
- }
1635
- });
1636
- }
1626
+ function formatMessagesForGoogle(messages) {
1627
+ return messages.map((msg) => {
1628
+ switch (msg.role) {
1629
+ case "system":
1630
+ return { role: "system", content: msg.content };
1631
+ case "user":
1632
+ if (typeof msg.content === "string") {
1633
+ return { role: "user", content: msg.content };
1637
1634
  }
1638
- }
1639
- contents.push({ role: "user", parts });
1640
- } else if (msg.role === "assistant") {
1641
- if (msg.content) {
1642
- parts.push({ text: msg.content });
1643
- }
1644
- if (msg.toolCalls?.length) {
1645
- for (const tc of msg.toolCalls) {
1646
- parts.push({
1647
- functionCall: {
1635
+ return {
1636
+ role: "user",
1637
+ content: msg.content.map((part) => {
1638
+ if (part.type === "text") {
1639
+ return { type: "text", text: part.text };
1640
+ }
1641
+ if (part.type === "image") {
1642
+ const imageData = typeof part.image === "string" ? part.image : Buffer.from(part.image).toString("base64");
1643
+ const url = imageData.startsWith("data:") ? imageData : `data:${part.mimeType ?? "image/png"};base64,${imageData}`;
1644
+ return { type: "image_url", image_url: { url, detail: "auto" } };
1645
+ }
1646
+ return { type: "text", text: "" };
1647
+ })
1648
+ };
1649
+ case "assistant":
1650
+ const assistantMsg = {
1651
+ role: "assistant",
1652
+ content: msg.content
1653
+ };
1654
+ if (msg.toolCalls && msg.toolCalls.length > 0) {
1655
+ assistantMsg.tool_calls = msg.toolCalls.map((tc) => ({
1656
+ id: tc.id,
1657
+ type: "function",
1658
+ function: {
1648
1659
  name: tc.name,
1649
- args: tc.args
1660
+ arguments: JSON.stringify(tc.args)
1650
1661
  }
1651
- });
1662
+ }));
1652
1663
  }
1653
- }
1654
- if (parts.length > 0) {
1655
- contents.push({ role: "model", parts });
1656
- }
1657
- } else if (msg.role === "tool") {
1658
- contents.push({
1659
- role: "user",
1660
- parts: [
1661
- {
1662
- functionResponse: {
1663
- name: "tool",
1664
- // Gemini doesn't track by ID
1665
- response: JSON.parse(msg.content || "{}")
1666
- }
1667
- }
1668
- ]
1669
- });
1670
- }
1671
- }
1672
- if (contents.length === 0 || contents[0].role !== "user") {
1673
- contents.unshift({ role: "user", parts: [{ text: "" }] });
1674
- }
1675
- const merged = [];
1676
- for (const content of contents) {
1677
- const last = merged[merged.length - 1];
1678
- if (last && last.role === content.role) {
1679
- last.parts.push(...content.parts);
1680
- } else {
1681
- merged.push({ ...content, parts: [...content.parts] });
1664
+ return assistantMsg;
1665
+ case "tool":
1666
+ return {
1667
+ role: "tool",
1668
+ tool_call_id: msg.toolCallId,
1669
+ content: msg.content
1670
+ };
1671
+ default:
1672
+ return msg;
1682
1673
  }
1683
- }
1684
- return { systemInstruction, contents: merged };
1685
- }
1686
- function formatToolsForGemini(tools) {
1687
- return tools.map((t) => ({
1688
- name: t.function.name,
1689
- description: t.function.description,
1690
- parameters: t.function.parameters
1691
- }));
1674
+ });
1692
1675
  }
1693
1676
 
1694
1677
  // src/adapters/base.ts
@@ -2594,7 +2577,7 @@ function messageToGeminiContent(msg) {
2594
2577
  parts
2595
2578
  };
2596
2579
  }
2597
- function formatToolsForGemini2(actions) {
2580
+ function formatToolsForGemini(actions) {
2598
2581
  if (!actions || actions.length === 0) return void 0;
2599
2582
  return {
2600
2583
  functionDeclarations: actions.map((action) => ({
@@ -2680,7 +2663,7 @@ var GoogleAdapter = class {
2680
2663
  mergedContents.push({ ...content, parts: [...content.parts] });
2681
2664
  }
2682
2665
  }
2683
- const tools = formatToolsForGemini2(request.actions);
2666
+ const tools = formatToolsForGemini(request.actions);
2684
2667
  const messageId = generateMessageId();
2685
2668
  yield { type: "message:start", id: messageId };
2686
2669
  try {
@@ -2786,7 +2769,7 @@ var GoogleAdapter = class {
2786
2769
  mergedContents.push({ ...content, parts: [...content.parts] });
2787
2770
  }
2788
2771
  }
2789
- const tools = formatToolsForGemini2(request.actions);
2772
+ const tools = formatToolsForGemini(request.actions);
2790
2773
  const chat = model.startChat({
2791
2774
  history: mergedContents.slice(0, -1),
2792
2775
  systemInstruction: systemInstruction ? { parts: [{ text: systemInstruction }] } : void 0,