@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 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 = "0.0.1";
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 RuntimeError5,
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
- let args;
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(args, ctx);
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
- let description;
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 properties = {};
304
- const required = [];
305
- for (const param of params) {
306
- const property = {};
307
- if (param.typeName !== null) {
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
- { name: "text", type: "string" },
504
- { name: "options", type: "dict", defaultValue: {} }
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[0];
510
- const options = args[1] ?? {};
654
+ const text = args["text"];
655
+ const options = args["options"] ?? {};
511
656
  if (text.trim().length === 0) {
512
- throw new RuntimeError5("RILL-R004", "prompt text cannot be empty");
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: "dict"
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
- { name: "messages", type: "list" },
586
- { name: "options", type: "dict", defaultValue: {} }
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[0];
592
- const options = args[1] ?? {};
749
+ const messages = args["messages"];
750
+ const options = args["options"] ?? {};
593
751
  if (messages.length === 0) {
594
- throw new RuntimeError5(
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 RuntimeError5(
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 RuntimeError5("RILL-R004", `invalid role '${role}'`);
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 RuntimeError5(
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 RuntimeError5(
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: "dict"
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: [{ name: "text", type: "string" }],
878
+ params: [p.str("text")],
711
879
  fn: async (args, ctx) => {
712
880
  const startTime = Date.now();
713
881
  try {
714
- const text = args[0];
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 RuntimeError5(
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: [{ name: "texts", type: "list" }],
929
+ params: [p.list("texts")],
762
930
  fn: async (args, ctx) => {
763
931
  const startTime = Date.now();
764
932
  try {
765
- const texts = args[0];
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 RuntimeError5(
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
- { name: "prompt", type: "string" },
824
- { name: "options", type: "dict", defaultValue: {} }
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[0];
830
- const options = args[1] ?? {};
1004
+ const prompt = args["prompt"];
1005
+ const options = args["options"] ?? {};
831
1006
  if (prompt.trim().length === 0) {
832
- throw new RuntimeError5("RILL-R004", "prompt text cannot be empty");
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 RuntimeError5(
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 RuntimeError5(
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 RuntimeError5("RILL-R004", `invalid role '${role}'`);
1037
+ throw new RuntimeError6("RILL-R004", `invalid role '${role}'`);
863
1038
  }
864
1039
  if (!("content" in msg) || typeof msg["content"] !== "string") {
865
- throw new RuntimeError5(
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: "dict"
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
- { name: "prompt", type: "string" },
1065
- { name: "options", type: "dict" }
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[0];
1071
- const options = args[1] ?? {};
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 RuntimeError5(
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 RuntimeError5(
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 RuntimeError5("RILL-R004", `invalid role '${role}'`);
1290
+ throw new RuntimeError6("RILL-R004", `invalid role '${role}'`);
1101
1291
  }
1102
1292
  if (!("content" in msg) || typeof msg["content"] !== "string") {
1103
- throw new RuntimeError5(
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 RuntimeError5(
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 RuntimeError5 ? error : mapProviderError("OpenAI", error, detectOpenAIError);
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: "dict"
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 VERSION = "0.0.1";
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.9.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": "^0.9.0"
20
+ "@rcrsr/rill": "~0.16.0"
21
21
  },
22
22
  "devDependencies": {
23
- "@rcrsr/rill": "^0.9.0",
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",