@rcrsr/rill-ext-gemini 0.9.0 → 0.16.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/dist/index.d.ts +3 -2
- package/dist/index.js +312 -104
- package/package.json +5 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Generated by dts-bundle-generator v9.5.1
|
|
2
2
|
|
|
3
|
-
import { ExtensionConfigSchema, ExtensionResult } from '@rcrsr/rill';
|
|
3
|
+
import { ExtensionConfigSchema, ExtensionManifest, ExtensionResult } from '@rcrsr/rill';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Base configuration for LLM extensions
|
|
@@ -73,8 +73,9 @@ export type GeminiExtensionConfig = LLMProviderConfig;
|
|
|
73
73
|
* ```
|
|
74
74
|
*/
|
|
75
75
|
export declare function createGeminiExtension(config: GeminiExtensionConfig): ExtensionResult;
|
|
76
|
-
export declare const VERSION
|
|
76
|
+
export declare const VERSION: string;
|
|
77
77
|
export declare const configSchema: ExtensionConfigSchema;
|
|
78
|
+
export declare const extensionManifest: ExtensionManifest;
|
|
78
79
|
|
|
79
80
|
export {
|
|
80
81
|
LLMProviderConfig as LLMExtensionConfig,
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { createRequire } from "module";
|
|
3
|
+
|
|
1
4
|
// src/factory.ts
|
|
2
5
|
import {
|
|
3
6
|
GoogleGenAI,
|
|
4
7
|
Type
|
|
5
8
|
} from "@google/genai";
|
|
6
9
|
import {
|
|
7
|
-
RuntimeError as
|
|
10
|
+
RuntimeError as RuntimeError6,
|
|
8
11
|
emitExtensionEvent,
|
|
9
12
|
createVector,
|
|
10
13
|
isVector,
|
|
11
|
-
isDict as isDict2
|
|
14
|
+
isDict as isDict2,
|
|
15
|
+
rillTypeToTypeValue
|
|
12
16
|
} from "@rcrsr/rill";
|
|
13
17
|
|
|
14
18
|
// ../../shared/ext-llm/dist/validation.js
|
|
@@ -99,6 +103,52 @@ function mapRillType(rillType) {
|
|
|
99
103
|
}
|
|
100
104
|
return jsonType;
|
|
101
105
|
}
|
|
106
|
+
function buildPropertyFromStructuralType(rillType) {
|
|
107
|
+
if (rillType.type === "closure" || rillType.type === "tuple") {
|
|
108
|
+
throw new RuntimeError3("RILL-R004", `unsupported type for JSON Schema: ${rillType.type}`);
|
|
109
|
+
}
|
|
110
|
+
if (rillType.type === "any") {
|
|
111
|
+
return {};
|
|
112
|
+
}
|
|
113
|
+
if (rillType.type === "list") {
|
|
114
|
+
const property = { type: "array" };
|
|
115
|
+
if (rillType.element !== void 0) {
|
|
116
|
+
property.items = buildPropertyFromStructuralType(rillType.element);
|
|
117
|
+
}
|
|
118
|
+
return property;
|
|
119
|
+
}
|
|
120
|
+
if (rillType.type === "dict") {
|
|
121
|
+
return { type: "object" };
|
|
122
|
+
}
|
|
123
|
+
return { type: mapRillType(rillType.type) };
|
|
124
|
+
}
|
|
125
|
+
function buildJsonSchemaFromStructuralType(type, params) {
|
|
126
|
+
const properties = {};
|
|
127
|
+
const required = [];
|
|
128
|
+
if (type.type === "closure") {
|
|
129
|
+
const closureParams = type.params ?? [];
|
|
130
|
+
for (let i = 0; i < closureParams.length; i++) {
|
|
131
|
+
const fieldDef = closureParams[i];
|
|
132
|
+
const paramName = fieldDef.name ?? `param${i}`;
|
|
133
|
+
const paramType = fieldDef.type;
|
|
134
|
+
const rillParam = params?.[i];
|
|
135
|
+
const property = buildPropertyFromStructuralType(paramType);
|
|
136
|
+
const description = rillParam?.annotations["description"];
|
|
137
|
+
if (typeof description === "string") {
|
|
138
|
+
property.description = description;
|
|
139
|
+
}
|
|
140
|
+
const enumAnnotation = rillParam?.annotations["enum"];
|
|
141
|
+
if (Array.isArray(enumAnnotation)) {
|
|
142
|
+
property.enum = enumAnnotation;
|
|
143
|
+
}
|
|
144
|
+
properties[paramName] = property;
|
|
145
|
+
if (rillParam === void 0 || rillParam.defaultValue === void 0) {
|
|
146
|
+
required.push(paramName);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return { type: "object", properties, required, additionalProperties: false };
|
|
151
|
+
}
|
|
102
152
|
function buildJsonSchema(rillSchema) {
|
|
103
153
|
const properties = {};
|
|
104
154
|
const required = [];
|
|
@@ -179,21 +229,20 @@ async function executeToolCall(toolName, toolInput, tools, context) {
|
|
|
179
229
|
throw new RuntimeError4("RILL-R004", `Invalid tool input for ${toolName}: tool must be application, runtime, or script callable`);
|
|
180
230
|
}
|
|
181
231
|
try {
|
|
182
|
-
|
|
183
|
-
if ((callable.kind === "application" || callable.kind === "script") && callable.params && callable.params.length > 0) {
|
|
184
|
-
const params = callable.params;
|
|
185
|
-
const inputDict = toolInput;
|
|
186
|
-
args = params.map((param) => {
|
|
187
|
-
const value = inputDict[param.name];
|
|
188
|
-
return value !== void 0 ? value : void 0;
|
|
189
|
-
});
|
|
190
|
-
} else {
|
|
191
|
-
args = [toolInput];
|
|
192
|
-
}
|
|
232
|
+
const inputDict = toolInput;
|
|
193
233
|
if (callable.kind === "script") {
|
|
194
234
|
if (!context) {
|
|
195
235
|
throw new RuntimeError4("RILL-R004", `Invalid tool input for ${toolName}: script callable requires a runtime context`);
|
|
196
236
|
}
|
|
237
|
+
let args;
|
|
238
|
+
if (callable.params && callable.params.length > 0) {
|
|
239
|
+
args = callable.params.map((param) => {
|
|
240
|
+
const value = inputDict[param.name];
|
|
241
|
+
return value !== void 0 ? value : void 0;
|
|
242
|
+
});
|
|
243
|
+
} else {
|
|
244
|
+
args = [inputDict];
|
|
245
|
+
}
|
|
197
246
|
return await invokeCallable(callable, args, context);
|
|
198
247
|
}
|
|
199
248
|
const ctx = context ?? {
|
|
@@ -201,7 +250,7 @@ async function executeToolCall(toolName, toolInput, tools, context) {
|
|
|
201
250
|
variables: /* @__PURE__ */ new Map(),
|
|
202
251
|
pipeValue: null
|
|
203
252
|
};
|
|
204
|
-
const result = callable.fn(
|
|
253
|
+
const result = callable.fn(inputDict, ctx);
|
|
205
254
|
return result instanceof Promise ? await result : result;
|
|
206
255
|
} catch (error) {
|
|
207
256
|
if (error instanceof RuntimeError4) {
|
|
@@ -294,48 +343,19 @@ async function executeToolLoop(messages, tools, maxErrors, callbacks, emitEvent,
|
|
|
294
343
|
throw new RuntimeError4("RILL-R004", `tool_loop: tool "${name}" is not a callable`);
|
|
295
344
|
}
|
|
296
345
|
const callable = fnValue;
|
|
297
|
-
|
|
298
|
-
if (callable.kind === "script") {
|
|
299
|
-
description = callable.annotations["description"] ?? "";
|
|
300
|
-
} else {
|
|
301
|
-
description = callable.description ?? "";
|
|
302
|
-
}
|
|
346
|
+
const description = callable.annotations?.["description"] ?? "";
|
|
303
347
|
let inputSchema;
|
|
304
348
|
const params = callable.kind === "application" ? callable.params ?? [] : callable.kind === "script" ? callable.params : [];
|
|
305
349
|
if (params.length > 0) {
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
const descriptor = {
|
|
312
|
-
[param.name]: { type: param.typeName }
|
|
313
|
-
};
|
|
314
|
-
const schema = buildJsonSchema(descriptor);
|
|
315
|
-
const built = schema.properties[param.name];
|
|
316
|
-
if (built !== void 0) {
|
|
317
|
-
Object.assign(property, built);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
let paramDesc;
|
|
321
|
-
if (callable.kind === "script") {
|
|
322
|
-
const annot = callable.paramAnnotations[param.name];
|
|
323
|
-
paramDesc = annot?.["description"] ?? "";
|
|
324
|
-
} else {
|
|
325
|
-
paramDesc = param.description ?? "";
|
|
326
|
-
}
|
|
327
|
-
if (paramDesc) {
|
|
328
|
-
property["description"] = paramDesc;
|
|
329
|
-
}
|
|
330
|
-
properties[param.name] = property;
|
|
331
|
-
if (param.defaultValue === null) {
|
|
332
|
-
required.push(param.name);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
350
|
+
const closureType = {
|
|
351
|
+
type: "closure",
|
|
352
|
+
params: params.map((p2) => ({ name: p2.name, type: p2.type ?? { type: "any" } }))
|
|
353
|
+
};
|
|
354
|
+
const builtSchema = buildJsonSchemaFromStructuralType(closureType, [...params]);
|
|
335
355
|
inputSchema = {
|
|
336
356
|
type: "object",
|
|
337
|
-
properties,
|
|
338
|
-
required
|
|
357
|
+
properties: builtSchema.properties,
|
|
358
|
+
required: builtSchema.required
|
|
339
359
|
};
|
|
340
360
|
} else {
|
|
341
361
|
inputSchema = { type: "object", properties: {}, required: [] };
|
|
@@ -455,6 +475,128 @@ async function executeToolLoop(messages, tools, maxErrors, callbacks, emitEvent,
|
|
|
455
475
|
};
|
|
456
476
|
}
|
|
457
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
|
+
* @param fields - Optional structural field definitions (RillFieldDef with type and optional defaultValue)
|
|
552
|
+
* @returns RillParam with type 'dict' (with fields if provided)
|
|
553
|
+
*/
|
|
554
|
+
dict(name, desc, def, fields) {
|
|
555
|
+
validateParamName(name);
|
|
556
|
+
const type = fields !== void 0 ? { type: "dict", fields } : { type: "dict" };
|
|
557
|
+
return {
|
|
558
|
+
name,
|
|
559
|
+
type,
|
|
560
|
+
defaultValue: def,
|
|
561
|
+
annotations: buildAnnotations(desc)
|
|
562
|
+
};
|
|
563
|
+
},
|
|
564
|
+
/**
|
|
565
|
+
* IR-5: Creates a list parameter descriptor.
|
|
566
|
+
*
|
|
567
|
+
* @param name - Parameter name (must be a valid identifier)
|
|
568
|
+
* @param itemType - Optional element type; omitted when not provided
|
|
569
|
+
* @param desc - Optional description
|
|
570
|
+
* @returns RillParam with type 'list' (with element if itemType provided)
|
|
571
|
+
*/
|
|
572
|
+
list(name, itemType, desc) {
|
|
573
|
+
validateParamName(name);
|
|
574
|
+
const type = itemType !== void 0 ? { type: "list", element: itemType } : { type: "list" };
|
|
575
|
+
return {
|
|
576
|
+
name,
|
|
577
|
+
type,
|
|
578
|
+
defaultValue: void 0,
|
|
579
|
+
annotations: buildAnnotations(desc)
|
|
580
|
+
};
|
|
581
|
+
},
|
|
582
|
+
/**
|
|
583
|
+
* IR-6: Creates a callable parameter descriptor.
|
|
584
|
+
*
|
|
585
|
+
* @param name - Parameter name (must be a valid identifier)
|
|
586
|
+
* @param desc - Optional description
|
|
587
|
+
* @returns RillParam with type 'closure'
|
|
588
|
+
*/
|
|
589
|
+
callable(name, desc) {
|
|
590
|
+
validateParamName(name);
|
|
591
|
+
return {
|
|
592
|
+
name,
|
|
593
|
+
type: { type: "closure" },
|
|
594
|
+
defaultValue: void 0,
|
|
595
|
+
annotations: buildAnnotations(desc)
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
|
|
458
600
|
// src/factory.ts
|
|
459
601
|
var DEFAULT_MAX_TOKENS = 8192;
|
|
460
602
|
var detectGeminiError = (error) => {
|
|
@@ -535,16 +677,19 @@ function createGeminiExtension(config) {
|
|
|
535
677
|
// IR-4: gemini::message
|
|
536
678
|
message: {
|
|
537
679
|
params: [
|
|
538
|
-
|
|
539
|
-
|
|
680
|
+
p.str("text"),
|
|
681
|
+
p.dict("options", void 0, {}, {
|
|
682
|
+
system: { type: { type: "string" }, defaultValue: "" },
|
|
683
|
+
max_tokens: { type: { type: "number" }, defaultValue: 0 }
|
|
684
|
+
})
|
|
540
685
|
],
|
|
541
686
|
fn: async (args, ctx) => {
|
|
542
687
|
const startTime = Date.now();
|
|
543
688
|
try {
|
|
544
|
-
const text = args[
|
|
545
|
-
const options = args[
|
|
689
|
+
const text = args["text"];
|
|
690
|
+
const options = args["options"] ?? {};
|
|
546
691
|
if (text.trim().length === 0) {
|
|
547
|
-
throw new
|
|
692
|
+
throw new RuntimeError6("RILL-R004", "prompt text cannot be empty");
|
|
548
693
|
}
|
|
549
694
|
const system = typeof options["system"] === "string" ? options["system"] : factorySystem;
|
|
550
695
|
const maxTokens = typeof options["max_tokens"] === "number" ? options["max_tokens"] : factoryMaxTokens;
|
|
@@ -600,7 +745,7 @@ function createGeminiExtension(config) {
|
|
|
600
745
|
return result2;
|
|
601
746
|
} catch (error) {
|
|
602
747
|
const duration = Date.now() - startTime;
|
|
603
|
-
const rillError = error instanceof
|
|
748
|
+
const rillError = error instanceof RuntimeError6 ? error : mapProviderError("Gemini", error, detectGeminiError);
|
|
604
749
|
emitExtensionEvent(ctx, {
|
|
605
750
|
event: "gemini:error",
|
|
606
751
|
subsystem: "extension:gemini",
|
|
@@ -610,22 +755,35 @@ function createGeminiExtension(config) {
|
|
|
610
755
|
throw rillError;
|
|
611
756
|
}
|
|
612
757
|
},
|
|
613
|
-
description: "Send single message to Gemini API",
|
|
614
|
-
returnType:
|
|
758
|
+
annotations: { description: "Send single message to Gemini API" },
|
|
759
|
+
returnType: rillTypeToTypeValue({
|
|
760
|
+
type: "dict",
|
|
761
|
+
fields: {
|
|
762
|
+
content: { type: { type: "string" } },
|
|
763
|
+
model: { type: { type: "string" } },
|
|
764
|
+
usage: { type: { type: "dict", fields: { input: { type: { type: "number" } }, output: { type: { type: "number" } } } } },
|
|
765
|
+
stop_reason: { type: { type: "string" } },
|
|
766
|
+
id: { type: { type: "string" } },
|
|
767
|
+
messages: { type: { type: "list", element: { type: "dict" } } }
|
|
768
|
+
}
|
|
769
|
+
})
|
|
615
770
|
},
|
|
616
771
|
// IR-5: gemini::messages
|
|
617
772
|
messages: {
|
|
618
773
|
params: [
|
|
619
|
-
{
|
|
620
|
-
|
|
774
|
+
p.list("messages", { type: "dict", fields: { role: { type: { type: "string" } }, content: { type: { type: "string" } } } }),
|
|
775
|
+
p.dict("options", void 0, {}, {
|
|
776
|
+
system: { type: { type: "string" }, defaultValue: "" },
|
|
777
|
+
max_tokens: { type: { type: "number" }, defaultValue: 0 }
|
|
778
|
+
})
|
|
621
779
|
],
|
|
622
780
|
fn: async (args, ctx) => {
|
|
623
781
|
const startTime = Date.now();
|
|
624
782
|
try {
|
|
625
|
-
const messages = args[
|
|
626
|
-
const options = args[
|
|
783
|
+
const messages = args["messages"];
|
|
784
|
+
const options = args["options"] ?? {};
|
|
627
785
|
if (messages.length === 0) {
|
|
628
|
-
throw new
|
|
786
|
+
throw new RuntimeError6(
|
|
629
787
|
"RILL-R004",
|
|
630
788
|
"messages list cannot be empty"
|
|
631
789
|
);
|
|
@@ -636,18 +794,18 @@ function createGeminiExtension(config) {
|
|
|
636
794
|
for (let i = 0; i < messages.length; i++) {
|
|
637
795
|
const msg = messages[i];
|
|
638
796
|
if (!msg || typeof msg !== "object" || !("role" in msg)) {
|
|
639
|
-
throw new
|
|
797
|
+
throw new RuntimeError6(
|
|
640
798
|
"RILL-R004",
|
|
641
799
|
"message missing required 'role' field"
|
|
642
800
|
);
|
|
643
801
|
}
|
|
644
802
|
const role = msg["role"];
|
|
645
803
|
if (role !== "user" && role !== "assistant" && role !== "tool") {
|
|
646
|
-
throw new
|
|
804
|
+
throw new RuntimeError6("RILL-R004", `invalid role '${role}'`);
|
|
647
805
|
}
|
|
648
806
|
if (role === "user" || role === "tool") {
|
|
649
807
|
if (!("content" in msg) || typeof msg["content"] !== "string") {
|
|
650
|
-
throw new
|
|
808
|
+
throw new RuntimeError6(
|
|
651
809
|
"RILL-R004",
|
|
652
810
|
`${role} message requires 'content'`
|
|
653
811
|
);
|
|
@@ -660,7 +818,7 @@ function createGeminiExtension(config) {
|
|
|
660
818
|
const hasContent = "content" in msg && msg["content"];
|
|
661
819
|
const hasToolCalls = "tool_calls" in msg && msg["tool_calls"];
|
|
662
820
|
if (!hasContent && !hasToolCalls) {
|
|
663
|
-
throw new
|
|
821
|
+
throw new RuntimeError6(
|
|
664
822
|
"RILL-R004",
|
|
665
823
|
"assistant message requires 'content' or 'tool_calls'"
|
|
666
824
|
);
|
|
@@ -724,7 +882,7 @@ function createGeminiExtension(config) {
|
|
|
724
882
|
return result2;
|
|
725
883
|
} catch (error) {
|
|
726
884
|
const duration = Date.now() - startTime;
|
|
727
|
-
const rillError = error instanceof
|
|
885
|
+
const rillError = error instanceof RuntimeError6 ? error : mapProviderError("Gemini", error, detectGeminiError);
|
|
728
886
|
emitExtensionEvent(ctx, {
|
|
729
887
|
event: "gemini:error",
|
|
730
888
|
subsystem: "extension:gemini",
|
|
@@ -734,16 +892,26 @@ function createGeminiExtension(config) {
|
|
|
734
892
|
throw rillError;
|
|
735
893
|
}
|
|
736
894
|
},
|
|
737
|
-
description: "Send multi-turn conversation to Gemini API",
|
|
738
|
-
returnType:
|
|
895
|
+
annotations: { description: "Send multi-turn conversation to Gemini API" },
|
|
896
|
+
returnType: rillTypeToTypeValue({
|
|
897
|
+
type: "dict",
|
|
898
|
+
fields: {
|
|
899
|
+
content: { type: { type: "string" } },
|
|
900
|
+
model: { type: { type: "string" } },
|
|
901
|
+
usage: { type: { type: "dict", fields: { input: { type: { type: "number" } }, output: { type: { type: "number" } } } } },
|
|
902
|
+
stop_reason: { type: { type: "string" } },
|
|
903
|
+
id: { type: { type: "string" } },
|
|
904
|
+
messages: { type: { type: "list", element: { type: "dict" } } }
|
|
905
|
+
}
|
|
906
|
+
})
|
|
739
907
|
},
|
|
740
908
|
// IR-6: gemini::embed
|
|
741
909
|
embed: {
|
|
742
|
-
params: [
|
|
910
|
+
params: [p.str("text")],
|
|
743
911
|
fn: async (args, ctx) => {
|
|
744
912
|
const startTime = Date.now();
|
|
745
913
|
try {
|
|
746
|
-
const text = args[
|
|
914
|
+
const text = args["text"];
|
|
747
915
|
validateEmbedText(text);
|
|
748
916
|
validateEmbedModel(factoryEmbedModel);
|
|
749
917
|
const response = await client.models.embedContent({
|
|
@@ -752,7 +920,7 @@ function createGeminiExtension(config) {
|
|
|
752
920
|
});
|
|
753
921
|
const embedding = response.embeddings?.[0];
|
|
754
922
|
if (!embedding || !embedding.values || embedding.values.length === 0) {
|
|
755
|
-
throw new
|
|
923
|
+
throw new RuntimeError6(
|
|
756
924
|
"RILL-R004",
|
|
757
925
|
"Gemini: empty embedding returned"
|
|
758
926
|
);
|
|
@@ -770,7 +938,7 @@ function createGeminiExtension(config) {
|
|
|
770
938
|
return vector;
|
|
771
939
|
} catch (error) {
|
|
772
940
|
const duration = Date.now() - startTime;
|
|
773
|
-
const rillError = error instanceof
|
|
941
|
+
const rillError = error instanceof RuntimeError6 ? error : mapProviderError("Gemini", error, detectGeminiError);
|
|
774
942
|
emitExtensionEvent(ctx, {
|
|
775
943
|
event: "gemini:error",
|
|
776
944
|
subsystem: "extension:gemini",
|
|
@@ -780,16 +948,16 @@ function createGeminiExtension(config) {
|
|
|
780
948
|
throw rillError;
|
|
781
949
|
}
|
|
782
950
|
},
|
|
783
|
-
description: "Generate embedding vector for text",
|
|
784
|
-
returnType: "vector"
|
|
951
|
+
annotations: { description: "Generate embedding vector for text" },
|
|
952
|
+
returnType: rillTypeToTypeValue({ type: "vector" })
|
|
785
953
|
},
|
|
786
954
|
// IR-7: gemini::embed_batch
|
|
787
955
|
embed_batch: {
|
|
788
|
-
params: [
|
|
956
|
+
params: [p.list("texts")],
|
|
789
957
|
fn: async (args, ctx) => {
|
|
790
958
|
const startTime = Date.now();
|
|
791
959
|
try {
|
|
792
|
-
const texts = args[
|
|
960
|
+
const texts = args["texts"];
|
|
793
961
|
if (texts.length === 0) {
|
|
794
962
|
return [];
|
|
795
963
|
}
|
|
@@ -801,14 +969,14 @@ function createGeminiExtension(config) {
|
|
|
801
969
|
});
|
|
802
970
|
const vectors = [];
|
|
803
971
|
if (!response.embeddings || response.embeddings.length === 0) {
|
|
804
|
-
throw new
|
|
972
|
+
throw new RuntimeError6(
|
|
805
973
|
"RILL-R004",
|
|
806
974
|
"Gemini: empty embeddings returned"
|
|
807
975
|
);
|
|
808
976
|
}
|
|
809
977
|
for (const embedding of response.embeddings) {
|
|
810
978
|
if (!embedding || !embedding.values || embedding.values.length === 0) {
|
|
811
|
-
throw new
|
|
979
|
+
throw new RuntimeError6(
|
|
812
980
|
"RILL-R004",
|
|
813
981
|
"Gemini: empty embedding returned"
|
|
814
982
|
);
|
|
@@ -831,7 +999,7 @@ function createGeminiExtension(config) {
|
|
|
831
999
|
return vectors;
|
|
832
1000
|
} catch (error) {
|
|
833
1001
|
const duration = Date.now() - startTime;
|
|
834
|
-
const rillError = error instanceof
|
|
1002
|
+
const rillError = error instanceof RuntimeError6 ? error : mapProviderError("Gemini", error, detectGeminiError);
|
|
835
1003
|
emitExtensionEvent(ctx, {
|
|
836
1004
|
event: "gemini:error",
|
|
837
1005
|
subsystem: "extension:gemini",
|
|
@@ -841,25 +1009,32 @@ function createGeminiExtension(config) {
|
|
|
841
1009
|
throw rillError;
|
|
842
1010
|
}
|
|
843
1011
|
},
|
|
844
|
-
description: "Generate embedding vectors for multiple texts",
|
|
845
|
-
returnType: "list"
|
|
1012
|
+
annotations: { description: "Generate embedding vectors for multiple texts" },
|
|
1013
|
+
returnType: rillTypeToTypeValue({ type: "list", element: { type: "vector" } })
|
|
846
1014
|
},
|
|
847
1015
|
// IR-8: gemini::tool_loop
|
|
848
1016
|
tool_loop: {
|
|
849
1017
|
params: [
|
|
850
|
-
|
|
851
|
-
|
|
1018
|
+
p.str("prompt"),
|
|
1019
|
+
p.dict("options", void 0, {}, {
|
|
1020
|
+
tools: { type: { type: "dict" } },
|
|
1021
|
+
system: { type: { type: "string" }, defaultValue: "" },
|
|
1022
|
+
max_tokens: { type: { type: "number" }, defaultValue: 0 },
|
|
1023
|
+
max_errors: { type: { type: "number" }, defaultValue: 3 },
|
|
1024
|
+
max_turns: { type: { type: "number" }, defaultValue: 10 },
|
|
1025
|
+
messages: { type: { type: "list", element: { type: "dict", fields: { role: { type: { type: "string" } }, content: { type: { type: "string" } } } } }, defaultValue: [] }
|
|
1026
|
+
})
|
|
852
1027
|
],
|
|
853
1028
|
fn: async (args, ctx) => {
|
|
854
1029
|
const startTime = Date.now();
|
|
855
1030
|
try {
|
|
856
|
-
const prompt = args[
|
|
857
|
-
const options = args[
|
|
1031
|
+
const prompt = args["prompt"];
|
|
1032
|
+
const options = args["options"] ?? {};
|
|
858
1033
|
if (prompt.trim().length === 0) {
|
|
859
|
-
throw new
|
|
1034
|
+
throw new RuntimeError6("RILL-R004", "prompt text cannot be empty");
|
|
860
1035
|
}
|
|
861
1036
|
if (!("tools" in options) || !isDict2(options["tools"])) {
|
|
862
|
-
throw new
|
|
1037
|
+
throw new RuntimeError6(
|
|
863
1038
|
"RILL-R004",
|
|
864
1039
|
"tool_loop requires 'tools' option"
|
|
865
1040
|
);
|
|
@@ -1036,7 +1211,7 @@ function createGeminiExtension(config) {
|
|
|
1036
1211
|
return result2;
|
|
1037
1212
|
} catch (error) {
|
|
1038
1213
|
const duration = Date.now() - startTime;
|
|
1039
|
-
const rillError = error instanceof
|
|
1214
|
+
const rillError = error instanceof RuntimeError6 ? error : mapProviderError("Gemini", error, detectGeminiError);
|
|
1040
1215
|
emitExtensionEvent(ctx, {
|
|
1041
1216
|
event: "gemini:error",
|
|
1042
1217
|
subsystem: "extension:gemini",
|
|
@@ -1046,22 +1221,37 @@ function createGeminiExtension(config) {
|
|
|
1046
1221
|
throw rillError;
|
|
1047
1222
|
}
|
|
1048
1223
|
},
|
|
1049
|
-
description: "Execute tool-use loop with Gemini API",
|
|
1050
|
-
returnType:
|
|
1224
|
+
annotations: { description: "Execute tool-use loop with Gemini API" },
|
|
1225
|
+
returnType: rillTypeToTypeValue({
|
|
1226
|
+
type: "dict",
|
|
1227
|
+
fields: {
|
|
1228
|
+
content: { type: { type: "string" } },
|
|
1229
|
+
model: { type: { type: "string" } },
|
|
1230
|
+
usage: { type: { type: "dict", fields: { input: { type: { type: "number" } }, output: { type: { type: "number" } } } } },
|
|
1231
|
+
stop_reason: { type: { type: "string" } },
|
|
1232
|
+
turns: { type: { type: "number" } },
|
|
1233
|
+
messages: { type: { type: "list", element: { type: "dict" } } }
|
|
1234
|
+
}
|
|
1235
|
+
})
|
|
1051
1236
|
},
|
|
1052
1237
|
// IR-3: gemini::generate
|
|
1053
1238
|
generate: {
|
|
1054
1239
|
params: [
|
|
1055
|
-
|
|
1056
|
-
|
|
1240
|
+
p.str("prompt"),
|
|
1241
|
+
p.dict("options", void 0, {}, {
|
|
1242
|
+
schema: { type: { type: "dict" } },
|
|
1243
|
+
system: { type: { type: "string" }, defaultValue: "" },
|
|
1244
|
+
max_tokens: { type: { type: "number" }, defaultValue: 0 },
|
|
1245
|
+
messages: { type: { type: "list", element: { type: "dict", fields: { role: { type: { type: "string" } }, content: { type: { type: "string" } } } } }, defaultValue: [] }
|
|
1246
|
+
})
|
|
1057
1247
|
],
|
|
1058
1248
|
fn: async (args, ctx) => {
|
|
1059
1249
|
const startTime = Date.now();
|
|
1060
1250
|
try {
|
|
1061
|
-
const prompt = args[
|
|
1062
|
-
const options = args[
|
|
1251
|
+
const prompt = args["prompt"];
|
|
1252
|
+
const options = args["options"] ?? {};
|
|
1063
1253
|
if (!("schema" in options) || options["schema"] === null || options["schema"] === void 0) {
|
|
1064
|
-
throw new
|
|
1254
|
+
throw new RuntimeError6(
|
|
1065
1255
|
"RILL-R004",
|
|
1066
1256
|
"generate requires 'schema' option"
|
|
1067
1257
|
);
|
|
@@ -1127,7 +1317,7 @@ function createGeminiExtension(config) {
|
|
|
1127
1317
|
data = JSON.parse(raw);
|
|
1128
1318
|
} catch (parseError) {
|
|
1129
1319
|
const detail = parseError instanceof Error ? parseError.message : String(parseError);
|
|
1130
|
-
throw new
|
|
1320
|
+
throw new RuntimeError6(
|
|
1131
1321
|
"RILL-R004",
|
|
1132
1322
|
`generate: failed to parse response JSON: ${detail}`
|
|
1133
1323
|
);
|
|
@@ -1160,7 +1350,7 @@ function createGeminiExtension(config) {
|
|
|
1160
1350
|
return generateResult;
|
|
1161
1351
|
} catch (error) {
|
|
1162
1352
|
const duration = Date.now() - startTime;
|
|
1163
|
-
const rillError = error instanceof
|
|
1353
|
+
const rillError = error instanceof RuntimeError6 ? error : mapProviderError("Gemini", error, detectGeminiError);
|
|
1164
1354
|
emitExtensionEvent(ctx, {
|
|
1165
1355
|
event: "gemini:error",
|
|
1166
1356
|
subsystem: "extension:gemini",
|
|
@@ -1170,8 +1360,18 @@ function createGeminiExtension(config) {
|
|
|
1170
1360
|
throw rillError;
|
|
1171
1361
|
}
|
|
1172
1362
|
},
|
|
1173
|
-
description: "Generate structured output from Gemini API",
|
|
1174
|
-
returnType:
|
|
1363
|
+
annotations: { description: "Generate structured output from Gemini API" },
|
|
1364
|
+
returnType: rillTypeToTypeValue({
|
|
1365
|
+
type: "dict",
|
|
1366
|
+
fields: {
|
|
1367
|
+
data: { type: { type: "any" } },
|
|
1368
|
+
raw: { type: { type: "string" } },
|
|
1369
|
+
model: { type: { type: "string" } },
|
|
1370
|
+
usage: { type: { type: "dict", fields: { input: { type: { type: "number" } }, output: { type: { type: "number" } } } } },
|
|
1371
|
+
stop_reason: { type: { type: "string" } },
|
|
1372
|
+
id: { type: { type: "string" } }
|
|
1373
|
+
}
|
|
1374
|
+
})
|
|
1175
1375
|
}
|
|
1176
1376
|
};
|
|
1177
1377
|
result.dispose = dispose;
|
|
@@ -1179,7 +1379,9 @@ function createGeminiExtension(config) {
|
|
|
1179
1379
|
}
|
|
1180
1380
|
|
|
1181
1381
|
// src/index.ts
|
|
1182
|
-
var
|
|
1382
|
+
var _require = createRequire(import.meta.url);
|
|
1383
|
+
var _pkg = _require("../package.json");
|
|
1384
|
+
var VERSION = _pkg.version;
|
|
1183
1385
|
var configSchema = {
|
|
1184
1386
|
api_key: { type: "string", required: true, secret: true },
|
|
1185
1387
|
model: { type: "string", required: true },
|
|
@@ -1191,8 +1393,14 @@ var configSchema = {
|
|
|
1191
1393
|
system: { type: "string" },
|
|
1192
1394
|
embed_model: { type: "string" }
|
|
1193
1395
|
};
|
|
1396
|
+
var extensionManifest = {
|
|
1397
|
+
factory: createGeminiExtension,
|
|
1398
|
+
configSchema,
|
|
1399
|
+
version: VERSION
|
|
1400
|
+
};
|
|
1194
1401
|
export {
|
|
1195
1402
|
VERSION,
|
|
1196
1403
|
configSchema,
|
|
1197
|
-
createGeminiExtension
|
|
1404
|
+
createGeminiExtension,
|
|
1405
|
+
extensionManifest
|
|
1198
1406
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rcrsr/rill-ext-gemini",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "rill extension for Google Gemini API integration",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Andre Bremer",
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"scripting"
|
|
18
18
|
],
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"@rcrsr/rill": "
|
|
20
|
+
"@rcrsr/rill": "~0.16.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@rcrsr/rill": "
|
|
23
|
+
"@rcrsr/rill": "~0.16.0",
|
|
24
24
|
"@types/node": "^25.3.0",
|
|
25
25
|
"dts-bundle-generator": "^9.5.1",
|
|
26
26
|
"tsup": "^8.5.1",
|
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@google/genai": "^1.42.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",
|