@rcrsr/rill-ext-openai 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 OpenAIExtensionConfig = LLMProviderConfig;
|
|
|
73
73
|
* ```
|
|
74
74
|
*/
|
|
75
75
|
export declare function createOpenAIExtension(config: OpenAIExtensionConfig): 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,11 +1,15 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { createRequire } from "module";
|
|
3
|
+
|
|
1
4
|
// src/factory.ts
|
|
2
5
|
import OpenAI from "openai";
|
|
3
6
|
import {
|
|
4
|
-
RuntimeError as
|
|
7
|
+
RuntimeError as RuntimeError6,
|
|
5
8
|
emitExtensionEvent,
|
|
6
9
|
createVector,
|
|
7
10
|
isDict as isDict2,
|
|
8
|
-
isVector
|
|
11
|
+
isVector,
|
|
12
|
+
rillTypeToTypeValue
|
|
9
13
|
} from "@rcrsr/rill";
|
|
10
14
|
|
|
11
15
|
// ../../shared/ext-llm/dist/validation.js
|
|
@@ -96,6 +100,52 @@ function mapRillType(rillType) {
|
|
|
96
100
|
}
|
|
97
101
|
return jsonType;
|
|
98
102
|
}
|
|
103
|
+
function buildPropertyFromStructuralType(rillType) {
|
|
104
|
+
if (rillType.type === "closure" || rillType.type === "tuple") {
|
|
105
|
+
throw new RuntimeError3("RILL-R004", `unsupported type for JSON Schema: ${rillType.type}`);
|
|
106
|
+
}
|
|
107
|
+
if (rillType.type === "any") {
|
|
108
|
+
return {};
|
|
109
|
+
}
|
|
110
|
+
if (rillType.type === "list") {
|
|
111
|
+
const property = { type: "array" };
|
|
112
|
+
if (rillType.element !== void 0) {
|
|
113
|
+
property.items = buildPropertyFromStructuralType(rillType.element);
|
|
114
|
+
}
|
|
115
|
+
return property;
|
|
116
|
+
}
|
|
117
|
+
if (rillType.type === "dict") {
|
|
118
|
+
return { type: "object" };
|
|
119
|
+
}
|
|
120
|
+
return { type: mapRillType(rillType.type) };
|
|
121
|
+
}
|
|
122
|
+
function buildJsonSchemaFromStructuralType(type, params) {
|
|
123
|
+
const properties = {};
|
|
124
|
+
const required = [];
|
|
125
|
+
if (type.type === "closure") {
|
|
126
|
+
const closureParams = type.params ?? [];
|
|
127
|
+
for (let i = 0; i < closureParams.length; i++) {
|
|
128
|
+
const fieldDef = closureParams[i];
|
|
129
|
+
const paramName = fieldDef.name ?? `param${i}`;
|
|
130
|
+
const paramType = fieldDef.type;
|
|
131
|
+
const rillParam = params?.[i];
|
|
132
|
+
const property = buildPropertyFromStructuralType(paramType);
|
|
133
|
+
const description = rillParam?.annotations["description"];
|
|
134
|
+
if (typeof description === "string") {
|
|
135
|
+
property.description = description;
|
|
136
|
+
}
|
|
137
|
+
const enumAnnotation = rillParam?.annotations["enum"];
|
|
138
|
+
if (Array.isArray(enumAnnotation)) {
|
|
139
|
+
property.enum = enumAnnotation;
|
|
140
|
+
}
|
|
141
|
+
properties[paramName] = property;
|
|
142
|
+
if (rillParam === void 0 || rillParam.defaultValue === void 0) {
|
|
143
|
+
required.push(paramName);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return { type: "object", properties, required, additionalProperties: false };
|
|
148
|
+
}
|
|
99
149
|
function buildJsonSchema(rillSchema) {
|
|
100
150
|
const properties = {};
|
|
101
151
|
const required = [];
|
|
@@ -176,21 +226,20 @@ async function executeToolCall(toolName, toolInput, tools, context) {
|
|
|
176
226
|
throw new RuntimeError4("RILL-R004", `Invalid tool input for ${toolName}: tool must be application, runtime, or script callable`);
|
|
177
227
|
}
|
|
178
228
|
try {
|
|
179
|
-
|
|
180
|
-
if ((callable.kind === "application" || callable.kind === "script") && callable.params && callable.params.length > 0) {
|
|
181
|
-
const params = callable.params;
|
|
182
|
-
const inputDict = toolInput;
|
|
183
|
-
args = params.map((param) => {
|
|
184
|
-
const value = inputDict[param.name];
|
|
185
|
-
return value !== void 0 ? value : void 0;
|
|
186
|
-
});
|
|
187
|
-
} else {
|
|
188
|
-
args = [toolInput];
|
|
189
|
-
}
|
|
229
|
+
const inputDict = toolInput;
|
|
190
230
|
if (callable.kind === "script") {
|
|
191
231
|
if (!context) {
|
|
192
232
|
throw new RuntimeError4("RILL-R004", `Invalid tool input for ${toolName}: script callable requires a runtime context`);
|
|
193
233
|
}
|
|
234
|
+
let args;
|
|
235
|
+
if (callable.params && callable.params.length > 0) {
|
|
236
|
+
args = callable.params.map((param) => {
|
|
237
|
+
const value = inputDict[param.name];
|
|
238
|
+
return value !== void 0 ? value : void 0;
|
|
239
|
+
});
|
|
240
|
+
} else {
|
|
241
|
+
args = [inputDict];
|
|
242
|
+
}
|
|
194
243
|
return await invokeCallable(callable, args, context);
|
|
195
244
|
}
|
|
196
245
|
const ctx = context ?? {
|
|
@@ -198,7 +247,7 @@ async function executeToolCall(toolName, toolInput, tools, context) {
|
|
|
198
247
|
variables: /* @__PURE__ */ new Map(),
|
|
199
248
|
pipeValue: null
|
|
200
249
|
};
|
|
201
|
-
const result = callable.fn(
|
|
250
|
+
const result = callable.fn(inputDict, ctx);
|
|
202
251
|
return result instanceof Promise ? await result : result;
|
|
203
252
|
} catch (error) {
|
|
204
253
|
if (error instanceof RuntimeError4) {
|
|
@@ -291,48 +340,19 @@ async function executeToolLoop(messages, tools, maxErrors, callbacks, emitEvent,
|
|
|
291
340
|
throw new RuntimeError4("RILL-R004", `tool_loop: tool "${name}" is not a callable`);
|
|
292
341
|
}
|
|
293
342
|
const callable = fnValue;
|
|
294
|
-
|
|
295
|
-
if (callable.kind === "script") {
|
|
296
|
-
description = callable.annotations["description"] ?? "";
|
|
297
|
-
} else {
|
|
298
|
-
description = callable.description ?? "";
|
|
299
|
-
}
|
|
343
|
+
const description = callable.annotations?.["description"] ?? "";
|
|
300
344
|
let inputSchema;
|
|
301
345
|
const params = callable.kind === "application" ? callable.params ?? [] : callable.kind === "script" ? callable.params : [];
|
|
302
346
|
if (params.length > 0) {
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const descriptor = {
|
|
309
|
-
[param.name]: { type: param.typeName }
|
|
310
|
-
};
|
|
311
|
-
const schema = buildJsonSchema(descriptor);
|
|
312
|
-
const built = schema.properties[param.name];
|
|
313
|
-
if (built !== void 0) {
|
|
314
|
-
Object.assign(property, built);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
let paramDesc;
|
|
318
|
-
if (callable.kind === "script") {
|
|
319
|
-
const annot = callable.paramAnnotations[param.name];
|
|
320
|
-
paramDesc = annot?.["description"] ?? "";
|
|
321
|
-
} else {
|
|
322
|
-
paramDesc = param.description ?? "";
|
|
323
|
-
}
|
|
324
|
-
if (paramDesc) {
|
|
325
|
-
property["description"] = paramDesc;
|
|
326
|
-
}
|
|
327
|
-
properties[param.name] = property;
|
|
328
|
-
if (param.defaultValue === null) {
|
|
329
|
-
required.push(param.name);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
347
|
+
const closureType = {
|
|
348
|
+
type: "closure",
|
|
349
|
+
params: params.map((p2) => ({ name: p2.name, type: p2.type ?? { type: "any" } }))
|
|
350
|
+
};
|
|
351
|
+
const builtSchema = buildJsonSchemaFromStructuralType(closureType, [...params]);
|
|
332
352
|
inputSchema = {
|
|
333
353
|
type: "object",
|
|
334
|
-
properties,
|
|
335
|
-
required
|
|
354
|
+
properties: builtSchema.properties,
|
|
355
|
+
required: builtSchema.required
|
|
336
356
|
};
|
|
337
357
|
} else {
|
|
338
358
|
inputSchema = { type: "object", properties: {}, required: [] };
|
|
@@ -452,6 +472,128 @@ async function executeToolLoop(messages, tools, maxErrors, callbacks, emitEvent,
|
|
|
452
472
|
};
|
|
453
473
|
}
|
|
454
474
|
|
|
475
|
+
// ../../shared/ext-param/dist/param.js
|
|
476
|
+
import { RuntimeError as RuntimeError5 } from "@rcrsr/rill";
|
|
477
|
+
function validateParamName(name) {
|
|
478
|
+
if (name === "") {
|
|
479
|
+
throw new RuntimeError5("RILL-R001", "param name must not be empty");
|
|
480
|
+
}
|
|
481
|
+
if (/\s/.test(name)) {
|
|
482
|
+
throw new RuntimeError5("RILL-R001", "param name must be a valid identifier");
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
function buildAnnotations(desc) {
|
|
486
|
+
if (desc !== void 0) {
|
|
487
|
+
return { description: desc };
|
|
488
|
+
}
|
|
489
|
+
return {};
|
|
490
|
+
}
|
|
491
|
+
var p = {
|
|
492
|
+
/**
|
|
493
|
+
* IR-1: Creates a string parameter descriptor.
|
|
494
|
+
*
|
|
495
|
+
* @param name - Parameter name (must be a valid identifier)
|
|
496
|
+
* @param desc - Optional description
|
|
497
|
+
* @returns RillParam with type 'string'
|
|
498
|
+
*/
|
|
499
|
+
str(name, desc) {
|
|
500
|
+
validateParamName(name);
|
|
501
|
+
return {
|
|
502
|
+
name,
|
|
503
|
+
type: { type: "string" },
|
|
504
|
+
defaultValue: void 0,
|
|
505
|
+
annotations: buildAnnotations(desc)
|
|
506
|
+
};
|
|
507
|
+
},
|
|
508
|
+
/**
|
|
509
|
+
* IR-2: Creates a number parameter descriptor.
|
|
510
|
+
*
|
|
511
|
+
* @param name - Parameter name (must be a valid identifier)
|
|
512
|
+
* @param desc - Optional description
|
|
513
|
+
* @param def - Optional default value
|
|
514
|
+
* @returns RillParam with type 'number'
|
|
515
|
+
*/
|
|
516
|
+
num(name, desc, def) {
|
|
517
|
+
validateParamName(name);
|
|
518
|
+
return {
|
|
519
|
+
name,
|
|
520
|
+
type: { type: "number" },
|
|
521
|
+
defaultValue: def,
|
|
522
|
+
annotations: buildAnnotations(desc)
|
|
523
|
+
};
|
|
524
|
+
},
|
|
525
|
+
/**
|
|
526
|
+
* IR-3: Creates a boolean parameter descriptor.
|
|
527
|
+
*
|
|
528
|
+
* @param name - Parameter name (must be a valid identifier)
|
|
529
|
+
* @param desc - Optional description
|
|
530
|
+
* @param def - Optional default value
|
|
531
|
+
* @returns RillParam with type 'bool'
|
|
532
|
+
*/
|
|
533
|
+
bool(name, desc, def) {
|
|
534
|
+
validateParamName(name);
|
|
535
|
+
return {
|
|
536
|
+
name,
|
|
537
|
+
type: { type: "bool" },
|
|
538
|
+
defaultValue: def,
|
|
539
|
+
annotations: buildAnnotations(desc)
|
|
540
|
+
};
|
|
541
|
+
},
|
|
542
|
+
/**
|
|
543
|
+
* IR-4: Creates a dict parameter descriptor.
|
|
544
|
+
*
|
|
545
|
+
* @param name - Parameter name (must be a valid identifier)
|
|
546
|
+
* @param desc - Optional description
|
|
547
|
+
* @param def - Optional default value
|
|
548
|
+
* @param fields - Optional structural field definitions (RillFieldDef with type and optional defaultValue)
|
|
549
|
+
* @returns RillParam with type 'dict' (with fields if provided)
|
|
550
|
+
*/
|
|
551
|
+
dict(name, desc, def, fields) {
|
|
552
|
+
validateParamName(name);
|
|
553
|
+
const type = fields !== void 0 ? { type: "dict", fields } : { type: "dict" };
|
|
554
|
+
return {
|
|
555
|
+
name,
|
|
556
|
+
type,
|
|
557
|
+
defaultValue: def,
|
|
558
|
+
annotations: buildAnnotations(desc)
|
|
559
|
+
};
|
|
560
|
+
},
|
|
561
|
+
/**
|
|
562
|
+
* IR-5: Creates a list parameter descriptor.
|
|
563
|
+
*
|
|
564
|
+
* @param name - Parameter name (must be a valid identifier)
|
|
565
|
+
* @param itemType - Optional element type; omitted when not provided
|
|
566
|
+
* @param desc - Optional description
|
|
567
|
+
* @returns RillParam with type 'list' (with element if itemType provided)
|
|
568
|
+
*/
|
|
569
|
+
list(name, itemType, desc) {
|
|
570
|
+
validateParamName(name);
|
|
571
|
+
const type = itemType !== void 0 ? { type: "list", element: itemType } : { type: "list" };
|
|
572
|
+
return {
|
|
573
|
+
name,
|
|
574
|
+
type,
|
|
575
|
+
defaultValue: void 0,
|
|
576
|
+
annotations: buildAnnotations(desc)
|
|
577
|
+
};
|
|
578
|
+
},
|
|
579
|
+
/**
|
|
580
|
+
* IR-6: Creates a callable parameter descriptor.
|
|
581
|
+
*
|
|
582
|
+
* @param name - Parameter name (must be a valid identifier)
|
|
583
|
+
* @param desc - Optional description
|
|
584
|
+
* @returns RillParam with type 'closure'
|
|
585
|
+
*/
|
|
586
|
+
callable(name, desc) {
|
|
587
|
+
validateParamName(name);
|
|
588
|
+
return {
|
|
589
|
+
name,
|
|
590
|
+
type: { type: "closure" },
|
|
591
|
+
defaultValue: void 0,
|
|
592
|
+
annotations: buildAnnotations(desc)
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
|
|
455
597
|
// src/factory.ts
|
|
456
598
|
var DEFAULT_MAX_COMPLETION_TOKENS = 4096;
|
|
457
599
|
var detectOpenAIError = (error) => {
|
|
@@ -500,16 +642,19 @@ function createOpenAIExtension(config) {
|
|
|
500
642
|
// IR-4: openai::message
|
|
501
643
|
message: {
|
|
502
644
|
params: [
|
|
503
|
-
|
|
504
|
-
|
|
645
|
+
p.str("text"),
|
|
646
|
+
p.dict("options", void 0, {}, {
|
|
647
|
+
system: { type: { type: "string" }, defaultValue: "" },
|
|
648
|
+
max_tokens: { type: { type: "number" }, defaultValue: 0 }
|
|
649
|
+
})
|
|
505
650
|
],
|
|
506
651
|
fn: async (args, ctx) => {
|
|
507
652
|
const startTime = Date.now();
|
|
508
653
|
try {
|
|
509
|
-
const text = args[
|
|
510
|
-
const options = args[
|
|
654
|
+
const text = args["text"];
|
|
655
|
+
const options = args["options"] ?? {};
|
|
511
656
|
if (text.trim().length === 0) {
|
|
512
|
-
throw new
|
|
657
|
+
throw new RuntimeError6("RILL-R004", "prompt text cannot be empty");
|
|
513
658
|
}
|
|
514
659
|
const system = typeof options["system"] === "string" ? options["system"] : factorySystem;
|
|
515
660
|
const maxTokens = typeof options["max_tokens"] === "number" ? options["max_tokens"] : factoryMaxTokens;
|
|
@@ -576,22 +721,35 @@ function createOpenAIExtension(config) {
|
|
|
576
721
|
throw rillError;
|
|
577
722
|
}
|
|
578
723
|
},
|
|
579
|
-
description: "Send single message to OpenAI API",
|
|
580
|
-
returnType:
|
|
724
|
+
annotations: { description: "Send single message to OpenAI API" },
|
|
725
|
+
returnType: rillTypeToTypeValue({
|
|
726
|
+
type: "dict",
|
|
727
|
+
fields: {
|
|
728
|
+
content: { type: { type: "string" } },
|
|
729
|
+
model: { type: { type: "string" } },
|
|
730
|
+
usage: { type: { type: "dict", fields: { input: { type: { type: "number" } }, output: { type: { type: "number" } } } } },
|
|
731
|
+
stop_reason: { type: { type: "string" } },
|
|
732
|
+
id: { type: { type: "string" } },
|
|
733
|
+
messages: { type: { type: "list", element: { type: "dict" } } }
|
|
734
|
+
}
|
|
735
|
+
})
|
|
581
736
|
},
|
|
582
737
|
// IR-5: openai::messages
|
|
583
738
|
messages: {
|
|
584
739
|
params: [
|
|
585
|
-
{
|
|
586
|
-
|
|
740
|
+
p.list("messages", { type: "dict", fields: { role: { type: { type: "string" } }, content: { type: { type: "string" } } } }),
|
|
741
|
+
p.dict("options", void 0, {}, {
|
|
742
|
+
system: { type: { type: "string" }, defaultValue: "" },
|
|
743
|
+
max_tokens: { type: { type: "number" }, defaultValue: 0 }
|
|
744
|
+
})
|
|
587
745
|
],
|
|
588
746
|
fn: async (args, ctx) => {
|
|
589
747
|
const startTime = Date.now();
|
|
590
748
|
try {
|
|
591
|
-
const messages = args[
|
|
592
|
-
const options = args[
|
|
749
|
+
const messages = args["messages"];
|
|
750
|
+
const options = args["options"] ?? {};
|
|
593
751
|
if (messages.length === 0) {
|
|
594
|
-
throw new
|
|
752
|
+
throw new RuntimeError6(
|
|
595
753
|
"RILL-R004",
|
|
596
754
|
"messages list cannot be empty"
|
|
597
755
|
);
|
|
@@ -608,18 +766,18 @@ function createOpenAIExtension(config) {
|
|
|
608
766
|
for (let i = 0; i < messages.length; i++) {
|
|
609
767
|
const msg = messages[i];
|
|
610
768
|
if (!msg || typeof msg !== "object" || !("role" in msg)) {
|
|
611
|
-
throw new
|
|
769
|
+
throw new RuntimeError6(
|
|
612
770
|
"RILL-R004",
|
|
613
771
|
"message missing required 'role' field"
|
|
614
772
|
);
|
|
615
773
|
}
|
|
616
774
|
const role = msg["role"];
|
|
617
775
|
if (role !== "user" && role !== "assistant" && role !== "tool") {
|
|
618
|
-
throw new
|
|
776
|
+
throw new RuntimeError6("RILL-R004", `invalid role '${role}'`);
|
|
619
777
|
}
|
|
620
778
|
if (role === "user" || role === "tool") {
|
|
621
779
|
if (!("content" in msg) || typeof msg["content"] !== "string") {
|
|
622
|
-
throw new
|
|
780
|
+
throw new RuntimeError6(
|
|
623
781
|
"RILL-R004",
|
|
624
782
|
`${role} message requires 'content'`
|
|
625
783
|
);
|
|
@@ -632,7 +790,7 @@ function createOpenAIExtension(config) {
|
|
|
632
790
|
const hasContent = "content" in msg && msg["content"];
|
|
633
791
|
const hasToolCalls = "tool_calls" in msg && msg["tool_calls"];
|
|
634
792
|
if (!hasContent && !hasToolCalls) {
|
|
635
|
-
throw new
|
|
793
|
+
throw new RuntimeError6(
|
|
636
794
|
"RILL-R004",
|
|
637
795
|
"assistant message requires 'content' or 'tool_calls'"
|
|
638
796
|
);
|
|
@@ -702,16 +860,26 @@ function createOpenAIExtension(config) {
|
|
|
702
860
|
throw rillError;
|
|
703
861
|
}
|
|
704
862
|
},
|
|
705
|
-
description: "Send multi-turn conversation to OpenAI API",
|
|
706
|
-
returnType:
|
|
863
|
+
annotations: { description: "Send multi-turn conversation to OpenAI API" },
|
|
864
|
+
returnType: rillTypeToTypeValue({
|
|
865
|
+
type: "dict",
|
|
866
|
+
fields: {
|
|
867
|
+
content: { type: { type: "string" } },
|
|
868
|
+
model: { type: { type: "string" } },
|
|
869
|
+
usage: { type: { type: "dict", fields: { input: { type: { type: "number" } }, output: { type: { type: "number" } } } } },
|
|
870
|
+
stop_reason: { type: { type: "string" } },
|
|
871
|
+
id: { type: { type: "string" } },
|
|
872
|
+
messages: { type: { type: "list", element: { type: "dict" } } }
|
|
873
|
+
}
|
|
874
|
+
})
|
|
707
875
|
},
|
|
708
876
|
// IR-6: openai::embed
|
|
709
877
|
embed: {
|
|
710
|
-
params: [
|
|
878
|
+
params: [p.str("text")],
|
|
711
879
|
fn: async (args, ctx) => {
|
|
712
880
|
const startTime = Date.now();
|
|
713
881
|
try {
|
|
714
|
-
const text = args[
|
|
882
|
+
const text = args["text"];
|
|
715
883
|
validateEmbedText(text.trim());
|
|
716
884
|
validateEmbedModel(factoryEmbedModel);
|
|
717
885
|
const response = await client.embeddings.create({
|
|
@@ -721,7 +889,7 @@ function createOpenAIExtension(config) {
|
|
|
721
889
|
});
|
|
722
890
|
const embeddingData = response.data[0]?.embedding;
|
|
723
891
|
if (!embeddingData || embeddingData.length === 0) {
|
|
724
|
-
throw new
|
|
892
|
+
throw new RuntimeError6(
|
|
725
893
|
"RILL-R004",
|
|
726
894
|
"OpenAI: empty embedding returned"
|
|
727
895
|
);
|
|
@@ -753,16 +921,16 @@ function createOpenAIExtension(config) {
|
|
|
753
921
|
throw rillError;
|
|
754
922
|
}
|
|
755
923
|
},
|
|
756
|
-
description: "Generate embedding vector for text",
|
|
757
|
-
returnType: "vector"
|
|
924
|
+
annotations: { description: "Generate embedding vector for text" },
|
|
925
|
+
returnType: rillTypeToTypeValue({ type: "vector" })
|
|
758
926
|
},
|
|
759
927
|
// IR-7: openai::embed_batch
|
|
760
928
|
embed_batch: {
|
|
761
|
-
params: [
|
|
929
|
+
params: [p.list("texts")],
|
|
762
930
|
fn: async (args, ctx) => {
|
|
763
931
|
const startTime = Date.now();
|
|
764
932
|
try {
|
|
765
|
-
const texts = args[
|
|
933
|
+
const texts = args["texts"];
|
|
766
934
|
if (texts.length === 0) {
|
|
767
935
|
return [];
|
|
768
936
|
}
|
|
@@ -777,7 +945,7 @@ function createOpenAIExtension(config) {
|
|
|
777
945
|
for (const embeddingItem of response.data) {
|
|
778
946
|
const embeddingData = embeddingItem.embedding;
|
|
779
947
|
if (!embeddingData || embeddingData.length === 0) {
|
|
780
|
-
throw new
|
|
948
|
+
throw new RuntimeError6(
|
|
781
949
|
"RILL-R004",
|
|
782
950
|
"OpenAI: empty embedding returned"
|
|
783
951
|
);
|
|
@@ -814,25 +982,32 @@ function createOpenAIExtension(config) {
|
|
|
814
982
|
throw rillError;
|
|
815
983
|
}
|
|
816
984
|
},
|
|
817
|
-
description: "Generate embedding vectors for multiple texts",
|
|
818
|
-
returnType: "list"
|
|
985
|
+
annotations: { description: "Generate embedding vectors for multiple texts" },
|
|
986
|
+
returnType: rillTypeToTypeValue({ type: "list", element: { type: "vector" } })
|
|
819
987
|
},
|
|
820
988
|
// IR-8: openai::tool_loop
|
|
821
989
|
tool_loop: {
|
|
822
990
|
params: [
|
|
823
|
-
|
|
824
|
-
|
|
991
|
+
p.str("prompt"),
|
|
992
|
+
p.dict("options", void 0, {}, {
|
|
993
|
+
tools: { type: { type: "dict" } },
|
|
994
|
+
system: { type: { type: "string" }, defaultValue: "" },
|
|
995
|
+
max_tokens: { type: { type: "number" }, defaultValue: 0 },
|
|
996
|
+
max_errors: { type: { type: "number" }, defaultValue: 3 },
|
|
997
|
+
max_turns: { type: { type: "number" }, defaultValue: 10 },
|
|
998
|
+
messages: { type: { type: "list", element: { type: "dict", fields: { role: { type: { type: "string" } }, content: { type: { type: "string" } } } } }, defaultValue: [] }
|
|
999
|
+
})
|
|
825
1000
|
],
|
|
826
1001
|
fn: async (args, ctx) => {
|
|
827
1002
|
const startTime = Date.now();
|
|
828
1003
|
try {
|
|
829
|
-
const prompt = args[
|
|
830
|
-
const options = args[
|
|
1004
|
+
const prompt = args["prompt"];
|
|
1005
|
+
const options = args["options"] ?? {};
|
|
831
1006
|
if (prompt.trim().length === 0) {
|
|
832
|
-
throw new
|
|
1007
|
+
throw new RuntimeError6("RILL-R004", "prompt text cannot be empty");
|
|
833
1008
|
}
|
|
834
1009
|
if (!("tools" in options) || !isDict2(options["tools"])) {
|
|
835
|
-
throw new
|
|
1010
|
+
throw new RuntimeError6(
|
|
836
1011
|
"RILL-R004",
|
|
837
1012
|
"tool_loop requires 'tools' option"
|
|
838
1013
|
);
|
|
@@ -852,17 +1027,17 @@ function createOpenAIExtension(config) {
|
|
|
852
1027
|
const prependedMessages = options["messages"];
|
|
853
1028
|
for (const msg of prependedMessages) {
|
|
854
1029
|
if (!msg || typeof msg !== "object" || !("role" in msg)) {
|
|
855
|
-
throw new
|
|
1030
|
+
throw new RuntimeError6(
|
|
856
1031
|
"RILL-R004",
|
|
857
1032
|
"message missing required 'role' field"
|
|
858
1033
|
);
|
|
859
1034
|
}
|
|
860
1035
|
const role = msg["role"];
|
|
861
1036
|
if (role !== "user" && role !== "assistant") {
|
|
862
|
-
throw new
|
|
1037
|
+
throw new RuntimeError6("RILL-R004", `invalid role '${role}'`);
|
|
863
1038
|
}
|
|
864
1039
|
if (!("content" in msg) || typeof msg["content"] !== "string") {
|
|
865
|
-
throw new
|
|
1040
|
+
throw new RuntimeError6(
|
|
866
1041
|
"RILL-R004",
|
|
867
1042
|
`${role} message requires 'content'`
|
|
868
1043
|
);
|
|
@@ -1055,22 +1230,37 @@ function createOpenAIExtension(config) {
|
|
|
1055
1230
|
throw rillError;
|
|
1056
1231
|
}
|
|
1057
1232
|
},
|
|
1058
|
-
description: "Execute tool-use loop with OpenAI API",
|
|
1059
|
-
returnType:
|
|
1233
|
+
annotations: { description: "Execute tool-use loop with OpenAI API" },
|
|
1234
|
+
returnType: rillTypeToTypeValue({
|
|
1235
|
+
type: "dict",
|
|
1236
|
+
fields: {
|
|
1237
|
+
content: { type: { type: "string" } },
|
|
1238
|
+
model: { type: { type: "string" } },
|
|
1239
|
+
usage: { type: { type: "dict", fields: { input: { type: { type: "number" } }, output: { type: { type: "number" } } } } },
|
|
1240
|
+
stop_reason: { type: { type: "string" } },
|
|
1241
|
+
turns: { type: { type: "number" } },
|
|
1242
|
+
messages: { type: { type: "list", element: { type: "dict" } } }
|
|
1243
|
+
}
|
|
1244
|
+
})
|
|
1060
1245
|
},
|
|
1061
1246
|
// IR-3: openai::generate
|
|
1062
1247
|
generate: {
|
|
1063
1248
|
params: [
|
|
1064
|
-
|
|
1065
|
-
|
|
1249
|
+
p.str("prompt"),
|
|
1250
|
+
p.dict("options", void 0, {}, {
|
|
1251
|
+
schema: { type: { type: "dict" } },
|
|
1252
|
+
system: { type: { type: "string" }, defaultValue: "" },
|
|
1253
|
+
max_tokens: { type: { type: "number" }, defaultValue: 0 },
|
|
1254
|
+
messages: { type: { type: "list", element: { type: "dict", fields: { role: { type: { type: "string" } }, content: { type: { type: "string" } } } } }, defaultValue: [] }
|
|
1255
|
+
})
|
|
1066
1256
|
],
|
|
1067
1257
|
fn: async (args, ctx) => {
|
|
1068
1258
|
const startTime = Date.now();
|
|
1069
1259
|
try {
|
|
1070
|
-
const prompt = args[
|
|
1071
|
-
const options = args[
|
|
1260
|
+
const prompt = args["prompt"];
|
|
1261
|
+
const options = args["options"] ?? {};
|
|
1072
1262
|
if (!("schema" in options) || options["schema"] === null || options["schema"] === void 0) {
|
|
1073
|
-
throw new
|
|
1263
|
+
throw new RuntimeError6(
|
|
1074
1264
|
"RILL-R004",
|
|
1075
1265
|
"generate requires 'schema' option"
|
|
1076
1266
|
);
|
|
@@ -1090,17 +1280,17 @@ function createOpenAIExtension(config) {
|
|
|
1090
1280
|
const prependedMessages = options["messages"];
|
|
1091
1281
|
for (const msg of prependedMessages) {
|
|
1092
1282
|
if (!msg || typeof msg !== "object" || !("role" in msg)) {
|
|
1093
|
-
throw new
|
|
1283
|
+
throw new RuntimeError6(
|
|
1094
1284
|
"RILL-R004",
|
|
1095
1285
|
"message missing required 'role' field"
|
|
1096
1286
|
);
|
|
1097
1287
|
}
|
|
1098
1288
|
const role = msg["role"];
|
|
1099
1289
|
if (role !== "user" && role !== "assistant") {
|
|
1100
|
-
throw new
|
|
1290
|
+
throw new RuntimeError6("RILL-R004", `invalid role '${role}'`);
|
|
1101
1291
|
}
|
|
1102
1292
|
if (!("content" in msg) || typeof msg["content"] !== "string") {
|
|
1103
|
-
throw new
|
|
1293
|
+
throw new RuntimeError6(
|
|
1104
1294
|
"RILL-R004",
|
|
1105
1295
|
`${role} message requires 'content'`
|
|
1106
1296
|
);
|
|
@@ -1135,7 +1325,7 @@ function createOpenAIExtension(config) {
|
|
|
1135
1325
|
data = JSON.parse(raw);
|
|
1136
1326
|
} catch (parseError) {
|
|
1137
1327
|
const detail = parseError instanceof Error ? parseError.message : String(parseError);
|
|
1138
|
-
throw new
|
|
1328
|
+
throw new RuntimeError6(
|
|
1139
1329
|
"RILL-R004",
|
|
1140
1330
|
`generate: failed to parse response JSON: ${detail}`
|
|
1141
1331
|
);
|
|
@@ -1164,7 +1354,7 @@ function createOpenAIExtension(config) {
|
|
|
1164
1354
|
return result2;
|
|
1165
1355
|
} catch (error) {
|
|
1166
1356
|
const duration = Date.now() - startTime;
|
|
1167
|
-
const rillError = error instanceof
|
|
1357
|
+
const rillError = error instanceof RuntimeError6 ? error : mapProviderError("OpenAI", error, detectOpenAIError);
|
|
1168
1358
|
emitExtensionEvent(ctx, {
|
|
1169
1359
|
event: "openai:error",
|
|
1170
1360
|
subsystem: "extension:openai",
|
|
@@ -1174,8 +1364,18 @@ function createOpenAIExtension(config) {
|
|
|
1174
1364
|
throw rillError;
|
|
1175
1365
|
}
|
|
1176
1366
|
},
|
|
1177
|
-
description: "Generate structured output from OpenAI API",
|
|
1178
|
-
returnType:
|
|
1367
|
+
annotations: { description: "Generate structured output from OpenAI API" },
|
|
1368
|
+
returnType: rillTypeToTypeValue({
|
|
1369
|
+
type: "dict",
|
|
1370
|
+
fields: {
|
|
1371
|
+
data: { type: { type: "any" } },
|
|
1372
|
+
raw: { type: { type: "string" } },
|
|
1373
|
+
model: { type: { type: "string" } },
|
|
1374
|
+
usage: { type: { type: "dict", fields: { input: { type: { type: "number" } }, output: { type: { type: "number" } } } } },
|
|
1375
|
+
stop_reason: { type: { type: "string" } },
|
|
1376
|
+
id: { type: { type: "string" } }
|
|
1377
|
+
}
|
|
1378
|
+
})
|
|
1179
1379
|
}
|
|
1180
1380
|
};
|
|
1181
1381
|
result.dispose = dispose;
|
|
@@ -1183,7 +1383,9 @@ function createOpenAIExtension(config) {
|
|
|
1183
1383
|
}
|
|
1184
1384
|
|
|
1185
1385
|
// src/index.ts
|
|
1186
|
-
var
|
|
1386
|
+
var _require = createRequire(import.meta.url);
|
|
1387
|
+
var _pkg = _require("../package.json");
|
|
1388
|
+
var VERSION = _pkg.version;
|
|
1187
1389
|
var configSchema = {
|
|
1188
1390
|
api_key: { type: "string", required: true, secret: true },
|
|
1189
1391
|
model: { type: "string", required: true },
|
|
@@ -1195,8 +1397,14 @@ var configSchema = {
|
|
|
1195
1397
|
system: { type: "string" },
|
|
1196
1398
|
embed_model: { type: "string" }
|
|
1197
1399
|
};
|
|
1400
|
+
var extensionManifest = {
|
|
1401
|
+
factory: createOpenAIExtension,
|
|
1402
|
+
configSchema,
|
|
1403
|
+
version: VERSION
|
|
1404
|
+
};
|
|
1198
1405
|
export {
|
|
1199
1406
|
VERSION,
|
|
1200
1407
|
configSchema,
|
|
1201
|
-
createOpenAIExtension
|
|
1408
|
+
createOpenAIExtension,
|
|
1409
|
+
extensionManifest
|
|
1202
1410
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rcrsr/rill-ext-openai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "rill extension for OpenAI 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
|
-
"openai": "^6.25.0"
|
|
46
|
+
"openai": "^6.25.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",
|