@yourgpt/llm-sdk 1.0.0 → 1.1.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.
- package/LICENSE +21 -0
- package/README.md +23 -15
- package/dist/index.js +160 -177
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +160 -177
- package/dist/index.mjs.map +1 -1
- package/dist/providers/google/index.d.mts +21 -8
- package/dist/providers/google/index.d.ts +21 -8
- package/dist/providers/google/index.js +160 -177
- package/dist/providers/google/index.js.map +1 -1
- package/dist/providers/google/index.mjs +160 -177
- package/dist/providers/google/index.mjs.map +1 -1
- package/package.json +12 -16
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 YourGPT
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -5,7 +5,13 @@ Multi-provider LLM SDK with streaming. One API, any provider.
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @yourgpt/llm-sdk
|
|
8
|
+
npm install @yourgpt/llm-sdk openai
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For Anthropic, install `@anthropic-ai/sdk` instead:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @yourgpt/llm-sdk @anthropic-ai/sdk
|
|
9
15
|
```
|
|
10
16
|
|
|
11
17
|
## Quick Start
|
|
@@ -18,7 +24,7 @@ export async function POST(req: Request) {
|
|
|
18
24
|
const { messages } = await req.json();
|
|
19
25
|
|
|
20
26
|
const result = await streamText({
|
|
21
|
-
model: openai("gpt-
|
|
27
|
+
model: openai("gpt-4o"),
|
|
22
28
|
system: "You are a helpful assistant.",
|
|
23
29
|
messages,
|
|
24
30
|
});
|
|
@@ -36,16 +42,16 @@ import { google } from "@yourgpt/llm-sdk/google";
|
|
|
36
42
|
import { xai } from "@yourgpt/llm-sdk/xai";
|
|
37
43
|
|
|
38
44
|
// OpenAI
|
|
39
|
-
await streamText({ model: openai("gpt-
|
|
45
|
+
await streamText({ model: openai("gpt-4o"), messages });
|
|
40
46
|
|
|
41
47
|
// Anthropic
|
|
42
48
|
await streamText({ model: anthropic("claude-sonnet-4-20250514"), messages });
|
|
43
49
|
|
|
44
|
-
// Google
|
|
50
|
+
// Google Gemini (uses OpenAI-compatible API)
|
|
45
51
|
await streamText({ model: google("gemini-2.0-flash"), messages });
|
|
46
52
|
|
|
47
|
-
// xAI
|
|
48
|
-
await streamText({ model: xai("grok-3"), messages });
|
|
53
|
+
// xAI Grok (uses OpenAI-compatible API)
|
|
54
|
+
await streamText({ model: xai("grok-3-fast-beta"), messages });
|
|
49
55
|
```
|
|
50
56
|
|
|
51
57
|
## Server-Side Tools
|
|
@@ -56,7 +62,7 @@ import { openai } from "@yourgpt/llm-sdk/openai";
|
|
|
56
62
|
import { z } from "zod";
|
|
57
63
|
|
|
58
64
|
const result = await streamText({
|
|
59
|
-
model: openai("gpt-
|
|
65
|
+
model: openai("gpt-4o"),
|
|
60
66
|
messages,
|
|
61
67
|
tools: {
|
|
62
68
|
getWeather: tool({
|
|
@@ -77,14 +83,16 @@ return result.toDataStreamResponse();
|
|
|
77
83
|
|
|
78
84
|
## Supported Providers
|
|
79
85
|
|
|
80
|
-
| Provider | Import |
|
|
81
|
-
| ------------- | ---------------------------- |
|
|
82
|
-
| OpenAI | `@yourgpt/llm-sdk/openai` |
|
|
83
|
-
| Anthropic | `@yourgpt/llm-sdk/anthropic` |
|
|
84
|
-
| Google Gemini | `@yourgpt/llm-sdk/google` |
|
|
85
|
-
| xAI (Grok) | `@yourgpt/llm-sdk/xai` |
|
|
86
|
-
| Ollama | `@yourgpt/llm-sdk/ollama` |
|
|
87
|
-
| Azure OpenAI | `@yourgpt/llm-sdk/azure` |
|
|
86
|
+
| Provider | Import | SDK Required |
|
|
87
|
+
| ------------- | ---------------------------- | ------------------- |
|
|
88
|
+
| OpenAI | `@yourgpt/llm-sdk/openai` | `openai` |
|
|
89
|
+
| Anthropic | `@yourgpt/llm-sdk/anthropic` | `@anthropic-ai/sdk` |
|
|
90
|
+
| Google Gemini | `@yourgpt/llm-sdk/google` | `openai` |
|
|
91
|
+
| xAI (Grok) | `@yourgpt/llm-sdk/xai` | `openai` |
|
|
92
|
+
| Ollama | `@yourgpt/llm-sdk/ollama` | `openai` |
|
|
93
|
+
| Azure OpenAI | `@yourgpt/llm-sdk/azure` | `openai` |
|
|
94
|
+
|
|
95
|
+
> **Note:** OpenAI, Google, xAI, Ollama, and Azure all use the `openai` SDK because they have OpenAI-compatible APIs. Only Anthropic requires its native SDK for full feature support.
|
|
88
96
|
|
|
89
97
|
## Documentation
|
|
90
98
|
|
package/dist/index.js
CHANGED
|
@@ -1393,6 +1393,21 @@ function formatMessagesForXAI(messages) {
|
|
|
1393
1393
|
|
|
1394
1394
|
// src/providers/google/provider.ts
|
|
1395
1395
|
var GOOGLE_MODELS = {
|
|
1396
|
+
// Gemini 2.5 (Experimental)
|
|
1397
|
+
"gemini-2.5-pro-preview-05-06": {
|
|
1398
|
+
vision: true,
|
|
1399
|
+
tools: true,
|
|
1400
|
+
audio: true,
|
|
1401
|
+
video: true,
|
|
1402
|
+
maxTokens: 1048576
|
|
1403
|
+
},
|
|
1404
|
+
"gemini-2.5-flash-preview-05-20": {
|
|
1405
|
+
vision: true,
|
|
1406
|
+
tools: true,
|
|
1407
|
+
audio: true,
|
|
1408
|
+
video: true,
|
|
1409
|
+
maxTokens: 1048576
|
|
1410
|
+
},
|
|
1396
1411
|
// Gemini 2.0
|
|
1397
1412
|
"gemini-2.0-flash": {
|
|
1398
1413
|
vision: true,
|
|
@@ -1408,6 +1423,13 @@ var GOOGLE_MODELS = {
|
|
|
1408
1423
|
video: true,
|
|
1409
1424
|
maxTokens: 1048576
|
|
1410
1425
|
},
|
|
1426
|
+
"gemini-2.0-flash-lite": {
|
|
1427
|
+
vision: true,
|
|
1428
|
+
tools: true,
|
|
1429
|
+
audio: false,
|
|
1430
|
+
video: false,
|
|
1431
|
+
maxTokens: 1048576
|
|
1432
|
+
},
|
|
1411
1433
|
"gemini-2.0-flash-thinking-exp": {
|
|
1412
1434
|
vision: true,
|
|
1413
1435
|
tools: false,
|
|
@@ -1454,11 +1476,15 @@ var GOOGLE_MODELS = {
|
|
|
1454
1476
|
};
|
|
1455
1477
|
function google(modelId, options = {}) {
|
|
1456
1478
|
const apiKey = options.apiKey ?? process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;
|
|
1479
|
+
const baseURL = options.baseURL ?? "https://generativelanguage.googleapis.com/v1beta/openai/";
|
|
1457
1480
|
let client = null;
|
|
1458
1481
|
async function getClient() {
|
|
1459
1482
|
if (!client) {
|
|
1460
|
-
const {
|
|
1461
|
-
client = new
|
|
1483
|
+
const { default: OpenAI } = await import('openai');
|
|
1484
|
+
client = new OpenAI({
|
|
1485
|
+
apiKey,
|
|
1486
|
+
baseURL
|
|
1487
|
+
});
|
|
1462
1488
|
}
|
|
1463
1489
|
return client;
|
|
1464
1490
|
}
|
|
@@ -1478,219 +1504,176 @@ function google(modelId, options = {}) {
|
|
|
1478
1504
|
},
|
|
1479
1505
|
async doGenerate(params) {
|
|
1480
1506
|
const client2 = await getClient();
|
|
1481
|
-
const
|
|
1507
|
+
const messages = formatMessagesForGoogle(params.messages);
|
|
1508
|
+
const response = await client2.chat.completions.create({
|
|
1482
1509
|
model: modelId,
|
|
1483
|
-
|
|
1510
|
+
messages,
|
|
1511
|
+
tools: params.tools,
|
|
1512
|
+
temperature: params.temperature,
|
|
1513
|
+
max_tokens: params.maxTokens
|
|
1484
1514
|
});
|
|
1485
|
-
const
|
|
1486
|
-
|
|
1515
|
+
const choice = response.choices[0];
|
|
1516
|
+
const message = choice.message;
|
|
1517
|
+
const toolCalls = (message.tool_calls ?? []).map(
|
|
1518
|
+
(tc) => ({
|
|
1519
|
+
id: tc.id,
|
|
1520
|
+
name: tc.function.name,
|
|
1521
|
+
args: JSON.parse(tc.function.arguments || "{}")
|
|
1522
|
+
})
|
|
1487
1523
|
);
|
|
1488
|
-
const chat = model.startChat({
|
|
1489
|
-
history: contents.slice(0, -1),
|
|
1490
|
-
systemInstruction: systemInstruction ? { parts: [{ text: systemInstruction }] } : void 0,
|
|
1491
|
-
tools: params.tools ? [{ functionDeclarations: formatToolsForGemini(params.tools) }] : void 0,
|
|
1492
|
-
generationConfig: {
|
|
1493
|
-
temperature: params.temperature,
|
|
1494
|
-
maxOutputTokens: params.maxTokens
|
|
1495
|
-
}
|
|
1496
|
-
});
|
|
1497
|
-
const lastMessage = contents[contents.length - 1];
|
|
1498
|
-
const result = await chat.sendMessage(lastMessage.parts);
|
|
1499
|
-
const response = result.response;
|
|
1500
|
-
let text = "";
|
|
1501
|
-
const toolCalls = [];
|
|
1502
|
-
let toolCallIndex = 0;
|
|
1503
|
-
const candidate = response.candidates?.[0];
|
|
1504
|
-
if (candidate?.content?.parts) {
|
|
1505
|
-
for (const part of candidate.content.parts) {
|
|
1506
|
-
if ("text" in part && part.text) {
|
|
1507
|
-
text += part.text;
|
|
1508
|
-
}
|
|
1509
|
-
if ("functionCall" in part && part.functionCall) {
|
|
1510
|
-
toolCalls.push({
|
|
1511
|
-
id: `call_${toolCallIndex++}`,
|
|
1512
|
-
name: part.functionCall.name,
|
|
1513
|
-
args: part.functionCall.args || {}
|
|
1514
|
-
});
|
|
1515
|
-
}
|
|
1516
|
-
}
|
|
1517
|
-
}
|
|
1518
1524
|
return {
|
|
1519
|
-
text,
|
|
1525
|
+
text: message.content ?? "",
|
|
1520
1526
|
toolCalls,
|
|
1521
|
-
finishReason: mapFinishReason4(
|
|
1527
|
+
finishReason: mapFinishReason4(choice.finish_reason),
|
|
1522
1528
|
usage: {
|
|
1523
|
-
promptTokens: response.
|
|
1524
|
-
completionTokens: response.
|
|
1525
|
-
totalTokens: response.
|
|
1529
|
+
promptTokens: response.usage?.prompt_tokens ?? 0,
|
|
1530
|
+
completionTokens: response.usage?.completion_tokens ?? 0,
|
|
1531
|
+
totalTokens: response.usage?.total_tokens ?? 0
|
|
1526
1532
|
},
|
|
1527
1533
|
rawResponse: response
|
|
1528
1534
|
};
|
|
1529
1535
|
},
|
|
1530
1536
|
async *doStream(params) {
|
|
1531
1537
|
const client2 = await getClient();
|
|
1532
|
-
const
|
|
1538
|
+
const messages = formatMessagesForGoogle(params.messages);
|
|
1539
|
+
const stream = await client2.chat.completions.create({
|
|
1533
1540
|
model: modelId,
|
|
1534
|
-
|
|
1541
|
+
messages,
|
|
1542
|
+
tools: params.tools,
|
|
1543
|
+
temperature: params.temperature,
|
|
1544
|
+
max_tokens: params.maxTokens,
|
|
1545
|
+
stream: true
|
|
1535
1546
|
});
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
const
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
generationConfig: {
|
|
1544
|
-
temperature: params.temperature,
|
|
1545
|
-
maxOutputTokens: params.maxTokens
|
|
1547
|
+
let currentToolCall = null;
|
|
1548
|
+
let totalPromptTokens = 0;
|
|
1549
|
+
let totalCompletionTokens = 0;
|
|
1550
|
+
for await (const chunk of stream) {
|
|
1551
|
+
if (params.signal?.aborted) {
|
|
1552
|
+
yield { type: "error", error: new Error("Aborted") };
|
|
1553
|
+
return;
|
|
1546
1554
|
}
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
id: `call_${toolCallIndex++}`,
|
|
1570
|
-
name: part.functionCall.name,
|
|
1571
|
-
args: part.functionCall.args || {}
|
|
1572
|
-
}
|
|
1555
|
+
const choice = chunk.choices[0];
|
|
1556
|
+
const delta = choice?.delta;
|
|
1557
|
+
if (delta?.content) {
|
|
1558
|
+
yield { type: "text-delta", text: delta.content };
|
|
1559
|
+
}
|
|
1560
|
+
if (delta?.tool_calls) {
|
|
1561
|
+
for (const tc of delta.tool_calls) {
|
|
1562
|
+
if (tc.id) {
|
|
1563
|
+
if (currentToolCall) {
|
|
1564
|
+
yield {
|
|
1565
|
+
type: "tool-call",
|
|
1566
|
+
toolCall: {
|
|
1567
|
+
id: currentToolCall.id,
|
|
1568
|
+
name: currentToolCall.name,
|
|
1569
|
+
args: JSON.parse(currentToolCall.arguments || "{}")
|
|
1570
|
+
}
|
|
1571
|
+
};
|
|
1572
|
+
}
|
|
1573
|
+
currentToolCall = {
|
|
1574
|
+
id: tc.id,
|
|
1575
|
+
name: tc.function?.name ?? "",
|
|
1576
|
+
arguments: tc.function?.arguments ?? ""
|
|
1573
1577
|
};
|
|
1578
|
+
} else if (currentToolCall && tc.function?.arguments) {
|
|
1579
|
+
currentToolCall.arguments += tc.function.arguments;
|
|
1574
1580
|
}
|
|
1575
1581
|
}
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
}
|
|
1580
|
-
if (candidate.finishReason) {
|
|
1582
|
+
}
|
|
1583
|
+
if (choice?.finish_reason) {
|
|
1584
|
+
if (currentToolCall) {
|
|
1581
1585
|
yield {
|
|
1582
|
-
type: "
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
totalTokens: promptTokens + completionTokens
|
|
1586
|
+
type: "tool-call",
|
|
1587
|
+
toolCall: {
|
|
1588
|
+
id: currentToolCall.id,
|
|
1589
|
+
name: currentToolCall.name,
|
|
1590
|
+
args: JSON.parse(currentToolCall.arguments || "{}")
|
|
1588
1591
|
}
|
|
1589
1592
|
};
|
|
1593
|
+
currentToolCall = null;
|
|
1594
|
+
}
|
|
1595
|
+
if (chunk.usage) {
|
|
1596
|
+
totalPromptTokens = chunk.usage.prompt_tokens;
|
|
1597
|
+
totalCompletionTokens = chunk.usage.completion_tokens;
|
|
1590
1598
|
}
|
|
1599
|
+
yield {
|
|
1600
|
+
type: "finish",
|
|
1601
|
+
finishReason: mapFinishReason4(choice.finish_reason),
|
|
1602
|
+
usage: {
|
|
1603
|
+
promptTokens: totalPromptTokens,
|
|
1604
|
+
completionTokens: totalCompletionTokens,
|
|
1605
|
+
totalTokens: totalPromptTokens + totalCompletionTokens
|
|
1606
|
+
}
|
|
1607
|
+
};
|
|
1591
1608
|
}
|
|
1592
|
-
} catch (error) {
|
|
1593
|
-
yield {
|
|
1594
|
-
type: "error",
|
|
1595
|
-
error: error instanceof Error ? error : new Error(String(error))
|
|
1596
|
-
};
|
|
1597
1609
|
}
|
|
1598
1610
|
}
|
|
1599
1611
|
};
|
|
1600
1612
|
}
|
|
1601
1613
|
function mapFinishReason4(reason) {
|
|
1602
1614
|
switch (reason) {
|
|
1603
|
-
case "
|
|
1615
|
+
case "stop":
|
|
1604
1616
|
return "stop";
|
|
1605
|
-
case "
|
|
1617
|
+
case "length":
|
|
1606
1618
|
return "length";
|
|
1607
|
-
case "
|
|
1619
|
+
case "tool_calls":
|
|
1620
|
+
case "function_call":
|
|
1621
|
+
return "tool-calls";
|
|
1622
|
+
case "content_filter":
|
|
1608
1623
|
return "content-filter";
|
|
1609
1624
|
default:
|
|
1610
1625
|
return "unknown";
|
|
1611
1626
|
}
|
|
1612
1627
|
}
|
|
1613
|
-
function
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
const parts = [];
|
|
1622
|
-
if (msg.role === "user") {
|
|
1623
|
-
if (typeof msg.content === "string") {
|
|
1624
|
-
parts.push({ text: msg.content });
|
|
1625
|
-
} else {
|
|
1626
|
-
for (const part of msg.content) {
|
|
1627
|
-
if (part.type === "text") {
|
|
1628
|
-
parts.push({ text: part.text });
|
|
1629
|
-
} else if (part.type === "image") {
|
|
1630
|
-
const imageData = typeof part.image === "string" ? part.image : Buffer.from(part.image).toString("base64");
|
|
1631
|
-
const base64 = imageData.startsWith("data:") ? imageData.split(",")[1] : imageData;
|
|
1632
|
-
parts.push({
|
|
1633
|
-
inlineData: {
|
|
1634
|
-
mimeType: part.mimeType ?? "image/png",
|
|
1635
|
-
data: base64
|
|
1636
|
-
}
|
|
1637
|
-
});
|
|
1638
|
-
}
|
|
1628
|
+
function formatMessagesForGoogle(messages) {
|
|
1629
|
+
return messages.map((msg) => {
|
|
1630
|
+
switch (msg.role) {
|
|
1631
|
+
case "system":
|
|
1632
|
+
return { role: "system", content: msg.content };
|
|
1633
|
+
case "user":
|
|
1634
|
+
if (typeof msg.content === "string") {
|
|
1635
|
+
return { role: "user", content: msg.content };
|
|
1639
1636
|
}
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1637
|
+
return {
|
|
1638
|
+
role: "user",
|
|
1639
|
+
content: msg.content.map((part) => {
|
|
1640
|
+
if (part.type === "text") {
|
|
1641
|
+
return { type: "text", text: part.text };
|
|
1642
|
+
}
|
|
1643
|
+
if (part.type === "image") {
|
|
1644
|
+
const imageData = typeof part.image === "string" ? part.image : Buffer.from(part.image).toString("base64");
|
|
1645
|
+
const url = imageData.startsWith("data:") ? imageData : `data:${part.mimeType ?? "image/png"};base64,${imageData}`;
|
|
1646
|
+
return { type: "image_url", image_url: { url, detail: "auto" } };
|
|
1647
|
+
}
|
|
1648
|
+
return { type: "text", text: "" };
|
|
1649
|
+
})
|
|
1650
|
+
};
|
|
1651
|
+
case "assistant":
|
|
1652
|
+
const assistantMsg = {
|
|
1653
|
+
role: "assistant",
|
|
1654
|
+
content: msg.content
|
|
1655
|
+
};
|
|
1656
|
+
if (msg.toolCalls && msg.toolCalls.length > 0) {
|
|
1657
|
+
assistantMsg.tool_calls = msg.toolCalls.map((tc) => ({
|
|
1658
|
+
id: tc.id,
|
|
1659
|
+
type: "function",
|
|
1660
|
+
function: {
|
|
1650
1661
|
name: tc.name,
|
|
1651
|
-
|
|
1662
|
+
arguments: JSON.stringify(tc.args)
|
|
1652
1663
|
}
|
|
1653
|
-
});
|
|
1664
|
+
}));
|
|
1654
1665
|
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
functionResponse: {
|
|
1665
|
-
name: "tool",
|
|
1666
|
-
// Gemini doesn't track by ID
|
|
1667
|
-
response: JSON.parse(msg.content || "{}")
|
|
1668
|
-
}
|
|
1669
|
-
}
|
|
1670
|
-
]
|
|
1671
|
-
});
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
if (contents.length === 0 || contents[0].role !== "user") {
|
|
1675
|
-
contents.unshift({ role: "user", parts: [{ text: "" }] });
|
|
1676
|
-
}
|
|
1677
|
-
const merged = [];
|
|
1678
|
-
for (const content of contents) {
|
|
1679
|
-
const last = merged[merged.length - 1];
|
|
1680
|
-
if (last && last.role === content.role) {
|
|
1681
|
-
last.parts.push(...content.parts);
|
|
1682
|
-
} else {
|
|
1683
|
-
merged.push({ ...content, parts: [...content.parts] });
|
|
1666
|
+
return assistantMsg;
|
|
1667
|
+
case "tool":
|
|
1668
|
+
return {
|
|
1669
|
+
role: "tool",
|
|
1670
|
+
tool_call_id: msg.toolCallId,
|
|
1671
|
+
content: msg.content
|
|
1672
|
+
};
|
|
1673
|
+
default:
|
|
1674
|
+
return msg;
|
|
1684
1675
|
}
|
|
1685
|
-
}
|
|
1686
|
-
return { systemInstruction, contents: merged };
|
|
1687
|
-
}
|
|
1688
|
-
function formatToolsForGemini(tools) {
|
|
1689
|
-
return tools.map((t) => ({
|
|
1690
|
-
name: t.function.name,
|
|
1691
|
-
description: t.function.description,
|
|
1692
|
-
parameters: t.function.parameters
|
|
1693
|
-
}));
|
|
1676
|
+
});
|
|
1694
1677
|
}
|
|
1695
1678
|
|
|
1696
1679
|
// src/adapters/base.ts
|
|
@@ -2596,7 +2579,7 @@ function messageToGeminiContent(msg) {
|
|
|
2596
2579
|
parts
|
|
2597
2580
|
};
|
|
2598
2581
|
}
|
|
2599
|
-
function
|
|
2582
|
+
function formatToolsForGemini(actions) {
|
|
2600
2583
|
if (!actions || actions.length === 0) return void 0;
|
|
2601
2584
|
return {
|
|
2602
2585
|
functionDeclarations: actions.map((action) => ({
|
|
@@ -2682,7 +2665,7 @@ var GoogleAdapter = class {
|
|
|
2682
2665
|
mergedContents.push({ ...content, parts: [...content.parts] });
|
|
2683
2666
|
}
|
|
2684
2667
|
}
|
|
2685
|
-
const tools =
|
|
2668
|
+
const tools = formatToolsForGemini(request.actions);
|
|
2686
2669
|
const messageId = core.generateMessageId();
|
|
2687
2670
|
yield { type: "message:start", id: messageId };
|
|
2688
2671
|
try {
|
|
@@ -2788,7 +2771,7 @@ var GoogleAdapter = class {
|
|
|
2788
2771
|
mergedContents.push({ ...content, parts: [...content.parts] });
|
|
2789
2772
|
}
|
|
2790
2773
|
}
|
|
2791
|
-
const tools =
|
|
2774
|
+
const tools = formatToolsForGemini(request.actions);
|
|
2792
2775
|
const chat = model.startChat({
|
|
2793
2776
|
history: mergedContents.slice(0, -1),
|
|
2794
2777
|
systemInstruction: systemInstruction ? { parts: [{ text: systemInstruction }] } : void 0,
|