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