@sudobility/shapeshyft_engine 1.0.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.
Files changed (83) hide show
  1. package/CLAUDE.md +27 -0
  2. package/README.md +11 -0
  3. package/dist/config/providers.d.ts +111 -0
  4. package/dist/config/providers.d.ts.map +1 -0
  5. package/dist/config/providers.js +1535 -0
  6. package/dist/config/providers.js.map +1 -0
  7. package/dist/index.d.ts +27 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +27 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/lib/api-helper.d.ts +35 -0
  12. package/dist/lib/api-helper.d.ts.map +1 -0
  13. package/dist/lib/api-helper.js +123 -0
  14. package/dist/lib/api-helper.js.map +1 -0
  15. package/dist/lib/capability-validator.d.ts +36 -0
  16. package/dist/lib/capability-validator.d.ts.map +1 -0
  17. package/dist/lib/capability-validator.js +140 -0
  18. package/dist/lib/capability-validator.js.map +1 -0
  19. package/dist/lib/media-constants.d.ts +55 -0
  20. package/dist/lib/media-constants.d.ts.map +1 -0
  21. package/dist/lib/media-constants.js +166 -0
  22. package/dist/lib/media-constants.js.map +1 -0
  23. package/dist/lib/media-conversion.d.ts +36 -0
  24. package/dist/lib/media-conversion.d.ts.map +1 -0
  25. package/dist/lib/media-conversion.js +87 -0
  26. package/dist/lib/media-conversion.js.map +1 -0
  27. package/dist/lib/media-utils.d.ts +35 -0
  28. package/dist/lib/media-utils.d.ts.map +1 -0
  29. package/dist/lib/media-utils.js +173 -0
  30. package/dist/lib/media-utils.js.map +1 -0
  31. package/dist/lib/output-limit.d.ts +38 -0
  32. package/dist/lib/output-limit.d.ts.map +1 -0
  33. package/dist/lib/output-limit.js +54 -0
  34. package/dist/lib/output-limit.js.map +1 -0
  35. package/dist/lib/prompt-builder.d.ts +94 -0
  36. package/dist/lib/prompt-builder.d.ts.map +1 -0
  37. package/dist/lib/prompt-builder.js +408 -0
  38. package/dist/lib/prompt-builder.js.map +1 -0
  39. package/dist/lib/reserved-fields.d.ts +41 -0
  40. package/dist/lib/reserved-fields.d.ts.map +1 -0
  41. package/dist/lib/reserved-fields.js +47 -0
  42. package/dist/lib/reserved-fields.js.map +1 -0
  43. package/dist/services/llm/anthropic.d.ts +16 -0
  44. package/dist/services/llm/anthropic.d.ts.map +1 -0
  45. package/dist/services/llm/anthropic.js +154 -0
  46. package/dist/services/llm/anthropic.js.map +1 -0
  47. package/dist/services/llm/custom.d.ts +51 -0
  48. package/dist/services/llm/custom.d.ts.map +1 -0
  49. package/dist/services/llm/custom.js +419 -0
  50. package/dist/services/llm/custom.js.map +1 -0
  51. package/dist/services/llm/extract-json.d.ts +17 -0
  52. package/dist/services/llm/extract-json.d.ts.map +1 -0
  53. package/dist/services/llm/extract-json.js +60 -0
  54. package/dist/services/llm/extract-json.js.map +1 -0
  55. package/dist/services/llm/finish-reason.d.ts +21 -0
  56. package/dist/services/llm/finish-reason.d.ts.map +1 -0
  57. package/dist/services/llm/finish-reason.js +55 -0
  58. package/dist/services/llm/finish-reason.js.map +1 -0
  59. package/dist/services/llm/gemini.d.ts +26 -0
  60. package/dist/services/llm/gemini.d.ts.map +1 -0
  61. package/dist/services/llm/gemini.js +178 -0
  62. package/dist/services/llm/gemini.js.map +1 -0
  63. package/dist/services/llm/groq.d.ts +28 -0
  64. package/dist/services/llm/groq.d.ts.map +1 -0
  65. package/dist/services/llm/groq.js +237 -0
  66. package/dist/services/llm/groq.js.map +1 -0
  67. package/dist/services/llm/index.d.ts +19 -0
  68. package/dist/services/llm/index.d.ts.map +1 -0
  69. package/dist/services/llm/index.js +88 -0
  70. package/dist/services/llm/index.js.map +1 -0
  71. package/dist/services/llm/openai.d.ts +101 -0
  72. package/dist/services/llm/openai.d.ts.map +1 -0
  73. package/dist/services/llm/openai.js +561 -0
  74. package/dist/services/llm/openai.js.map +1 -0
  75. package/dist/services/llm/types.d.ts +110 -0
  76. package/dist/services/llm/types.d.ts.map +1 -0
  77. package/dist/services/llm/types.js +16 -0
  78. package/dist/services/llm/types.js.map +1 -0
  79. package/dist/types/index.d.ts +812 -0
  80. package/dist/types/index.d.ts.map +1 -0
  81. package/dist/types/index.js +366 -0
  82. package/dist/types/index.js.map +1 -0
  83. package/package.json +93 -0
@@ -0,0 +1,561 @@
1
+ /**
2
+ * @fileoverview OpenAI LLM provider
3
+ * @description Implements the ILLMProvider interface for OpenAI models.
4
+ * Also used by Mistral, xAI, DeepSeek, Perplexity, and Cohere
5
+ * (OpenAI-compatible APIs). Supports function calling for structured output,
6
+ * multimodal input (images, audio), and audio output generation.
7
+ */
8
+ import OpenAI from "openai";
9
+ import { requiresEntityId, } from "./types.js";
10
+ import { getOpenAIAudioFormat } from "../../lib/media-constants.js";
11
+ import { getModelCapabilities } from "../../config/providers.js";
12
+ import { buildOutputStructureSection, buildResponseFormatSection, buildWebSearchRoutingSection, } from "../../lib/prompt-builder.js";
13
+ import { normalizeFinishReason } from "./finish-reason.js";
14
+ const DEFAULT_MODEL = "gpt-4o-mini";
15
+ class OpenAIProviderError extends Error {
16
+ details;
17
+ constructor(message, details) {
18
+ super(message);
19
+ this.name = "OpenAIProviderError";
20
+ this.details = details;
21
+ }
22
+ }
23
+ /**
24
+ * OpenAI models that reject `max_tokens`.
25
+ *
26
+ * The reasoning-era families — GPT-5 and the o-series. Everything before them
27
+ * (GPT-4o, GPT-4.1) still takes `max_tokens`, and every OpenAI-compatible third
28
+ * party knows only that, so the rule is deliberately narrow rather than
29
+ * "OpenAI always uses the new name".
30
+ *
31
+ * Matched on the family prefix, not an exhaustive list: the point of a family
32
+ * is that its next member behaves like the last, and a list of exact ids would
33
+ * be wrong the day one ships.
34
+ */
35
+ const REQUIRES_MAX_COMPLETION_TOKENS = /^(gpt-5|o[1-9])/i;
36
+ /**
37
+ * What to call the output cap for this provider and model.
38
+ *
39
+ * Both halves matter. The provider decides the vocabulary available; the model
40
+ * decides which of it applies, and the model is chosen per endpoint rather than
41
+ * per provider — so this cannot be settled when the client is constructed.
42
+ */
43
+ export function tokenLimitParamFor(isOpenAi, model) {
44
+ return isOpenAi && REQUIRES_MAX_COMPLETION_TOKENS.test(model)
45
+ ? "max_completion_tokens"
46
+ : "max_tokens";
47
+ }
48
+ export class OpenAIProvider {
49
+ providerName = "openai";
50
+ client;
51
+ defaultModel;
52
+ disableThinking;
53
+ /** Whether this client talks to OpenAI itself, or an OpenAI-compatible third party. */
54
+ isOpenAi;
55
+ constructor(config,
56
+ /**
57
+ * Per-provider quirks. Defaults keep every provider that works today
58
+ * working; only one known to need otherwise opts out.
59
+ */
60
+ options = {}) {
61
+ this.disableThinking = options.disableThinking ?? false;
62
+ this.isOpenAi = options.isOpenAi ?? false;
63
+ if (!config.apiKey) {
64
+ throw new Error("OpenAI API key is required");
65
+ }
66
+ // Honor a custom base URL so OpenAI-compatible providers (Mistral, xAI,
67
+ // DeepSeek, Perplexity) reach their own API instead of api.openai.com.
68
+ this.client = new OpenAI({
69
+ apiKey: config.apiKey,
70
+ ...(config.endpointUrl ? { baseURL: config.endpointUrl } : {}),
71
+ });
72
+ this.defaultModel = config.model ?? DEFAULT_MODEL;
73
+ }
74
+ async generate(request) {
75
+ console.log(`[llm] generate() called, webSearch=${request.webSearch}, model=${request.model}`);
76
+ // Use Responses API when web search is enabled
77
+ if (request.webSearch) {
78
+ return this.generateWithSearch(request);
79
+ }
80
+ const model = request.model ?? this.defaultModel;
81
+ const startTime = Date.now();
82
+ const caps = getModelCapabilities(model);
83
+ const generatedMedia = [];
84
+ // Build user message content (multimodal)
85
+ const userContent = [];
86
+ if (request.media?.length) {
87
+ for (const m of request.media) {
88
+ if (m.type === "image") {
89
+ userContent.push({
90
+ type: "image_url",
91
+ image_url: {
92
+ url: m.format === "base64"
93
+ ? `data:${m.mimeType};base64,${m.data}`
94
+ : m.data,
95
+ },
96
+ });
97
+ }
98
+ if (m.type === "audio") {
99
+ // Format already validated at capability validation layer
100
+ const format = getOpenAIAudioFormat(m.mimeType);
101
+ userContent.push({
102
+ type: "input_audio",
103
+ input_audio: {
104
+ data: m.data,
105
+ format,
106
+ },
107
+ });
108
+ }
109
+ }
110
+ }
111
+ userContent.push({ type: "text", text: request.prompt });
112
+ // Build messages array
113
+ const messages = [];
114
+ if (request.systemPrompt) {
115
+ messages.push({ role: "system", content: request.systemPrompt });
116
+ }
117
+ messages.push({ role: "user", content: userContent });
118
+ // Use function calling for structured output
119
+ const tools = [
120
+ {
121
+ type: "function",
122
+ function: {
123
+ name: "structured_response",
124
+ description: "Generate structured response matching the schema",
125
+ parameters: request.outputSchema,
126
+ },
127
+ },
128
+ ];
129
+ // Audio output configuration - ONLY enable when endpoint expects audio output
130
+ const modalities = ["text"];
131
+ let audioConfig;
132
+ if (request.expectsMediaOutput?.audio && caps.audioOutput) {
133
+ modalities.push("audio");
134
+ // V1: Output audio format is fixed to mp3
135
+ audioConfig = {
136
+ voice: "alloy", // V1: Fixed to "alloy"
137
+ format: "mp3", // V1: Fixed to "mp3"
138
+ };
139
+ }
140
+ const response = (await this.client.chat.completions.create({
141
+ model,
142
+ messages,
143
+ ...(audioConfig ? { modalities, audio: audioConfig } : {}),
144
+ tools,
145
+ tool_choice: {
146
+ type: "function",
147
+ function: { name: "structured_response" },
148
+ },
149
+ // Off where the model reasons by default: thinking mode rejects
150
+ // `tool_choice` outright, so this is what keeps the line above legal.
151
+ ...(this.disableThinking ? { thinking: { type: "disabled" } } : {}),
152
+ temperature: request.temperature ?? 0,
153
+ [tokenLimitParamFor(this.isOpenAi, model)]: request.maxTokens,
154
+ stream: false,
155
+ }));
156
+ const latencyMs = Date.now() - startTime;
157
+ // Extract audio from response if present
158
+ const message = response.choices[0]
159
+ ?.message;
160
+ const audioData = message?.audio;
161
+ if (audioData) {
162
+ const audioMimeType = `audio/${audioData.format}`;
163
+ if (requiresEntityId(request)) {
164
+ // URL output requested but storage upload not implemented in v1
165
+ // For now, return base64 with a warning in the logs
166
+ console.warn("URL output requested but storage upload not implemented. Returning base64.");
167
+ generatedMedia.push({
168
+ type: "audio",
169
+ mimeType: audioMimeType,
170
+ data: audioData.data,
171
+ });
172
+ }
173
+ else {
174
+ // Return base64
175
+ generatedMedia.push({
176
+ type: "audio",
177
+ mimeType: audioMimeType,
178
+ data: audioData.data,
179
+ });
180
+ }
181
+ }
182
+ // Extract structured response from function call
183
+ const toolCall = response.choices[0]?.message.tool_calls?.[0];
184
+ if (!toolCall || toolCall.function.name !== "structured_response") {
185
+ throw new Error("Expected function call response from OpenAI");
186
+ }
187
+ const rawResponse = toolCall.function.arguments;
188
+ const finishReason = normalizeFinishReason(response.choices[0]?.finish_reason);
189
+ const usage = {
190
+ promptTokens: response.usage?.prompt_tokens ?? 0,
191
+ completionTokens: response.usage?.completion_tokens ?? 0,
192
+ totalTokens: response.usage?.total_tokens ?? 0,
193
+ };
194
+ /*
195
+ Why the stop reason is read BEFORE parsing.
196
+
197
+ A model that hits the output ceiling returns arguments cut off mid-value,
198
+ and `JSON.parse` then fails with something like "Expected ']'". Return the
199
+ raw truncated arguments with finishReason instead, so the route can mark
200
+ the response as truncated and preserve usage for the caller.
201
+ */
202
+ if (finishReason === "length") {
203
+ return {
204
+ content: rawResponse,
205
+ rawResponse,
206
+ usage,
207
+ model: response.model,
208
+ provider: this.providerName,
209
+ latencyMs,
210
+ finishReason,
211
+ generatedMedia: generatedMedia.length > 0 ? generatedMedia : undefined,
212
+ };
213
+ }
214
+ let content;
215
+ try {
216
+ content = JSON.parse(rawResponse);
217
+ }
218
+ catch (error) {
219
+ // Not truncated, so genuinely malformed. Carry a head of the payload:
220
+ // "Unable to parse JSON string" alone leaves nothing to diagnose from.
221
+ throw new Error(`Model returned unparseable JSON (${error instanceof Error ? error.message : String(error)}). First 300 chars: ${rawResponse.slice(0, 300)}`);
222
+ }
223
+ return {
224
+ content,
225
+ rawResponse,
226
+ usage,
227
+ model: response.model,
228
+ provider: this.providerName,
229
+ latencyMs,
230
+ finishReason,
231
+ generatedMedia: generatedMedia.length > 0 ? generatedMedia : undefined,
232
+ };
233
+ }
234
+ /**
235
+ * Generate using the OpenAI Responses API with web search enabled.
236
+ * The model can search the web and then call the structured_response function.
237
+ */
238
+ // ---------------------------------------------------------------------------
239
+ // Web-search-aware generation (3-step)
240
+ // ---------------------------------------------------------------------------
241
+ static INPUT_LAYOUTS = new Set([
242
+ "input_text",
243
+ "input_numeric",
244
+ "input_date",
245
+ "input_email",
246
+ "input_phone",
247
+ "search",
248
+ "line_select",
249
+ "line_toggle",
250
+ "line_slider",
251
+ ]);
252
+ /** Check if a renderable tree contains input controls (clarification). */
253
+ containsInputControls(data) {
254
+ if (typeof data !== "object" || data === null)
255
+ return false;
256
+ const obj = data;
257
+ const view = obj.view;
258
+ if (view?.layout && OpenAIProvider.INPUT_LAYOUTS.has(view.layout))
259
+ return true;
260
+ const children = (view?.children ?? obj.children);
261
+ if (Array.isArray(children)) {
262
+ return children.some(child => this.containsInputControls(child));
263
+ }
264
+ return false;
265
+ }
266
+ /**
267
+ * Wrap the user's output schema in a container that lets the AI signal
268
+ * whether it needs a web search before it can answer.
269
+ */
270
+ buildTriageSchema(userSchema) {
271
+ return {
272
+ type: "object",
273
+ required: ["user_data"],
274
+ properties: {
275
+ user_data: userSchema,
276
+ web_search_needed: {
277
+ type: "boolean",
278
+ default: false,
279
+ description: "Set to true when you would say 'I don't have real-time data' or " +
280
+ "'I cannot access current listings'. The system WILL perform a web search " +
281
+ "and provide you the results. Set to false when asking for clarification " +
282
+ "or when you can answer from training data.",
283
+ },
284
+ },
285
+ additionalProperties: false,
286
+ };
287
+ }
288
+ /**
289
+ * Build the system prompt for step 1: try to answer fully, signal
290
+ * web_search_needed only if real-time data is genuinely required.
291
+ */
292
+ /**
293
+ * Call the Responses API with a forced function call.
294
+ * Used for both the triage step and the structuring step.
295
+ */
296
+ async callResponsesStructured(model, input, schema, temperature, maxTokens) {
297
+ console.log(`[web-search] callResponsesStructured() calling Responses API, model=${model}`);
298
+ const response = await this.client.responses.create({
299
+ model,
300
+ input,
301
+ tools: [
302
+ {
303
+ type: "function",
304
+ name: "structured_response",
305
+ description: "Generate structured response matching the schema",
306
+ parameters: schema,
307
+ strict: false,
308
+ },
309
+ ],
310
+ tool_choice: {
311
+ type: "function",
312
+ name: "structured_response",
313
+ },
314
+ temperature,
315
+ max_output_tokens: maxTokens,
316
+ });
317
+ const functionCall = response.output.find((item) => item.type === "function_call" && item.name === "structured_response");
318
+ if (!functionCall) {
319
+ throw new OpenAIProviderError("Expected structured_response function call from Responses API", {
320
+ model,
321
+ responseId: response.id,
322
+ outputItems: response.output.map(item => ({
323
+ type: item.type,
324
+ ...("name" in item ? { name: item.name } : {}),
325
+ })),
326
+ });
327
+ }
328
+ return {
329
+ content: JSON.parse(functionCall.arguments),
330
+ rawResponse: functionCall.arguments,
331
+ usage: {
332
+ inputTokens: response.usage?.input_tokens ?? 0,
333
+ outputTokens: response.usage?.output_tokens ?? 0,
334
+ },
335
+ model: response.model,
336
+ // The Responses API reports truncation as an incomplete status with a
337
+ // reason, rather than a finish_reason on the choice.
338
+ finishReason: response.status === "incomplete"
339
+ ? normalizeFinishReason(response.incomplete_details?.reason)
340
+ : "stop",
341
+ };
342
+ }
343
+ /**
344
+ * Search the web via the Responses API and return a text summary.
345
+ */
346
+ async searchWeb(model, query, temperature) {
347
+ console.log(`[web-search] searchWeb() calling Responses API for query: "${query.substring(0, 100)}..."`);
348
+ const response = await this.client.responses.create({
349
+ model,
350
+ input: [
351
+ {
352
+ role: "developer",
353
+ content: "Search the web for the requested information. " +
354
+ "Return a thorough summary of the results with specific details, " +
355
+ "names, addresses, dates, and URLs when available.",
356
+ },
357
+ { role: "user", content: query },
358
+ ],
359
+ tools: [{ type: "web_search_preview" }],
360
+ temperature,
361
+ });
362
+ return {
363
+ summary: response.output_text ?? "",
364
+ usage: {
365
+ inputTokens: response.usage?.input_tokens ?? 0,
366
+ outputTokens: response.usage?.output_tokens ?? 0,
367
+ },
368
+ };
369
+ }
370
+ /** Build Responses API input from an LLM request. */
371
+ buildResponsesInput(systemPrompt, userPrompt, media) {
372
+ const input = [];
373
+ if (systemPrompt) {
374
+ input.push({ role: "developer", content: systemPrompt });
375
+ }
376
+ const userContent = [];
377
+ if (media?.length) {
378
+ for (const m of media) {
379
+ if (m.type === "image") {
380
+ userContent.push({
381
+ type: "input_image",
382
+ image_url: m.format === "base64"
383
+ ? `data:${m.mimeType};base64,${m.data}`
384
+ : m.data,
385
+ detail: "auto",
386
+ });
387
+ }
388
+ }
389
+ }
390
+ userContent.push({ type: "input_text", text: userPrompt });
391
+ input.push({ role: "user", content: userContent });
392
+ return input;
393
+ }
394
+ /**
395
+ * Main entry point when web search is enabled on the endpoint.
396
+ *
397
+ * 1. Try to answer via Responses API with triage wrapper schema.
398
+ * AI provides full answer OR signals web_search_needed.
399
+ * 2. If no search needed → return user_data directly.
400
+ * 3. If search needed → web search → structure results.
401
+ */
402
+ async generateWithSearch(request) {
403
+ console.log(`[web-search] generateWithSearch() entered`);
404
+ const model = request.model ?? this.defaultModel;
405
+ const startTime = Date.now();
406
+ const userSchema = request.outputSchema;
407
+ const temperature = request.temperature ?? 0;
408
+ let totalInputTokens = 0;
409
+ let totalOutputTokens = 0;
410
+ // --- Step 1: Try to answer (Responses API, forced function call) ------
411
+ console.log(`[web-search] Step 1: Triage via Responses API, model=${model}`);
412
+ const triageSchema = this.buildTriageSchema(userSchema);
413
+ // Replace the output structure / example / response format sections
414
+ // with ones generated from the triage wrapper schema.
415
+ // Keep everything before "## Output Structure" (base + task description + rules).
416
+ const systemPrompt = request.systemPrompt ?? "";
417
+ const outputStructureIdx = systemPrompt.indexOf("\n## Output Structure");
418
+ const basePart = outputStructureIdx >= 0
419
+ ? systemPrompt.substring(0, outputStructureIdx)
420
+ : systemPrompt;
421
+ const triageSystemPrompt = basePart +
422
+ buildWebSearchRoutingSection() +
423
+ buildOutputStructureSection(triageSchema) +
424
+ buildResponseFormatSection();
425
+ console.log(`[web-search] System prompt:\n${triageSystemPrompt}`);
426
+ const triageInput = this.buildResponsesInput(triageSystemPrompt, request.prompt, request.media);
427
+ const triageResult = await this.callResponsesStructured(model, triageInput, triageSchema, temperature, request.maxTokens);
428
+ totalInputTokens += triageResult.usage.inputTokens;
429
+ totalOutputTokens += triageResult.usage.outputTokens;
430
+ const triageData = triageResult.content;
431
+ console.log(`[web-search] Triage result: web_search_needed=${triageData.web_search_needed}`);
432
+ // --- If no search needed, or user_data is a clarification form, return directly
433
+ const isClarification = this.containsInputControls(triageData.user_data);
434
+ const shouldSearch = triageData.web_search_needed === true && !isClarification;
435
+ if (!shouldSearch) {
436
+ if (isClarification && triageData.web_search_needed) {
437
+ console.log(`[web-search] AI set web_search_needed=true but response contains input controls — returning clarification`);
438
+ }
439
+ else {
440
+ console.log(`[web-search] No search needed (web_search_needed=${triageData.web_search_needed}), returning user_data`);
441
+ }
442
+ const rawResponse = JSON.stringify(triageData.user_data);
443
+ return {
444
+ content: triageData.user_data,
445
+ rawResponse,
446
+ usage: {
447
+ promptTokens: totalInputTokens,
448
+ completionTokens: totalOutputTokens,
449
+ totalTokens: totalInputTokens + totalOutputTokens,
450
+ },
451
+ model: triageResult.model,
452
+ provider: this.providerName,
453
+ latencyMs: Date.now() - startTime,
454
+ finishReason: triageResult.finishReason,
455
+ };
456
+ }
457
+ // --- Step 2: Web search -----------------------------------------------
458
+ console.log(`[web-search] Step 2: Searching the web`);
459
+ const searchResult = await this.searchWeb(model, request.prompt, temperature);
460
+ totalInputTokens += searchResult.usage.inputTokens;
461
+ totalOutputTokens += searchResult.usage.outputTokens;
462
+ console.log(`[web-search] Step 2 done: ${searchResult.summary.length} chars`);
463
+ // --- Step 3: Structure search results (Responses API) -----------------
464
+ console.log(`[web-search] Step 3: Structuring search results`);
465
+ const structureSystemPrompt = (request.systemPrompt ?? "") +
466
+ "\n\n## Important\n" +
467
+ "You are being given web search results. Use ONLY the facts from " +
468
+ "these results to build your response. Do not fabricate any names, " +
469
+ "addresses, or data not found in the search results.";
470
+ const structureInput = this.buildResponsesInput(structureSystemPrompt, `Original request: ${request.prompt}\n\n` +
471
+ `Web search results:\n\n${searchResult.summary}\n\n` +
472
+ "Using ONLY the information from the web search results above, " +
473
+ "generate the structured response.");
474
+ const structureResult = await this.callResponsesStructured(model, structureInput, userSchema, temperature, request.maxTokens);
475
+ totalInputTokens += structureResult.usage.inputTokens;
476
+ totalOutputTokens += structureResult.usage.outputTokens;
477
+ console.log(`[web-search] Step 3 done, total time: ${Date.now() - startTime}ms`);
478
+ return {
479
+ content: structureResult.content,
480
+ rawResponse: structureResult.rawResponse,
481
+ usage: {
482
+ promptTokens: totalInputTokens,
483
+ completionTokens: totalOutputTokens,
484
+ totalTokens: totalInputTokens + totalOutputTokens,
485
+ },
486
+ model: structureResult.model,
487
+ provider: this.providerName,
488
+ latencyMs: Date.now() - startTime,
489
+ finishReason: structureResult.finishReason,
490
+ };
491
+ }
492
+ buildApiPayload(request) {
493
+ const model = request.model ?? this.defaultModel;
494
+ const caps = getModelCapabilities(model);
495
+ // Build user message content (multimodal)
496
+ const userContent = [];
497
+ if (request.media?.length) {
498
+ for (const m of request.media) {
499
+ if (m.type === "image") {
500
+ userContent.push({
501
+ type: "image_url",
502
+ image_url: {
503
+ url: m.format === "base64"
504
+ ? `data:${m.mimeType};base64,${m.data}`
505
+ : m.data,
506
+ },
507
+ });
508
+ }
509
+ if (m.type === "audio") {
510
+ const format = getOpenAIAudioFormat(m.mimeType);
511
+ userContent.push({
512
+ type: "input_audio",
513
+ input_audio: {
514
+ data: m.data,
515
+ format,
516
+ },
517
+ });
518
+ }
519
+ }
520
+ }
521
+ userContent.push({ type: "text", text: request.prompt });
522
+ // Build messages array
523
+ const messages = [];
524
+ if (request.systemPrompt) {
525
+ messages.push({ role: "system", content: request.systemPrompt });
526
+ }
527
+ messages.push({ role: "user", content: userContent });
528
+ // Audio output configuration
529
+ const modalities = ["text"];
530
+ let audioConfig;
531
+ if (request.expectsMediaOutput?.audio && caps.audioOutput) {
532
+ modalities.push("audio");
533
+ audioConfig = {
534
+ voice: "alloy",
535
+ format: "mp3",
536
+ };
537
+ }
538
+ return {
539
+ model,
540
+ messages,
541
+ ...(audioConfig ? { modalities, audio: audioConfig } : {}),
542
+ tools: [
543
+ {
544
+ type: "function",
545
+ function: {
546
+ name: "structured_response",
547
+ description: "Generate structured response matching the schema",
548
+ parameters: request.outputSchema,
549
+ },
550
+ },
551
+ ],
552
+ tool_choice: {
553
+ type: "function",
554
+ function: { name: "structured_response" },
555
+ },
556
+ temperature: request.temperature ?? 0,
557
+ [tokenLimitParamFor(this.isOpenAi, model)]: request.maxTokens,
558
+ };
559
+ }
560
+ }
561
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/services/llm/openai.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAM5B,OAAO,EACL,gBAAgB,GAKjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,aAAa,GAAG,aAAa,CAAC;AAEpC,MAAM,mBAAoB,SAAQ,KAAK;IACrC,OAAO,CAA2B;IAElC,YAAY,OAAe,EAAE,OAAiC;QAC5D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAaD;;;;;;;;;;;GAWG;AACH,MAAM,8BAA8B,GAAG,kBAAkB,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAiB,EACjB,KAAa;IAEb,OAAO,QAAQ,IAAI,8BAA8B,CAAC,IAAI,CAAC,KAAK,CAAC;QAC3D,CAAC,CAAC,uBAAuB;QACzB,CAAC,CAAC,YAAY,CAAC;AACnB,CAAC;AAED,MAAM,OAAO,cAAc;IAChB,YAAY,GAAG,QAAiB,CAAC;IAClC,MAAM,CAAS;IACf,YAAY,CAAS;IAErB,eAAe,CAAU;IAEjC,uFAAuF;IAC/E,QAAQ,CAAU;IAE1B,YACE,MAAsB;IACtB;;;OAGG;IACH,UAsBI,EAAE;QAEN,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,KAAK,CAAC;QACxD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QACD,wEAAwE;QACxE,uEAAuE;QACvE,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC/D,CAAC,CAAC;QACH,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,IAAI,aAAa,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAmB;QAChC,OAAO,CAAC,GAAG,CACT,sCAAsC,OAAO,CAAC,SAAS,WAAW,OAAO,CAAC,KAAK,EAAE,CAClF,CAAC;QACF,+CAA+C;QAC/C,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC1C,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,YAAY,CAAC;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,cAAc,GAAqB,EAAE,CAAC;QAE5C,0CAA0C;QAC1C,MAAM,WAAW,GAA4C,EAAE,CAAC;QAEhE,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;YAC1B,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC9B,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBACvB,WAAW,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,WAAW;wBACjB,SAAS,EAAE;4BACT,GAAG,EACD,CAAC,CAAC,MAAM,KAAK,QAAQ;gCACnB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,WAAW,CAAC,CAAC,IAAI,EAAE;gCACvC,CAAC,CAAC,CAAC,CAAC,IAAI;yBACb;qBACF,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBACvB,0DAA0D;oBAC1D,MAAM,MAAM,GAAG,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;oBAChD,WAAW,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,aAAa;wBACnB,WAAW,EAAE;4BACX,IAAI,EAAE,CAAC,CAAC,IAAI;4BACZ,MAAM;yBACP;qBACuC,CAAC,CAAC;gBAC9C,CAAC;YACH,CAAC;QACH,CAAC;QAED,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAEzD,uBAAuB;QACvB,MAAM,QAAQ,GAA6C,EAAE,CAAC;QAC9D,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;QAEtD,6CAA6C;QAC7C,MAAM,KAAK,GAAqC;YAC9C;gBACE,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE;oBACR,IAAI,EAAE,qBAAqB;oBAC3B,WAAW,EAAE,kDAAkD;oBAC/D,UAAU,EAAE,OAAO,CAAC,YAAuC;iBAC5D;aACF;SACF,CAAC;QAEF,8EAA8E;QAC9E,MAAM,UAAU,GAAyB,CAAC,MAAM,CAAC,CAAC;QAClD,IAAI,WAA0D,CAAC;QAE/D,IAAI,OAAO,CAAC,kBAAkB,EAAE,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1D,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,0CAA0C;YAC1C,WAAW,GAAG;gBACZ,KAAK,EAAE,OAAO,EAAE,uBAAuB;gBACvC,MAAM,EAAE,KAAK,EAAE,qBAAqB;aACrC,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;YAC1D,KAAK;YACL,QAAQ;YACR,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,KAAK;YACL,WAAW,EAAE;gBACX,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE;aAC1C;YACD,gEAAgE;YAChE,sEAAsE;YACtE,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC;YACrC,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS;YAC7D,MAAM,EAAE,KAAK;SAC4B,CAAC,CAA+B,CAAC;QAE5E,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAEzC,yCAAyC;QACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YACjC,EAAE,OAEH,CAAC;QACF,MAAM,SAAS,GAAG,OAAO,EAAE,KAAK,CAAC;QACjC,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,aAAa,GAAG,SAAS,SAAS,CAAC,MAAM,EAAE,CAAC;YAElD,IAAI,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9B,gEAAgE;gBAChE,oDAAoD;gBACpD,OAAO,CAAC,IAAI,CACV,4EAA4E,CAC7E,CAAC;gBACF,cAAc,CAAC,IAAI,CAAC;oBAClB,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE,aAAa;oBACvB,IAAI,EAAE,SAAS,CAAC,IAAI;iBACrB,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,gBAAgB;gBAChB,cAAc,CAAC,IAAI,CAAC;oBAClB,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE,aAAa;oBACvB,IAAI,EAAE,SAAS,CAAC,IAAI;iBACrB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,iDAAiD;QACjD,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;YAClE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAEhD,MAAM,YAAY,GAAG,qBAAqB,CACxC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,aAAa,CACnC,CAAC;QACF,MAAM,KAAK,GAAG;YACZ,YAAY,EAAE,QAAQ,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC;YAChD,gBAAgB,EAAE,QAAQ,CAAC,KAAK,EAAE,iBAAiB,IAAI,CAAC;YACxD,WAAW,EAAE,QAAQ,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC;SAC/C,CAAC;QAEF;;;;;;;UAOE;QACF,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO;gBACL,OAAO,EAAE,WAAW;gBACpB,WAAW;gBACX,KAAK;gBACL,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,QAAQ,EAAE,IAAI,CAAC,YAAY;gBAC3B,SAAS;gBACT,YAAY;gBACZ,cAAc,EAAE,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS;aACvE,CAAC;QACJ,CAAC;QAED,IAAI,OAAgB,CAAC;QACrB,IAAI,CAAC;YACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,sEAAsE;YACtE,uEAAuE;YACvE,MAAM,IAAI,KAAK,CACb,oCAAoC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAC7I,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO;YACP,WAAW;YACX,KAAK;YACL,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,QAAQ,EAAE,IAAI,CAAC,YAAY;YAC3B,SAAS;YACT,YAAY;YACZ,cAAc,EAAE,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS;SACvE,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,8EAA8E;IAC9E,uCAAuC;IACvC,8EAA8E;IAEtE,MAAM,CAAC,aAAa,GAAG,IAAI,GAAG,CAAC;QACrC,YAAY;QACZ,eAAe;QACf,YAAY;QACZ,aAAa;QACb,aAAa;QACb,QAAQ;QACR,aAAa;QACb,aAAa;QACb,aAAa;KACd,CAAC,CAAC;IAEH,0EAA0E;IAClE,qBAAqB,CAAC,IAAa;QACzC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAC5D,MAAM,GAAG,GAAG,IAA+B,CAAC;QAC5C,MAAM,IAAI,GAAG,GAAG,CAAC,IAA2C,CAAC;QAC7D,IAAI,IAAI,EAAE,MAAM,IAAI,cAAc,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,MAAgB,CAAC;YACzE,OAAO,IAAI,CAAC;QACd,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAA0B,CAAC;QAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACK,iBAAiB,CACvB,UAAmC;QAEnC,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,WAAW,CAAC;YACvB,UAAU,EAAE;gBACV,SAAS,EAAE,UAAU;gBACrB,iBAAiB,EAAE;oBACjB,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE,KAAK;oBACd,WAAW,EACT,kEAAkE;wBAClE,2EAA2E;wBAC3E,0EAA0E;wBAC1E,4CAA4C;iBAC/C;aACF;YACD,oBAAoB,EAAE,KAAK;SAC5B,CAAC;IACJ,CAAC;IAED;;;OAGG;IAEH;;;OAGG;IACK,KAAK,CAAC,uBAAuB,CACnC,KAAa,EACb,KAA2C,EAC3C,MAA+B,EAC/B,WAAmB,EACnB,SAAkB;QAQlB,OAAO,CAAC,GAAG,CACT,uEAAuE,KAAK,EAAE,CAC/E,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;YAClD,KAAK;YACL,KAAK;YACL,KAAK,EAAE;gBACL;oBACE,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,qBAAqB;oBAC3B,WAAW,EAAE,kDAAkD;oBAC/D,UAAU,EAAE,MAAM;oBAClB,MAAM,EAAE,KAAK;iBACd;aACF;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,qBAAqB;aAC5B;YACD,WAAW;YACX,iBAAiB,EAAE,SAAS;SAC7B,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CACvC,CAAC,IAAI,EAAqD,EAAE,CAC1D,IAAI,CAAC,IAAI,KAAK,eAAe,IAAI,IAAI,CAAC,IAAI,KAAK,qBAAqB,CACvE,CAAC;QAEF,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,mBAAmB,CAC3B,+DAA+D,EAC/D;gBACE,KAAK;gBACL,UAAU,EAAE,QAAQ,CAAC,EAAE;gBACvB,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACxC,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC/C,CAAC,CAAC;aACJ,CACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC;YAC3C,WAAW,EAAE,YAAY,CAAC,SAAS;YACnC,KAAK,EAAE;gBACL,WAAW,EAAE,QAAQ,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC;gBAC9C,YAAY,EAAE,QAAQ,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC;aACjD;YACD,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,sEAAsE;YACtE,qDAAqD;YACrD,YAAY,EACV,QAAQ,CAAC,MAAM,KAAK,YAAY;gBAC9B,CAAC,CAAC,qBAAqB,CAAC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;gBAC5D,CAAC,CAAC,MAAM;SACb,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS,CACrB,KAAa,EACb,KAAa,EACb,WAAmB;QAKnB,OAAO,CAAC,GAAG,CACT,8DAA8D,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAC5F,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;YAClD,KAAK;YACL,KAAK,EAAE;gBACL;oBACE,IAAI,EAAE,WAAoB;oBAC1B,OAAO,EACL,gDAAgD;wBAChD,kEAAkE;wBAClE,mDAAmD;iBACtD;gBACD,EAAE,IAAI,EAAE,MAAe,EAAE,OAAO,EAAE,KAAK,EAAE;aAC1C;YACD,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC;YACvC,WAAW;SACZ,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE,QAAQ,CAAC,WAAW,IAAI,EAAE;YACnC,KAAK,EAAE;gBACL,WAAW,EAAE,QAAQ,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC;gBAC9C,YAAY,EAAE,QAAQ,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC;aACjD;SACF,CAAC;IACJ,CAAC;IAED,qDAAqD;IAC7C,mBAAmB,CACzB,YAAgC,EAChC,UAAkB,EAClB,KAA2B;QAE3B,MAAM,KAAK,GAAyC,EAAE,CAAC;QAEvD,IAAI,YAAY,EAAE,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAoB,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,WAAW,GAA4C,EAAE,CAAC;QAChE,IAAI,KAAK,EAAE,MAAM,EAAE,CAAC;YAClB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBACvB,WAAW,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,aAAa;wBACnB,SAAS,EACP,CAAC,CAAC,MAAM,KAAK,QAAQ;4BACnB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,WAAW,CAAC,CAAC,IAAI,EAAE;4BACvC,CAAC,CAAC,CAAC,CAAC,IAAI;wBACZ,MAAM,EAAE,MAAM;qBACf,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAC3D,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;QAE5D,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;OAOG;IACK,KAAK,CAAC,kBAAkB,CAAC,OAAmB;QAClD,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,YAAY,CAAC;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,YAAuC,CAAC;QACnE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC;QAE7C,IAAI,gBAAgB,GAAG,CAAC,CAAC;QACzB,IAAI,iBAAiB,GAAG,CAAC,CAAC;QAE1B,yEAAyE;QACzE,OAAO,CAAC,GAAG,CACT,wDAAwD,KAAK,EAAE,CAChE,CAAC;QAEF,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAExD,oEAAoE;QACpE,sDAAsD;QACtD,kFAAkF;QAClF,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;QAChD,MAAM,kBAAkB,GAAG,YAAY,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;QACzE,MAAM,QAAQ,GACZ,kBAAkB,IAAI,CAAC;YACrB,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,kBAAkB,CAAC;YAC/C,CAAC,CAAC,YAAY,CAAC;QAEnB,MAAM,kBAAkB,GACtB,QAAQ;YACR,4BAA4B,EAAE;YAC9B,2BAA2B,CAAC,YAA0B,CAAC;YACvD,0BAA0B,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,gCAAgC,kBAAkB,EAAE,CAAC,CAAC;QAElE,MAAM,WAAW,GAAG,IAAI,CAAC,mBAAmB,CAC1C,kBAAkB,EAClB,OAAO,CAAC,MAAM,EACd,OAAO,CAAC,KAAK,CACd,CAAC;QAEF,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,uBAAuB,CACrD,KAAK,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,OAAO,CAAC,SAAS,CAClB,CAAC;QAEF,gBAAgB,IAAI,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC;QACnD,iBAAiB,IAAI,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC;QAErD,MAAM,UAAU,GAAG,YAAY,CAAC,OAG/B,CAAC;QAEF,OAAO,CAAC,GAAG,CACT,iDAAiD,UAAU,CAAC,iBAAiB,EAAE,CAChF,CAAC;QAEF,iFAAiF;QACjF,MAAM,eAAe,GAAG,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACzE,MAAM,YAAY,GAChB,UAAU,CAAC,iBAAiB,KAAK,IAAI,IAAI,CAAC,eAAe,CAAC;QAE5D,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,IAAI,eAAe,IAAI,UAAU,CAAC,iBAAiB,EAAE,CAAC;gBACpD,OAAO,CAAC,GAAG,CACT,2GAA2G,CAC5G,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CACT,oDAAoD,UAAU,CAAC,iBAAiB,wBAAwB,CACzG,CAAC;YACJ,CAAC;YACD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YACzD,OAAO;gBACL,OAAO,EAAE,UAAU,CAAC,SAAS;gBAC7B,WAAW;gBACX,KAAK,EAAE;oBACL,YAAY,EAAE,gBAAgB;oBAC9B,gBAAgB,EAAE,iBAAiB;oBACnC,WAAW,EAAE,gBAAgB,GAAG,iBAAiB;iBAClD;gBACD,KAAK,EAAE,YAAY,CAAC,KAAK;gBACzB,QAAQ,EAAE,IAAI,CAAC,YAAY;gBAC3B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;gBACjC,YAAY,EAAE,YAAY,CAAC,YAAY;aACxC,CAAC;QACJ,CAAC;QAED,yEAAyE;QACzE,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QACtD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,SAAS,CACvC,KAAK,EACL,OAAO,CAAC,MAAM,EACd,WAAW,CACZ,CAAC;QAEF,gBAAgB,IAAI,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC;QACnD,iBAAiB,IAAI,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC;QACrD,OAAO,CAAC,GAAG,CACT,6BAA6B,YAAY,CAAC,OAAO,CAAC,MAAM,QAAQ,CACjE,CAAC;QAEF,yEAAyE;QACzE,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAE/D,MAAM,qBAAqB,GACzB,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;YAC5B,oBAAoB;YACpB,kEAAkE;YAClE,oEAAoE;YACpE,qDAAqD,CAAC;QAExD,MAAM,cAAc,GAAG,IAAI,CAAC,mBAAmB,CAC7C,qBAAqB,EACrB,qBAAqB,OAAO,CAAC,MAAM,MAAM;YACvC,0BAA0B,YAAY,CAAC,OAAO,MAAM;YACpD,gEAAgE;YAChE,mCAAmC,CACtC,CAAC;QAEF,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,uBAAuB,CACxD,KAAK,EACL,cAAc,EACd,UAAU,EACV,WAAW,EACX,OAAO,CAAC,SAAS,CAClB,CAAC;QAEF,gBAAgB,IAAI,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC;QACtD,iBAAiB,IAAI,eAAe,CAAC,KAAK,CAAC,YAAY,CAAC;QAExD,OAAO,CAAC,GAAG,CACT,yCAAyC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,CACpE,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,eAAe,CAAC,OAAO;YAChC,WAAW,EAAE,eAAe,CAAC,WAAW;YACxC,KAAK,EAAE;gBACL,YAAY,EAAE,gBAAgB;gBAC9B,gBAAgB,EAAE,iBAAiB;gBACnC,WAAW,EAAE,gBAAgB,GAAG,iBAAiB;aAClD;YACD,KAAK,EAAE,eAAe,CAAC,KAAK;YAC5B,QAAQ,EAAE,IAAI,CAAC,YAAY;YAC3B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;YACjC,YAAY,EAAE,eAAe,CAAC,YAAY;SAC3C,CAAC;IACJ,CAAC;IAED,eAAe,CAAC,OAAmB;QACjC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,YAAY,CAAC;QACjD,MAAM,IAAI,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAEzC,0CAA0C;QAC1C,MAAM,WAAW,GAAmC,EAAE,CAAC;QAEvD,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;YAC1B,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC9B,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBACvB,WAAW,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,WAAW;wBACjB,SAAS,EAAE;4BACT,GAAG,EACD,CAAC,CAAC,MAAM,KAAK,QAAQ;gCACnB,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,WAAW,CAAC,CAAC,IAAI,EAAE;gCACvC,CAAC,CAAC,CAAC,CAAC,IAAI;yBACb;qBACF,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBACvB,MAAM,MAAM,GAAG,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;oBAChD,WAAW,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,aAAa;wBACnB,WAAW,EAAE;4BACX,IAAI,EAAE,CAAC,CAAC,IAAI;4BACZ,MAAM;yBACP;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAEzD,uBAAuB;QACvB,MAAM,QAAQ,GAAmC,EAAE,CAAC;QACpD,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;QAEtD,6BAA6B;QAC7B,MAAM,UAAU,GAAa,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,WAAgD,CAAC;QAErD,IAAI,OAAO,CAAC,kBAAkB,EAAE,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1D,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,WAAW,GAAG;gBACZ,KAAK,EAAE,OAAO;gBACd,MAAM,EAAE,KAAK;aACd,CAAC;QACJ,CAAC;QAED,OAAO;YACL,KAAK;YACL,QAAQ;YACR,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,KAAK,EAAE;gBACL;oBACE,IAAI,EAAE,UAAU;oBAChB,QAAQ,EAAE;wBACR,IAAI,EAAE,qBAAqB;wBAC3B,WAAW,EAAE,kDAAkD;wBAC/D,UAAU,EAAE,OAAO,CAAC,YAAY;qBACjC;iBACF;aACF;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE;aAC1C;YACD,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC;YACrC,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS;SAC9D,CAAC;IACJ,CAAC"}