@grafana/sigil-sdk-js 0.0.1
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 +3 -0
- package/README.md +367 -0
- package/dist/client.d.ts +102 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +1502 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +190 -0
- package/dist/config.js.map +1 -0
- package/dist/content_capture.d.ts +35 -0
- package/dist/content_capture.d.ts.map +1 -0
- package/dist/content_capture.js +123 -0
- package/dist/content_capture.js.map +1 -0
- package/dist/context.d.ts +11 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +53 -0
- package/dist/context.js.map +1 -0
- package/dist/exporters/default.d.ts +3 -0
- package/dist/exporters/default.d.ts.map +1 -0
- package/dist/exporters/default.js +34 -0
- package/dist/exporters/default.js.map +1 -0
- package/dist/exporters/grpc.d.ts +14 -0
- package/dist/exporters/grpc.d.ts.map +1 -0
- package/dist/exporters/grpc.js +369 -0
- package/dist/exporters/grpc.js.map +1 -0
- package/dist/exporters/http.d.ts +8 -0
- package/dist/exporters/http.d.ts.map +1 -0
- package/dist/exporters/http.js +258 -0
- package/dist/exporters/http.js.map +1 -0
- package/dist/frameworks/google-adk/index.d.ts +136 -0
- package/dist/frameworks/google-adk/index.d.ts.map +1 -0
- package/dist/frameworks/google-adk/index.js +509 -0
- package/dist/frameworks/google-adk/index.js.map +1 -0
- package/dist/frameworks/langchain/index.d.ts +29 -0
- package/dist/frameworks/langchain/index.d.ts.map +1 -0
- package/dist/frameworks/langchain/index.js +70 -0
- package/dist/frameworks/langchain/index.js.map +1 -0
- package/dist/frameworks/langgraph/index.d.ts +29 -0
- package/dist/frameworks/langgraph/index.d.ts.map +1 -0
- package/dist/frameworks/langgraph/index.js +70 -0
- package/dist/frameworks/langgraph/index.js.map +1 -0
- package/dist/frameworks/llamaindex/index.d.ts +43 -0
- package/dist/frameworks/llamaindex/index.d.ts.map +1 -0
- package/dist/frameworks/llamaindex/index.js +493 -0
- package/dist/frameworks/llamaindex/index.js.map +1 -0
- package/dist/frameworks/openai-agents/index.d.ts +33 -0
- package/dist/frameworks/openai-agents/index.d.ts.map +1 -0
- package/dist/frameworks/openai-agents/index.js +531 -0
- package/dist/frameworks/openai-agents/index.js.map +1 -0
- package/dist/frameworks/shared.d.ts +57 -0
- package/dist/frameworks/shared.d.ts.map +1 -0
- package/dist/frameworks/shared.js +1032 -0
- package/dist/frameworks/shared.js.map +1 -0
- package/dist/frameworks/vercel-ai-sdk/hooks.d.ts +18 -0
- package/dist/frameworks/vercel-ai-sdk/hooks.d.ts.map +1 -0
- package/dist/frameworks/vercel-ai-sdk/hooks.js +672 -0
- package/dist/frameworks/vercel-ai-sdk/hooks.js.map +1 -0
- package/dist/frameworks/vercel-ai-sdk/index.d.ts +8 -0
- package/dist/frameworks/vercel-ai-sdk/index.d.ts.map +1 -0
- package/dist/frameworks/vercel-ai-sdk/index.js +7 -0
- package/dist/frameworks/vercel-ai-sdk/index.js.map +1 -0
- package/dist/frameworks/vercel-ai-sdk/mapping.d.ts +49 -0
- package/dist/frameworks/vercel-ai-sdk/mapping.d.ts.map +1 -0
- package/dist/frameworks/vercel-ai-sdk/mapping.js +660 -0
- package/dist/frameworks/vercel-ai-sdk/mapping.js.map +1 -0
- package/dist/frameworks/vercel-ai-sdk/types.d.ts +126 -0
- package/dist/frameworks/vercel-ai-sdk/types.d.ts.map +1 -0
- package/dist/frameworks/vercel-ai-sdk/types.js +2 -0
- package/dist/frameworks/vercel-ai-sdk/types.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/anthropic.d.ts +35 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +581 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/gemini.d.ts +42 -0
- package/dist/providers/gemini.d.ts.map +1 -0
- package/dist/providers/gemini.js +650 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/providers/openai.d.ts +67 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +1007 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/types.d.ts +461 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +25 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +331 -0
- package/dist/utils.js.map +1 -0
- package/docs/frameworks/google-adk.md +84 -0
- package/docs/frameworks/langchain.md +102 -0
- package/docs/frameworks/langgraph.md +137 -0
- package/docs/frameworks/llamaindex.md +82 -0
- package/docs/frameworks/openai-agents.md +88 -0
- package/docs/frameworks/vercel-ai-sdk.md +124 -0
- package/docs/index.md +22 -0
- package/docs/providers/anthropic.md +69 -0
- package/docs/providers/gemini.md +86 -0
- package/docs/providers/openai.md +151 -0
- package/package.json +80 -0
- package/proto/opentelemetry/proto/collector/trace/v1/trace_service.proto +77 -0
- package/proto/opentelemetry/proto/common/v1/common.proto +115 -0
- package/proto/opentelemetry/proto/resource/v1/resource.proto +44 -0
- package/proto/opentelemetry/proto/trace/v1/trace.proto +357 -0
- package/proto/sigil/v1/generation_ingest.proto +145 -0
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
const thinkingBudgetMetadataKey = 'sigil.gen_ai.request.thinking.budget_tokens';
|
|
2
|
+
const thinkingLevelMetadataKey = 'sigil.gen_ai.request.thinking.level';
|
|
3
|
+
const usageToolUsePromptTokensMetadataKey = 'sigil.gen_ai.usage.tool_use_prompt_tokens';
|
|
4
|
+
async function geminiGenerateContent(client, model, contents, config, providerCall, options = {}) {
|
|
5
|
+
const controls = mapGeminiRequestControls(config);
|
|
6
|
+
return client.startGeneration({
|
|
7
|
+
conversationId: options.conversationId,
|
|
8
|
+
agentName: options.agentName,
|
|
9
|
+
agentVersion: options.agentVersion,
|
|
10
|
+
model: {
|
|
11
|
+
provider: 'gemini',
|
|
12
|
+
name: model,
|
|
13
|
+
},
|
|
14
|
+
systemPrompt: extractGeminiSystemPrompt(config),
|
|
15
|
+
maxTokens: controls.maxTokens,
|
|
16
|
+
temperature: controls.temperature,
|
|
17
|
+
topP: controls.topP,
|
|
18
|
+
toolChoice: controls.toolChoice,
|
|
19
|
+
thinkingEnabled: controls.thinkingEnabled,
|
|
20
|
+
tools: mapGeminiTools(config),
|
|
21
|
+
tags: options.tags,
|
|
22
|
+
metadata: metadataWithThinkingBudget(options.metadata, controls.thinkingBudget, controls.thinkingLevel),
|
|
23
|
+
}, async (recorder) => {
|
|
24
|
+
const response = await providerCall(model, contents, config);
|
|
25
|
+
recorder.setResult(geminiFromRequestResponse(model, contents, config, response, options));
|
|
26
|
+
return response;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async function geminiGenerateContentStream(client, model, contents, config, providerCall, options = {}) {
|
|
30
|
+
const controls = mapGeminiRequestControls(config);
|
|
31
|
+
return client.startStreamingGeneration({
|
|
32
|
+
conversationId: options.conversationId,
|
|
33
|
+
agentName: options.agentName,
|
|
34
|
+
agentVersion: options.agentVersion,
|
|
35
|
+
model: {
|
|
36
|
+
provider: 'gemini',
|
|
37
|
+
name: model,
|
|
38
|
+
},
|
|
39
|
+
systemPrompt: extractGeminiSystemPrompt(config),
|
|
40
|
+
maxTokens: controls.maxTokens,
|
|
41
|
+
temperature: controls.temperature,
|
|
42
|
+
topP: controls.topP,
|
|
43
|
+
toolChoice: controls.toolChoice,
|
|
44
|
+
thinkingEnabled: controls.thinkingEnabled,
|
|
45
|
+
tools: mapGeminiTools(config),
|
|
46
|
+
tags: options.tags,
|
|
47
|
+
metadata: metadataWithThinkingBudget(options.metadata, controls.thinkingBudget, controls.thinkingLevel),
|
|
48
|
+
}, async (recorder) => {
|
|
49
|
+
const summary = await providerCall(model, contents, config);
|
|
50
|
+
const firstChunkAt = asDate(summary.firstChunkAt);
|
|
51
|
+
if (firstChunkAt !== undefined) {
|
|
52
|
+
recorder.setFirstTokenAt(firstChunkAt);
|
|
53
|
+
}
|
|
54
|
+
recorder.setResult(geminiFromStream(model, contents, config, summary, options));
|
|
55
|
+
return summary;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
async function geminiEmbedContent(client, model, contents, config, providerCall, options = {}) {
|
|
59
|
+
const requestedDimensions = readIntFromAny(config?.outputDimensionality) ??
|
|
60
|
+
readIntFromAny(config?.output_dimensionality);
|
|
61
|
+
return client.startEmbedding({
|
|
62
|
+
agentName: options.agentName,
|
|
63
|
+
agentVersion: options.agentVersion,
|
|
64
|
+
model: {
|
|
65
|
+
provider: 'gemini',
|
|
66
|
+
name: model,
|
|
67
|
+
},
|
|
68
|
+
dimensions: requestedDimensions,
|
|
69
|
+
tags: options.tags,
|
|
70
|
+
metadata: options.metadata,
|
|
71
|
+
}, async (recorder) => {
|
|
72
|
+
const response = await providerCall(model, contents, config);
|
|
73
|
+
recorder.setResult(geminiEmbeddingFromResponse(model, contents, config, response));
|
|
74
|
+
return response;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function geminiEmbeddingFromResponse(_model, contents, config, response) {
|
|
78
|
+
const result = {
|
|
79
|
+
inputCount: embeddingInputCount(contents),
|
|
80
|
+
inputTexts: embeddingInputTexts(contents),
|
|
81
|
+
};
|
|
82
|
+
const requestedDimensions = readIntFromAny(config?.outputDimensionality) ??
|
|
83
|
+
readIntFromAny(config?.output_dimensionality);
|
|
84
|
+
if (!isRecord(response)) {
|
|
85
|
+
if (requestedDimensions !== undefined && requestedDimensions > 0) {
|
|
86
|
+
result.dimensions = requestedDimensions;
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
const embeddings = Array.isArray(response.embeddings) ? response.embeddings : [];
|
|
91
|
+
let inputTokens = 0;
|
|
92
|
+
for (const embedding of embeddings) {
|
|
93
|
+
if (!isRecord(embedding)) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const statistics = isRecord(embedding.statistics) ? embedding.statistics : undefined;
|
|
97
|
+
const tokenCount = readIntFromAny(statistics?.tokenCount) ?? readIntFromAny(statistics?.token_count);
|
|
98
|
+
if (tokenCount !== undefined && tokenCount > 0) {
|
|
99
|
+
inputTokens += tokenCount;
|
|
100
|
+
}
|
|
101
|
+
if (result.dimensions === undefined && Array.isArray(embedding.values) && embedding.values.length > 0) {
|
|
102
|
+
result.dimensions = embedding.values.length;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (inputTokens > 0) {
|
|
106
|
+
result.inputTokens = inputTokens;
|
|
107
|
+
}
|
|
108
|
+
if (result.dimensions === undefined && requestedDimensions !== undefined && requestedDimensions > 0) {
|
|
109
|
+
result.dimensions = requestedDimensions;
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
function geminiFromRequestResponse(model, contents, config, response, options = {}) {
|
|
114
|
+
const controls = mapGeminiRequestControls(config);
|
|
115
|
+
const output = mapGeminiResponseOutput(response);
|
|
116
|
+
const usageMetadata = geminiUsageMetadata(response.usageMetadata);
|
|
117
|
+
const result = {
|
|
118
|
+
responseId: asString(response.responseId),
|
|
119
|
+
responseModel: asString(response.modelVersion) || model,
|
|
120
|
+
maxTokens: controls.maxTokens,
|
|
121
|
+
temperature: controls.temperature,
|
|
122
|
+
topP: controls.topP,
|
|
123
|
+
toolChoice: controls.toolChoice,
|
|
124
|
+
thinkingEnabled: controls.thinkingEnabled,
|
|
125
|
+
input: mapGeminiInput(contents),
|
|
126
|
+
output,
|
|
127
|
+
tools: mapGeminiTools(config),
|
|
128
|
+
usage: mapGeminiUsage(response.usageMetadata),
|
|
129
|
+
stopReason: mapGeminiStopReason(response),
|
|
130
|
+
metadata: mergeMetadata(metadataWithThinkingBudget(options.metadata, controls.thinkingBudget, controls.thinkingLevel), usageMetadata),
|
|
131
|
+
tags: options.tags ? { ...options.tags } : undefined,
|
|
132
|
+
};
|
|
133
|
+
if (options.rawArtifacts) {
|
|
134
|
+
result.artifacts = [
|
|
135
|
+
jsonArtifact('request', 'gemini.models.request', { model, contents, config }),
|
|
136
|
+
jsonArtifact('response', 'gemini.models.response', response),
|
|
137
|
+
];
|
|
138
|
+
if ((result.tools ?? []).length > 0) {
|
|
139
|
+
result.artifacts.push(jsonArtifact('tools', 'gemini.models.tools', result.tools));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
function geminiFromStream(model, contents, config, summary, options = {}) {
|
|
145
|
+
const controls = mapGeminiRequestControls(config);
|
|
146
|
+
const responses = summary.responses ?? [];
|
|
147
|
+
const finalResponse = summary.finalResponse ?? (responses.length > 0 ? responses[responses.length - 1] : undefined);
|
|
148
|
+
const outputText = summary.outputText ?? extractGeminiStreamText(responses);
|
|
149
|
+
const fallbackOutput = outputText.length > 0 ? [{ role: 'assistant', content: outputText }] : [];
|
|
150
|
+
const streamUsageMetadata = geminiStreamUsageMetadata(responses);
|
|
151
|
+
const result = finalResponse
|
|
152
|
+
? {
|
|
153
|
+
...geminiFromRequestResponse(model, contents, config, finalResponse, options),
|
|
154
|
+
output: mapGeminiResponseOutput(finalResponse).length > 0 ? mapGeminiResponseOutput(finalResponse) : fallbackOutput,
|
|
155
|
+
}
|
|
156
|
+
: {
|
|
157
|
+
responseModel: model,
|
|
158
|
+
maxTokens: controls.maxTokens,
|
|
159
|
+
temperature: controls.temperature,
|
|
160
|
+
topP: controls.topP,
|
|
161
|
+
toolChoice: controls.toolChoice,
|
|
162
|
+
thinkingEnabled: controls.thinkingEnabled,
|
|
163
|
+
input: mapGeminiInput(contents),
|
|
164
|
+
output: fallbackOutput,
|
|
165
|
+
tools: mapGeminiTools(config),
|
|
166
|
+
metadata: mergeMetadata(metadataWithThinkingBudget(options.metadata, controls.thinkingBudget, controls.thinkingLevel), streamUsageMetadata),
|
|
167
|
+
tags: options.tags ? { ...options.tags } : undefined,
|
|
168
|
+
};
|
|
169
|
+
if (options.rawArtifacts) {
|
|
170
|
+
const existing = result.artifacts ?? [];
|
|
171
|
+
if (!existing.some((artifact) => artifact.type === 'request')) {
|
|
172
|
+
existing.push(jsonArtifact('request', 'gemini.models.request', { model, contents, config }));
|
|
173
|
+
}
|
|
174
|
+
if ((result.tools ?? []).length > 0 && !existing.some((artifact) => artifact.type === 'tools')) {
|
|
175
|
+
existing.push(jsonArtifact('tools', 'gemini.models.tools', result.tools));
|
|
176
|
+
}
|
|
177
|
+
existing.push(jsonArtifact('provider_event', 'gemini.models.stream_events', responses));
|
|
178
|
+
result.artifacts = existing;
|
|
179
|
+
}
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
export const models = {
|
|
183
|
+
generateContent: geminiGenerateContent,
|
|
184
|
+
generateContentStream: geminiGenerateContentStream,
|
|
185
|
+
embedContent: geminiEmbedContent,
|
|
186
|
+
fromRequestResponse: geminiFromRequestResponse,
|
|
187
|
+
fromStream: geminiFromStream,
|
|
188
|
+
embeddingFromResponse: geminiEmbeddingFromResponse,
|
|
189
|
+
};
|
|
190
|
+
function embeddingInputCount(contents) {
|
|
191
|
+
let count = 0;
|
|
192
|
+
for (const content of contents) {
|
|
193
|
+
if (content !== undefined && content !== null) {
|
|
194
|
+
count += 1;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return count;
|
|
198
|
+
}
|
|
199
|
+
function embeddingInputTexts(contents) {
|
|
200
|
+
const output = [];
|
|
201
|
+
for (const content of contents) {
|
|
202
|
+
if (typeof content === 'string') {
|
|
203
|
+
const text = content.trim();
|
|
204
|
+
if (text.length > 0) {
|
|
205
|
+
output.push(text);
|
|
206
|
+
}
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (!isRecord(content)) {
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
const text = extractText(content.parts);
|
|
213
|
+
if (text.length > 0) {
|
|
214
|
+
output.push(text);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return output.length > 0 ? output : undefined;
|
|
218
|
+
}
|
|
219
|
+
function mapGeminiInput(contents) {
|
|
220
|
+
const input = [];
|
|
221
|
+
for (const rawContent of contents) {
|
|
222
|
+
if (typeof rawContent === 'string') {
|
|
223
|
+
const text = rawContent.trim();
|
|
224
|
+
if (text.length > 0) {
|
|
225
|
+
input.push({ role: 'user', content: text });
|
|
226
|
+
}
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (!isRecord(rawContent)) {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const role = normalizeRole(asString(rawContent.role));
|
|
233
|
+
const parts = mapGeminiParts(rawContent.parts, role);
|
|
234
|
+
const text = extractText(rawContent.parts);
|
|
235
|
+
if (parts.length > 0) {
|
|
236
|
+
const hasToolResult = parts.some((part) => part.type === 'tool_result');
|
|
237
|
+
input.push({
|
|
238
|
+
role: hasToolResult ? 'tool' : role,
|
|
239
|
+
content: text || undefined,
|
|
240
|
+
parts,
|
|
241
|
+
});
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (text.length > 0) {
|
|
245
|
+
input.push({ role, content: text });
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return input;
|
|
249
|
+
}
|
|
250
|
+
function mapGeminiResponseOutput(response) {
|
|
251
|
+
const output = [];
|
|
252
|
+
const candidates = Array.isArray(response.candidates)
|
|
253
|
+
? response.candidates
|
|
254
|
+
: [];
|
|
255
|
+
for (const rawCandidate of candidates) {
|
|
256
|
+
if (!isRecord(rawCandidate) || !isRecord(rawCandidate.content)) {
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
const role = normalizeRole(asString(rawCandidate.content.role) || 'assistant');
|
|
260
|
+
const parts = mapGeminiParts(rawCandidate.content.parts, role);
|
|
261
|
+
const text = extractText(rawCandidate.content.parts);
|
|
262
|
+
if (parts.length === 0 && text.length === 0) {
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
output.push({
|
|
266
|
+
role,
|
|
267
|
+
content: text || undefined,
|
|
268
|
+
parts: parts.length > 0 ? parts : undefined,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
return output;
|
|
272
|
+
}
|
|
273
|
+
function mapGeminiParts(rawParts, role) {
|
|
274
|
+
if (!Array.isArray(rawParts)) {
|
|
275
|
+
return [];
|
|
276
|
+
}
|
|
277
|
+
const parts = [];
|
|
278
|
+
for (const rawPart of rawParts) {
|
|
279
|
+
if (!isRecord(rawPart)) {
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
if (typeof rawPart.text === 'string' && rawPart.text.trim().length > 0) {
|
|
283
|
+
if (rawPart.thought === true && role === 'assistant') {
|
|
284
|
+
parts.push({
|
|
285
|
+
type: 'thinking',
|
|
286
|
+
thinking: rawPart.text,
|
|
287
|
+
metadata: { providerType: 'thought' },
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
parts.push({
|
|
292
|
+
type: 'text',
|
|
293
|
+
text: rawPart.text,
|
|
294
|
+
metadata: { providerType: 'text' },
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (isRecord(rawPart.functionCall)) {
|
|
299
|
+
const name = asString(rawPart.functionCall.name);
|
|
300
|
+
if (name.length > 0) {
|
|
301
|
+
parts.push({
|
|
302
|
+
type: 'tool_call',
|
|
303
|
+
toolCall: {
|
|
304
|
+
id: asString(rawPart.functionCall.id) || undefined,
|
|
305
|
+
name,
|
|
306
|
+
inputJSON: jsonString(rawPart.functionCall.args),
|
|
307
|
+
},
|
|
308
|
+
metadata: { providerType: 'function_call' },
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (isRecord(rawPart.functionResponse)) {
|
|
313
|
+
const responseValue = rawPart.functionResponse.response;
|
|
314
|
+
parts.push({
|
|
315
|
+
type: 'tool_result',
|
|
316
|
+
toolResult: {
|
|
317
|
+
toolCallId: asString(rawPart.functionResponse.id) || undefined,
|
|
318
|
+
name: asString(rawPart.functionResponse.name) || undefined,
|
|
319
|
+
content: extractText(responseValue) || undefined,
|
|
320
|
+
contentJSON: jsonString(responseValue),
|
|
321
|
+
isError: typeof rawPart.functionResponse.isError === 'boolean' ? rawPart.functionResponse.isError : undefined,
|
|
322
|
+
},
|
|
323
|
+
metadata: { providerType: 'function_response' },
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return parts;
|
|
328
|
+
}
|
|
329
|
+
function mapGeminiTools(config) {
|
|
330
|
+
if (!isRecord(config) || !Array.isArray(config.tools)) {
|
|
331
|
+
return [];
|
|
332
|
+
}
|
|
333
|
+
const out = [];
|
|
334
|
+
for (const rawTool of config.tools) {
|
|
335
|
+
if (!isRecord(rawTool) || !Array.isArray(rawTool.functionDeclarations)) {
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
for (const rawDeclaration of rawTool.functionDeclarations) {
|
|
339
|
+
if (!isRecord(rawDeclaration)) {
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
const name = asString(rawDeclaration.name);
|
|
343
|
+
if (name.length === 0) {
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
out.push({
|
|
347
|
+
name,
|
|
348
|
+
description: asString(rawDeclaration.description) || undefined,
|
|
349
|
+
type: 'function',
|
|
350
|
+
inputSchemaJSON: hasValue(rawDeclaration.parametersJsonSchema)
|
|
351
|
+
? jsonString(rawDeclaration.parametersJsonSchema)
|
|
352
|
+
: undefined,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return out;
|
|
357
|
+
}
|
|
358
|
+
function mapGeminiUsage(rawUsage) {
|
|
359
|
+
if (!isRecord(rawUsage)) {
|
|
360
|
+
return undefined;
|
|
361
|
+
}
|
|
362
|
+
const inputTokens = readIntFromAny(rawUsage.promptTokenCount);
|
|
363
|
+
const outputTokens = readIntFromAny(rawUsage.candidatesTokenCount);
|
|
364
|
+
const totalTokens = readIntFromAny(rawUsage.totalTokenCount);
|
|
365
|
+
const cacheReadInputTokens = readIntFromAny(rawUsage.cachedContentTokenCount);
|
|
366
|
+
const cacheCreationInputTokens = readIntFromAny(rawUsage.cacheCreationInputTokenCount);
|
|
367
|
+
const toolUsePromptTokens = readIntFromAny(rawUsage.toolUsePromptTokenCount);
|
|
368
|
+
const reasoningTokens = readIntFromAny(rawUsage.thoughtsTokenCount);
|
|
369
|
+
const out = {};
|
|
370
|
+
if (inputTokens !== undefined) {
|
|
371
|
+
out.inputTokens = inputTokens;
|
|
372
|
+
}
|
|
373
|
+
if (outputTokens !== undefined) {
|
|
374
|
+
out.outputTokens = outputTokens;
|
|
375
|
+
}
|
|
376
|
+
if (totalTokens !== undefined) {
|
|
377
|
+
out.totalTokens = totalTokens;
|
|
378
|
+
}
|
|
379
|
+
else if (inputTokens !== undefined || outputTokens !== undefined) {
|
|
380
|
+
out.totalTokens = (inputTokens ?? 0) + (outputTokens ?? 0) + (toolUsePromptTokens ?? 0) + (reasoningTokens ?? 0);
|
|
381
|
+
}
|
|
382
|
+
if (cacheReadInputTokens !== undefined) {
|
|
383
|
+
out.cacheReadInputTokens = cacheReadInputTokens;
|
|
384
|
+
}
|
|
385
|
+
if (cacheCreationInputTokens !== undefined) {
|
|
386
|
+
out.cacheCreationInputTokens = cacheCreationInputTokens;
|
|
387
|
+
}
|
|
388
|
+
if (reasoningTokens !== undefined) {
|
|
389
|
+
out.reasoningTokens = reasoningTokens;
|
|
390
|
+
}
|
|
391
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
392
|
+
}
|
|
393
|
+
function geminiUsageMetadata(rawUsage) {
|
|
394
|
+
if (!isRecord(rawUsage)) {
|
|
395
|
+
return undefined;
|
|
396
|
+
}
|
|
397
|
+
const toolUsePromptTokens = readIntFromAny(rawUsage.toolUsePromptTokenCount ?? rawUsage.tool_use_prompt_token_count);
|
|
398
|
+
if (toolUsePromptTokens === undefined || toolUsePromptTokens <= 0) {
|
|
399
|
+
return undefined;
|
|
400
|
+
}
|
|
401
|
+
return {
|
|
402
|
+
[usageToolUsePromptTokensMetadataKey]: toolUsePromptTokens,
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
function mapGeminiStopReason(response) {
|
|
406
|
+
const candidates = Array.isArray(response.candidates)
|
|
407
|
+
? response.candidates
|
|
408
|
+
: [];
|
|
409
|
+
let stopReason;
|
|
410
|
+
for (const rawCandidate of candidates) {
|
|
411
|
+
if (!isRecord(rawCandidate)) {
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
const candidateStopReason = asString(rawCandidate.finishReason);
|
|
415
|
+
if (candidateStopReason.length > 0) {
|
|
416
|
+
stopReason = candidateStopReason.toUpperCase();
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return stopReason;
|
|
420
|
+
}
|
|
421
|
+
function mapGeminiRequestControls(config) {
|
|
422
|
+
if (!isRecord(config)) {
|
|
423
|
+
return {};
|
|
424
|
+
}
|
|
425
|
+
const toolConfig = isRecord(config.toolConfig) ? config.toolConfig : undefined;
|
|
426
|
+
const functionCallingConfig = toolConfig && isRecord(toolConfig.functionCallingConfig) ? toolConfig.functionCallingConfig : undefined;
|
|
427
|
+
const thinkingConfig = isRecord(config.thinkingConfig) ? config.thinkingConfig : undefined;
|
|
428
|
+
return {
|
|
429
|
+
maxTokens: readIntFromAny(config.maxOutputTokens),
|
|
430
|
+
temperature: readNumberFromAny(config.temperature),
|
|
431
|
+
topP: readNumberFromAny(config.topP),
|
|
432
|
+
toolChoice: canonicalToolChoice(functionCallingConfig?.mode),
|
|
433
|
+
thinkingEnabled: typeof thinkingConfig?.includeThoughts === 'boolean' ? thinkingConfig.includeThoughts : undefined,
|
|
434
|
+
thinkingBudget: readIntFromAny(thinkingConfig?.thinkingBudget),
|
|
435
|
+
thinkingLevel: geminiThinkingLevel(thinkingConfig?.thinkingLevel),
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
function extractGeminiSystemPrompt(config) {
|
|
439
|
+
if (!isRecord(config)) {
|
|
440
|
+
return undefined;
|
|
441
|
+
}
|
|
442
|
+
const instruction = config.systemInstruction;
|
|
443
|
+
if (!hasValue(instruction)) {
|
|
444
|
+
return undefined;
|
|
445
|
+
}
|
|
446
|
+
if (typeof instruction === 'string') {
|
|
447
|
+
const text = instruction.trim();
|
|
448
|
+
return text.length > 0 ? text : undefined;
|
|
449
|
+
}
|
|
450
|
+
if (isRecord(instruction) && Array.isArray(instruction.parts)) {
|
|
451
|
+
const chunks = instruction.parts
|
|
452
|
+
.map((part) => {
|
|
453
|
+
if (!isRecord(part)) {
|
|
454
|
+
return '';
|
|
455
|
+
}
|
|
456
|
+
return typeof part.text === 'string' ? part.text.trim() : '';
|
|
457
|
+
})
|
|
458
|
+
.filter((chunk) => chunk.length > 0);
|
|
459
|
+
if (chunks.length > 0) {
|
|
460
|
+
return chunks.join('\n');
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
const fallback = extractText(instruction);
|
|
464
|
+
return fallback.length > 0 ? fallback : undefined;
|
|
465
|
+
}
|
|
466
|
+
function extractGeminiStreamText(responses) {
|
|
467
|
+
const chunks = [];
|
|
468
|
+
for (const response of responses) {
|
|
469
|
+
const output = mapGeminiResponseOutput(response);
|
|
470
|
+
for (const message of output) {
|
|
471
|
+
if (typeof message.content === 'string' && message.content.trim().length > 0) {
|
|
472
|
+
chunks.push(message.content.trim());
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
return chunks.join('\n');
|
|
477
|
+
}
|
|
478
|
+
function normalizeRole(value) {
|
|
479
|
+
const normalized = value.trim().toLowerCase();
|
|
480
|
+
if (normalized === 'assistant' || normalized === 'model') {
|
|
481
|
+
return 'assistant';
|
|
482
|
+
}
|
|
483
|
+
if (normalized === 'tool') {
|
|
484
|
+
return 'tool';
|
|
485
|
+
}
|
|
486
|
+
return 'user';
|
|
487
|
+
}
|
|
488
|
+
function canonicalToolChoice(value) {
|
|
489
|
+
if (value === undefined || value === null) {
|
|
490
|
+
return undefined;
|
|
491
|
+
}
|
|
492
|
+
if (typeof value === 'string') {
|
|
493
|
+
const normalized = value.trim().toLowerCase();
|
|
494
|
+
return normalized.length > 0 ? normalized : undefined;
|
|
495
|
+
}
|
|
496
|
+
if (isRecord(value) && 'value' in value) {
|
|
497
|
+
const normalized = String(value.value ?? '')
|
|
498
|
+
.trim()
|
|
499
|
+
.toLowerCase();
|
|
500
|
+
return normalized.length > 0 ? normalized : undefined;
|
|
501
|
+
}
|
|
502
|
+
return jsonString(value);
|
|
503
|
+
}
|
|
504
|
+
function metadataWithThinkingBudget(metadata, thinkingBudget, thinkingLevel) {
|
|
505
|
+
if (thinkingBudget === undefined && thinkingLevel === undefined) {
|
|
506
|
+
return metadata ? { ...metadata } : undefined;
|
|
507
|
+
}
|
|
508
|
+
const out = metadata ? { ...metadata } : {};
|
|
509
|
+
if (thinkingBudget !== undefined) {
|
|
510
|
+
out[thinkingBudgetMetadataKey] = thinkingBudget;
|
|
511
|
+
}
|
|
512
|
+
if (thinkingLevel !== undefined) {
|
|
513
|
+
out[thinkingLevelMetadataKey] = thinkingLevel;
|
|
514
|
+
}
|
|
515
|
+
return out;
|
|
516
|
+
}
|
|
517
|
+
function geminiThinkingLevel(value) {
|
|
518
|
+
const raw = asString(value).toLowerCase();
|
|
519
|
+
if (raw.length === 0 || raw === 'thinking_level_unspecified') {
|
|
520
|
+
return undefined;
|
|
521
|
+
}
|
|
522
|
+
if (raw === 'thinking_level_low' || raw === 'low') {
|
|
523
|
+
return 'low';
|
|
524
|
+
}
|
|
525
|
+
if (raw === 'thinking_level_medium' || raw === 'medium') {
|
|
526
|
+
return 'medium';
|
|
527
|
+
}
|
|
528
|
+
if (raw === 'thinking_level_high' || raw === 'high') {
|
|
529
|
+
return 'high';
|
|
530
|
+
}
|
|
531
|
+
if (raw === 'thinking_level_minimal' || raw === 'minimal') {
|
|
532
|
+
return 'minimal';
|
|
533
|
+
}
|
|
534
|
+
return raw;
|
|
535
|
+
}
|
|
536
|
+
function geminiStreamUsageMetadata(responses) {
|
|
537
|
+
for (let index = responses.length - 1; index >= 0; index -= 1) {
|
|
538
|
+
const metadata = geminiUsageMetadata(responses[index].usageMetadata);
|
|
539
|
+
if (metadata !== undefined) {
|
|
540
|
+
return metadata;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
return undefined;
|
|
544
|
+
}
|
|
545
|
+
function mergeMetadata(base, extra) {
|
|
546
|
+
if (base === undefined) {
|
|
547
|
+
return extra ? { ...extra } : undefined;
|
|
548
|
+
}
|
|
549
|
+
if (extra === undefined) {
|
|
550
|
+
return { ...base };
|
|
551
|
+
}
|
|
552
|
+
return { ...base, ...extra };
|
|
553
|
+
}
|
|
554
|
+
function extractText(value) {
|
|
555
|
+
if (!hasValue(value)) {
|
|
556
|
+
return '';
|
|
557
|
+
}
|
|
558
|
+
if (typeof value === 'string') {
|
|
559
|
+
return value.trim();
|
|
560
|
+
}
|
|
561
|
+
if (Array.isArray(value)) {
|
|
562
|
+
const chunks = [];
|
|
563
|
+
for (const item of value) {
|
|
564
|
+
const chunk = extractText(item);
|
|
565
|
+
if (chunk.length > 0) {
|
|
566
|
+
chunks.push(chunk);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
return chunks.join('\n');
|
|
570
|
+
}
|
|
571
|
+
if (isRecord(value)) {
|
|
572
|
+
if (typeof value.text === 'string' && value.text.trim().length > 0) {
|
|
573
|
+
return value.text.trim();
|
|
574
|
+
}
|
|
575
|
+
if ('content' in value && value.content !== undefined && value.content !== null) {
|
|
576
|
+
return extractText(value.content);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
return String(value).trim();
|
|
580
|
+
}
|
|
581
|
+
function asString(value) {
|
|
582
|
+
if (typeof value === 'string') {
|
|
583
|
+
return value.trim();
|
|
584
|
+
}
|
|
585
|
+
return value === undefined || value === null ? '' : String(value).trim();
|
|
586
|
+
}
|
|
587
|
+
function readIntFromAny(value) {
|
|
588
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
589
|
+
const asInt = Math.trunc(value);
|
|
590
|
+
return Number.isNaN(asInt) ? undefined : asInt;
|
|
591
|
+
}
|
|
592
|
+
if (typeof value === 'string') {
|
|
593
|
+
const parsed = Number.parseInt(value.trim(), 10);
|
|
594
|
+
return Number.isNaN(parsed) ? undefined : parsed;
|
|
595
|
+
}
|
|
596
|
+
return undefined;
|
|
597
|
+
}
|
|
598
|
+
function readNumberFromAny(value) {
|
|
599
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
600
|
+
return value;
|
|
601
|
+
}
|
|
602
|
+
if (typeof value === 'string') {
|
|
603
|
+
const parsed = Number.parseFloat(value.trim());
|
|
604
|
+
return Number.isNaN(parsed) ? undefined : parsed;
|
|
605
|
+
}
|
|
606
|
+
return undefined;
|
|
607
|
+
}
|
|
608
|
+
function jsonArtifact(type, name, payload) {
|
|
609
|
+
return {
|
|
610
|
+
type,
|
|
611
|
+
name,
|
|
612
|
+
payload: jsonString(payload),
|
|
613
|
+
mimeType: 'application/json',
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
function jsonString(value) {
|
|
617
|
+
try {
|
|
618
|
+
return JSON.stringify(value, objectKeySorter);
|
|
619
|
+
}
|
|
620
|
+
catch {
|
|
621
|
+
return String(value ?? '');
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
function objectKeySorter(_key, value) {
|
|
625
|
+
if (!isRecord(value) || Array.isArray(value)) {
|
|
626
|
+
return value;
|
|
627
|
+
}
|
|
628
|
+
const sorted = {};
|
|
629
|
+
for (const key of Object.keys(value).sort()) {
|
|
630
|
+
sorted[key] = value[key];
|
|
631
|
+
}
|
|
632
|
+
return sorted;
|
|
633
|
+
}
|
|
634
|
+
function hasValue(value) {
|
|
635
|
+
return value !== undefined && value !== null;
|
|
636
|
+
}
|
|
637
|
+
function isRecord(value) {
|
|
638
|
+
return typeof value === 'object' && value !== null;
|
|
639
|
+
}
|
|
640
|
+
function asDate(value) {
|
|
641
|
+
if (value === undefined) {
|
|
642
|
+
return undefined;
|
|
643
|
+
}
|
|
644
|
+
const date = value instanceof Date ? new Date(value) : new Date(value);
|
|
645
|
+
if (Number.isNaN(date.getTime())) {
|
|
646
|
+
return undefined;
|
|
647
|
+
}
|
|
648
|
+
return date;
|
|
649
|
+
}
|
|
650
|
+
//# sourceMappingURL=gemini.js.map
|