@shareai-lab/kode-sdk 2.7.1 → 2.7.2
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/core/agent/breakpoint-manager.js +36 -0
- package/dist/core/agent/message-queue.js +57 -0
- package/dist/core/agent/permission-manager.js +32 -0
- package/dist/core/agent/todo-manager.js +91 -0
- package/dist/core/agent/tool-runner.js +45 -0
- package/dist/core/agent.js +2035 -0
- package/dist/core/config.js +2 -0
- package/dist/core/context-manager.js +241 -0
- package/dist/core/errors.js +49 -0
- package/dist/core/events.js +329 -0
- package/dist/core/file-pool.d.ts +2 -0
- package/dist/core/file-pool.js +125 -0
- package/dist/core/hooks.js +71 -0
- package/dist/core/permission-modes.js +61 -0
- package/dist/core/pool.js +301 -0
- package/dist/core/room.js +57 -0
- package/dist/core/scheduler.js +58 -0
- package/dist/core/skills/index.js +20 -0
- package/dist/core/skills/management-manager.js +557 -0
- package/dist/core/skills/manager.js +243 -0
- package/dist/core/skills/operation-queue.js +113 -0
- package/dist/core/skills/sandbox-file-manager.js +183 -0
- package/dist/core/skills/types.js +9 -0
- package/dist/core/skills/xml-generator.js +70 -0
- package/dist/core/template.js +35 -0
- package/dist/core/time-bridge.js +100 -0
- package/dist/core/todo.js +89 -0
- package/dist/core/types.js +3 -0
- package/dist/index.js +148 -60461
- package/dist/infra/db/postgres/postgres-store.js +1073 -0
- package/dist/infra/db/sqlite/sqlite-store.js +800 -0
- package/dist/infra/e2b/e2b-fs.js +128 -0
- package/dist/infra/e2b/e2b-sandbox.js +156 -0
- package/dist/infra/e2b/e2b-template.js +105 -0
- package/dist/infra/e2b/index.js +9 -0
- package/dist/infra/e2b/types.js +2 -0
- package/dist/infra/provider.js +67 -0
- package/dist/infra/providers/anthropic.js +308 -0
- package/dist/infra/providers/core/errors.js +353 -0
- package/dist/infra/providers/core/fork.js +418 -0
- package/dist/infra/providers/core/index.js +76 -0
- package/dist/infra/providers/core/logger.js +191 -0
- package/dist/infra/providers/core/retry.js +189 -0
- package/dist/infra/providers/core/usage.js +376 -0
- package/dist/infra/providers/gemini.js +493 -0
- package/dist/infra/providers/index.js +83 -0
- package/dist/infra/providers/openai.js +662 -0
- package/dist/infra/providers/types.js +20 -0
- package/dist/infra/providers/utils.js +400 -0
- package/dist/infra/sandbox-factory.js +30 -0
- package/dist/infra/sandbox.js +243 -0
- package/dist/infra/store/factory.js +80 -0
- package/dist/infra/store/index.js +26 -0
- package/dist/infra/store/json-store.js +606 -0
- package/dist/infra/store/types.js +2 -0
- package/dist/infra/store.js +29 -0
- package/dist/tools/bash_kill/index.js +35 -0
- package/dist/tools/bash_kill/prompt.js +14 -0
- package/dist/tools/bash_logs/index.js +40 -0
- package/dist/tools/bash_logs/prompt.js +14 -0
- package/dist/tools/bash_run/index.js +61 -0
- package/dist/tools/bash_run/prompt.js +18 -0
- package/dist/tools/builtin.js +26 -0
- package/dist/tools/define.js +214 -0
- package/dist/tools/fs_edit/index.js +62 -0
- package/dist/tools/fs_edit/prompt.js +15 -0
- package/dist/tools/fs_glob/index.js +40 -0
- package/dist/tools/fs_glob/prompt.js +15 -0
- package/dist/tools/fs_grep/index.js +66 -0
- package/dist/tools/fs_grep/prompt.js +16 -0
- package/dist/tools/fs_multi_edit/index.js +106 -0
- package/dist/tools/fs_multi_edit/prompt.js +16 -0
- package/dist/tools/fs_read/index.js +40 -0
- package/dist/tools/fs_read/prompt.js +16 -0
- package/dist/tools/fs_write/index.js +40 -0
- package/dist/tools/fs_write/prompt.js +15 -0
- package/dist/tools/index.js +61 -0
- package/dist/tools/mcp.js +185 -0
- package/dist/tools/registry.js +26 -0
- package/dist/tools/scripts.js +205 -0
- package/dist/tools/skills.js +115 -0
- package/dist/tools/task_run/index.js +58 -0
- package/dist/tools/task_run/prompt.js +25 -0
- package/dist/tools/todo_read/index.js +29 -0
- package/dist/tools/todo_read/prompt.js +18 -0
- package/dist/tools/todo_write/index.js +42 -0
- package/dist/tools/todo_write/prompt.js +23 -0
- package/dist/tools/tool.js +211 -0
- package/dist/tools/toolkit.js +98 -0
- package/dist/tools/type-inference.js +207 -0
- package/dist/utils/agent-id.js +28 -0
- package/dist/utils/logger.js +44 -0
- package/dist/utils/session-id.js +64 -0
- package/package.json +7 -38
- package/dist/index.js.map +0 -7
- package/dist/index.mjs +0 -60385
- package/dist/index.mjs.map +0 -7
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Gemini Provider Adapter
|
|
4
|
+
*
|
|
5
|
+
* Converts internal Anthropic-style messages to Gemini API format.
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Thinking with thinkingBudget (2.5 models) or thinkingLevel (3.x models)
|
|
8
|
+
* - Files API with GCS URIs
|
|
9
|
+
* - Streaming with SSE
|
|
10
|
+
* - Function calling
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.GeminiProvider = void 0;
|
|
14
|
+
const utils_1 = require("./utils");
|
|
15
|
+
class GeminiProvider {
|
|
16
|
+
constructor(apiKey, model = 'gemini-3.0-flash', baseUrl = 'https://generativelanguage.googleapis.com/v1beta', proxyUrl, options) {
|
|
17
|
+
this.apiKey = apiKey;
|
|
18
|
+
this.maxWindowSize = 1000000;
|
|
19
|
+
this.maxOutputTokens = 4096;
|
|
20
|
+
this.temperature = 0.7;
|
|
21
|
+
this.model = model;
|
|
22
|
+
this.baseUrl = (0, utils_1.normalizeGeminiBaseUrl)(baseUrl);
|
|
23
|
+
this.dispatcher = (0, utils_1.getProxyDispatcher)(proxyUrl);
|
|
24
|
+
this.reasoningTransport = options?.reasoningTransport ?? 'text';
|
|
25
|
+
this.extraHeaders = options?.extraHeaders;
|
|
26
|
+
this.extraBody = options?.extraBody;
|
|
27
|
+
this.providerOptions = options?.providerOptions;
|
|
28
|
+
this.multimodal = options?.multimodal;
|
|
29
|
+
this.thinking = options?.thinking;
|
|
30
|
+
}
|
|
31
|
+
async uploadFile(input) {
|
|
32
|
+
if (input.kind !== 'file') {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const url = new URL(`${this.baseUrl}/files`);
|
|
36
|
+
url.searchParams.set('key', this.apiKey);
|
|
37
|
+
const body = {
|
|
38
|
+
file: {
|
|
39
|
+
display_name: input.filename || 'file.pdf',
|
|
40
|
+
mime_type: input.mimeType,
|
|
41
|
+
},
|
|
42
|
+
content: input.data.toString('base64'),
|
|
43
|
+
};
|
|
44
|
+
const response = await fetch(url.toString(), (0, utils_1.withProxy)({
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: {
|
|
47
|
+
'Content-Type': 'application/json',
|
|
48
|
+
...(this.extraHeaders || {}),
|
|
49
|
+
},
|
|
50
|
+
body: JSON.stringify(body),
|
|
51
|
+
}, this.dispatcher));
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
const error = await response.text();
|
|
54
|
+
throw new Error(`Gemini file upload error: ${response.status} ${error}`);
|
|
55
|
+
}
|
|
56
|
+
const data = await response.json();
|
|
57
|
+
const fileUri = data?.file?.uri ?? data?.uri ?? data?.file_uri;
|
|
58
|
+
if (!fileUri) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return { fileUri };
|
|
62
|
+
}
|
|
63
|
+
async complete(messages, opts) {
|
|
64
|
+
const body = {
|
|
65
|
+
...(this.extraBody || {}),
|
|
66
|
+
...this.buildGeminiRequestBody(messages, {
|
|
67
|
+
system: opts?.system,
|
|
68
|
+
tools: opts?.tools,
|
|
69
|
+
maxTokens: opts?.maxTokens ?? this.maxOutputTokens,
|
|
70
|
+
temperature: opts?.temperature ?? this.temperature,
|
|
71
|
+
reasoningTransport: this.reasoningTransport,
|
|
72
|
+
thinking: opts?.thinking ?? this.thinking,
|
|
73
|
+
}),
|
|
74
|
+
};
|
|
75
|
+
const url = this.buildGeminiUrl('generateContent');
|
|
76
|
+
const response = await fetch(url.toString(), (0, utils_1.withProxy)({
|
|
77
|
+
method: 'POST',
|
|
78
|
+
headers: {
|
|
79
|
+
'Content-Type': 'application/json',
|
|
80
|
+
...(this.extraHeaders || {}),
|
|
81
|
+
},
|
|
82
|
+
body: JSON.stringify(body),
|
|
83
|
+
}, this.dispatcher));
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
const error = await response.text();
|
|
86
|
+
throw new Error(`Gemini API error: ${response.status} ${error}`);
|
|
87
|
+
}
|
|
88
|
+
const data = await response.json();
|
|
89
|
+
const candidate = data?.candidates?.[0];
|
|
90
|
+
const contentBlocks = (0, utils_1.normalizeThinkBlocks)(this.extractGeminiContentBlocks(candidate?.content), this.reasoningTransport);
|
|
91
|
+
const usage = data?.usageMetadata;
|
|
92
|
+
return {
|
|
93
|
+
role: 'assistant',
|
|
94
|
+
content: contentBlocks,
|
|
95
|
+
usage: usage
|
|
96
|
+
? {
|
|
97
|
+
input_tokens: usage.promptTokenCount ?? 0,
|
|
98
|
+
output_tokens: usage.candidatesTokenCount ?? 0,
|
|
99
|
+
}
|
|
100
|
+
: undefined,
|
|
101
|
+
stop_reason: candidate?.finishReason,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
async *stream(messages, opts) {
|
|
105
|
+
const body = {
|
|
106
|
+
...(this.extraBody || {}),
|
|
107
|
+
...this.buildGeminiRequestBody(messages, {
|
|
108
|
+
system: opts?.system,
|
|
109
|
+
tools: opts?.tools,
|
|
110
|
+
maxTokens: opts?.maxTokens ?? this.maxOutputTokens,
|
|
111
|
+
temperature: opts?.temperature ?? this.temperature,
|
|
112
|
+
reasoningTransport: this.reasoningTransport,
|
|
113
|
+
thinking: opts?.thinking ?? this.thinking,
|
|
114
|
+
}),
|
|
115
|
+
};
|
|
116
|
+
const url = this.buildGeminiUrl('streamGenerateContent');
|
|
117
|
+
const response = await fetch(url.toString(), (0, utils_1.withProxy)({
|
|
118
|
+
method: 'POST',
|
|
119
|
+
headers: {
|
|
120
|
+
'Content-Type': 'application/json',
|
|
121
|
+
...(this.extraHeaders || {}),
|
|
122
|
+
},
|
|
123
|
+
body: JSON.stringify(body),
|
|
124
|
+
}, this.dispatcher));
|
|
125
|
+
if (!response.ok) {
|
|
126
|
+
const error = await response.text();
|
|
127
|
+
throw new Error(`Gemini API error: ${response.status} ${error}`);
|
|
128
|
+
}
|
|
129
|
+
const reader = response.body?.getReader();
|
|
130
|
+
if (!reader)
|
|
131
|
+
throw new Error('No response body');
|
|
132
|
+
const decoder = new TextDecoder();
|
|
133
|
+
let buffer = '';
|
|
134
|
+
let textStarted = false;
|
|
135
|
+
const textIndex = 0;
|
|
136
|
+
let toolIndex = 1;
|
|
137
|
+
const toolCalls = [];
|
|
138
|
+
let lastUsage;
|
|
139
|
+
let collectAll = false;
|
|
140
|
+
while (true) {
|
|
141
|
+
const { done, value } = await reader.read();
|
|
142
|
+
if (done)
|
|
143
|
+
break;
|
|
144
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
145
|
+
if (collectAll) {
|
|
146
|
+
buffer += chunk;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
buffer += chunk;
|
|
150
|
+
const lines = buffer.split('\n');
|
|
151
|
+
buffer = lines.pop() || '';
|
|
152
|
+
for (let i = 0; i < lines.length; i++) {
|
|
153
|
+
let trimmed = lines[i].trim();
|
|
154
|
+
if (!trimmed)
|
|
155
|
+
continue;
|
|
156
|
+
if (trimmed.startsWith('event:') || trimmed.startsWith(':'))
|
|
157
|
+
continue;
|
|
158
|
+
if (trimmed.startsWith('data:')) {
|
|
159
|
+
trimmed = trimmed.slice(5).trim();
|
|
160
|
+
}
|
|
161
|
+
if (!trimmed || trimmed === '[DONE]')
|
|
162
|
+
continue;
|
|
163
|
+
if (trimmed.startsWith('[')) {
|
|
164
|
+
collectAll = true;
|
|
165
|
+
buffer = [trimmed, ...lines.slice(i + 1), buffer].filter(Boolean).join('\n');
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
let event;
|
|
169
|
+
try {
|
|
170
|
+
event = JSON.parse(trimmed);
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
collectAll = true;
|
|
174
|
+
buffer = [trimmed, ...lines.slice(i + 1), buffer].filter(Boolean).join('\n');
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
const { textChunks, functionCalls, usage } = this.parseGeminiChunk(event);
|
|
178
|
+
if (usage) {
|
|
179
|
+
lastUsage = usage;
|
|
180
|
+
}
|
|
181
|
+
for (const text of textChunks) {
|
|
182
|
+
if (!textStarted) {
|
|
183
|
+
textStarted = true;
|
|
184
|
+
yield {
|
|
185
|
+
type: 'content_block_start',
|
|
186
|
+
index: textIndex,
|
|
187
|
+
content_block: { type: 'text', text: '' },
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
yield {
|
|
191
|
+
type: 'content_block_delta',
|
|
192
|
+
index: textIndex,
|
|
193
|
+
delta: { type: 'text_delta', text },
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
for (const call of functionCalls) {
|
|
197
|
+
toolCalls.push(call);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (buffer.trim()) {
|
|
202
|
+
try {
|
|
203
|
+
const parsed = JSON.parse(buffer.trim());
|
|
204
|
+
const events = Array.isArray(parsed) ? parsed : [parsed];
|
|
205
|
+
for (const event of events) {
|
|
206
|
+
const { textChunks, functionCalls, usage } = this.parseGeminiChunk(event);
|
|
207
|
+
if (usage) {
|
|
208
|
+
lastUsage = usage;
|
|
209
|
+
}
|
|
210
|
+
for (const text of textChunks) {
|
|
211
|
+
if (!textStarted) {
|
|
212
|
+
textStarted = true;
|
|
213
|
+
yield {
|
|
214
|
+
type: 'content_block_start',
|
|
215
|
+
index: textIndex,
|
|
216
|
+
content_block: { type: 'text', text: '' },
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
yield {
|
|
220
|
+
type: 'content_block_delta',
|
|
221
|
+
index: textIndex,
|
|
222
|
+
delta: { type: 'text_delta', text },
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
for (const call of functionCalls) {
|
|
226
|
+
toolCalls.push(call);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
// ignore trailing buffer
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (textStarted) {
|
|
235
|
+
yield { type: 'content_block_stop', index: textIndex };
|
|
236
|
+
}
|
|
237
|
+
for (const call of toolCalls) {
|
|
238
|
+
const id = `toolcall-${Date.now()}-${toolIndex}`;
|
|
239
|
+
const meta = call.thoughtSignature ? { thought_signature: call.thoughtSignature } : undefined;
|
|
240
|
+
yield {
|
|
241
|
+
type: 'content_block_start',
|
|
242
|
+
index: toolIndex,
|
|
243
|
+
content_block: { type: 'tool_use', id, name: call.name, input: {}, ...(meta ? { meta } : {}) },
|
|
244
|
+
};
|
|
245
|
+
yield {
|
|
246
|
+
type: 'content_block_delta',
|
|
247
|
+
index: toolIndex,
|
|
248
|
+
delta: { type: 'input_json_delta', partial_json: (0, utils_1.safeJsonStringify)(call.args) },
|
|
249
|
+
};
|
|
250
|
+
yield { type: 'content_block_stop', index: toolIndex };
|
|
251
|
+
toolIndex += 1;
|
|
252
|
+
}
|
|
253
|
+
if (lastUsage) {
|
|
254
|
+
yield {
|
|
255
|
+
type: 'message_delta',
|
|
256
|
+
usage: {
|
|
257
|
+
input_tokens: lastUsage.input,
|
|
258
|
+
output_tokens: lastUsage.output,
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
toConfig() {
|
|
264
|
+
return {
|
|
265
|
+
provider: 'gemini',
|
|
266
|
+
model: this.model,
|
|
267
|
+
baseUrl: this.baseUrl,
|
|
268
|
+
apiKey: this.apiKey,
|
|
269
|
+
maxTokens: this.maxOutputTokens,
|
|
270
|
+
temperature: this.temperature,
|
|
271
|
+
reasoningTransport: this.reasoningTransport,
|
|
272
|
+
extraHeaders: this.extraHeaders,
|
|
273
|
+
extraBody: this.extraBody,
|
|
274
|
+
providerOptions: this.providerOptions,
|
|
275
|
+
multimodal: this.multimodal,
|
|
276
|
+
thinking: this.thinking,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
buildGeminiUrl(action) {
|
|
280
|
+
const url = new URL(`${this.baseUrl.replace(/\/+$/, '')}/models/${this.model}:${action}`);
|
|
281
|
+
url.searchParams.set('key', this.apiKey);
|
|
282
|
+
if (action === 'streamGenerateContent') {
|
|
283
|
+
url.searchParams.set('alt', 'sse');
|
|
284
|
+
}
|
|
285
|
+
return url;
|
|
286
|
+
}
|
|
287
|
+
buildGeminiRequestBody(messages, opts) {
|
|
288
|
+
const systemInstruction = this.buildGeminiSystemInstruction(messages, opts.system, opts.reasoningTransport);
|
|
289
|
+
const contents = this.buildGeminiContents(messages, opts.reasoningTransport);
|
|
290
|
+
const tools = opts.tools && opts.tools.length > 0 ? this.buildGeminiTools(opts.tools) : undefined;
|
|
291
|
+
const generationConfig = {};
|
|
292
|
+
if (opts.temperature !== undefined)
|
|
293
|
+
generationConfig.temperature = opts.temperature;
|
|
294
|
+
if (opts.maxTokens !== undefined)
|
|
295
|
+
generationConfig.maxOutputTokens = opts.maxTokens;
|
|
296
|
+
if (opts.thinking?.budgetTokens) {
|
|
297
|
+
generationConfig.thinkingConfig = { thinkingBudget: opts.thinking.budgetTokens };
|
|
298
|
+
}
|
|
299
|
+
else if (opts.thinking?.level) {
|
|
300
|
+
generationConfig.thinkingConfig = { thinkingLevel: opts.thinking.level.toUpperCase() };
|
|
301
|
+
}
|
|
302
|
+
const body = {
|
|
303
|
+
contents,
|
|
304
|
+
};
|
|
305
|
+
if (systemInstruction) {
|
|
306
|
+
body.systemInstruction = { parts: [{ text: systemInstruction }] };
|
|
307
|
+
}
|
|
308
|
+
if (tools) {
|
|
309
|
+
body.tools = tools;
|
|
310
|
+
}
|
|
311
|
+
if (Object.keys(generationConfig).length > 0) {
|
|
312
|
+
body.generationConfig = generationConfig;
|
|
313
|
+
}
|
|
314
|
+
return body;
|
|
315
|
+
}
|
|
316
|
+
buildGeminiSystemInstruction(messages, system, reasoningTransport = 'text') {
|
|
317
|
+
const parts = [];
|
|
318
|
+
if (system)
|
|
319
|
+
parts.push(system);
|
|
320
|
+
for (const msg of messages) {
|
|
321
|
+
if (msg.role !== 'system')
|
|
322
|
+
continue;
|
|
323
|
+
const text = (0, utils_1.concatTextWithReasoning)((0, utils_1.getMessageBlocks)(msg), reasoningTransport);
|
|
324
|
+
if (text)
|
|
325
|
+
parts.push(text);
|
|
326
|
+
}
|
|
327
|
+
if (parts.length === 0)
|
|
328
|
+
return undefined;
|
|
329
|
+
return parts.join('\n\n---\n\n');
|
|
330
|
+
}
|
|
331
|
+
buildGeminiContents(messages, reasoningTransport = 'text') {
|
|
332
|
+
const contents = [];
|
|
333
|
+
const toolNameById = new Map();
|
|
334
|
+
const toolSignatureById = new Map();
|
|
335
|
+
for (const msg of messages) {
|
|
336
|
+
for (const block of (0, utils_1.getMessageBlocks)(msg)) {
|
|
337
|
+
if (block.type === 'tool_use') {
|
|
338
|
+
toolNameById.set(block.id, block.name);
|
|
339
|
+
const signature = block.meta?.thought_signature ?? block.meta?.thoughtSignature;
|
|
340
|
+
if (typeof signature === 'string' && signature.length > 0) {
|
|
341
|
+
toolSignatureById.set(block.id, signature);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
for (const msg of messages) {
|
|
347
|
+
if (msg.role === 'system')
|
|
348
|
+
continue;
|
|
349
|
+
const role = msg.role === 'assistant' ? 'model' : 'user';
|
|
350
|
+
const parts = [];
|
|
351
|
+
let degraded = false;
|
|
352
|
+
const blocks = (0, utils_1.getMessageBlocks)(msg);
|
|
353
|
+
for (const block of blocks) {
|
|
354
|
+
if (block.type === 'text') {
|
|
355
|
+
if (block.text)
|
|
356
|
+
parts.push({ text: block.text });
|
|
357
|
+
}
|
|
358
|
+
else if (block.type === 'reasoning') {
|
|
359
|
+
if (reasoningTransport === 'text') {
|
|
360
|
+
const text = `<think>${block.reasoning}</think>`;
|
|
361
|
+
parts.push({ text });
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
else if (block.type === 'image') {
|
|
365
|
+
const imagePart = (0, utils_1.buildGeminiImagePart)(block);
|
|
366
|
+
if (imagePart) {
|
|
367
|
+
parts.push(imagePart);
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
degraded = true;
|
|
371
|
+
parts.push({ text: utils_1.IMAGE_UNSUPPORTED_TEXT });
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
else if (block.type === 'audio') {
|
|
375
|
+
degraded = true;
|
|
376
|
+
parts.push({ text: utils_1.AUDIO_UNSUPPORTED_TEXT });
|
|
377
|
+
}
|
|
378
|
+
else if (block.type === 'file') {
|
|
379
|
+
const filePart = (0, utils_1.buildGeminiFilePart)(block);
|
|
380
|
+
if (filePart) {
|
|
381
|
+
parts.push(filePart);
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
degraded = true;
|
|
385
|
+
parts.push({ text: utils_1.FILE_UNSUPPORTED_TEXT });
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
else if (block.type === 'tool_use') {
|
|
389
|
+
const part = {
|
|
390
|
+
functionCall: {
|
|
391
|
+
name: block.name,
|
|
392
|
+
args: this.normalizeGeminiArgs(block.input),
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
const signature = toolSignatureById.get(block.id);
|
|
396
|
+
if (signature) {
|
|
397
|
+
part.thoughtSignature = signature;
|
|
398
|
+
}
|
|
399
|
+
parts.push(part);
|
|
400
|
+
}
|
|
401
|
+
else if (block.type === 'tool_result') {
|
|
402
|
+
const toolName = toolNameById.get(block.tool_use_id) ?? 'tool';
|
|
403
|
+
parts.push({
|
|
404
|
+
functionResponse: {
|
|
405
|
+
name: toolName,
|
|
406
|
+
response: { content: this.formatGeminiToolResult(block.content) },
|
|
407
|
+
},
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
if (degraded) {
|
|
412
|
+
(0, utils_1.markTransportIfDegraded)(msg, blocks);
|
|
413
|
+
}
|
|
414
|
+
if (parts.length > 0) {
|
|
415
|
+
contents.push({ role, parts });
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
return contents;
|
|
419
|
+
}
|
|
420
|
+
buildGeminiTools(tools) {
|
|
421
|
+
return [
|
|
422
|
+
{
|
|
423
|
+
functionDeclarations: tools.map((tool) => ({
|
|
424
|
+
name: tool.name,
|
|
425
|
+
description: tool.description,
|
|
426
|
+
parameters: (0, utils_1.sanitizeGeminiSchema)(tool.input_schema),
|
|
427
|
+
})),
|
|
428
|
+
},
|
|
429
|
+
];
|
|
430
|
+
}
|
|
431
|
+
normalizeGeminiArgs(input) {
|
|
432
|
+
if (input && typeof input === 'object' && !Array.isArray(input)) {
|
|
433
|
+
return input;
|
|
434
|
+
}
|
|
435
|
+
return { value: input };
|
|
436
|
+
}
|
|
437
|
+
formatGeminiToolResult(content) {
|
|
438
|
+
if (typeof content === 'string')
|
|
439
|
+
return content;
|
|
440
|
+
return (0, utils_1.safeJsonStringify)(content);
|
|
441
|
+
}
|
|
442
|
+
extractGeminiContentBlocks(content) {
|
|
443
|
+
const blocks = [];
|
|
444
|
+
const parts = content?.parts ?? [];
|
|
445
|
+
for (const part of parts) {
|
|
446
|
+
if (typeof part?.text === 'string') {
|
|
447
|
+
blocks.push({ type: 'text', text: part.text });
|
|
448
|
+
}
|
|
449
|
+
else if (part?.functionCall) {
|
|
450
|
+
const call = part.functionCall;
|
|
451
|
+
const thoughtSignature = part?.thoughtSignature ?? call?.thoughtSignature;
|
|
452
|
+
blocks.push({
|
|
453
|
+
type: 'tool_use',
|
|
454
|
+
id: `toolcall-${Date.now()}-${blocks.length}`,
|
|
455
|
+
name: call.name ?? 'tool',
|
|
456
|
+
input: call.args ?? {},
|
|
457
|
+
...(thoughtSignature ? { meta: { thought_signature: thoughtSignature } } : {}),
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return blocks;
|
|
462
|
+
}
|
|
463
|
+
parseGeminiChunk(event) {
|
|
464
|
+
const textChunks = [];
|
|
465
|
+
const functionCalls = [];
|
|
466
|
+
const candidates = Array.isArray(event?.candidates) ? event.candidates : [];
|
|
467
|
+
for (const candidate of candidates) {
|
|
468
|
+
const parts = candidate?.content?.parts ?? [];
|
|
469
|
+
for (const part of parts) {
|
|
470
|
+
if (typeof part?.text === 'string') {
|
|
471
|
+
textChunks.push(part.text);
|
|
472
|
+
}
|
|
473
|
+
else if (part?.functionCall) {
|
|
474
|
+
const thoughtSignature = part?.thoughtSignature ?? part?.functionCall?.thoughtSignature;
|
|
475
|
+
functionCalls.push({
|
|
476
|
+
name: part.functionCall.name ?? 'tool',
|
|
477
|
+
args: part.functionCall.args ?? {},
|
|
478
|
+
...(thoughtSignature ? { thoughtSignature } : {}),
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
const usageMetadata = event?.usageMetadata;
|
|
484
|
+
const usage = usageMetadata
|
|
485
|
+
? {
|
|
486
|
+
input: usageMetadata.promptTokenCount ?? 0,
|
|
487
|
+
output: usageMetadata.candidatesTokenCount ?? 0,
|
|
488
|
+
}
|
|
489
|
+
: undefined;
|
|
490
|
+
return { textChunks, functionCalls, usage };
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
exports.GeminiProvider = GeminiProvider;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Provider Adapters Module
|
|
4
|
+
*
|
|
5
|
+
* KODE Agent SDK uses Anthropic-style messages as the internal canonical format.
|
|
6
|
+
* Each provider is an adapter that converts to/from this internal format.
|
|
7
|
+
*
|
|
8
|
+
* Message Flow:
|
|
9
|
+
* ```
|
|
10
|
+
* Internal Message[] (Anthropic-style)
|
|
11
|
+
* -> Provider.formatMessages() -> External API format
|
|
12
|
+
* -> API call
|
|
13
|
+
* -> Response -> normalizeContent() -> Internal ContentBlock[]
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* Supported Providers:
|
|
17
|
+
* - AnthropicProvider: Claude models with thinking blocks, files API
|
|
18
|
+
* - OpenAIProvider: GPT models via Chat Completions or Responses API
|
|
19
|
+
* - GeminiProvider: Gemini models with thinking support
|
|
20
|
+
*/
|
|
21
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
24
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
25
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
26
|
+
}
|
|
27
|
+
Object.defineProperty(o, k2, desc);
|
|
28
|
+
}) : (function(o, m, k, k2) {
|
|
29
|
+
if (k2 === undefined) k2 = k;
|
|
30
|
+
o[k2] = m[k];
|
|
31
|
+
}));
|
|
32
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
33
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
34
|
+
};
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.normalizeAnthropicDelta = exports.normalizeAnthropicContentBlock = exports.normalizeAnthropicContent = exports.mergeAnthropicBetaHeader = exports.hasAnthropicFileBlocks = exports.sanitizeGeminiSchema = exports.buildGeminiFilePart = exports.buildGeminiImagePart = exports.extractReasoningDetails = exports.splitThinkText = exports.normalizeThinkBlocks = exports.joinReasoningBlocks = exports.concatTextWithReasoning = exports.AUDIO_UNSUPPORTED_TEXT = exports.IMAGE_UNSUPPORTED_TEXT = exports.FILE_UNSUPPORTED_TEXT = exports.safeJsonStringify = exports.formatToolResult = exports.joinTextBlocks = exports.markTransportIfDegraded = exports.getMessageBlocks = exports.normalizeGeminiBaseUrl = exports.normalizeAnthropicBaseUrl = exports.normalizeOpenAIBaseUrl = exports.normalizeBaseUrl = exports.withProxy = exports.getProxyDispatcher = exports.resolveProxyUrl = exports.GeminiProvider = exports.OpenAIProvider = exports.AnthropicProvider = void 0;
|
|
37
|
+
// Provider implementations
|
|
38
|
+
var anthropic_1 = require("./anthropic");
|
|
39
|
+
Object.defineProperty(exports, "AnthropicProvider", { enumerable: true, get: function () { return anthropic_1.AnthropicProvider; } });
|
|
40
|
+
var openai_1 = require("./openai");
|
|
41
|
+
Object.defineProperty(exports, "OpenAIProvider", { enumerable: true, get: function () { return openai_1.OpenAIProvider; } });
|
|
42
|
+
var gemini_1 = require("./gemini");
|
|
43
|
+
Object.defineProperty(exports, "GeminiProvider", { enumerable: true, get: function () { return gemini_1.GeminiProvider; } });
|
|
44
|
+
// Utilities (for custom provider implementations)
|
|
45
|
+
var utils_1 = require("./utils");
|
|
46
|
+
// Proxy
|
|
47
|
+
Object.defineProperty(exports, "resolveProxyUrl", { enumerable: true, get: function () { return utils_1.resolveProxyUrl; } });
|
|
48
|
+
Object.defineProperty(exports, "getProxyDispatcher", { enumerable: true, get: function () { return utils_1.getProxyDispatcher; } });
|
|
49
|
+
Object.defineProperty(exports, "withProxy", { enumerable: true, get: function () { return utils_1.withProxy; } });
|
|
50
|
+
// URL normalization
|
|
51
|
+
Object.defineProperty(exports, "normalizeBaseUrl", { enumerable: true, get: function () { return utils_1.normalizeBaseUrl; } });
|
|
52
|
+
Object.defineProperty(exports, "normalizeOpenAIBaseUrl", { enumerable: true, get: function () { return utils_1.normalizeOpenAIBaseUrl; } });
|
|
53
|
+
Object.defineProperty(exports, "normalizeAnthropicBaseUrl", { enumerable: true, get: function () { return utils_1.normalizeAnthropicBaseUrl; } });
|
|
54
|
+
Object.defineProperty(exports, "normalizeGeminiBaseUrl", { enumerable: true, get: function () { return utils_1.normalizeGeminiBaseUrl; } });
|
|
55
|
+
// Content blocks
|
|
56
|
+
Object.defineProperty(exports, "getMessageBlocks", { enumerable: true, get: function () { return utils_1.getMessageBlocks; } });
|
|
57
|
+
Object.defineProperty(exports, "markTransportIfDegraded", { enumerable: true, get: function () { return utils_1.markTransportIfDegraded; } });
|
|
58
|
+
// Text formatting
|
|
59
|
+
Object.defineProperty(exports, "joinTextBlocks", { enumerable: true, get: function () { return utils_1.joinTextBlocks; } });
|
|
60
|
+
Object.defineProperty(exports, "formatToolResult", { enumerable: true, get: function () { return utils_1.formatToolResult; } });
|
|
61
|
+
Object.defineProperty(exports, "safeJsonStringify", { enumerable: true, get: function () { return utils_1.safeJsonStringify; } });
|
|
62
|
+
// Unsupported content messages
|
|
63
|
+
Object.defineProperty(exports, "FILE_UNSUPPORTED_TEXT", { enumerable: true, get: function () { return utils_1.FILE_UNSUPPORTED_TEXT; } });
|
|
64
|
+
Object.defineProperty(exports, "IMAGE_UNSUPPORTED_TEXT", { enumerable: true, get: function () { return utils_1.IMAGE_UNSUPPORTED_TEXT; } });
|
|
65
|
+
Object.defineProperty(exports, "AUDIO_UNSUPPORTED_TEXT", { enumerable: true, get: function () { return utils_1.AUDIO_UNSUPPORTED_TEXT; } });
|
|
66
|
+
// Reasoning/thinking
|
|
67
|
+
Object.defineProperty(exports, "concatTextWithReasoning", { enumerable: true, get: function () { return utils_1.concatTextWithReasoning; } });
|
|
68
|
+
Object.defineProperty(exports, "joinReasoningBlocks", { enumerable: true, get: function () { return utils_1.joinReasoningBlocks; } });
|
|
69
|
+
Object.defineProperty(exports, "normalizeThinkBlocks", { enumerable: true, get: function () { return utils_1.normalizeThinkBlocks; } });
|
|
70
|
+
Object.defineProperty(exports, "splitThinkText", { enumerable: true, get: function () { return utils_1.splitThinkText; } });
|
|
71
|
+
Object.defineProperty(exports, "extractReasoningDetails", { enumerable: true, get: function () { return utils_1.extractReasoningDetails; } });
|
|
72
|
+
// Gemini helpers
|
|
73
|
+
Object.defineProperty(exports, "buildGeminiImagePart", { enumerable: true, get: function () { return utils_1.buildGeminiImagePart; } });
|
|
74
|
+
Object.defineProperty(exports, "buildGeminiFilePart", { enumerable: true, get: function () { return utils_1.buildGeminiFilePart; } });
|
|
75
|
+
Object.defineProperty(exports, "sanitizeGeminiSchema", { enumerable: true, get: function () { return utils_1.sanitizeGeminiSchema; } });
|
|
76
|
+
// Anthropic helpers
|
|
77
|
+
Object.defineProperty(exports, "hasAnthropicFileBlocks", { enumerable: true, get: function () { return utils_1.hasAnthropicFileBlocks; } });
|
|
78
|
+
Object.defineProperty(exports, "mergeAnthropicBetaHeader", { enumerable: true, get: function () { return utils_1.mergeAnthropicBetaHeader; } });
|
|
79
|
+
Object.defineProperty(exports, "normalizeAnthropicContent", { enumerable: true, get: function () { return utils_1.normalizeAnthropicContent; } });
|
|
80
|
+
Object.defineProperty(exports, "normalizeAnthropicContentBlock", { enumerable: true, get: function () { return utils_1.normalizeAnthropicContentBlock; } });
|
|
81
|
+
Object.defineProperty(exports, "normalizeAnthropicDelta", { enumerable: true, get: function () { return utils_1.normalizeAnthropicDelta; } });
|
|
82
|
+
// Core module (errors, usage, retry, logging, fork)
|
|
83
|
+
__exportStar(require("./core"), exports);
|