@rcrsr/rill-ext-gemini 0.8.6 → 0.11.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @rcrsr/rill-ext-gemini
2
2
 
3
- [rill](https://rill.run) extension for [Google Gemini](https://ai.google.dev/docs) API integration. Provides `message`, `messages`, `embed`, `embed_batch`, and `tool_loop` host functions.
3
+ [rill](https://rill.run) extension for [Google Gemini](https://ai.google.dev/docs) API integration. Provides `message`, `messages`, `embed`, `embed_batch`, `tool_loop`, and `generate` host functions.
4
4
 
5
5
  > **Experimental.** Breaking changes will occur before stabilization.
6
6
 
@@ -36,131 +36,15 @@ const result = await execute(parse(script), ctx);
36
36
  dispose?.();
37
37
  ```
38
38
 
39
- ## Host Functions
40
-
41
- All functions return a dict with `content`, `model`, `usage`, `stop_reason`, `id`, and `messages`.
42
-
43
- ### gemini::message(text, options?)
44
-
45
- Send a single message to Gemini.
46
-
47
- ```rill
48
- gemini::message("Analyze this code for security issues") => $response
49
- $response.content -> log
50
- $response.usage.output -> log
51
- ```
52
-
53
- ### gemini::messages(messages, options?)
54
-
55
- Send a multi-turn conversation.
56
-
57
- ```rill
58
- gemini::messages([
59
- [role: "user", content: "What is rill?"],
60
- [role: "assistant", content: "A scripting language for AI agents."],
61
- [role: "user", content: "Show me an example."]
62
- ]) => $response
63
- $response.content -> log
64
- ```
65
-
66
- ### gemini::embed(text)
67
-
68
- Generate an embedding vector for text. Requires `embed_model` in config.
69
-
70
- ```rill
71
- gemini::embed("Hello world") => $vector
72
- ```
73
-
74
- ### gemini::embed_batch(texts)
75
-
76
- Generate embedding vectors for multiple texts in a single API call.
77
-
78
- ```rill
79
- gemini::embed_batch(["Hello", "World"]) => $vectors
80
- ```
81
-
82
- ### gemini::tool_loop(prompt, options)
83
-
84
- Execute a tool-use loop where the model calls rill functions iteratively.
85
-
86
- ```rill
87
- gemini::tool_loop("Find the weather", [tools: $my_tools]) => $result
88
- $result.content -> log
89
- $result.turns -> log
90
- ```
91
-
92
- ## Configuration
93
-
94
- ```typescript
95
- const ext = createGeminiExtension({
96
- api_key: process.env.GOOGLE_API_KEY!,
97
- model: 'gemini-2.0-flash',
98
- temperature: 0.7,
99
- max_tokens: 8192,
100
- system: 'You are a helpful assistant.',
101
- embed_model: 'text-embedding-004',
102
- });
103
- ```
104
-
105
- | Option | Type | Default | Description |
106
- |--------|------|---------|-------------|
107
- | `api_key` | string | required | Google API key |
108
- | `model` | string | required | Model identifier |
109
- | `temperature` | number | undefined | Temperature (0.0-2.0) |
110
- | `base_url` | string | undefined | Custom API endpoint URL |
111
- | `max_tokens` | number | `8192` | Max tokens in response |
112
- | `max_retries` | number | undefined | Max retry attempts |
113
- | `timeout` | number | undefined | Request timeout in ms |
114
- | `system` | string | undefined | Default system instruction |
115
- | `embed_model` | string | undefined | Embedding model identifier |
116
-
117
- ## Result Shape
118
-
119
- ```typescript
120
- interface GeminiResult {
121
- content: string; // response text
122
- model: string; // model used
123
- usage: {
124
- input: number; // prompt tokens
125
- output: number; // completion tokens
126
- };
127
- stop_reason: string; // finish reason
128
- id: string; // request ID
129
- messages: Array<{ // full conversation history
130
- role: string;
131
- content: string;
132
- }>;
133
- }
134
- ```
135
-
136
- ## Lifecycle
137
-
138
- Call `dispose()` on the extension to cancel pending requests:
139
-
140
- ```typescript
141
- const ext = createGeminiExtension({ ... });
142
- // ... use extension ...
143
- await ext.dispose?.();
144
- ```
145
-
146
- ## Test Host
147
-
148
- A runnable example at `examples/test-host.ts` wires up the extension with the rill runtime:
149
-
150
- ```bash
151
- pnpm exec tsx examples/test-host.ts
152
- pnpm exec tsx examples/test-host.ts -e 'gemini::message("Tell me a joke") -> log'
153
- pnpm exec tsx examples/test-host.ts script.rill
154
- ```
39
+ ## Documentation
155
40
 
156
- Requires `GOOGLE_API_KEY` environment variable.
41
+ See [full documentation](docs/extension-llm-gemini.md) for configuration, functions, error handling, events, and examples.
157
42
 
158
- ## Documentation
43
+ ## Related
159
44
 
160
- | Document | Description |
161
- |----------|-------------|
162
- | [Extensions Guide](https://github.com/rcrsr/rill/blob/main/docs/integration-extensions.md) | Extension contract and patterns |
163
- | [Host API Reference](https://github.com/rcrsr/rill/blob/main/docs/ref-host-api.md) | Runtime context and host functions |
45
+ - [rill](https://github.com/rcrsr/rill) Core language runtime
46
+ - [Extensions Guide](https://github.com/rcrsr/rill/blob/main/docs/integration-extensions.md) — Extension contract and patterns
47
+ - [Host API Reference](https://github.com/rcrsr/rill/blob/main/docs/ref-host-api.md) Runtime context and host functions
164
48
 
165
49
  ## License
166
50
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // Generated by dts-bundle-generator v9.5.1
2
2
 
3
- import { ExtensionResult } from '@rcrsr/rill';
3
+ import { ExtensionConfigSchema, ExtensionResult } from '@rcrsr/rill';
4
4
 
5
5
  /**
6
6
  * Base configuration for LLM extensions
@@ -73,12 +73,8 @@ export type GeminiExtensionConfig = LLMProviderConfig;
73
73
  * ```
74
74
  */
75
75
  export declare function createGeminiExtension(config: GeminiExtensionConfig): ExtensionResult;
76
- /**
77
- * @rcrsr/rill-ext-gemini
78
- *
79
- * Extension for Google Gemini API integration with rill scripts.
80
- */
81
76
  export declare const VERSION = "0.0.1";
77
+ export declare const configSchema: ExtensionConfigSchema;
82
78
 
83
79
  export {
84
80
  LLMProviderConfig as LLMExtensionConfig,
package/dist/index.js CHANGED
@@ -4,11 +4,11 @@ import {
4
4
  Type
5
5
  } from "@google/genai";
6
6
  import {
7
- RuntimeError as RuntimeError4,
7
+ RuntimeError as RuntimeError6,
8
8
  emitExtensionEvent,
9
9
  createVector,
10
10
  isVector,
11
- isCallable as isCallable2
11
+ isDict as isDict2
12
12
  } from "@rcrsr/rill";
13
13
 
14
14
  // ../../shared/ext-llm/dist/validation.js
@@ -79,29 +79,152 @@ function mapProviderError(providerName, error, detect) {
79
79
  }
80
80
 
81
81
  // ../../shared/ext-llm/dist/tool-loop.js
82
- import { isCallable, isDict, RuntimeError as RuntimeError3 } from "@rcrsr/rill";
82
+ import { invokeCallable, isCallable, isDict, isRuntimeCallable, RuntimeError as RuntimeError4 } from "@rcrsr/rill";
83
+
84
+ // ../../shared/ext-llm/dist/schema.js
85
+ import { RuntimeError as RuntimeError3 } from "@rcrsr/rill";
86
+ var RILL_TYPE_MAP = {
87
+ string: "string",
88
+ number: "number",
89
+ bool: "boolean",
90
+ list: "array",
91
+ dict: "object",
92
+ vector: "object",
93
+ shape: "object"
94
+ };
95
+ function mapRillType(rillType) {
96
+ const jsonType = RILL_TYPE_MAP[rillType];
97
+ if (jsonType === void 0) {
98
+ throw new RuntimeError3("RILL-R004", `unsupported type: ${rillType}`);
99
+ }
100
+ return jsonType;
101
+ }
102
+ function buildPropertyFromStructuralType(rillType) {
103
+ if (rillType.type === "closure" || rillType.type === "tuple") {
104
+ throw new RuntimeError3("RILL-R004", `unsupported type for JSON Schema: ${rillType.type}`);
105
+ }
106
+ if (rillType.type === "any") {
107
+ return {};
108
+ }
109
+ if (rillType.type === "list") {
110
+ const property = { type: "array" };
111
+ if (rillType.element !== void 0) {
112
+ property.items = buildPropertyFromStructuralType(rillType.element);
113
+ }
114
+ return property;
115
+ }
116
+ if (rillType.type === "dict") {
117
+ return { type: "object" };
118
+ }
119
+ return { type: mapRillType(rillType.type) };
120
+ }
121
+ function buildJsonSchemaFromStructuralType(type, params) {
122
+ const properties = {};
123
+ const required = [];
124
+ if (type.type === "closure") {
125
+ const closureParams = type.params ?? [];
126
+ for (let i = 0; i < closureParams.length; i++) {
127
+ const [paramName, paramType] = closureParams[i];
128
+ const rillParam = params?.[i];
129
+ const property = buildPropertyFromStructuralType(paramType);
130
+ const description = rillParam?.annotations["description"];
131
+ if (typeof description === "string") {
132
+ property.description = description;
133
+ }
134
+ const enumAnnotation = rillParam?.annotations["enum"];
135
+ if (Array.isArray(enumAnnotation)) {
136
+ property.enum = enumAnnotation;
137
+ }
138
+ properties[paramName] = property;
139
+ if (rillParam === void 0 || rillParam.defaultValue === void 0) {
140
+ required.push(paramName);
141
+ }
142
+ }
143
+ }
144
+ return { type: "object", properties, required, additionalProperties: false };
145
+ }
146
+ function buildJsonSchema(rillSchema) {
147
+ const properties = {};
148
+ const required = [];
149
+ for (const [key, value] of Object.entries(rillSchema)) {
150
+ if (typeof value === "string") {
151
+ properties[key] = buildProperty(value);
152
+ } else if (typeof value === "object" && value !== null) {
153
+ properties[key] = buildProperty(value);
154
+ } else {
155
+ throw new RuntimeError3("RILL-R004", `unsupported type: ${String(value)}`);
156
+ }
157
+ required.push(key);
158
+ }
159
+ return { type: "object", properties, required, additionalProperties: false };
160
+ }
161
+ function buildProperty(descriptor) {
162
+ if (typeof descriptor === "string") {
163
+ const jsonType2 = mapRillType(descriptor);
164
+ return { type: jsonType2 };
165
+ }
166
+ const rillType = descriptor["type"];
167
+ if (typeof rillType !== "string") {
168
+ throw new RuntimeError3("RILL-R004", `unsupported type: ${String(rillType)}`);
169
+ }
170
+ const jsonType = mapRillType(rillType);
171
+ const property = { type: jsonType };
172
+ const description = descriptor["description"];
173
+ if (typeof description === "string") {
174
+ property.description = description;
175
+ }
176
+ if ("enum" in descriptor) {
177
+ if (rillType !== "string") {
178
+ throw new RuntimeError3("RILL-R004", "enum is only valid for string type");
179
+ }
180
+ const enumValues = descriptor["enum"];
181
+ if (Array.isArray(enumValues)) {
182
+ property.enum = enumValues;
183
+ }
184
+ }
185
+ if (rillType === "list" && "items" in descriptor) {
186
+ const items = descriptor["items"];
187
+ if (typeof items === "string") {
188
+ property.items = buildProperty(items);
189
+ } else if (typeof items === "object" && items !== null) {
190
+ property.items = buildProperty(items);
191
+ }
192
+ }
193
+ if (rillType === "dict" && "properties" in descriptor) {
194
+ const nestedProps = descriptor["properties"];
195
+ if (typeof nestedProps === "object" && nestedProps !== null) {
196
+ const subSchema = buildJsonSchema(nestedProps);
197
+ property.properties = subSchema.properties;
198
+ property.required = subSchema.required;
199
+ property.additionalProperties = false;
200
+ }
201
+ }
202
+ return property;
203
+ }
204
+
205
+ // ../../shared/ext-llm/dist/tool-loop.js
83
206
  async function executeToolCall(toolName, toolInput, tools, context) {
84
207
  if (!isDict(tools)) {
85
- throw new RuntimeError3("RILL-R004", "tools must be a dict mapping tool names to functions");
208
+ throw new RuntimeError4("RILL-R004", "tool_loop: tools must be a dict of name \u2192 callable");
86
209
  }
87
210
  const toolsDict = tools;
88
211
  const toolFn = toolsDict[toolName];
89
212
  if (toolFn === void 0 || toolFn === null) {
90
- throw new RuntimeError3("RILL-R004", `Unknown tool: ${toolName}`);
213
+ throw new RuntimeError4("RILL-R004", `Unknown tool: ${toolName}`);
91
214
  }
92
215
  if (!isCallable(toolFn)) {
93
- throw new RuntimeError3("RILL-R004", `Invalid tool input for ${toolName}: tool must be callable`);
216
+ throw new RuntimeError4("RILL-R004", `Invalid tool input for ${toolName}: tool must be callable`);
94
217
  }
95
218
  if (typeof toolInput !== "object" || toolInput === null) {
96
- throw new RuntimeError3("RILL-R004", `Invalid tool input for ${toolName}: input must be an object`);
219
+ throw new RuntimeError4("RILL-R004", `Invalid tool input for ${toolName}: input must be an object`);
97
220
  }
98
221
  const callable = toolFn;
99
- if (callable.kind !== "runtime" && callable.kind !== "application") {
100
- throw new RuntimeError3("RILL-R004", `Invalid tool input for ${toolName}: tool must be application or runtime callable`);
222
+ if (callable.kind !== "runtime" && callable.kind !== "application" && callable.kind !== "script") {
223
+ throw new RuntimeError4("RILL-R004", `Invalid tool input for ${toolName}: tool must be application, runtime, or script callable`);
101
224
  }
102
225
  try {
103
226
  let args;
104
- if (callable.kind === "application" && callable.params) {
227
+ if ((callable.kind === "application" || callable.kind === "script") && callable.params && callable.params.length > 0) {
105
228
  const params = callable.params;
106
229
  const inputDict = toolInput;
107
230
  args = params.map((param) => {
@@ -111,6 +234,12 @@ async function executeToolCall(toolName, toolInput, tools, context) {
111
234
  } else {
112
235
  args = [toolInput];
113
236
  }
237
+ if (callable.kind === "script") {
238
+ if (!context) {
239
+ throw new RuntimeError4("RILL-R004", `Invalid tool input for ${toolName}: script callable requires a runtime context`);
240
+ }
241
+ return await invokeCallable(callable, args, context);
242
+ }
114
243
  const ctx = context ?? {
115
244
  parent: void 0,
116
245
  variables: /* @__PURE__ */ new Map(),
@@ -119,77 +248,122 @@ async function executeToolCall(toolName, toolInput, tools, context) {
119
248
  const result = callable.fn(args, ctx);
120
249
  return result instanceof Promise ? await result : result;
121
250
  } catch (error) {
122
- if (error instanceof RuntimeError3) {
251
+ if (error instanceof RuntimeError4) {
123
252
  throw error;
124
253
  }
125
254
  const message = error instanceof Error ? error.message : "Unknown error";
126
- throw new RuntimeError3("RILL-R004", `Invalid tool input for ${toolName}: ${message}`);
255
+ throw new RuntimeError4("RILL-R004", `Invalid tool input for ${toolName}: ${message}`);
256
+ }
257
+ }
258
+ function sanitizeToolName(name) {
259
+ const match = name.match(/^[a-zA-Z0-9_-]*/);
260
+ const sanitized = match ? match[0] : "";
261
+ return sanitized.length > 0 ? sanitized : name;
262
+ }
263
+ function patchResponseToolCallNames(response, nameMap) {
264
+ if (!nameMap.size || !response || typeof response !== "object")
265
+ return;
266
+ const resp = response;
267
+ if (Array.isArray(resp["choices"])) {
268
+ for (const choice of resp["choices"]) {
269
+ const msg = choice?.["message"];
270
+ const tcs = msg?.["tool_calls"];
271
+ if (Array.isArray(tcs)) {
272
+ for (const tc of tcs) {
273
+ const fn = tc?.["function"];
274
+ if (fn && typeof fn["name"] === "string") {
275
+ const orig = fn["name"];
276
+ const san = nameMap.get(orig);
277
+ if (san !== void 0)
278
+ fn["name"] = san;
279
+ }
280
+ }
281
+ }
282
+ }
283
+ }
284
+ if (Array.isArray(resp["content"])) {
285
+ for (const block of resp["content"]) {
286
+ const b = block;
287
+ if (b?.["type"] === "tool_use" && typeof b?.["name"] === "string") {
288
+ const orig = b["name"];
289
+ const san = nameMap.get(orig);
290
+ if (san !== void 0)
291
+ b["name"] = san;
292
+ }
293
+ }
294
+ }
295
+ if (Array.isArray(resp["functionCalls"])) {
296
+ for (const fc of resp["functionCalls"]) {
297
+ const f = fc;
298
+ if (typeof f?.["name"] === "string") {
299
+ const orig = f["name"];
300
+ const san = nameMap.get(orig);
301
+ if (san !== void 0)
302
+ f["name"] = san;
303
+ }
304
+ }
305
+ }
306
+ if (Array.isArray(resp["candidates"])) {
307
+ for (const cand of resp["candidates"]) {
308
+ const content = cand?.["content"];
309
+ const parts = content?.["parts"];
310
+ if (Array.isArray(parts)) {
311
+ for (const part of parts) {
312
+ const fc = part?.["functionCall"];
313
+ if (fc && typeof fc["name"] === "string") {
314
+ const orig = fc["name"];
315
+ const san = nameMap.get(orig);
316
+ if (san !== void 0)
317
+ fc["name"] = san;
318
+ }
319
+ }
320
+ }
321
+ }
127
322
  }
128
323
  }
129
324
  async function executeToolLoop(messages, tools, maxErrors, callbacks, emitEvent, maxTurns = 10, context) {
130
325
  if (tools === void 0) {
131
- throw new RuntimeError3("RILL-R004", "tools parameter is required");
326
+ throw new RuntimeError4("RILL-R004", "tools parameter is required");
132
327
  }
133
328
  if (!isDict(tools)) {
134
- throw new RuntimeError3("RILL-R004", "tools must be a dict mapping tool names to functions");
329
+ throw new RuntimeError4("RILL-R004", "tool_loop: tools must be a dict of name \u2192 callable");
135
330
  }
136
331
  const toolsDict = tools;
137
332
  const toolDescriptors = Object.entries(toolsDict).map(([name, fn]) => {
138
333
  const fnValue = fn;
334
+ if (isRuntimeCallable(fnValue)) {
335
+ throw new RuntimeError4("RILL-R004", `tool_loop: builtin "${name}" cannot be used as a tool \u2014 wrap in a closure`);
336
+ }
139
337
  if (!isCallable(fnValue)) {
140
- throw new RuntimeError3("RILL-R004", `tool '${name}' must be callable function`);
338
+ throw new RuntimeError4("RILL-R004", `tool_loop: tool "${name}" is not a callable`);
141
339
  }
142
340
  const callable = fnValue;
143
- const description = callable.kind === "application" && callable.description ? callable.description : "";
144
- const properties = {};
145
- const required = [];
146
- if (callable.kind === "application" && callable.params) {
147
- for (const param of callable.params) {
148
- let jsonSchemaType;
149
- switch (param.typeName) {
150
- case "string":
151
- jsonSchemaType = "string";
152
- break;
153
- case "number":
154
- jsonSchemaType = "number";
155
- break;
156
- case "bool":
157
- jsonSchemaType = "boolean";
158
- break;
159
- case "list":
160
- jsonSchemaType = "array";
161
- break;
162
- case "dict":
163
- case "vector":
164
- jsonSchemaType = "object";
165
- break;
166
- case null:
167
- jsonSchemaType = "string";
168
- break;
169
- default:
170
- jsonSchemaType = "string";
171
- break;
172
- }
173
- const property = {
174
- type: jsonSchemaType
175
- };
176
- if (param.description) {
177
- property["description"] = param.description;
178
- }
179
- properties[param.name] = property;
180
- if (param.defaultValue === null) {
181
- required.push(param.name);
182
- }
183
- }
341
+ let description;
342
+ if (callable.kind === "script") {
343
+ description = callable.annotations["description"] ?? "";
344
+ } else {
345
+ description = callable.description ?? "";
346
+ }
347
+ let inputSchema;
348
+ const params = callable.kind === "application" ? callable.params ?? [] : callable.kind === "script" ? callable.params : [];
349
+ if (params.length > 0) {
350
+ const closureType = {
351
+ type: "closure",
352
+ params: params.map((p2) => [p2.name, p2.type ?? { type: "any" }])
353
+ };
354
+ const builtSchema = buildJsonSchemaFromStructuralType(closureType, [...params]);
355
+ inputSchema = {
356
+ type: "object",
357
+ properties: builtSchema.properties,
358
+ required: builtSchema.required
359
+ };
360
+ } else {
361
+ inputSchema = { type: "object", properties: {}, required: [] };
184
362
  }
185
363
  return {
186
364
  name,
187
365
  description,
188
- input_schema: {
189
- type: "object",
190
- properties,
191
- required
192
- }
366
+ input_schema: inputSchema
193
367
  };
194
368
  });
195
369
  const providerTools = callbacks.buildTools(toolDescriptors);
@@ -206,7 +380,7 @@ async function executeToolLoop(messages, tools, maxErrors, callbacks, emitEvent,
206
380
  response = await callbacks.callAPI(currentMessages, providerTools);
207
381
  } catch (error) {
208
382
  const message = error instanceof Error ? error.message : "Unknown error";
209
- throw new RuntimeError3("RILL-R004", `Provider API error: ${message}`, void 0, { cause: error });
383
+ throw new RuntimeError4("RILL-R004", `Provider API error: ${message}`, void 0, { cause: error });
210
384
  }
211
385
  if (typeof response === "object" && response !== null && "usage" in response) {
212
386
  const usage = response["usage"];
@@ -218,7 +392,17 @@ async function executeToolLoop(messages, tools, maxErrors, callbacks, emitEvent,
218
392
  totalOutputTokens += outputTokens;
219
393
  }
220
394
  }
221
- const toolCalls = callbacks.extractToolCalls(response);
395
+ const rawToolCalls = callbacks.extractToolCalls(response);
396
+ const nameMap = /* @__PURE__ */ new Map();
397
+ const toolCalls = rawToolCalls?.map((tc) => {
398
+ const sanitized = sanitizeToolName(tc.name);
399
+ if (sanitized !== tc.name)
400
+ nameMap.set(tc.name, sanitized);
401
+ return sanitized !== tc.name ? { ...tc, name: sanitized } : tc;
402
+ }) ?? null;
403
+ if (nameMap.size > 0) {
404
+ patchResponseToolCallNames(response, nameMap);
405
+ }
222
406
  if (toolCalls === null || toolCalls.length === 0) {
223
407
  return {
224
408
  response,
@@ -243,7 +427,7 @@ async function executeToolLoop(messages, tools, maxErrors, callbacks, emitEvent,
243
427
  const duration = Date.now() - toolStartTime;
244
428
  consecutiveErrors++;
245
429
  let originalError;
246
- if (error instanceof RuntimeError3) {
430
+ if (error instanceof RuntimeError4) {
247
431
  const prefix = `Invalid tool input for ${name}: `;
248
432
  if (error.message.startsWith(prefix)) {
249
433
  originalError = error.message.slice(prefix.length);
@@ -268,12 +452,20 @@ async function executeToolLoop(messages, tools, maxErrors, callbacks, emitEvent,
268
452
  duration
269
453
  });
270
454
  if (consecutiveErrors >= maxErrors) {
271
- throw new RuntimeError3("RILL-R004", `Tool execution failed: ${maxErrors} consecutive errors`);
455
+ throw new RuntimeError4("RILL-R004", `Tool execution failed: ${maxErrors} consecutive errors (last: ${name}: ${originalError})`);
272
456
  }
273
457
  }
274
458
  }
459
+ const assistantMessage = callbacks.formatAssistantMessage(response);
460
+ if (assistantMessage != null) {
461
+ currentMessages.push(assistantMessage);
462
+ }
275
463
  const toolResultMessage = callbacks.formatToolResult(toolResults);
276
- currentMessages.push(toolResultMessage);
464
+ if (Array.isArray(toolResultMessage)) {
465
+ currentMessages.push(...toolResultMessage);
466
+ } else {
467
+ currentMessages.push(toolResultMessage);
468
+ }
277
469
  }
278
470
  return {
279
471
  response: null,
@@ -283,6 +475,126 @@ async function executeToolLoop(messages, tools, maxErrors, callbacks, emitEvent,
283
475
  };
284
476
  }
285
477
 
478
+ // ../../shared/ext-param/dist/param.js
479
+ import { RuntimeError as RuntimeError5 } from "@rcrsr/rill";
480
+ function validateParamName(name) {
481
+ if (name === "") {
482
+ throw new RuntimeError5("RILL-R001", "param name must not be empty");
483
+ }
484
+ if (/\s/.test(name)) {
485
+ throw new RuntimeError5("RILL-R001", "param name must be a valid identifier");
486
+ }
487
+ }
488
+ function buildAnnotations(desc) {
489
+ if (desc !== void 0) {
490
+ return { description: desc };
491
+ }
492
+ return {};
493
+ }
494
+ var p = {
495
+ /**
496
+ * IR-1: Creates a string parameter descriptor.
497
+ *
498
+ * @param name - Parameter name (must be a valid identifier)
499
+ * @param desc - Optional description
500
+ * @returns RillParam with type 'string'
501
+ */
502
+ str(name, desc) {
503
+ validateParamName(name);
504
+ return {
505
+ name,
506
+ type: { type: "string" },
507
+ defaultValue: void 0,
508
+ annotations: buildAnnotations(desc)
509
+ };
510
+ },
511
+ /**
512
+ * IR-2: Creates a number parameter descriptor.
513
+ *
514
+ * @param name - Parameter name (must be a valid identifier)
515
+ * @param desc - Optional description
516
+ * @param def - Optional default value
517
+ * @returns RillParam with type 'number'
518
+ */
519
+ num(name, desc, def) {
520
+ validateParamName(name);
521
+ return {
522
+ name,
523
+ type: { type: "number" },
524
+ defaultValue: def,
525
+ annotations: buildAnnotations(desc)
526
+ };
527
+ },
528
+ /**
529
+ * IR-3: Creates a boolean parameter descriptor.
530
+ *
531
+ * @param name - Parameter name (must be a valid identifier)
532
+ * @param desc - Optional description
533
+ * @param def - Optional default value
534
+ * @returns RillParam with type 'bool'
535
+ */
536
+ bool(name, desc, def) {
537
+ validateParamName(name);
538
+ return {
539
+ name,
540
+ type: { type: "bool" },
541
+ defaultValue: def,
542
+ annotations: buildAnnotations(desc)
543
+ };
544
+ },
545
+ /**
546
+ * IR-4: Creates a dict parameter descriptor.
547
+ *
548
+ * @param name - Parameter name (must be a valid identifier)
549
+ * @param desc - Optional description
550
+ * @param def - Optional default value
551
+ * @returns RillParam with type 'dict'
552
+ */
553
+ dict(name, desc, def) {
554
+ validateParamName(name);
555
+ return {
556
+ name,
557
+ type: { type: "dict" },
558
+ defaultValue: def,
559
+ annotations: buildAnnotations(desc)
560
+ };
561
+ },
562
+ /**
563
+ * IR-5: Creates a list parameter descriptor.
564
+ *
565
+ * @param name - Parameter name (must be a valid identifier)
566
+ * @param itemType - Optional element type; omitted when not provided
567
+ * @param desc - Optional description
568
+ * @returns RillParam with type 'list' (with element if itemType provided)
569
+ */
570
+ list(name, itemType, desc) {
571
+ validateParamName(name);
572
+ const type = itemType !== void 0 ? { type: "list", element: itemType } : { type: "list" };
573
+ return {
574
+ name,
575
+ type,
576
+ defaultValue: void 0,
577
+ annotations: buildAnnotations(desc)
578
+ };
579
+ },
580
+ /**
581
+ * IR-6: Creates a callable parameter descriptor.
582
+ *
583
+ * @param name - Parameter name (must be a valid identifier)
584
+ * @param desc - Optional description
585
+ * @returns RillParam with type 'closure'
586
+ */
587
+ callable(name, desc) {
588
+ validateParamName(name);
589
+ return {
590
+ name,
591
+ type: { type: "closure" },
592
+ defaultValue: void 0,
593
+ annotations: buildAnnotations(desc)
594
+ };
595
+ }
596
+ };
597
+
286
598
  // src/factory.ts
287
599
  var DEFAULT_MAX_TOKENS = 8192;
288
600
  var detectGeminiError = (error) => {
@@ -301,6 +613,35 @@ var detectGeminiError = (error) => {
301
613
  }
302
614
  return null;
303
615
  };
616
+ function toGeminiSchema(prop) {
617
+ let schemaType = Type.STRING;
618
+ if (prop.type === "number") schemaType = Type.NUMBER;
619
+ if (prop.type === "boolean") schemaType = Type.BOOLEAN;
620
+ if (prop.type === "integer") schemaType = Type.INTEGER;
621
+ if (prop.type === "array") schemaType = Type.ARRAY;
622
+ if (prop.type === "object") schemaType = Type.OBJECT;
623
+ const schema = { type: schemaType };
624
+ if (prop.description !== void 0) {
625
+ schema.description = prop.description;
626
+ }
627
+ if (prop.enum !== void 0) {
628
+ schema.enum = prop.enum;
629
+ }
630
+ if (prop.type === "array" && prop.items !== void 0) {
631
+ schema.items = toGeminiSchema(prop.items);
632
+ }
633
+ if (prop.type === "object" && prop.properties !== void 0) {
634
+ const nestedProperties = {};
635
+ for (const [key, nestedProp] of Object.entries(prop.properties)) {
636
+ nestedProperties[key] = toGeminiSchema(nestedProp);
637
+ }
638
+ schema.properties = nestedProperties;
639
+ if (prop.required !== void 0) {
640
+ schema.required = prop.required;
641
+ }
642
+ }
643
+ return schema;
644
+ }
304
645
  function createGeminiExtension(config) {
305
646
  validateApiKey(config.api_key);
306
647
  validateModel(config.model);
@@ -334,8 +675,8 @@ function createGeminiExtension(config) {
334
675
  // IR-4: gemini::message
335
676
  message: {
336
677
  params: [
337
- { name: "text", type: "string" },
338
- { name: "options", type: "dict", defaultValue: {} }
678
+ p.str("text"),
679
+ p.dict("options", void 0, {})
339
680
  ],
340
681
  fn: async (args, ctx) => {
341
682
  const startTime = Date.now();
@@ -343,7 +684,7 @@ function createGeminiExtension(config) {
343
684
  const text = args[0];
344
685
  const options = args[1] ?? {};
345
686
  if (text.trim().length === 0) {
346
- throw new RuntimeError4("RILL-R004", "prompt text cannot be empty");
687
+ throw new RuntimeError6("RILL-R004", "prompt text cannot be empty");
347
688
  }
348
689
  const system = typeof options["system"] === "string" ? options["system"] : factorySystem;
349
690
  const maxTokens = typeof options["max_tokens"] === "number" ? options["max_tokens"] : factoryMaxTokens;
@@ -392,12 +733,14 @@ function createGeminiExtension(config) {
392
733
  subsystem: "extension:gemini",
393
734
  duration,
394
735
  model: factoryModel,
395
- usage: result2.usage
736
+ usage: result2.usage,
737
+ request: contents,
738
+ content
396
739
  });
397
740
  return result2;
398
741
  } catch (error) {
399
742
  const duration = Date.now() - startTime;
400
- const rillError = error instanceof RuntimeError4 ? error : mapProviderError("Gemini", error, detectGeminiError);
743
+ const rillError = error instanceof RuntimeError6 ? error : mapProviderError("Gemini", error, detectGeminiError);
401
744
  emitExtensionEvent(ctx, {
402
745
  event: "gemini:error",
403
746
  subsystem: "extension:gemini",
@@ -408,13 +751,13 @@ function createGeminiExtension(config) {
408
751
  }
409
752
  },
410
753
  description: "Send single message to Gemini API",
411
- returnType: "dict"
754
+ returnType: { type: "dict" }
412
755
  },
413
756
  // IR-5: gemini::messages
414
757
  messages: {
415
758
  params: [
416
- { name: "messages", type: "list" },
417
- { name: "options", type: "dict", defaultValue: {} }
759
+ p.list("messages"),
760
+ p.dict("options", void 0, {})
418
761
  ],
419
762
  fn: async (args, ctx) => {
420
763
  const startTime = Date.now();
@@ -422,7 +765,7 @@ function createGeminiExtension(config) {
422
765
  const messages = args[0];
423
766
  const options = args[1] ?? {};
424
767
  if (messages.length === 0) {
425
- throw new RuntimeError4(
768
+ throw new RuntimeError6(
426
769
  "RILL-R004",
427
770
  "messages list cannot be empty"
428
771
  );
@@ -433,18 +776,18 @@ function createGeminiExtension(config) {
433
776
  for (let i = 0; i < messages.length; i++) {
434
777
  const msg = messages[i];
435
778
  if (!msg || typeof msg !== "object" || !("role" in msg)) {
436
- throw new RuntimeError4(
779
+ throw new RuntimeError6(
437
780
  "RILL-R004",
438
781
  "message missing required 'role' field"
439
782
  );
440
783
  }
441
784
  const role = msg["role"];
442
785
  if (role !== "user" && role !== "assistant" && role !== "tool") {
443
- throw new RuntimeError4("RILL-R004", `invalid role '${role}'`);
786
+ throw new RuntimeError6("RILL-R004", `invalid role '${role}'`);
444
787
  }
445
788
  if (role === "user" || role === "tool") {
446
789
  if (!("content" in msg) || typeof msg["content"] !== "string") {
447
- throw new RuntimeError4(
790
+ throw new RuntimeError6(
448
791
  "RILL-R004",
449
792
  `${role} message requires 'content'`
450
793
  );
@@ -457,7 +800,7 @@ function createGeminiExtension(config) {
457
800
  const hasContent = "content" in msg && msg["content"];
458
801
  const hasToolCalls = "tool_calls" in msg && msg["tool_calls"];
459
802
  if (!hasContent && !hasToolCalls) {
460
- throw new RuntimeError4(
803
+ throw new RuntimeError6(
461
804
  "RILL-R004",
462
805
  "assistant message requires 'content' or 'tool_calls'"
463
806
  );
@@ -514,12 +857,14 @@ function createGeminiExtension(config) {
514
857
  subsystem: "extension:gemini",
515
858
  duration,
516
859
  model: factoryModel,
517
- usage: result2.usage
860
+ usage: result2.usage,
861
+ request: contents,
862
+ content
518
863
  });
519
864
  return result2;
520
865
  } catch (error) {
521
866
  const duration = Date.now() - startTime;
522
- const rillError = error instanceof RuntimeError4 ? error : mapProviderError("Gemini", error, detectGeminiError);
867
+ const rillError = error instanceof RuntimeError6 ? error : mapProviderError("Gemini", error, detectGeminiError);
523
868
  emitExtensionEvent(ctx, {
524
869
  event: "gemini:error",
525
870
  subsystem: "extension:gemini",
@@ -530,11 +875,11 @@ function createGeminiExtension(config) {
530
875
  }
531
876
  },
532
877
  description: "Send multi-turn conversation to Gemini API",
533
- returnType: "dict"
878
+ returnType: { type: "dict" }
534
879
  },
535
880
  // IR-6: gemini::embed
536
881
  embed: {
537
- params: [{ name: "text", type: "string" }],
882
+ params: [p.str("text")],
538
883
  fn: async (args, ctx) => {
539
884
  const startTime = Date.now();
540
885
  try {
@@ -547,7 +892,7 @@ function createGeminiExtension(config) {
547
892
  });
548
893
  const embedding = response.embeddings?.[0];
549
894
  if (!embedding || !embedding.values || embedding.values.length === 0) {
550
- throw new RuntimeError4(
895
+ throw new RuntimeError6(
551
896
  "RILL-R004",
552
897
  "Gemini: empty embedding returned"
553
898
  );
@@ -565,7 +910,7 @@ function createGeminiExtension(config) {
565
910
  return vector;
566
911
  } catch (error) {
567
912
  const duration = Date.now() - startTime;
568
- const rillError = error instanceof RuntimeError4 ? error : mapProviderError("Gemini", error, detectGeminiError);
913
+ const rillError = error instanceof RuntimeError6 ? error : mapProviderError("Gemini", error, detectGeminiError);
569
914
  emitExtensionEvent(ctx, {
570
915
  event: "gemini:error",
571
916
  subsystem: "extension:gemini",
@@ -576,11 +921,11 @@ function createGeminiExtension(config) {
576
921
  }
577
922
  },
578
923
  description: "Generate embedding vector for text",
579
- returnType: "vector"
924
+ returnType: { type: "vector" }
580
925
  },
581
926
  // IR-7: gemini::embed_batch
582
927
  embed_batch: {
583
- params: [{ name: "texts", type: "list" }],
928
+ params: [p.list("texts")],
584
929
  fn: async (args, ctx) => {
585
930
  const startTime = Date.now();
586
931
  try {
@@ -596,14 +941,14 @@ function createGeminiExtension(config) {
596
941
  });
597
942
  const vectors = [];
598
943
  if (!response.embeddings || response.embeddings.length === 0) {
599
- throw new RuntimeError4(
944
+ throw new RuntimeError6(
600
945
  "RILL-R004",
601
946
  "Gemini: empty embeddings returned"
602
947
  );
603
948
  }
604
949
  for (const embedding of response.embeddings) {
605
950
  if (!embedding || !embedding.values || embedding.values.length === 0) {
606
- throw new RuntimeError4(
951
+ throw new RuntimeError6(
607
952
  "RILL-R004",
608
953
  "Gemini: empty embedding returned"
609
954
  );
@@ -626,7 +971,7 @@ function createGeminiExtension(config) {
626
971
  return vectors;
627
972
  } catch (error) {
628
973
  const duration = Date.now() - startTime;
629
- const rillError = error instanceof RuntimeError4 ? error : mapProviderError("Gemini", error, detectGeminiError);
974
+ const rillError = error instanceof RuntimeError6 ? error : mapProviderError("Gemini", error, detectGeminiError);
630
975
  emitExtensionEvent(ctx, {
631
976
  event: "gemini:error",
632
977
  subsystem: "extension:gemini",
@@ -637,13 +982,13 @@ function createGeminiExtension(config) {
637
982
  }
638
983
  },
639
984
  description: "Generate embedding vectors for multiple texts",
640
- returnType: "list"
985
+ returnType: { type: "list" }
641
986
  },
642
987
  // IR-8: gemini::tool_loop
643
988
  tool_loop: {
644
989
  params: [
645
- { name: "prompt", type: "string" },
646
- { name: "options", type: "dict", defaultValue: {} }
990
+ p.str("prompt"),
991
+ p.dict("options", void 0, {})
647
992
  ],
648
993
  fn: async (args, ctx) => {
649
994
  const startTime = Date.now();
@@ -651,39 +996,15 @@ function createGeminiExtension(config) {
651
996
  const prompt = args[0];
652
997
  const options = args[1] ?? {};
653
998
  if (prompt.trim().length === 0) {
654
- throw new RuntimeError4("RILL-R004", "prompt text cannot be empty");
999
+ throw new RuntimeError6("RILL-R004", "prompt text cannot be empty");
655
1000
  }
656
- if (!("tools" in options) || !Array.isArray(options["tools"])) {
657
- throw new RuntimeError4(
1001
+ if (!("tools" in options) || !isDict2(options["tools"])) {
1002
+ throw new RuntimeError6(
658
1003
  "RILL-R004",
659
1004
  "tool_loop requires 'tools' option"
660
1005
  );
661
1006
  }
662
- const toolDescriptors = options["tools"];
663
- const toolsDict = {};
664
- for (const descriptor of toolDescriptors) {
665
- const name = typeof descriptor["name"] === "string" ? descriptor["name"] : null;
666
- if (!name) {
667
- throw new RuntimeError4(
668
- "RILL-R004",
669
- "tool descriptor missing name"
670
- );
671
- }
672
- const toolFnValue = descriptor["fn"];
673
- if (!toolFnValue) {
674
- throw new RuntimeError4(
675
- "RILL-R004",
676
- `tool '${name}' missing fn property`
677
- );
678
- }
679
- if (!isCallable2(toolFnValue)) {
680
- throw new RuntimeError4(
681
- "RILL-R004",
682
- `tool '${name}' fn must be callable`
683
- );
684
- }
685
- toolsDict[name] = toolFnValue;
686
- }
1007
+ const toolsDict = options["tools"];
687
1008
  const system = typeof options["system"] === "string" ? options["system"] : factorySystem;
688
1009
  const maxTokens = typeof options["max_tokens"] === "number" ? options["max_tokens"] : factoryMaxTokens;
689
1010
  const maxTurns = typeof options["max_turns"] === "number" ? options["max_turns"] : 10;
@@ -778,6 +1099,21 @@ function createGeminiExtension(config) {
778
1099
  };
779
1100
  });
780
1101
  },
1102
+ // Extract the model's content from Gemini response for conversation history
1103
+ formatAssistantMessage: (response2) => {
1104
+ if (!response2 || typeof response2 !== "object" || !("candidates" in response2)) {
1105
+ return null;
1106
+ }
1107
+ const candidates = response2.candidates;
1108
+ if (!Array.isArray(candidates) || candidates.length === 0) {
1109
+ return null;
1110
+ }
1111
+ const candidate = candidates[0];
1112
+ if (!candidate || typeof candidate !== "object" || !("content" in candidate)) {
1113
+ return null;
1114
+ }
1115
+ return candidate.content;
1116
+ },
781
1117
  // Format tool results into Gemini message format
782
1118
  formatToolResult: (toolResults) => {
783
1119
  const functionResponseParts = toolResults.map((tr) => ({
@@ -810,7 +1146,8 @@ function createGeminiExtension(config) {
810
1146
  ...data
811
1147
  });
812
1148
  },
813
- maxTurns
1149
+ maxTurns,
1150
+ ctx
814
1151
  );
815
1152
  const response = loopResult.response;
816
1153
  const content = response && typeof response === "object" && "text" in response ? response.text ?? "" : "";
@@ -832,12 +1169,14 @@ function createGeminiExtension(config) {
832
1169
  subsystem: "extension:gemini",
833
1170
  turns: result2.turns,
834
1171
  total_duration: duration,
835
- usage: result2.usage
1172
+ usage: result2.usage,
1173
+ request: contents,
1174
+ content
836
1175
  });
837
1176
  return result2;
838
1177
  } catch (error) {
839
1178
  const duration = Date.now() - startTime;
840
- const rillError = error instanceof RuntimeError4 ? error : mapProviderError("Gemini", error, detectGeminiError);
1179
+ const rillError = error instanceof RuntimeError6 ? error : mapProviderError("Gemini", error, detectGeminiError);
841
1180
  emitExtensionEvent(ctx, {
842
1181
  event: "gemini:error",
843
1182
  subsystem: "extension:gemini",
@@ -848,7 +1187,131 @@ function createGeminiExtension(config) {
848
1187
  }
849
1188
  },
850
1189
  description: "Execute tool-use loop with Gemini API",
851
- returnType: "dict"
1190
+ returnType: { type: "dict" }
1191
+ },
1192
+ // IR-3: gemini::generate
1193
+ generate: {
1194
+ params: [
1195
+ p.str("prompt"),
1196
+ p.dict("options")
1197
+ ],
1198
+ fn: async (args, ctx) => {
1199
+ const startTime = Date.now();
1200
+ try {
1201
+ const prompt = args[0];
1202
+ const options = args[1] ?? {};
1203
+ if (!("schema" in options) || options["schema"] === null || options["schema"] === void 0) {
1204
+ throw new RuntimeError6(
1205
+ "RILL-R004",
1206
+ "generate requires 'schema' option"
1207
+ );
1208
+ }
1209
+ const rillSchema = options["schema"];
1210
+ const jsonSchema = buildJsonSchema(rillSchema);
1211
+ const geminiProperties = {};
1212
+ for (const [key, prop] of Object.entries(jsonSchema.properties)) {
1213
+ geminiProperties[key] = toGeminiSchema(prop);
1214
+ }
1215
+ const responseSchema = {
1216
+ type: Type.OBJECT,
1217
+ properties: geminiProperties,
1218
+ required: jsonSchema.required
1219
+ };
1220
+ const system = typeof options["system"] === "string" ? options["system"] : factorySystem;
1221
+ const maxTokens = typeof options["max_tokens"] === "number" ? options["max_tokens"] : factoryMaxTokens;
1222
+ const contents = [];
1223
+ if ("messages" in options && Array.isArray(options["messages"])) {
1224
+ const prependedMessages = options["messages"];
1225
+ for (const msg of prependedMessages) {
1226
+ if (typeof msg === "object" && msg !== null && "role" in msg && "content" in msg) {
1227
+ const role = msg["role"];
1228
+ if (role === "user") {
1229
+ contents.push({
1230
+ role: "user",
1231
+ parts: [{ text: msg["content"] }]
1232
+ });
1233
+ } else if (role === "assistant") {
1234
+ contents.push({
1235
+ role: "model",
1236
+ parts: [{ text: msg["content"] }]
1237
+ });
1238
+ }
1239
+ }
1240
+ }
1241
+ }
1242
+ contents.push({
1243
+ role: "user",
1244
+ parts: [{ text: prompt }]
1245
+ });
1246
+ const apiConfig = {
1247
+ responseSchema,
1248
+ responseMimeType: "application/json"
1249
+ };
1250
+ if (system !== void 0) {
1251
+ apiConfig.systemInstruction = system;
1252
+ }
1253
+ if (maxTokens !== void 0) {
1254
+ apiConfig.maxOutputTokens = maxTokens;
1255
+ }
1256
+ if (factoryTemperature !== void 0) {
1257
+ apiConfig.temperature = factoryTemperature;
1258
+ }
1259
+ const response = await client.models.generateContent({
1260
+ model: factoryModel,
1261
+ contents,
1262
+ config: apiConfig
1263
+ });
1264
+ const raw = response.text ?? "";
1265
+ let data;
1266
+ try {
1267
+ data = JSON.parse(raw);
1268
+ } catch (parseError) {
1269
+ const detail = parseError instanceof Error ? parseError.message : String(parseError);
1270
+ throw new RuntimeError6(
1271
+ "RILL-R004",
1272
+ `generate: failed to parse response JSON: ${detail}`
1273
+ );
1274
+ }
1275
+ const inputTokens = response.usageMetadata?.promptTokenCount ?? 0;
1276
+ const outputTokens = response.usageMetadata?.candidatesTokenCount ?? 0;
1277
+ const stopReason = response.candidates?.[0]?.finishReason ?? "stop";
1278
+ const id = response.responseId ?? "";
1279
+ const generateResult = {
1280
+ data,
1281
+ raw,
1282
+ model: factoryModel,
1283
+ usage: {
1284
+ input: inputTokens,
1285
+ output: outputTokens
1286
+ },
1287
+ stop_reason: stopReason,
1288
+ id
1289
+ };
1290
+ const duration = Date.now() - startTime;
1291
+ emitExtensionEvent(ctx, {
1292
+ event: "gemini:generate",
1293
+ subsystem: "extension:gemini",
1294
+ duration,
1295
+ model: factoryModel,
1296
+ usage: generateResult.usage,
1297
+ request: contents,
1298
+ content: raw
1299
+ });
1300
+ return generateResult;
1301
+ } catch (error) {
1302
+ const duration = Date.now() - startTime;
1303
+ const rillError = error instanceof RuntimeError6 ? error : mapProviderError("Gemini", error, detectGeminiError);
1304
+ emitExtensionEvent(ctx, {
1305
+ event: "gemini:error",
1306
+ subsystem: "extension:gemini",
1307
+ error: rillError.message,
1308
+ duration
1309
+ });
1310
+ throw rillError;
1311
+ }
1312
+ },
1313
+ description: "Generate structured output from Gemini API",
1314
+ returnType: { type: "dict" }
852
1315
  }
853
1316
  };
854
1317
  result.dispose = dispose;
@@ -857,7 +1320,19 @@ function createGeminiExtension(config) {
857
1320
 
858
1321
  // src/index.ts
859
1322
  var VERSION = "0.0.1";
1323
+ var configSchema = {
1324
+ api_key: { type: "string", required: true, secret: true },
1325
+ model: { type: "string", required: true },
1326
+ base_url: { type: "string" },
1327
+ temperature: { type: "number" },
1328
+ max_tokens: { type: "number" },
1329
+ timeout: { type: "number" },
1330
+ max_retries: { type: "number" },
1331
+ system: { type: "string" },
1332
+ embed_model: { type: "string" }
1333
+ };
860
1334
  export {
861
1335
  VERSION,
1336
+ configSchema,
862
1337
  createGeminiExtension
863
1338
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rcrsr/rill-ext-gemini",
3
- "version": "0.8.6",
3
+ "version": "0.11.0",
4
4
  "description": "rill extension for Google Gemini API integration",
5
5
  "license": "MIT",
6
6
  "author": "Andre Bremer",
@@ -17,14 +17,14 @@
17
17
  "scripting"
18
18
  ],
19
19
  "peerDependencies": {
20
- "@rcrsr/rill": "^0.8.6"
20
+ "@rcrsr/rill": "^0.11.0"
21
21
  },
22
22
  "devDependencies": {
23
- "@types/node": "^25.2.3",
23
+ "@rcrsr/rill": "^0.11.0",
24
+ "@types/node": "^25.3.0",
24
25
  "dts-bundle-generator": "^9.5.1",
25
- "tsup": "^8.5.0",
26
- "undici-types": "^7.21.0",
27
- "@rcrsr/rill": "^0.8.6",
26
+ "tsup": "^8.5.1",
27
+ "undici-types": "^7.22.0",
28
28
  "@rcrsr/rill-ext-llm-shared": "^0.0.1"
29
29
  },
30
30
  "files": [
@@ -32,18 +32,19 @@
32
32
  ],
33
33
  "repository": {
34
34
  "type": "git",
35
- "url": "git+https://github.com/rcrsr/rill.git",
35
+ "url": "git+https://github.com/rcrsr/rill-ext.git",
36
36
  "directory": "packages/ext/llm-gemini"
37
37
  },
38
- "homepage": "https://rill.run/docs/extensions/gemini/",
38
+ "homepage": "https://github.com/rcrsr/rill-ext/tree/main/packages/ext/llm-gemini#readme",
39
39
  "bugs": {
40
- "url": "https://github.com/rcrsr/rill/issues"
40
+ "url": "https://github.com/rcrsr/rill-ext/issues"
41
41
  },
42
42
  "publishConfig": {
43
43
  "access": "public"
44
44
  },
45
45
  "dependencies": {
46
- "@google/genai": "^1.40.0"
46
+ "@google/genai": "^1.42.0",
47
+ "@rcrsr/rill-ext-param-shared": "0.0.1"
47
48
  },
48
49
  "scripts": {
49
50
  "build": "tsup && dts-bundle-generator --config dts-bundle-generator.config.cjs",