@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.
- package/README.md +23 -15
- package/dist/adapters/index.d.mts +23 -9
- package/dist/adapters/index.d.ts +23 -9
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/index.mjs.map +1 -1
- package/dist/{base-D_FyHFKj.d.mts → base-CXNMfvXg.d.mts} +10 -2
- package/dist/{base-D_FyHFKj.d.ts → base-CXNMfvXg.d.ts} +10 -2
- package/dist/index.d.mts +33 -13
- package/dist/index.d.ts +33 -13
- 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/anthropic/index.d.mts +2 -2
- package/dist/providers/anthropic/index.d.ts +2 -2
- package/dist/providers/anthropic/index.js.map +1 -1
- package/dist/providers/anthropic/index.mjs.map +1 -1
- package/dist/providers/azure/index.d.mts +2 -2
- package/dist/providers/azure/index.d.ts +2 -2
- package/dist/providers/azure/index.js.map +1 -1
- package/dist/providers/azure/index.mjs.map +1 -1
- package/dist/providers/google/index.d.mts +23 -10
- package/dist/providers/google/index.d.ts +23 -10
- 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/dist/providers/ollama/index.d.mts +2 -2
- package/dist/providers/ollama/index.d.ts +2 -2
- package/dist/providers/ollama/index.js.map +1 -1
- package/dist/providers/ollama/index.mjs.map +1 -1
- package/dist/providers/openai/index.d.mts +2 -2
- package/dist/providers/openai/index.d.ts +2 -2
- package/dist/providers/openai/index.js.map +1 -1
- package/dist/providers/openai/index.mjs.map +1 -1
- package/dist/providers/xai/index.d.mts +2 -2
- package/dist/providers/xai/index.d.ts +2 -2
- package/dist/providers/xai/index.js.map +1 -1
- package/dist/providers/xai/index.mjs.map +1 -1
- package/dist/{types-BBCZ3Fxy.d.mts → types-B8rxpnYi.d.mts} +1 -1
- package/dist/{types-DcoCaVVC.d.ts → types-CrQftISG.d.ts} +1 -1
- package/package.json +3 -7
|
@@ -2,6 +2,21 @@ import { generateMessageId, generateToolCallId } from '@yourgpt/copilot-sdk/core
|
|
|
2
2
|
|
|
3
3
|
// src/providers/google/provider.ts
|
|
4
4
|
var GOOGLE_MODELS = {
|
|
5
|
+
// Gemini 2.5 (Experimental)
|
|
6
|
+
"gemini-2.5-pro-preview-05-06": {
|
|
7
|
+
vision: true,
|
|
8
|
+
tools: true,
|
|
9
|
+
audio: true,
|
|
10
|
+
video: true,
|
|
11
|
+
maxTokens: 1048576
|
|
12
|
+
},
|
|
13
|
+
"gemini-2.5-flash-preview-05-20": {
|
|
14
|
+
vision: true,
|
|
15
|
+
tools: true,
|
|
16
|
+
audio: true,
|
|
17
|
+
video: true,
|
|
18
|
+
maxTokens: 1048576
|
|
19
|
+
},
|
|
5
20
|
// Gemini 2.0
|
|
6
21
|
"gemini-2.0-flash": {
|
|
7
22
|
vision: true,
|
|
@@ -17,6 +32,13 @@ var GOOGLE_MODELS = {
|
|
|
17
32
|
video: true,
|
|
18
33
|
maxTokens: 1048576
|
|
19
34
|
},
|
|
35
|
+
"gemini-2.0-flash-lite": {
|
|
36
|
+
vision: true,
|
|
37
|
+
tools: true,
|
|
38
|
+
audio: false,
|
|
39
|
+
video: false,
|
|
40
|
+
maxTokens: 1048576
|
|
41
|
+
},
|
|
20
42
|
"gemini-2.0-flash-thinking-exp": {
|
|
21
43
|
vision: true,
|
|
22
44
|
tools: false,
|
|
@@ -63,11 +85,15 @@ var GOOGLE_MODELS = {
|
|
|
63
85
|
};
|
|
64
86
|
function google(modelId, options = {}) {
|
|
65
87
|
const apiKey = options.apiKey ?? process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;
|
|
88
|
+
const baseURL = options.baseURL ?? "https://generativelanguage.googleapis.com/v1beta/openai/";
|
|
66
89
|
let client = null;
|
|
67
90
|
async function getClient() {
|
|
68
91
|
if (!client) {
|
|
69
|
-
const {
|
|
70
|
-
client = new
|
|
92
|
+
const { default: OpenAI } = await import('openai');
|
|
93
|
+
client = new OpenAI({
|
|
94
|
+
apiKey,
|
|
95
|
+
baseURL
|
|
96
|
+
});
|
|
71
97
|
}
|
|
72
98
|
return client;
|
|
73
99
|
}
|
|
@@ -87,219 +113,176 @@ function google(modelId, options = {}) {
|
|
|
87
113
|
},
|
|
88
114
|
async doGenerate(params) {
|
|
89
115
|
const client2 = await getClient();
|
|
90
|
-
const
|
|
116
|
+
const messages = formatMessagesForGoogle(params.messages);
|
|
117
|
+
const response = await client2.chat.completions.create({
|
|
91
118
|
model: modelId,
|
|
92
|
-
|
|
119
|
+
messages,
|
|
120
|
+
tools: params.tools,
|
|
121
|
+
temperature: params.temperature,
|
|
122
|
+
max_tokens: params.maxTokens
|
|
93
123
|
});
|
|
94
|
-
const
|
|
95
|
-
|
|
124
|
+
const choice = response.choices[0];
|
|
125
|
+
const message = choice.message;
|
|
126
|
+
const toolCalls = (message.tool_calls ?? []).map(
|
|
127
|
+
(tc) => ({
|
|
128
|
+
id: tc.id,
|
|
129
|
+
name: tc.function.name,
|
|
130
|
+
args: JSON.parse(tc.function.arguments || "{}")
|
|
131
|
+
})
|
|
96
132
|
);
|
|
97
|
-
const chat = model.startChat({
|
|
98
|
-
history: contents.slice(0, -1),
|
|
99
|
-
systemInstruction: systemInstruction ? { parts: [{ text: systemInstruction }] } : void 0,
|
|
100
|
-
tools: params.tools ? [{ functionDeclarations: formatToolsForGemini(params.tools) }] : void 0,
|
|
101
|
-
generationConfig: {
|
|
102
|
-
temperature: params.temperature,
|
|
103
|
-
maxOutputTokens: params.maxTokens
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
const lastMessage = contents[contents.length - 1];
|
|
107
|
-
const result = await chat.sendMessage(lastMessage.parts);
|
|
108
|
-
const response = result.response;
|
|
109
|
-
let text = "";
|
|
110
|
-
const toolCalls = [];
|
|
111
|
-
let toolCallIndex = 0;
|
|
112
|
-
const candidate = response.candidates?.[0];
|
|
113
|
-
if (candidate?.content?.parts) {
|
|
114
|
-
for (const part of candidate.content.parts) {
|
|
115
|
-
if ("text" in part && part.text) {
|
|
116
|
-
text += part.text;
|
|
117
|
-
}
|
|
118
|
-
if ("functionCall" in part && part.functionCall) {
|
|
119
|
-
toolCalls.push({
|
|
120
|
-
id: `call_${toolCallIndex++}`,
|
|
121
|
-
name: part.functionCall.name,
|
|
122
|
-
args: part.functionCall.args || {}
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
133
|
return {
|
|
128
|
-
text,
|
|
134
|
+
text: message.content ?? "",
|
|
129
135
|
toolCalls,
|
|
130
|
-
finishReason: mapFinishReason(
|
|
136
|
+
finishReason: mapFinishReason(choice.finish_reason),
|
|
131
137
|
usage: {
|
|
132
|
-
promptTokens: response.
|
|
133
|
-
completionTokens: response.
|
|
134
|
-
totalTokens: response.
|
|
138
|
+
promptTokens: response.usage?.prompt_tokens ?? 0,
|
|
139
|
+
completionTokens: response.usage?.completion_tokens ?? 0,
|
|
140
|
+
totalTokens: response.usage?.total_tokens ?? 0
|
|
135
141
|
},
|
|
136
142
|
rawResponse: response
|
|
137
143
|
};
|
|
138
144
|
},
|
|
139
145
|
async *doStream(params) {
|
|
140
146
|
const client2 = await getClient();
|
|
141
|
-
const
|
|
147
|
+
const messages = formatMessagesForGoogle(params.messages);
|
|
148
|
+
const stream = await client2.chat.completions.create({
|
|
142
149
|
model: modelId,
|
|
143
|
-
|
|
150
|
+
messages,
|
|
151
|
+
tools: params.tools,
|
|
152
|
+
temperature: params.temperature,
|
|
153
|
+
max_tokens: params.maxTokens,
|
|
154
|
+
stream: true
|
|
144
155
|
});
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
generationConfig: {
|
|
153
|
-
temperature: params.temperature,
|
|
154
|
-
maxOutputTokens: params.maxTokens
|
|
156
|
+
let currentToolCall = null;
|
|
157
|
+
let totalPromptTokens = 0;
|
|
158
|
+
let totalCompletionTokens = 0;
|
|
159
|
+
for await (const chunk of stream) {
|
|
160
|
+
if (params.signal?.aborted) {
|
|
161
|
+
yield { type: "error", error: new Error("Aborted") };
|
|
162
|
+
return;
|
|
155
163
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
id: `call_${toolCallIndex++}`,
|
|
179
|
-
name: part.functionCall.name,
|
|
180
|
-
args: part.functionCall.args || {}
|
|
181
|
-
}
|
|
164
|
+
const choice = chunk.choices[0];
|
|
165
|
+
const delta = choice?.delta;
|
|
166
|
+
if (delta?.content) {
|
|
167
|
+
yield { type: "text-delta", text: delta.content };
|
|
168
|
+
}
|
|
169
|
+
if (delta?.tool_calls) {
|
|
170
|
+
for (const tc of delta.tool_calls) {
|
|
171
|
+
if (tc.id) {
|
|
172
|
+
if (currentToolCall) {
|
|
173
|
+
yield {
|
|
174
|
+
type: "tool-call",
|
|
175
|
+
toolCall: {
|
|
176
|
+
id: currentToolCall.id,
|
|
177
|
+
name: currentToolCall.name,
|
|
178
|
+
args: JSON.parse(currentToolCall.arguments || "{}")
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
currentToolCall = {
|
|
183
|
+
id: tc.id,
|
|
184
|
+
name: tc.function?.name ?? "",
|
|
185
|
+
arguments: tc.function?.arguments ?? ""
|
|
182
186
|
};
|
|
187
|
+
} else if (currentToolCall && tc.function?.arguments) {
|
|
188
|
+
currentToolCall.arguments += tc.function.arguments;
|
|
183
189
|
}
|
|
184
190
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
if (candidate.finishReason) {
|
|
191
|
+
}
|
|
192
|
+
if (choice?.finish_reason) {
|
|
193
|
+
if (currentToolCall) {
|
|
190
194
|
yield {
|
|
191
|
-
type: "
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
totalTokens: promptTokens + completionTokens
|
|
195
|
+
type: "tool-call",
|
|
196
|
+
toolCall: {
|
|
197
|
+
id: currentToolCall.id,
|
|
198
|
+
name: currentToolCall.name,
|
|
199
|
+
args: JSON.parse(currentToolCall.arguments || "{}")
|
|
197
200
|
}
|
|
198
201
|
};
|
|
202
|
+
currentToolCall = null;
|
|
203
|
+
}
|
|
204
|
+
if (chunk.usage) {
|
|
205
|
+
totalPromptTokens = chunk.usage.prompt_tokens;
|
|
206
|
+
totalCompletionTokens = chunk.usage.completion_tokens;
|
|
199
207
|
}
|
|
208
|
+
yield {
|
|
209
|
+
type: "finish",
|
|
210
|
+
finishReason: mapFinishReason(choice.finish_reason),
|
|
211
|
+
usage: {
|
|
212
|
+
promptTokens: totalPromptTokens,
|
|
213
|
+
completionTokens: totalCompletionTokens,
|
|
214
|
+
totalTokens: totalPromptTokens + totalCompletionTokens
|
|
215
|
+
}
|
|
216
|
+
};
|
|
200
217
|
}
|
|
201
|
-
} catch (error) {
|
|
202
|
-
yield {
|
|
203
|
-
type: "error",
|
|
204
|
-
error: error instanceof Error ? error : new Error(String(error))
|
|
205
|
-
};
|
|
206
218
|
}
|
|
207
219
|
}
|
|
208
220
|
};
|
|
209
221
|
}
|
|
210
222
|
function mapFinishReason(reason) {
|
|
211
223
|
switch (reason) {
|
|
212
|
-
case "
|
|
224
|
+
case "stop":
|
|
213
225
|
return "stop";
|
|
214
|
-
case "
|
|
226
|
+
case "length":
|
|
215
227
|
return "length";
|
|
216
|
-
case "
|
|
228
|
+
case "tool_calls":
|
|
229
|
+
case "function_call":
|
|
230
|
+
return "tool-calls";
|
|
231
|
+
case "content_filter":
|
|
217
232
|
return "content-filter";
|
|
218
233
|
default:
|
|
219
234
|
return "unknown";
|
|
220
235
|
}
|
|
221
236
|
}
|
|
222
|
-
function
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const parts = [];
|
|
231
|
-
if (msg.role === "user") {
|
|
232
|
-
if (typeof msg.content === "string") {
|
|
233
|
-
parts.push({ text: msg.content });
|
|
234
|
-
} else {
|
|
235
|
-
for (const part of msg.content) {
|
|
236
|
-
if (part.type === "text") {
|
|
237
|
-
parts.push({ text: part.text });
|
|
238
|
-
} else if (part.type === "image") {
|
|
239
|
-
const imageData = typeof part.image === "string" ? part.image : Buffer.from(part.image).toString("base64");
|
|
240
|
-
const base64 = imageData.startsWith("data:") ? imageData.split(",")[1] : imageData;
|
|
241
|
-
parts.push({
|
|
242
|
-
inlineData: {
|
|
243
|
-
mimeType: part.mimeType ?? "image/png",
|
|
244
|
-
data: base64
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
}
|
|
237
|
+
function formatMessagesForGoogle(messages) {
|
|
238
|
+
return messages.map((msg) => {
|
|
239
|
+
switch (msg.role) {
|
|
240
|
+
case "system":
|
|
241
|
+
return { role: "system", content: msg.content };
|
|
242
|
+
case "user":
|
|
243
|
+
if (typeof msg.content === "string") {
|
|
244
|
+
return { role: "user", content: msg.content };
|
|
248
245
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
246
|
+
return {
|
|
247
|
+
role: "user",
|
|
248
|
+
content: msg.content.map((part) => {
|
|
249
|
+
if (part.type === "text") {
|
|
250
|
+
return { type: "text", text: part.text };
|
|
251
|
+
}
|
|
252
|
+
if (part.type === "image") {
|
|
253
|
+
const imageData = typeof part.image === "string" ? part.image : Buffer.from(part.image).toString("base64");
|
|
254
|
+
const url = imageData.startsWith("data:") ? imageData : `data:${part.mimeType ?? "image/png"};base64,${imageData}`;
|
|
255
|
+
return { type: "image_url", image_url: { url, detail: "auto" } };
|
|
256
|
+
}
|
|
257
|
+
return { type: "text", text: "" };
|
|
258
|
+
})
|
|
259
|
+
};
|
|
260
|
+
case "assistant":
|
|
261
|
+
const assistantMsg = {
|
|
262
|
+
role: "assistant",
|
|
263
|
+
content: msg.content
|
|
264
|
+
};
|
|
265
|
+
if (msg.toolCalls && msg.toolCalls.length > 0) {
|
|
266
|
+
assistantMsg.tool_calls = msg.toolCalls.map((tc) => ({
|
|
267
|
+
id: tc.id,
|
|
268
|
+
type: "function",
|
|
269
|
+
function: {
|
|
259
270
|
name: tc.name,
|
|
260
|
-
|
|
271
|
+
arguments: JSON.stringify(tc.args)
|
|
261
272
|
}
|
|
262
|
-
});
|
|
273
|
+
}));
|
|
263
274
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
functionResponse: {
|
|
274
|
-
name: "tool",
|
|
275
|
-
// Gemini doesn't track by ID
|
|
276
|
-
response: JSON.parse(msg.content || "{}")
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
]
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
if (contents.length === 0 || contents[0].role !== "user") {
|
|
284
|
-
contents.unshift({ role: "user", parts: [{ text: "" }] });
|
|
285
|
-
}
|
|
286
|
-
const merged = [];
|
|
287
|
-
for (const content of contents) {
|
|
288
|
-
const last = merged[merged.length - 1];
|
|
289
|
-
if (last && last.role === content.role) {
|
|
290
|
-
last.parts.push(...content.parts);
|
|
291
|
-
} else {
|
|
292
|
-
merged.push({ ...content, parts: [...content.parts] });
|
|
275
|
+
return assistantMsg;
|
|
276
|
+
case "tool":
|
|
277
|
+
return {
|
|
278
|
+
role: "tool",
|
|
279
|
+
tool_call_id: msg.toolCallId,
|
|
280
|
+
content: msg.content
|
|
281
|
+
};
|
|
282
|
+
default:
|
|
283
|
+
return msg;
|
|
293
284
|
}
|
|
294
|
-
}
|
|
295
|
-
return { systemInstruction, contents: merged };
|
|
296
|
-
}
|
|
297
|
-
function formatToolsForGemini(tools) {
|
|
298
|
-
return tools.map((t) => ({
|
|
299
|
-
name: t.function.name,
|
|
300
|
-
description: t.function.description,
|
|
301
|
-
parameters: t.function.parameters
|
|
302
|
-
}));
|
|
285
|
+
});
|
|
303
286
|
}
|
|
304
287
|
function attachmentToGeminiPart(attachment) {
|
|
305
288
|
if (!attachment.data) {
|
|
@@ -392,7 +375,7 @@ function messageToGeminiContent(msg) {
|
|
|
392
375
|
parts
|
|
393
376
|
};
|
|
394
377
|
}
|
|
395
|
-
function
|
|
378
|
+
function formatToolsForGemini(actions) {
|
|
396
379
|
if (!actions || actions.length === 0) return void 0;
|
|
397
380
|
return {
|
|
398
381
|
functionDeclarations: actions.map((action) => ({
|
|
@@ -478,7 +461,7 @@ var GoogleAdapter = class {
|
|
|
478
461
|
mergedContents.push({ ...content, parts: [...content.parts] });
|
|
479
462
|
}
|
|
480
463
|
}
|
|
481
|
-
const tools =
|
|
464
|
+
const tools = formatToolsForGemini(request.actions);
|
|
482
465
|
const messageId = generateMessageId();
|
|
483
466
|
yield { type: "message:start", id: messageId };
|
|
484
467
|
try {
|
|
@@ -584,7 +567,7 @@ var GoogleAdapter = class {
|
|
|
584
567
|
mergedContents.push({ ...content, parts: [...content.parts] });
|
|
585
568
|
}
|
|
586
569
|
}
|
|
587
|
-
const tools =
|
|
570
|
+
const tools = formatToolsForGemini(request.actions);
|
|
588
571
|
const chat = model.startChat({
|
|
589
572
|
history: mergedContents.slice(0, -1),
|
|
590
573
|
systemInstruction: systemInstruction ? { parts: [{ text: systemInstruction }] } : void 0,
|