@proposit/proposit-core 1.0.2 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/dist/cli/commands/parse.d.ts.map +1 -1
  2. package/dist/cli/commands/parse.js +62 -27
  3. package/dist/cli/commands/parse.js.map +1 -1
  4. package/dist/cli/llm/index.d.ts +5 -4
  5. package/dist/cli/llm/index.d.ts.map +1 -1
  6. package/dist/cli/llm/index.js +15 -3
  7. package/dist/cli/llm/index.js.map +1 -1
  8. package/dist/extensions/argument-ingestion/index.d.ts +9 -0
  9. package/dist/extensions/argument-ingestion/index.d.ts.map +1 -0
  10. package/dist/extensions/argument-ingestion/index.js +11 -0
  11. package/dist/extensions/argument-ingestion/index.js.map +1 -0
  12. package/dist/extensions/argument-ingestion/shared/basics-extension.d.ts +9 -0
  13. package/dist/extensions/argument-ingestion/shared/basics-extension.d.ts.map +1 -0
  14. package/dist/extensions/argument-ingestion/shared/basics-extension.js +25 -0
  15. package/dist/extensions/argument-ingestion/shared/basics-extension.js.map +1 -0
  16. package/dist/extensions/argument-ingestion/shared/finalize-response.d.ts +21 -0
  17. package/dist/extensions/argument-ingestion/shared/finalize-response.d.ts.map +1 -0
  18. package/dist/extensions/argument-ingestion/shared/finalize-response.js +33 -0
  19. package/dist/extensions/argument-ingestion/shared/finalize-response.js.map +1 -0
  20. package/dist/extensions/argument-ingestion/shared/role-derivation.d.ts +11 -0
  21. package/dist/extensions/argument-ingestion/shared/role-derivation.d.ts.map +1 -0
  22. package/dist/extensions/argument-ingestion/shared/role-derivation.js +26 -0
  23. package/dist/extensions/argument-ingestion/shared/role-derivation.js.map +1 -0
  24. package/dist/extensions/argument-ingestion/shared/types.d.ts +34 -0
  25. package/dist/extensions/argument-ingestion/shared/types.d.ts.map +1 -0
  26. package/dist/extensions/argument-ingestion/shared/types.js +16 -0
  27. package/dist/extensions/argument-ingestion/shared/types.js.map +1 -0
  28. package/dist/extensions/argument-ingestion/v1-single-shot.d.ts +18 -0
  29. package/dist/extensions/argument-ingestion/v1-single-shot.d.ts.map +1 -0
  30. package/dist/extensions/argument-ingestion/v1-single-shot.js +105 -0
  31. package/dist/extensions/argument-ingestion/v1-single-shot.js.map +1 -0
  32. package/dist/extensions/basics/schemata.d.ts +39 -0
  33. package/dist/extensions/basics/schemata.d.ts.map +1 -1
  34. package/dist/extensions/basics/schemata.js +21 -7
  35. package/dist/extensions/basics/schemata.js.map +1 -1
  36. package/dist/extensions/openai/errors.d.ts +49 -0
  37. package/dist/extensions/openai/errors.d.ts.map +1 -0
  38. package/dist/extensions/openai/errors.js +85 -0
  39. package/dist/extensions/openai/errors.js.map +1 -0
  40. package/dist/extensions/openai/index.d.ts +7 -0
  41. package/dist/extensions/openai/index.d.ts.map +1 -0
  42. package/dist/extensions/openai/index.js +10 -0
  43. package/dist/extensions/openai/index.js.map +1 -0
  44. package/dist/extensions/openai/provider.d.ts +22 -0
  45. package/dist/extensions/openai/provider.d.ts.map +1 -0
  46. package/dist/extensions/openai/provider.js +385 -0
  47. package/dist/extensions/openai/provider.js.map +1 -0
  48. package/dist/extensions/openai/structured-output.d.ts +18 -0
  49. package/dist/extensions/openai/structured-output.d.ts.map +1 -0
  50. package/dist/extensions/openai/structured-output.js +201 -0
  51. package/dist/extensions/openai/structured-output.js.map +1 -0
  52. package/dist/extensions/openai/types.d.ts +81 -0
  53. package/dist/extensions/openai/types.d.ts.map +1 -0
  54. package/dist/extensions/openai/types.js +21 -0
  55. package/dist/extensions/openai/types.js.map +1 -0
  56. package/dist/lib/index.d.ts +8 -0
  57. package/dist/lib/index.d.ts.map +1 -1
  58. package/dist/lib/index.js +15 -0
  59. package/dist/lib/index.js.map +1 -1
  60. package/dist/lib/llm/index.d.ts +2 -0
  61. package/dist/lib/llm/index.d.ts.map +1 -0
  62. package/dist/lib/llm/index.js +3 -0
  63. package/dist/lib/llm/index.js.map +1 -0
  64. package/dist/lib/llm/types.d.ts +49 -0
  65. package/dist/lib/llm/types.d.ts.map +1 -0
  66. package/dist/lib/llm/types.js +15 -0
  67. package/dist/lib/llm/types.js.map +1 -0
  68. package/dist/lib/pipelines/execute.d.ts +23 -0
  69. package/dist/lib/pipelines/execute.d.ts.map +1 -0
  70. package/dist/lib/pipelines/execute.js +541 -0
  71. package/dist/lib/pipelines/execute.js.map +1 -0
  72. package/dist/lib/pipelines/index.d.ts +7 -0
  73. package/dist/lib/pipelines/index.d.ts.map +1 -0
  74. package/dist/lib/pipelines/index.js +5 -0
  75. package/dist/lib/pipelines/index.js.map +1 -0
  76. package/dist/lib/pipelines/stage-helpers.d.ts +94 -0
  77. package/dist/lib/pipelines/stage-helpers.d.ts.map +1 -0
  78. package/dist/lib/pipelines/stage-helpers.js +354 -0
  79. package/dist/lib/pipelines/stage-helpers.js.map +1 -0
  80. package/dist/lib/pipelines/types.d.ts +88 -0
  81. package/dist/lib/pipelines/types.d.ts.map +1 -0
  82. package/dist/lib/pipelines/types.js +36 -0
  83. package/dist/lib/pipelines/types.js.map +1 -0
  84. package/package.json +14 -1
  85. package/dist/cli/llm/openai.d.ts +0 -4
  86. package/dist/cli/llm/openai.d.ts.map +0 -1
  87. package/dist/cli/llm/openai.js +0 -44
  88. package/dist/cli/llm/openai.js.map +0 -1
  89. package/dist/cli/llm/types.d.ts +0 -14
  90. package/dist/cli/llm/types.d.ts.map +0 -1
  91. package/dist/cli/llm/types.js +0 -2
  92. package/dist/cli/llm/types.js.map +0 -1
@@ -0,0 +1,385 @@
1
+ // Concrete `TLlmProvider` backed by the OpenAI Responses API.
2
+ //
3
+ // Slice 1B (per the agenda + spec §6) provides the V1 adapter: raw
4
+ // `fetch` to `https://api.openai.com/v1/responses` with strict-mode
5
+ // structured output via the inlined TypeBox → JSON Schema converter,
6
+ // translation of the framework's `TToolSpec` discriminated union
7
+ // into the Responses-API tool-shape, and a function-tool agent loop
8
+ // capped by `maxToolCallRounds` (default 6). Built-in tools
9
+ // (`web_search` / `file_search` / `mcp`) execute on OpenAI's
10
+ // infrastructure and don't enter the loop.
11
+ //
12
+ // The provider deliberately uses raw `fetch` rather than the
13
+ // `openai` npm SDK. `openai` is declared as an optional peer in
14
+ // `package.json` for forward-looking insurance — future slices may
15
+ // adopt it; V1 keeps the dependency surface minimal.
16
+ //
17
+ // Error classification routes HTTP-status families into framework-
18
+ // recognized error classes (see `./errors.ts`):
19
+ //
20
+ // * 5xx → `TransientLlmError`
21
+ // * 429 → `RateLimitLlmError`
22
+ // * 400, 422 → `SchemaValidationLlmError`
23
+ // * 401, 403, other 4xx → `NonRetryableLlmError`
24
+ // * loop cap exceeded → `ToolLoopExhaustedError`
25
+ //
26
+ // The framework's `llmStage` retry policy classifies via the
27
+ // `retryReason` tag on the thrown error; the class names exist for
28
+ // caller observability (`instanceof` checks) and stack-trace
29
+ // readability.
30
+ import { typeboxToOpenAiSchema } from "./structured-output.js";
31
+ import { NonRetryableLlmError, RateLimitLlmError, SchemaValidationLlmError, ToolLoopExhaustedError, TransientLlmError, } from "./errors.js";
32
+ const DEFAULT_BASE_URL = "https://api.openai.com/v1/responses";
33
+ const DEFAULT_MAX_TOOL_ROUNDS = 6;
34
+ export function createOpenAiResponsesProvider(options) {
35
+ const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
36
+ const fetchImpl = options.fetch ?? globalThis.fetch;
37
+ if (!fetchImpl) {
38
+ throw new Error("createOpenAiResponsesProvider: no fetch implementation available. Pass `fetch` explicitly or run in an environment that provides `globalThis.fetch` (Node ≥18, modern browsers, Expo).");
39
+ }
40
+ const maxToolRounds = options.maxToolCallRounds ?? DEFAULT_MAX_TOOL_ROUNDS;
41
+ const respond = async (req) => {
42
+ const schemaName = deriveSchemaName(req.outputSchema);
43
+ const convertedSchema = typeboxToOpenAiSchema(req.outputSchema);
44
+ const tools = req.tools ? translateTools(req.tools) : undefined;
45
+ // Build the running `input` array. Subsequent agent-loop
46
+ // iterations append tool-result messages to this same array.
47
+ const input = [
48
+ { role: "system", content: req.systemPrompt },
49
+ { role: "user", content: req.userMessage },
50
+ ];
51
+ let lastUsage = { input: 0, output: 0 };
52
+ let lastResponseId;
53
+ for (let round = 0; round < maxToolRounds; round += 1) {
54
+ const body = {
55
+ model: req.model,
56
+ input,
57
+ text: {
58
+ format: {
59
+ type: "json_schema",
60
+ name: schemaName,
61
+ strict: true,
62
+ schema: convertedSchema,
63
+ },
64
+ },
65
+ };
66
+ if (req.maxOutputTokens !== undefined) {
67
+ body.max_output_tokens = req.maxOutputTokens;
68
+ }
69
+ if (req.reasoningEffort) {
70
+ body.reasoning = { effort: req.reasoningEffort };
71
+ }
72
+ if (tools) {
73
+ body.tools = tools;
74
+ }
75
+ const response = await callOnce({
76
+ url: baseUrl,
77
+ apiKey: options.apiKey,
78
+ body,
79
+ fetchImpl,
80
+ signal: req.signal,
81
+ });
82
+ const envelope = await response
83
+ .json()
84
+ .then((j) => j)
85
+ .catch((err) => {
86
+ throw new TransientLlmError({
87
+ message: `OpenAI response body was not valid JSON: ${err instanceof Error ? err.message : String(err)}`,
88
+ });
89
+ });
90
+ lastResponseId = envelope.id ?? lastResponseId;
91
+ lastUsage = mergeUsage(lastUsage, extractUsage(envelope));
92
+ const functionCalls = pickFunctionCalls(envelope.output);
93
+ // Edge case — simultaneous `function_call` + final
94
+ // `message` in the same response: the Responses API
95
+ // contract says the model emits either tool calls or a
96
+ // final answer in a given turn, not both, but a
97
+ // misbehaving prompt could in principle yield both. The
98
+ // provider's policy here is conservative: if any
99
+ // `function_call` items appear, treat the round as a
100
+ // tool-call round (execute handlers, ignore the message,
101
+ // re-call). The follow-up round gets to produce the
102
+ // final answer. Callers that want the message even when
103
+ // tools fire would need a different exit condition; we
104
+ // accept this behavior as V1.
105
+ if (functionCalls.length > 0) {
106
+ // Per the Responses-API conversation-history
107
+ // contract, the next request must include each
108
+ // original `function_call` item the model emitted,
109
+ // immediately followed by its matching
110
+ // `function_call_output`. Omitting the
111
+ // `function_call` items returns a 400 with a
112
+ // conversation-state error on round 2+. Order is
113
+ // preserved across all calls in the round (slice
114
+ // 1B.1 reviewer fold P1 #1).
115
+ for (const call of functionCalls) {
116
+ const handler = findFunctionHandler(req.tools, call.name);
117
+ if (!handler) {
118
+ throw new NonRetryableLlmError({
119
+ message: `OpenAI requested unknown function tool "${call.name}".`,
120
+ });
121
+ }
122
+ const parsedArgs = safeParseJson(call.arguments);
123
+ const handlerResult = await handler.handler(parsedArgs);
124
+ // Echo the original function_call (verbatim
125
+ // wire-shape) before its matching output. The
126
+ // API enforces this pairing by `call_id`.
127
+ input.push({
128
+ type: "function_call",
129
+ call_id: call.callId,
130
+ name: call.name,
131
+ arguments: call.arguments,
132
+ });
133
+ input.push({
134
+ type: "function_call_output",
135
+ call_id: call.callId,
136
+ output: typeof handlerResult === "string"
137
+ ? handlerResult
138
+ : JSON.stringify(handlerResult),
139
+ });
140
+ }
141
+ // Loop back for the next round.
142
+ continue;
143
+ }
144
+ const text = extractAssistantText(envelope.output);
145
+ if (text === undefined) {
146
+ throw new TransientLlmError({
147
+ message: "OpenAI Responses API returned no assistant text content.",
148
+ });
149
+ }
150
+ const parsed = safeParseJson(text);
151
+ return {
152
+ output: parsed,
153
+ tokenUsage: lastUsage,
154
+ rawResponseId: lastResponseId,
155
+ };
156
+ }
157
+ throw new ToolLoopExhaustedError({
158
+ message: `Function-tool agent loop exceeded ${maxToolRounds.toString()} rounds without a final response.`,
159
+ rounds: maxToolRounds,
160
+ });
161
+ };
162
+ return { respond };
163
+ }
164
+ // -- HTTP --
165
+ async function callOnce(args) {
166
+ let response;
167
+ try {
168
+ response = await args.fetchImpl(args.url, {
169
+ method: "POST",
170
+ headers: {
171
+ "Content-Type": "application/json",
172
+ Authorization: `Bearer ${args.apiKey}`,
173
+ },
174
+ body: JSON.stringify(args.body),
175
+ signal: args.signal,
176
+ });
177
+ }
178
+ catch (err) {
179
+ // Aborts come through as a thrown error with `name === "AbortError"`
180
+ // (DOM spec). Surface as-is so `llmStage`'s mid-flight-abort
181
+ // detector turns it into `StageAbortedError`. Other low-level
182
+ // fetch failures are transient.
183
+ if (isAbortError(err)) {
184
+ throw err;
185
+ }
186
+ throw new TransientLlmError({
187
+ message: `Network error calling OpenAI: ${err instanceof Error ? err.message : String(err)}`,
188
+ });
189
+ }
190
+ if (response.ok) {
191
+ return response;
192
+ }
193
+ const errorBody = await response.text().catch(() => "");
194
+ const message = `OpenAI Responses API ${response.status.toString()}: ${errorBody || response.statusText}`;
195
+ throw classifyHttpError(response.status, message);
196
+ }
197
+ function classifyHttpError(status, message) {
198
+ if (status >= 500) {
199
+ return new TransientLlmError({ message, status });
200
+ }
201
+ if (status === 429) {
202
+ return new RateLimitLlmError({ message, status });
203
+ }
204
+ // 400 vs 422 split (slice 1B.1 reviewer fold P2 #1):
205
+ //
206
+ // OpenAI returns 400 for malformed requests — typically a
207
+ // converter bug, an unsupported parameter, or a request shape
208
+ // the API doesn't accept. Retrying a 400 just burns the second
209
+ // attempt; classify as non-retryable so the framework surfaces
210
+ // the error immediately.
211
+ //
212
+ // OpenAI returns 422 when the model's structured-output reply
213
+ // failed server-side strict-mode validation. A re-roll can
214
+ // sometimes succeed, so we route 422 through the
215
+ // schema-validation class (which carries `retryReason:
216
+ // "transient"` as the V1 retry workaround until the framework
217
+ // grows a dedicated `schema_validation` retry tag).
218
+ if (status === 400) {
219
+ return new NonRetryableLlmError({ message, status });
220
+ }
221
+ if (status === 422) {
222
+ return new SchemaValidationLlmError({ message, status });
223
+ }
224
+ return new NonRetryableLlmError({ message, status });
225
+ }
226
+ function isAbortError(err) {
227
+ return (typeof err === "object" &&
228
+ err !== null &&
229
+ err.name === "AbortError");
230
+ }
231
+ function pickFunctionCalls(output) {
232
+ if (!output)
233
+ return [];
234
+ const calls = [];
235
+ for (const item of output) {
236
+ if (item.type === "function_call") {
237
+ /* eslint-disable @typescript-eslint/naming-convention */
238
+ const fc = item;
239
+ /* eslint-enable @typescript-eslint/naming-convention */
240
+ calls.push({
241
+ callId: fc.call_id,
242
+ name: fc.name,
243
+ arguments: fc.arguments,
244
+ });
245
+ }
246
+ }
247
+ return calls;
248
+ }
249
+ function extractAssistantText(output) {
250
+ if (!output)
251
+ return undefined;
252
+ for (const item of output) {
253
+ if (item.type === "message") {
254
+ const msg = item;
255
+ const blocks = msg.content ?? [];
256
+ const textBlock = blocks.find((b) => b.type === "output_text" || b.type === "text");
257
+ if (textBlock?.text !== undefined) {
258
+ return textBlock.text;
259
+ }
260
+ }
261
+ }
262
+ return undefined;
263
+ }
264
+ function safeParseJson(raw) {
265
+ try {
266
+ return JSON.parse(raw);
267
+ }
268
+ catch (err) {
269
+ throw new SchemaValidationLlmError({
270
+ message: `OpenAI returned malformed JSON in structured-output text: ${err instanceof Error ? err.message : String(err)}`,
271
+ });
272
+ }
273
+ }
274
+ function extractUsage(envelope) {
275
+ const usage = envelope.usage;
276
+ if (!usage)
277
+ return { input: 0, output: 0 };
278
+ const result = {
279
+ input: usage.input_tokens ?? 0,
280
+ output: usage.output_tokens ?? 0,
281
+ };
282
+ const reasoning = usage.output_tokens_details?.reasoning_tokens;
283
+ if (reasoning !== undefined) {
284
+ result.reasoning = reasoning;
285
+ }
286
+ return result;
287
+ }
288
+ function mergeUsage(accumulated, next) {
289
+ const merged = {
290
+ input: accumulated.input + next.input,
291
+ output: accumulated.output + next.output,
292
+ };
293
+ if (accumulated.reasoning !== undefined || next.reasoning !== undefined) {
294
+ merged.reasoning = (accumulated.reasoning ?? 0) + (next.reasoning ?? 0);
295
+ }
296
+ return merged;
297
+ }
298
+ // -- tool translation --
299
+ function translateTools(tools) {
300
+ return tools.map((tool) => {
301
+ switch (tool.kind) {
302
+ case "web_search":
303
+ return { type: "web_search" };
304
+ case "file_search":
305
+ return {
306
+ type: "file_search",
307
+ vector_store_ids: [tool.vectorStoreId],
308
+ };
309
+ case "mcp": {
310
+ const out = {
311
+ type: "mcp",
312
+ server_url: tool.serverUrl,
313
+ };
314
+ if (tool.toolName) {
315
+ return {
316
+ ...out,
317
+ allowed_tools: [tool.toolName],
318
+ };
319
+ }
320
+ return out;
321
+ }
322
+ case "function":
323
+ return {
324
+ type: "function",
325
+ name: tool.name,
326
+ description: tool.description,
327
+ parameters: typeboxToOpenAiSchema(tool.parameters),
328
+ strict: true,
329
+ };
330
+ }
331
+ });
332
+ }
333
+ function findFunctionHandler(tools, name) {
334
+ if (!tools)
335
+ return undefined;
336
+ for (const tool of tools) {
337
+ if (tool.kind === "function" && tool.name === name) {
338
+ return tool;
339
+ }
340
+ }
341
+ return undefined;
342
+ }
343
+ // -- schema name derivation --
344
+ function deriveSchemaName(schema) {
345
+ const id = schema.$id;
346
+ if (typeof id === "string" && id.length > 0) {
347
+ return sanitizeName(id);
348
+ }
349
+ const serialized = canonicalJson(schema);
350
+ return `schema_${shortHash(serialized)}`;
351
+ }
352
+ function sanitizeName(raw) {
353
+ // OpenAI requires schema names match `^[a-zA-Z0-9_-]{1,64}$`.
354
+ const cleaned = raw.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
355
+ return cleaned.length > 0 ? cleaned : "schema";
356
+ }
357
+ function canonicalJson(value) {
358
+ return JSON.stringify(value, (_key, v) => {
359
+ if (v !== null && typeof v === "object" && !Array.isArray(v)) {
360
+ const obj = v;
361
+ const sorted = {};
362
+ for (const key of Object.keys(obj).sort()) {
363
+ sorted[key] = obj[key];
364
+ }
365
+ return sorted;
366
+ }
367
+ return v;
368
+ });
369
+ }
370
+ function shortHash(input) {
371
+ // Stable 12-hex-char hash. We avoid pulling `crypto.subtle` because
372
+ // it's async and would force `deriveSchemaName` to be async too;
373
+ // FNV-1a is sufficient for naming uniqueness within a process.
374
+ let h1 = 0xcbf29ce4;
375
+ let h2 = 0x84222325;
376
+ for (let i = 0; i < input.length; i += 1) {
377
+ const c = input.charCodeAt(i);
378
+ h1 = Math.imul(h1 ^ c, 0x01000193) >>> 0;
379
+ h2 = Math.imul(h2 ^ c, 0x01000193) >>> 0;
380
+ }
381
+ const hex1 = h1.toString(16).padStart(8, "0");
382
+ const hex2 = h2.toString(16).padStart(8, "0");
383
+ return (hex1 + hex2).slice(0, 12);
384
+ }
385
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/extensions/openai/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { TSchema } from "typebox";
2
+ /**
3
+ * The output shape is intentionally typed as a plain object literal
4
+ * (not a full JSON-Schema TS type) — the OpenAI Responses API
5
+ * accepts this shape and we round-trip it through JSON.stringify
6
+ * when building the request body. Keeping the return type loose
7
+ * avoids dragging a JSON-Schema dependency into the converter.
8
+ */
9
+ export type TOpenAiJsonSchema = Record<string, unknown>;
10
+ /**
11
+ * Convert a TypeBox schema into an OpenAI Responses-API
12
+ * strict-mode-compatible JSON Schema document.
13
+ *
14
+ * Throws `UnsupportedSchemaError` when the source schema contains a
15
+ * TypeBox primitive outside the supported subset.
16
+ */
17
+ export declare function typeboxToOpenAiSchema(schema: TSchema): TOpenAiJsonSchema;
18
+ //# sourceMappingURL=structured-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured-output.d.ts","sourceRoot":"","sources":["../../../src/extensions/openai/structured-output.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtC;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AA6BvD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,iBAAiB,CA0BxE"}
@@ -0,0 +1,201 @@
1
+ // TypeBox → OpenAI Responses-API strict-mode JSON Schema converter.
2
+ //
3
+ // Slice 1B (per the agenda + spec §14 item 2) inlines this converter
4
+ // rather than pulling in the external `typebox-to-openai` package.
5
+ // The supported subset covers the primitives actually used by the
6
+ // parsing schema today plus the primitives we expect ingestion-
7
+ // pipeline stages to need: Object, Array, String, Number, Integer,
8
+ // Boolean, Literal, Union (including Union of Literals → enum
9
+ // shorthand and Union containing Null for the Nullable pattern),
10
+ // Optional (modifier — removes a property from the strict `required`
11
+ // list while keeping it under `properties`), Record, Null.
12
+ //
13
+ // Unsupported primitives throw at conversion time with a clear
14
+ // message naming the unsupported kind — extending the converter is
15
+ // preferable to silently producing schema OpenAI will reject.
16
+ //
17
+ // Strict-mode encoding rules we apply (per OpenAI Responses-API
18
+ // structured-output docs):
19
+ //
20
+ // * Every object lists `additionalProperties: false`.
21
+ // * Every object lists `required` with **every** declared property
22
+ // name — strict mode requires every declared property be present
23
+ // in `required`; omitting a key from `required` is rejected.
24
+ // * `Type.Optional(T)` properties surface as
25
+ // `{ anyOf: [<T>, { type: "null" }] }` and remain in `required`.
26
+ // This is the strict-mode-compatible way to express "this field
27
+ // can be absent" — the model emits `null` when no value applies
28
+ // and our downstream TypeBox check tolerates the null/undefined
29
+ // equivalence for Optional members. Naively dropping Optional
30
+ // keys from `required` produces a schema OpenAI rejects with a
31
+ // 400 strict-mode error (folded from slice 1B reviewer P1 #2).
32
+ // * `Type.Union` of literals of one JSON-Schema type collapses to
33
+ // a single `enum`; general unions surface as `anyOf`.
34
+ //
35
+ // The converter ignores TypeBox `$id` / `description` / other
36
+ // metadata on inner types — only structural fields are projected.
37
+ class UnsupportedSchemaError extends Error {
38
+ constructor(kind) {
39
+ super(`TypeBox primitive "${kind}" is not supported by the OpenAI structured-output converter. ` +
40
+ `Supported subset: Object, Array, String, Number, Integer, Boolean, Literal, Union, Optional, Record, Null.`);
41
+ this.name = "UnsupportedSchemaError";
42
+ }
43
+ }
44
+ function kindOf(schema) {
45
+ return schema["~kind"];
46
+ }
47
+ function isOptional(schema) {
48
+ // eslint-disable-next-line @typescript-eslint/naming-convention
49
+ return schema["~optional"] === true;
50
+ }
51
+ /**
52
+ * Convert a TypeBox schema into an OpenAI Responses-API
53
+ * strict-mode-compatible JSON Schema document.
54
+ *
55
+ * Throws `UnsupportedSchemaError` when the source schema contains a
56
+ * TypeBox primitive outside the supported subset.
57
+ */
58
+ export function typeboxToOpenAiSchema(schema) {
59
+ const kind = kindOf(schema);
60
+ switch (kind) {
61
+ case "String":
62
+ return { type: "string" };
63
+ case "Number":
64
+ return { type: "number" };
65
+ case "Integer":
66
+ return { type: "integer" };
67
+ case "Boolean":
68
+ return { type: "boolean" };
69
+ case "Null":
70
+ return { type: "null" };
71
+ case "Literal":
72
+ return convertLiteral(schema);
73
+ case "Union":
74
+ return convertUnion(schema);
75
+ case "Array":
76
+ return convertArray(schema);
77
+ case "Object":
78
+ return convertObject(schema);
79
+ case "Record":
80
+ return convertRecord(schema);
81
+ default:
82
+ throw new UnsupportedSchemaError(kind ?? "(unknown)");
83
+ }
84
+ }
85
+ function convertLiteral(schema) {
86
+ const literal = schema;
87
+ const value = literal.const;
88
+ const jsType = literal.type ?? jsonSchemaTypeOf(value);
89
+ return { type: jsType, enum: [value] };
90
+ }
91
+ function jsonSchemaTypeOf(value) {
92
+ if (value === null)
93
+ return "null";
94
+ switch (typeof value) {
95
+ case "string":
96
+ return "string";
97
+ case "number":
98
+ return "number";
99
+ case "bigint":
100
+ return "integer";
101
+ case "boolean":
102
+ return "boolean";
103
+ default:
104
+ throw new Error(`Literal value of type "${typeof value}" cannot be converted to a JSON Schema primitive type.`);
105
+ }
106
+ }
107
+ function convertUnion(schema) {
108
+ const union = schema;
109
+ const branches = union.anyOf;
110
+ if (branches.length === 0) {
111
+ throw new Error("Cannot convert an empty Type.Union.");
112
+ }
113
+ // Shorthand: collapse a union of same-typed literals into a single
114
+ // `enum`. Mixed-type literal unions still convert correctly via
115
+ // the general anyOf branch — we only collapse when every literal
116
+ // shares the same JSON Schema type.
117
+ if (branches.every(isLiteralKind)) {
118
+ const literalTypes = new Set(branches.map((b) => b.type));
119
+ if (literalTypes.size === 1) {
120
+ const literalType = [...literalTypes][0] ?? "string";
121
+ return {
122
+ type: literalType,
123
+ enum: branches.map((b) => b.const),
124
+ };
125
+ }
126
+ }
127
+ return { anyOf: branches.map((b) => typeboxToOpenAiSchema(b)) };
128
+ }
129
+ function isLiteralKind(schema) {
130
+ return kindOf(schema) === "Literal";
131
+ }
132
+ function convertArray(schema) {
133
+ const array = schema;
134
+ return {
135
+ type: "array",
136
+ items: typeboxToOpenAiSchema(array.items),
137
+ };
138
+ }
139
+ function convertObject(schema) {
140
+ const object = schema;
141
+ const properties = {};
142
+ const required = [];
143
+ for (const [key, propSchema] of Object.entries(object.properties)) {
144
+ // OpenAI strict mode requires every declared key in `required`.
145
+ // For `Type.Optional(T)` we widen the schema to allow null and
146
+ // keep the key in `required`; this is the strict-mode-compatible
147
+ // way to express optionality (a literally omitted key is
148
+ // rejected by the API).
149
+ if (isOptional(propSchema)) {
150
+ properties[key] = nullableSchemaFor(propSchema);
151
+ }
152
+ else {
153
+ properties[key] = typeboxToOpenAiSchema(propSchema);
154
+ }
155
+ required.push(key);
156
+ }
157
+ return {
158
+ type: "object",
159
+ additionalProperties: false,
160
+ properties,
161
+ required,
162
+ };
163
+ }
164
+ function nullableSchemaFor(propSchema) {
165
+ const inner = typeboxToOpenAiSchema(propSchema);
166
+ // If the inner schema is already an anyOf (e.g. an explicit
167
+ // Union, including a Nullable that already added null), preserve
168
+ // the existing structure and just ensure a `{ type: "null" }`
169
+ // branch is present rather than wrapping in a redundant anyOf.
170
+ if (isPlainAnyOf(inner)) {
171
+ const branches = inner.anyOf;
172
+ if (branches.some(isNullBranch)) {
173
+ return inner;
174
+ }
175
+ return { anyOf: [...branches, { type: "null" }] };
176
+ }
177
+ return { anyOf: [inner, { type: "null" }] };
178
+ }
179
+ function isPlainAnyOf(schema) {
180
+ const candidate = schema;
181
+ return Array.isArray(candidate.anyOf);
182
+ }
183
+ function isNullBranch(branch) {
184
+ return branch.type === "null";
185
+ }
186
+ function convertRecord(schema) {
187
+ const record = schema;
188
+ // TypeBox encodes Record(Type.String(), V) as
189
+ // { patternProperties: { "^.*$": V } }. We collapse this to the
190
+ // canonical OpenAI shape `additionalProperties: <V>`.
191
+ const patterns = Object.values(record.patternProperties);
192
+ if (patterns.length !== 1) {
193
+ throw new Error("Type.Record with multiple pattern keys is not supported by the converter.");
194
+ }
195
+ const valueSchema = patterns[0];
196
+ return {
197
+ type: "object",
198
+ additionalProperties: typeboxToOpenAiSchema(valueSchema),
199
+ };
200
+ }
201
+ //# sourceMappingURL=structured-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured-output.js","sourceRoot":"","sources":["../../../src/extensions/openai/structured-output.ts"],"names":[],"mappings":"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"}