lootforge 0.3.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 (243) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/README.md +764 -0
  3. package/bin/lootforge.js +28 -0
  4. package/dist/benchmarks/coarseToFineCost.d.ts +21 -0
  5. package/dist/benchmarks/coarseToFineCost.js +49 -0
  6. package/dist/benchmarks/coarseToFineCost.js.map +1 -0
  7. package/dist/checks/boundaryMetrics.d.ts +12 -0
  8. package/dist/checks/boundaryMetrics.js +102 -0
  9. package/dist/checks/boundaryMetrics.js.map +1 -0
  10. package/dist/checks/candidateScore.d.ts +11 -0
  11. package/dist/checks/candidateScore.js +462 -0
  12. package/dist/checks/candidateScore.js.map +1 -0
  13. package/dist/checks/commandParser.d.ts +5 -0
  14. package/dist/checks/commandParser.js +99 -0
  15. package/dist/checks/commandParser.js.map +1 -0
  16. package/dist/checks/consistencyOutliers.d.ts +42 -0
  17. package/dist/checks/consistencyOutliers.js +156 -0
  18. package/dist/checks/consistencyOutliers.js.map +1 -0
  19. package/dist/checks/imageAcceptance.d.ts +67 -0
  20. package/dist/checks/imageAcceptance.js +967 -0
  21. package/dist/checks/imageAcceptance.js.map +1 -0
  22. package/dist/checks/packInvariants.d.ts +56 -0
  23. package/dist/checks/packInvariants.js +1064 -0
  24. package/dist/checks/packInvariants.js.map +1 -0
  25. package/dist/checks/softAdapters.d.ts +25 -0
  26. package/dist/checks/softAdapters.js +275 -0
  27. package/dist/checks/softAdapters.js.map +1 -0
  28. package/dist/checks/vlmGate.d.ts +8 -0
  29. package/dist/checks/vlmGate.js +200 -0
  30. package/dist/checks/vlmGate.js.map +1 -0
  31. package/dist/cli/commands/atlas.d.ts +5 -0
  32. package/dist/cli/commands/atlas.js +18 -0
  33. package/dist/cli/commands/atlas.js.map +1 -0
  34. package/dist/cli/commands/eval.d.ts +6 -0
  35. package/dist/cli/commands/eval.js +23 -0
  36. package/dist/cli/commands/eval.js.map +1 -0
  37. package/dist/cli/commands/generate.d.ts +18 -0
  38. package/dist/cli/commands/generate.js +66 -0
  39. package/dist/cli/commands/generate.js.map +1 -0
  40. package/dist/cli/commands/init.d.ts +15 -0
  41. package/dist/cli/commands/init.js +146 -0
  42. package/dist/cli/commands/init.js.map +1 -0
  43. package/dist/cli/commands/package.d.ts +6 -0
  44. package/dist/cli/commands/package.js +27 -0
  45. package/dist/cli/commands/package.js.map +1 -0
  46. package/dist/cli/commands/plan.d.ts +16 -0
  47. package/dist/cli/commands/plan.js +49 -0
  48. package/dist/cli/commands/plan.js.map +1 -0
  49. package/dist/cli/commands/process.d.ts +14 -0
  50. package/dist/cli/commands/process.js +29 -0
  51. package/dist/cli/commands/process.js.map +1 -0
  52. package/dist/cli/commands/regenerate.d.ts +29 -0
  53. package/dist/cli/commands/regenerate.js +244 -0
  54. package/dist/cli/commands/regenerate.js.map +1 -0
  55. package/dist/cli/commands/review.d.ts +5 -0
  56. package/dist/cli/commands/review.js +18 -0
  57. package/dist/cli/commands/review.js.map +1 -0
  58. package/dist/cli/commands/select.d.ts +6 -0
  59. package/dist/cli/commands/select.js +21 -0
  60. package/dist/cli/commands/select.js.map +1 -0
  61. package/dist/cli/commands/serve.d.ts +16 -0
  62. package/dist/cli/commands/serve.js +100 -0
  63. package/dist/cli/commands/serve.js.map +1 -0
  64. package/dist/cli/commands/validate.d.ts +17 -0
  65. package/dist/cli/commands/validate.js +108 -0
  66. package/dist/cli/commands/validate.js.map +1 -0
  67. package/dist/cli/index.d.ts +1 -0
  68. package/dist/cli/index.js +157 -0
  69. package/dist/cli/index.js.map +1 -0
  70. package/dist/cli/parseArgs.d.ts +3 -0
  71. package/dist/cli/parseArgs.js +37 -0
  72. package/dist/cli/parseArgs.js.map +1 -0
  73. package/dist/contracts/stageArtifacts.d.ts +4031 -0
  74. package/dist/contracts/stageArtifacts.js +663 -0
  75. package/dist/contracts/stageArtifacts.js.map +1 -0
  76. package/dist/manifest/load.d.ts +3 -0
  77. package/dist/manifest/load.js +50 -0
  78. package/dist/manifest/load.js.map +1 -0
  79. package/dist/manifest/normalize-palette.d.ts +17 -0
  80. package/dist/manifest/normalize-palette.js +235 -0
  81. package/dist/manifest/normalize-palette.js.map +1 -0
  82. package/dist/manifest/normalize-policy.d.ts +48 -0
  83. package/dist/manifest/normalize-policy.js +239 -0
  84. package/dist/manifest/normalize-policy.js.map +1 -0
  85. package/dist/manifest/normalize-prompt.d.ts +14 -0
  86. package/dist/manifest/normalize-prompt.js +73 -0
  87. package/dist/manifest/normalize-prompt.js.map +1 -0
  88. package/dist/manifest/normalize-target.d.ts +49 -0
  89. package/dist/manifest/normalize-target.js +542 -0
  90. package/dist/manifest/normalize-target.js.map +1 -0
  91. package/dist/manifest/schema.d.ts +7570 -0
  92. package/dist/manifest/schema.js +373 -0
  93. package/dist/manifest/schema.js.map +1 -0
  94. package/dist/manifest/semantic-validation.d.ts +4 -0
  95. package/dist/manifest/semantic-validation.js +526 -0
  96. package/dist/manifest/semantic-validation.js.map +1 -0
  97. package/dist/manifest/types.d.ts +263 -0
  98. package/dist/manifest/types.js +2 -0
  99. package/dist/manifest/types.js.map +1 -0
  100. package/dist/manifest/validate.d.ts +12 -0
  101. package/dist/manifest/validate.js +221 -0
  102. package/dist/manifest/validate.js.map +1 -0
  103. package/dist/output/assetPackManifest.d.ts +19 -0
  104. package/dist/output/assetPackManifest.js +20 -0
  105. package/dist/output/assetPackManifest.js.map +1 -0
  106. package/dist/output/catalog.d.ts +60 -0
  107. package/dist/output/catalog.js +107 -0
  108. package/dist/output/catalog.js.map +1 -0
  109. package/dist/output/contactSheet.d.ts +13 -0
  110. package/dist/output/contactSheet.js +124 -0
  111. package/dist/output/contactSheet.js.map +1 -0
  112. package/dist/output/phaserManifest.d.ts +8 -0
  113. package/dist/output/phaserManifest.js +25 -0
  114. package/dist/output/phaserManifest.js.map +1 -0
  115. package/dist/output/pixiManifest.d.ts +8 -0
  116. package/dist/output/pixiManifest.js +37 -0
  117. package/dist/output/pixiManifest.js.map +1 -0
  118. package/dist/output/provenance.d.ts +121 -0
  119. package/dist/output/provenance.js +10 -0
  120. package/dist/output/provenance.js.map +1 -0
  121. package/dist/output/runtimeManifests.d.ts +21 -0
  122. package/dist/output/runtimeManifests.js +82 -0
  123. package/dist/output/runtimeManifests.js.map +1 -0
  124. package/dist/output/unityImportManifest.d.ts +10 -0
  125. package/dist/output/unityImportManifest.js +58 -0
  126. package/dist/output/unityImportManifest.js.map +1 -0
  127. package/dist/output/zip.d.ts +5 -0
  128. package/dist/output/zip.js +68 -0
  129. package/dist/output/zip.js.map +1 -0
  130. package/dist/pipeline/atlas.d.ts +33 -0
  131. package/dist/pipeline/atlas.js +286 -0
  132. package/dist/pipeline/atlas.js.map +1 -0
  133. package/dist/pipeline/eval.d.ts +104 -0
  134. package/dist/pipeline/eval.js +246 -0
  135. package/dist/pipeline/eval.js.map +1 -0
  136. package/dist/pipeline/generate.d.ts +44 -0
  137. package/dist/pipeline/generate.js +1088 -0
  138. package/dist/pipeline/generate.js.map +1 -0
  139. package/dist/pipeline/package.d.ts +18 -0
  140. package/dist/pipeline/package.js +218 -0
  141. package/dist/pipeline/package.js.map +1 -0
  142. package/dist/pipeline/process.d.ts +15 -0
  143. package/dist/pipeline/process.js +776 -0
  144. package/dist/pipeline/process.js.map +1 -0
  145. package/dist/pipeline/review.d.ts +10 -0
  146. package/dist/pipeline/review.js +341 -0
  147. package/dist/pipeline/review.js.map +1 -0
  148. package/dist/pipeline/seamHeal.d.ts +2 -0
  149. package/dist/pipeline/seamHeal.js +70 -0
  150. package/dist/pipeline/seamHeal.js.map +1 -0
  151. package/dist/pipeline/select.d.ts +39 -0
  152. package/dist/pipeline/select.js +79 -0
  153. package/dist/pipeline/select.js.map +1 -0
  154. package/dist/providers/job.d.ts +29 -0
  155. package/dist/providers/job.js +113 -0
  156. package/dist/providers/job.js.map +1 -0
  157. package/dist/providers/localDiffusion.d.ts +28 -0
  158. package/dist/providers/localDiffusion.js +235 -0
  159. package/dist/providers/localDiffusion.js.map +1 -0
  160. package/dist/providers/nano.d.ts +36 -0
  161. package/dist/providers/nano.js +402 -0
  162. package/dist/providers/nano.js.map +1 -0
  163. package/dist/providers/openai.d.ts +37 -0
  164. package/dist/providers/openai.js +378 -0
  165. package/dist/providers/openai.js.map +1 -0
  166. package/dist/providers/policy.d.ts +9 -0
  167. package/dist/providers/policy.js +192 -0
  168. package/dist/providers/policy.js.map +1 -0
  169. package/dist/providers/prompt.d.ts +3 -0
  170. package/dist/providers/prompt.js +63 -0
  171. package/dist/providers/prompt.js.map +1 -0
  172. package/dist/providers/registry.d.ts +24 -0
  173. package/dist/providers/registry.js +92 -0
  174. package/dist/providers/registry.js.map +1 -0
  175. package/dist/providers/runtime.d.ts +15 -0
  176. package/dist/providers/runtime.js +101 -0
  177. package/dist/providers/runtime.js.map +1 -0
  178. package/dist/providers/runtimeConfig.d.ts +20 -0
  179. package/dist/providers/runtimeConfig.js +146 -0
  180. package/dist/providers/runtimeConfig.js.map +1 -0
  181. package/dist/providers/types-core.d.ts +514 -0
  182. package/dist/providers/types-core.js +60 -0
  183. package/dist/providers/types-core.js.map +1 -0
  184. package/dist/providers/types.d.ts +4 -0
  185. package/dist/providers/types.js +5 -0
  186. package/dist/providers/types.js.map +1 -0
  187. package/dist/service/generationRequest.d.ts +58 -0
  188. package/dist/service/generationRequest.js +203 -0
  189. package/dist/service/generationRequest.js.map +1 -0
  190. package/dist/service/providerCapabilities.d.ts +40 -0
  191. package/dist/service/providerCapabilities.js +114 -0
  192. package/dist/service/providerCapabilities.js.map +1 -0
  193. package/dist/service/server.d.ts +31 -0
  194. package/dist/service/server.js +774 -0
  195. package/dist/service/server.js.map +1 -0
  196. package/dist/shared/errors.d.ts +13 -0
  197. package/dist/shared/errors.js +24 -0
  198. package/dist/shared/errors.js.map +1 -0
  199. package/dist/shared/fs.d.ts +6 -0
  200. package/dist/shared/fs.js +30 -0
  201. package/dist/shared/fs.js.map +1 -0
  202. package/dist/shared/image.d.ts +25 -0
  203. package/dist/shared/image.js +136 -0
  204. package/dist/shared/image.js.map +1 -0
  205. package/dist/shared/paths.d.ts +30 -0
  206. package/dist/shared/paths.js +103 -0
  207. package/dist/shared/paths.js.map +1 -0
  208. package/dist/shared/schemas.d.ts +209 -0
  209. package/dist/shared/schemas.js +93 -0
  210. package/dist/shared/schemas.js.map +1 -0
  211. package/dist/shared/typeGuards.d.ts +1 -0
  212. package/dist/shared/typeGuards.js +4 -0
  213. package/dist/shared/typeGuards.js.map +1 -0
  214. package/dist/shared/zod.d.ts +1 -0
  215. package/dist/shared/zod.js +14 -0
  216. package/dist/shared/zod.js.map +1 -0
  217. package/dist/showcase/format.d.ts +9 -0
  218. package/dist/showcase/format.js +61 -0
  219. package/dist/showcase/format.js.map +1 -0
  220. package/dist/showcase/panelRenderer.d.ts +59 -0
  221. package/dist/showcase/panelRenderer.js +294 -0
  222. package/dist/showcase/panelRenderer.js.map +1 -0
  223. package/dist/showcase/releaseConfig.d.ts +233 -0
  224. package/dist/showcase/releaseConfig.js +75 -0
  225. package/dist/showcase/releaseConfig.js.map +1 -0
  226. package/dist/showcase/releaseEvidence.d.ts +25 -0
  227. package/dist/showcase/releaseEvidence.js +540 -0
  228. package/dist/showcase/releaseEvidence.js.map +1 -0
  229. package/dist/showcase/releaseEvidenceSchema.d.ts +1611 -0
  230. package/dist/showcase/releaseEvidenceSchema.js +165 -0
  231. package/dist/showcase/releaseEvidenceSchema.js.map +1 -0
  232. package/dist/showcase/scenarioRenderer.d.ts +19 -0
  233. package/dist/showcase/scenarioRenderer.js +488 -0
  234. package/dist/showcase/scenarioRenderer.js.map +1 -0
  235. package/docs/ADAPTER_CONTRACT.md +141 -0
  236. package/docs/ENGINE_TARGETING.md +86 -0
  237. package/docs/MANIFEST_POLICY_COVERAGE.md +130 -0
  238. package/docs/RELEASE_WORKFLOW.md +117 -0
  239. package/docs/ROADMAP.md +411 -0
  240. package/docs/ROADMAP_ISSUES.md +244 -0
  241. package/docs/SERVICE_MODE.md +137 -0
  242. package/docs/manifest-schema.md +254 -0
  243. package/package.json +70 -0
@@ -0,0 +1,378 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS, fetchWithTimeout, MAX_DECODED_IMAGE_BYTES, normalizeNonNegativeInteger, normalizePositiveInteger, ProviderRequestTimeoutError, toOptionalNonNegativeInteger, validateImageUrl, withCandidateSuffix, } from "./runtime.js";
4
+ import { createProviderJob, nowIso, ProviderError, PROVIDER_CAPABILITIES, } from "./types.js";
5
+ import { resolvePathWithinRoot } from "../shared/paths.js";
6
+ const OPENAI_IMAGES_ENDPOINT = "https://api.openai.com/v1/images/generations";
7
+ const OPENAI_EDITS_ENDPOINT = "https://api.openai.com/v1/images/edits";
8
+ export const DEFAULT_OPENAI_MODEL = "gpt-image-1";
9
+ const DEFAULT_EDIT_IMAGE_MIME_TYPE = "image/png";
10
+ export class OpenAIProvider {
11
+ name = "openai";
12
+ capabilities;
13
+ model;
14
+ endpoint;
15
+ editsEndpoint;
16
+ timeoutMs;
17
+ maxRetries;
18
+ constructor(options = {}) {
19
+ const defaults = PROVIDER_CAPABILITIES.openai;
20
+ this.capabilities = {
21
+ ...defaults,
22
+ defaultConcurrency: normalizePositiveInteger(options.defaultConcurrency, defaults.defaultConcurrency),
23
+ minDelayMs: normalizeNonNegativeInteger(options.minDelayMs, defaults.minDelayMs),
24
+ };
25
+ this.model = options.model ?? DEFAULT_OPENAI_MODEL;
26
+ this.endpoint = options.endpoint ?? OPENAI_IMAGES_ENDPOINT;
27
+ this.editsEndpoint = options.editsEndpoint ?? OPENAI_EDITS_ENDPOINT;
28
+ this.timeoutMs = normalizePositiveInteger(options.timeoutMs, DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS);
29
+ this.maxRetries = toOptionalNonNegativeInteger(options.maxRetries);
30
+ }
31
+ prepareJobs(targets, ctx) {
32
+ return targets.map((target) => createProviderJob({
33
+ provider: this.name,
34
+ target,
35
+ model: target.model ?? this.model,
36
+ imagesDir: ctx.imagesDir,
37
+ defaults: {
38
+ maxRetries: this.maxRetries,
39
+ },
40
+ }));
41
+ }
42
+ supports(feature) {
43
+ if (feature === "image-generation")
44
+ return true;
45
+ if (feature === "transparent-background")
46
+ return true;
47
+ if (feature === "image-edits")
48
+ return true;
49
+ if (feature === "multi-candidate")
50
+ return true;
51
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
52
+ if (feature === "controlnet")
53
+ return false;
54
+ return false;
55
+ }
56
+ normalizeError(error) {
57
+ if (error instanceof ProviderError && error.provider === this.name) {
58
+ return error;
59
+ }
60
+ if (error instanceof Error) {
61
+ return new ProviderError({
62
+ provider: this.name,
63
+ code: "openai_request_failed",
64
+ message: error.message,
65
+ cause: error,
66
+ actionable: "Check OPENAI_API_KEY and provider/model settings, then retry generation.",
67
+ });
68
+ }
69
+ return new ProviderError({
70
+ provider: this.name,
71
+ code: "openai_request_failed",
72
+ message: "OpenAI provider failed with a non-error throwable.",
73
+ cause: error,
74
+ actionable: "Check OPENAI_API_KEY and provider/model settings, then retry generation.",
75
+ });
76
+ }
77
+ async runJob(job, ctx) {
78
+ const startedAt = nowIso(ctx.now);
79
+ const fetchImpl = ctx.fetchImpl ?? globalThis.fetch;
80
+ const apiKey = process.env.OPENAI_API_KEY?.trim();
81
+ if (!apiKey) {
82
+ throw new ProviderError({
83
+ provider: this.name,
84
+ code: "missing_api_key",
85
+ message: "OPENAI_API_KEY is required for OpenAI image generation.",
86
+ actionable: "Set OPENAI_API_KEY in the environment and rerun generate.",
87
+ });
88
+ }
89
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
90
+ if (!fetchImpl) {
91
+ throw new ProviderError({
92
+ provider: this.name,
93
+ code: "missing_fetch",
94
+ message: "Global fetch is unavailable for OpenAI provider.",
95
+ actionable: "Use Node.js 18+ or pass a fetch implementation in the run context.",
96
+ });
97
+ }
98
+ try {
99
+ const useEdits = this.shouldUseEdits(job);
100
+ const actualPrompt = useEdits ? this.buildEditPrompt(job) : job.prompt;
101
+ const response = useEdits
102
+ ? await this.runEditRequest(job, ctx, fetchImpl, apiKey)
103
+ : await this.requestWithTimeout(fetchImpl, this.endpoint, {
104
+ method: "POST",
105
+ headers: {
106
+ Authorization: `Bearer ${apiKey}`,
107
+ "Content-Type": "application/json",
108
+ },
109
+ body: JSON.stringify({
110
+ model: job.model,
111
+ prompt: job.prompt,
112
+ size: job.size,
113
+ quality: job.quality,
114
+ background: job.background,
115
+ output_format: job.outputFormat,
116
+ n: Math.max(1, job.candidateCount),
117
+ }),
118
+ });
119
+ if (!response.ok) {
120
+ const bodyText = await response.text();
121
+ throw this.buildHttpError(response.status, bodyText);
122
+ }
123
+ const payload = (await response.json());
124
+ const images = payload.data ?? [];
125
+ if (images.length === 0) {
126
+ throw new ProviderError({
127
+ provider: this.name,
128
+ code: "openai_missing_image",
129
+ message: "OpenAI returned no image data for this job.",
130
+ actionable: "Check prompt/model compatibility and retry with a simpler prompt.",
131
+ });
132
+ }
133
+ const candidateOutputs = [];
134
+ const count = Math.max(job.candidateCount, 1);
135
+ for (let index = 0; index < count; index += 1) {
136
+ const image = images[index] ?? images[0];
137
+ const imageBytes = await this.resolveImageBytes(image, fetchImpl);
138
+ const outputPath = index === 0 ? job.outPath : withCandidateSuffix(job.outPath, index + 1);
139
+ await mkdir(path.dirname(outputPath), { recursive: true });
140
+ await writeFile(outputPath, imageBytes);
141
+ candidateOutputs.push({
142
+ outputPath,
143
+ bytesWritten: imageBytes.byteLength,
144
+ });
145
+ }
146
+ return {
147
+ jobId: job.id,
148
+ provider: this.name,
149
+ model: job.model,
150
+ targetId: job.targetId,
151
+ prompt: actualPrompt,
152
+ outputPath: candidateOutputs[0].outputPath,
153
+ bytesWritten: candidateOutputs[0].bytesWritten,
154
+ inputHash: job.inputHash,
155
+ startedAt,
156
+ finishedAt: nowIso(ctx.now),
157
+ candidateOutputs,
158
+ };
159
+ }
160
+ catch (error) {
161
+ throw this.normalizeError(error);
162
+ }
163
+ }
164
+ shouldUseEdits(job) {
165
+ if (job.target.generationMode !== "edit-first") {
166
+ return false;
167
+ }
168
+ return (job.target.edit?.inputs?.length ?? 0) > 0;
169
+ }
170
+ async runEditRequest(job, ctx, fetchImpl, apiKey) {
171
+ const editInputs = job.target.edit?.inputs ?? [];
172
+ const baseAndReferenceInputs = editInputs.filter((input) => input.role !== "mask");
173
+ const maskInputs = editInputs.filter((input) => input.role === "mask");
174
+ if (baseAndReferenceInputs.length === 0) {
175
+ throw new ProviderError({
176
+ provider: this.name,
177
+ code: "openai_edit_missing_base_image",
178
+ message: `Target "${job.targetId}" requested edit-first mode but no base/reference images were provided.`,
179
+ actionable: "Add at least one edit input with role base/reference for generationMode=edit-first.",
180
+ });
181
+ }
182
+ const form = new FormData();
183
+ form.set("model", job.model);
184
+ form.set("prompt", this.buildEditPrompt(job));
185
+ form.set("size", job.size);
186
+ form.set("quality", job.quality);
187
+ form.set("background", job.background);
188
+ form.set("output_format", job.outputFormat);
189
+ form.set("n", String(Math.max(1, job.candidateCount)));
190
+ for (const input of baseAndReferenceInputs) {
191
+ const resolvedPath = this.resolveEditInputPath(input.path, ctx.outDir, job.targetId);
192
+ const imageBytes = await this.readEditInputBytes(resolvedPath, job.targetId);
193
+ const imageData = new Uint8Array(imageBytes);
194
+ if (baseAndReferenceInputs.length === 1) {
195
+ form.append("image", new Blob([imageData], { type: this.mimeTypeForPath(resolvedPath) }), path.basename(resolvedPath));
196
+ }
197
+ else {
198
+ form.append("image[]", new Blob([imageData], { type: this.mimeTypeForPath(resolvedPath) }), path.basename(resolvedPath));
199
+ }
200
+ }
201
+ if (maskInputs.length > 0) {
202
+ const maskPath = this.resolveEditInputPath(maskInputs[0].path, ctx.outDir, job.targetId);
203
+ const maskBytes = await this.readEditInputBytes(maskPath, job.targetId);
204
+ const maskData = new Uint8Array(maskBytes);
205
+ form.append("mask", new Blob([maskData], { type: this.mimeTypeForPath(maskPath) }), path.basename(maskPath));
206
+ }
207
+ return this.requestWithTimeout(fetchImpl, this.editsEndpoint, {
208
+ method: "POST",
209
+ headers: {
210
+ Authorization: `Bearer ${apiKey}`,
211
+ },
212
+ body: form,
213
+ });
214
+ }
215
+ resolveEditInputPath(inputPath, outDir, targetId) {
216
+ try {
217
+ return resolvePathWithinRoot(outDir, inputPath, `edit input path for target "${targetId}"`);
218
+ }
219
+ catch (error) {
220
+ throw new ProviderError({
221
+ provider: this.name,
222
+ code: "openai_edit_input_unsafe_path",
223
+ message: `Unsafe edit input path "${inputPath}" for target "${targetId}".`,
224
+ actionable: `Edit input paths must stay within the output root (${path.resolve(outDir)}).`,
225
+ cause: error,
226
+ });
227
+ }
228
+ }
229
+ async readEditInputBytes(inputPath, targetId) {
230
+ try {
231
+ return await readFile(inputPath);
232
+ }
233
+ catch (error) {
234
+ throw new ProviderError({
235
+ provider: this.name,
236
+ code: "openai_edit_input_unreadable",
237
+ message: `Failed to read edit input "${inputPath}" for target "${targetId}".`,
238
+ actionable: "Ensure edit input files exist and paths are correct relative to --out (or absolute).",
239
+ cause: error,
240
+ });
241
+ }
242
+ }
243
+ buildEditPrompt(job) {
244
+ const instruction = job.target.edit?.instruction?.trim();
245
+ const preserveCompositionHint = job.target.edit?.preserveComposition
246
+ ? "Preserve composition and camera framing unless the instruction explicitly changes them."
247
+ : "";
248
+ if (!instruction) {
249
+ return [job.prompt, preserveCompositionHint].filter(Boolean).join("\n\n");
250
+ }
251
+ return [instruction, preserveCompositionHint, "Target style/output requirements:", job.prompt]
252
+ .filter(Boolean)
253
+ .join("\n\n");
254
+ }
255
+ mimeTypeForPath(filePath) {
256
+ const ext = path.extname(filePath).toLowerCase();
257
+ if (ext === ".jpg" || ext === ".jpeg")
258
+ return "image/jpeg";
259
+ if (ext === ".webp")
260
+ return "image/webp";
261
+ if (ext === ".gif")
262
+ return "image/gif";
263
+ if (ext === ".bmp")
264
+ return "image/bmp";
265
+ if (ext === ".svg")
266
+ return "image/svg+xml";
267
+ return DEFAULT_EDIT_IMAGE_MIME_TYPE;
268
+ }
269
+ async resolveImageBytes(imageData, fetchImpl) {
270
+ if (typeof imageData.b64_json === "string" && imageData.b64_json.length > 0) {
271
+ const buffer = Buffer.from(imageData.b64_json, "base64");
272
+ if (buffer.byteLength > MAX_DECODED_IMAGE_BYTES) {
273
+ throw new ProviderError({
274
+ provider: this.name,
275
+ code: "openai_image_too_large",
276
+ message: `Decoded image exceeds ${MAX_DECODED_IMAGE_BYTES} byte safety limit.`,
277
+ actionable: "Request smaller images or reduce candidate count.",
278
+ });
279
+ }
280
+ return buffer;
281
+ }
282
+ if (typeof imageData.url === "string" && imageData.url.length > 0) {
283
+ validateImageUrl(imageData.url, "OpenAI image download");
284
+ const imageResponse = await this.requestWithTimeout(fetchImpl, imageData.url);
285
+ if (!imageResponse.ok) {
286
+ throw new ProviderError({
287
+ provider: this.name,
288
+ code: "openai_image_download_failed",
289
+ status: imageResponse.status,
290
+ message: `OpenAI image download failed with status ${imageResponse.status}.`,
291
+ actionable: "Retry generation; if this persists, verify network egress and OpenAI response format.",
292
+ });
293
+ }
294
+ const buffer = Buffer.from(await imageResponse.arrayBuffer());
295
+ if (buffer.byteLength === 0) {
296
+ throw new ProviderError({
297
+ provider: this.name,
298
+ code: "openai_empty_image",
299
+ message: "OpenAI returned an empty image payload.",
300
+ actionable: "Retry generation and verify the requested model can output images.",
301
+ });
302
+ }
303
+ if (buffer.byteLength > MAX_DECODED_IMAGE_BYTES) {
304
+ throw new ProviderError({
305
+ provider: this.name,
306
+ code: "openai_image_too_large",
307
+ message: `Decoded image exceeds ${MAX_DECODED_IMAGE_BYTES} byte safety limit.`,
308
+ actionable: "Request smaller images or reduce candidate count.",
309
+ });
310
+ }
311
+ return buffer;
312
+ }
313
+ throw new ProviderError({
314
+ provider: this.name,
315
+ code: "openai_missing_image",
316
+ message: "OpenAI response had neither b64_json nor url image data.",
317
+ actionable: "Switch model or prompt format and verify the Images API response schema.",
318
+ });
319
+ }
320
+ buildHttpError(status, bodyText) {
321
+ const details = this.parseErrorPayload(bodyText);
322
+ let message = `OpenAI images request failed with status ${status}`;
323
+ if (details.code) {
324
+ message += ` (${details.code})`;
325
+ }
326
+ message += ".";
327
+ if (details.message) {
328
+ message += ` ${details.message}`;
329
+ }
330
+ return new ProviderError({
331
+ provider: this.name,
332
+ code: "openai_http_error",
333
+ status,
334
+ message,
335
+ actionable: this.httpErrorActionable(details.code),
336
+ cause: bodyText,
337
+ });
338
+ }
339
+ parseErrorPayload(bodyText) {
340
+ try {
341
+ const payload = JSON.parse(bodyText);
342
+ return {
343
+ message: payload.error?.message?.trim() ?? undefined,
344
+ code: payload.error?.code?.trim() ?? undefined,
345
+ };
346
+ }
347
+ catch {
348
+ return {};
349
+ }
350
+ }
351
+ httpErrorActionable(code) {
352
+ if (code?.includes("billing") || code?.includes("quota")) {
353
+ return "Increase the OpenAI billing limit or switch providers, then retry generation.";
354
+ }
355
+ return "Confirm OPENAI_API_KEY permissions and model availability for the Images API.";
356
+ }
357
+ async requestWithTimeout(fetchImpl, input, init) {
358
+ try {
359
+ return await fetchWithTimeout(fetchImpl, input, init, this.timeoutMs);
360
+ }
361
+ catch (error) {
362
+ if (error instanceof ProviderRequestTimeoutError) {
363
+ throw new ProviderError({
364
+ provider: this.name,
365
+ code: "openai_request_timeout",
366
+ message: `OpenAI request timed out after ${error.timeoutMs}ms.`,
367
+ actionable: "Increase providers.openai.timeoutMs or LOOTFORGE_OPENAI_TIMEOUT_MS and retry.",
368
+ cause: error,
369
+ });
370
+ }
371
+ throw error;
372
+ }
373
+ }
374
+ }
375
+ export function createOpenAIProvider(options = {}) {
376
+ return new OpenAIProvider(options);
377
+ }
378
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type GenerationMode, type NormalizedGenerationPolicy, type NormalizedOutputFormat, type PlannedTarget, type PostProcessPolicy, type ProviderCapabilities, type ProviderName, type ProviderPolicyNormalizationResult } from "./types-core.js";
2
+ export declare function normalizeOutputFormatAlias(value: string | undefined): NormalizedOutputFormat;
3
+ export declare function getProviderCapabilities(provider: ProviderName): ProviderCapabilities;
4
+ export declare function isProviderName(value: unknown): value is ProviderName;
5
+ export declare function getTargetGenerationPolicy(target: PlannedTarget): NormalizedGenerationPolicy;
6
+ export declare function getTargetGenerationMode(target: PlannedTarget): GenerationMode;
7
+ export declare function normalizeGenerationPolicyForProvider(provider: ProviderName, rawPolicy: NormalizedGenerationPolicy): ProviderPolicyNormalizationResult;
8
+ export declare function getTargetPostProcessPolicy(target: PlannedTarget): PostProcessPolicy;
9
+ export declare function nowIso(now?: () => Date): string;
@@ -0,0 +1,192 @@
1
+ import { PROVIDER_CAPABILITIES, PROVIDER_NAMES } from "./types-core.js";
2
+ const DEFAULT_SIZE = "1024x1024";
3
+ const DEFAULT_QUALITY = "high";
4
+ const DEFAULT_BACKGROUND = "opaque";
5
+ const DEFAULT_OUTPUT_FORMAT = "png";
6
+ const DEFAULT_POST_PROCESS_ALGORITHM = "lanczos3";
7
+ const DEFAULT_CANDIDATE_COUNT = 1;
8
+ const DEFAULT_GENERATION_MODE = "text";
9
+ export function normalizeOutputFormatAlias(value) {
10
+ const normalized = value?.trim().toLowerCase() ?? "";
11
+ if (normalized === "jpg")
12
+ return "jpeg";
13
+ if (normalized === "jpeg")
14
+ return "jpeg";
15
+ if (normalized === "webp")
16
+ return "webp";
17
+ return "png";
18
+ }
19
+ export function getProviderCapabilities(provider) {
20
+ return PROVIDER_CAPABILITIES[provider];
21
+ }
22
+ export function isProviderName(value) {
23
+ return typeof value === "string" && PROVIDER_NAMES.includes(value);
24
+ }
25
+ export function getTargetGenerationPolicy(target) {
26
+ const policy = target.generationPolicy ?? {};
27
+ const normalizedHiresFix = normalizeHiresFixPolicy(policy.hiresFix);
28
+ const candidatesRaw = typeof policy.candidates === "number" && Number.isFinite(policy.candidates)
29
+ ? Math.round(policy.candidates)
30
+ : DEFAULT_CANDIDATE_COUNT;
31
+ const maxRetriesRaw = typeof policy.maxRetries === "number" && Number.isFinite(policy.maxRetries)
32
+ ? Math.round(policy.maxRetries)
33
+ : undefined;
34
+ const draftQuality = policy.draftQuality?.trim();
35
+ const finalQuality = policy.finalQuality?.trim();
36
+ return {
37
+ size: policy.size?.trim() ?? DEFAULT_SIZE,
38
+ quality: policy.quality?.trim() ?? DEFAULT_QUALITY,
39
+ ...(draftQuality ? { draftQuality } : {}),
40
+ ...(finalQuality ? { finalQuality } : {}),
41
+ background: policy.background?.trim() ?? DEFAULT_BACKGROUND,
42
+ outputFormat: normalizeOutputFormatAlias(policy.outputFormat ?? DEFAULT_OUTPUT_FORMAT),
43
+ ...(typeof policy.highQuality === "boolean" ? { highQuality: policy.highQuality } : {}),
44
+ ...(normalizedHiresFix ? { hiresFix: normalizedHiresFix } : {}),
45
+ candidates: Math.max(1, candidatesRaw),
46
+ ...(typeof maxRetriesRaw === "number" ? { maxRetries: Math.max(0, maxRetriesRaw) } : {}),
47
+ fallbackProviders: Array.isArray(policy.fallbackProviders)
48
+ ? policy.fallbackProviders.filter((name) => isProviderName(name))
49
+ : [],
50
+ providerConcurrency: typeof policy.providerConcurrency === "number" &&
51
+ Number.isFinite(policy.providerConcurrency) &&
52
+ policy.providerConcurrency > 0
53
+ ? Math.round(policy.providerConcurrency)
54
+ : undefined,
55
+ rateLimitPerMinute: typeof policy.rateLimitPerMinute === "number" &&
56
+ Number.isFinite(policy.rateLimitPerMinute) &&
57
+ policy.rateLimitPerMinute > 0
58
+ ? Math.round(policy.rateLimitPerMinute)
59
+ : undefined,
60
+ vlmGate: normalizeVlmGatePolicy(policy.vlmGate),
61
+ coarseToFine: normalizeCoarseToFinePolicy(policy.coarseToFine),
62
+ agenticRetry: normalizeAgenticRetryPolicy(policy.agenticRetry),
63
+ };
64
+ }
65
+ function normalizeHiresFixPolicy(policy) {
66
+ if (!policy) {
67
+ return undefined;
68
+ }
69
+ const normalized = {};
70
+ if (typeof policy.enabled === "boolean") {
71
+ normalized.enabled = policy.enabled;
72
+ }
73
+ if (typeof policy.upscale === "number" && Number.isFinite(policy.upscale)) {
74
+ normalized.upscale = Math.max(1.01, Math.min(4, policy.upscale));
75
+ }
76
+ if (typeof policy.denoiseStrength === "number" && Number.isFinite(policy.denoiseStrength)) {
77
+ normalized.denoiseStrength = Math.max(0, Math.min(1, policy.denoiseStrength));
78
+ }
79
+ return Object.keys(normalized).length > 0 ? normalized : undefined;
80
+ }
81
+ function normalizeVlmGatePolicy(policy) {
82
+ if (!policy) {
83
+ return undefined;
84
+ }
85
+ const threshold = typeof policy.threshold === "number" && Number.isFinite(policy.threshold)
86
+ ? policy.threshold
87
+ : 4;
88
+ const normalized = {
89
+ threshold: Math.max(0, Math.min(5, threshold)),
90
+ };
91
+ if (typeof policy.rubric === "string" && policy.rubric.trim()) {
92
+ normalized.rubric = policy.rubric.trim();
93
+ }
94
+ return normalized;
95
+ }
96
+ function normalizeCoarseToFinePolicy(policy) {
97
+ if (!policy) {
98
+ return undefined;
99
+ }
100
+ const promoteTopK = typeof policy.promoteTopK === "number" && Number.isFinite(policy.promoteTopK)
101
+ ? Math.max(1, Math.round(policy.promoteTopK))
102
+ : 1;
103
+ const minDraftScore = typeof policy.minDraftScore === "number" && Number.isFinite(policy.minDraftScore)
104
+ ? policy.minDraftScore
105
+ : undefined;
106
+ return {
107
+ enabled: policy.enabled ?? true,
108
+ promoteTopK,
109
+ ...(typeof minDraftScore === "number" ? { minDraftScore } : {}),
110
+ requireDraftAcceptance: policy.requireDraftAcceptance ?? true,
111
+ };
112
+ }
113
+ function normalizeAgenticRetryPolicy(policy) {
114
+ if (!policy) {
115
+ return undefined;
116
+ }
117
+ const maxRetries = typeof policy.maxRetries === "number" && Number.isFinite(policy.maxRetries)
118
+ ? Math.max(0, Math.round(policy.maxRetries))
119
+ : 1;
120
+ return {
121
+ enabled: policy.enabled ?? true,
122
+ maxRetries,
123
+ };
124
+ }
125
+ export function getTargetGenerationMode(target) {
126
+ if (target.generationMode === "edit-first") {
127
+ return "edit-first";
128
+ }
129
+ return DEFAULT_GENERATION_MODE;
130
+ }
131
+ export function normalizeGenerationPolicyForProvider(provider, rawPolicy) {
132
+ const capabilities = getProviderCapabilities(provider);
133
+ const issues = [];
134
+ const policy = {
135
+ ...rawPolicy,
136
+ outputFormat: normalizeOutputFormatAlias(rawPolicy.outputFormat),
137
+ };
138
+ if (!capabilities.supportedOutputFormats.has(policy.outputFormat)) {
139
+ issues.push({
140
+ level: "error",
141
+ code: "unsupported_output_format",
142
+ message: `${provider} does not support output format "${policy.outputFormat}".`,
143
+ });
144
+ }
145
+ if (policy.background === "transparent" && policy.outputFormat === "jpeg") {
146
+ policy.outputFormat = "png";
147
+ issues.push({
148
+ level: "warning",
149
+ code: "jpg_transparency_normalized",
150
+ message: "Transparent background requested with JPEG output; outputFormat normalized to png.",
151
+ });
152
+ }
153
+ if (policy.background === "transparent" && !capabilities.supportsTransparentBackground) {
154
+ issues.push({
155
+ level: "error",
156
+ code: "transparent_background_unsupported",
157
+ message: `${provider} does not support transparent backgrounds.`,
158
+ });
159
+ }
160
+ if (policy.candidates > capabilities.maxCandidates) {
161
+ issues.push({
162
+ level: "warning",
163
+ code: "candidate_count_clamped",
164
+ message: `${provider} max candidates is ${capabilities.maxCandidates}; clamped requested value.`,
165
+ });
166
+ policy.candidates = capabilities.maxCandidates;
167
+ }
168
+ if (policy.coarseToFine && policy.coarseToFine.promoteTopK > policy.candidates) {
169
+ issues.push({
170
+ level: "warning",
171
+ code: "coarse_to_fine_topk_clamped",
172
+ message: `coarseToFine.promoteTopK exceeds candidates; clamped to ${policy.candidates}.`,
173
+ });
174
+ policy.coarseToFine.promoteTopK = policy.candidates;
175
+ }
176
+ policy.fallbackProviders = policy.fallbackProviders.filter((name) => name !== provider);
177
+ return { policy, issues };
178
+ }
179
+ export function getTargetPostProcessPolicy(target) {
180
+ const policy = target.postProcess ?? {};
181
+ return {
182
+ resizeTo: policy.resizeTo,
183
+ algorithm: policy.algorithm ?? DEFAULT_POST_PROCESS_ALGORITHM,
184
+ stripMetadata: policy.stripMetadata ?? true,
185
+ pngPaletteColors: policy.pngPaletteColors,
186
+ operations: policy.operations,
187
+ };
188
+ }
189
+ export function nowIso(now) {
190
+ return (now ?? (() => new Date()))().toISOString();
191
+ }
192
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/providers/policy.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAExE,MAAM,YAAY,GAAG,WAAW,CAAC;AACjC,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,MAAM,kBAAkB,GAAG,QAAQ,CAAC;AACpC,MAAM,qBAAqB,GAA2B,KAAK,CAAC;AAC5D,MAAM,8BAA8B,GAAyB,UAAU,CAAC;AACxE,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAClC,MAAM,uBAAuB,GAAmB,MAAM,CAAC;AAEvD,MAAM,UAAU,0BAA0B,CAAC,KAAyB;IAClE,MAAM,UAAU,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IACrD,IAAI,UAAU,KAAK,KAAK;QAAE,OAAO,MAAM,CAAC;IACxC,IAAI,UAAU,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACzC,IAAI,UAAU,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACzC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,QAAsB;IAC5D,OAAO,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,cAAc,CAAC,QAAQ,CAAC,KAAqB,CAAC,CAAC;AACrF,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAqB;IAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,IAAI,EAAE,CAAC;IAC7C,MAAM,kBAAkB,GAAG,uBAAuB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACpE,MAAM,aAAa,GACjB,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC;QACzE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC;QAC/B,CAAC,CAAC,uBAAuB,CAAC;IAC9B,MAAM,aAAa,GACjB,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC;QACzE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC;QAC/B,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC;IACjD,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC;IAEjD,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,YAAY;QACzC,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,eAAe;QAClD,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,kBAAkB;QAC3D,YAAY,EAAE,0BAA0B,CAAC,MAAM,CAAC,YAAY,IAAI,qBAAqB,CAAC;QACtF,GAAG,CAAC,OAAO,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvF,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,CAAC;QACtC,GAAG,CAAC,OAAO,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,iBAAiB,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC;YACxD,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAwB,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YACvF,CAAC,CAAC,EAAE;QACN,mBAAmB,EACjB,OAAO,MAAM,CAAC,mBAAmB,KAAK,QAAQ;YAC9C,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,mBAAmB,CAAC;YAC3C,MAAM,CAAC,mBAAmB,GAAG,CAAC;YAC5B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC;YACxC,CAAC,CAAC,SAAS;QACf,kBAAkB,EAChB,OAAO,MAAM,CAAC,kBAAkB,KAAK,QAAQ;YAC7C,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CAAC;YAC1C,MAAM,CAAC,kBAAkB,GAAG,CAAC;YAC3B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC;YACvC,CAAC,CAAC,SAAS;QACf,OAAO,EAAE,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC;QAC/C,YAAY,EAAE,2BAA2B,CAAC,MAAM,CAAC,YAAY,CAAC;QAC9D,YAAY,EAAE,2BAA2B,CAAC,MAAM,CAAC,YAAY,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAC9B,MAAgD;IAEhD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,UAAU,GAAwD,EAAE,CAAC;IAE3E,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACxC,UAAU,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IACtC,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1E,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,eAAe,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC;QAC1F,UAAU,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;AACrE,CAAC;AAED,SAAS,sBAAsB,CAAC,MAAiC;IAC/D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,SAAS,GACb,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;QACvE,CAAC,CAAC,MAAM,CAAC,SAAS;QAClB,CAAC,CAAC,CAAC,CAAC;IACR,MAAM,UAAU,GAAkB;QAChC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;KAC/C,CAAC;IAEF,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9D,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC3C,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,2BAA2B,CAClC,MAAsC;IAEtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,WAAW,GACf,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC;QAC3E,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC,CAAC;IACR,MAAM,aAAa,GACjB,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC;QAC/E,CAAC,CAAC,MAAM,CAAC,aAAa;QACtB,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;QAC/B,WAAW;QACX,GAAG,CAAC,OAAO,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,sBAAsB,EAAE,MAAM,CAAC,sBAAsB,IAAI,IAAI;KAC9D,CAAC;AACJ,CAAC;AAED,SAAS,2BAA2B,CAClC,MAAsC;IAEtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,UAAU,GACd,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC;QACzE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC,CAAC;IAER,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;QAC/B,UAAU;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAqB;IAC3D,IAAI,MAAM,CAAC,cAAc,KAAK,YAAY,EAAE,CAAC;QAC3C,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,uBAAuB,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,oCAAoC,CAClD,QAAsB,EACtB,SAAqC;IAErC,MAAM,YAAY,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACvD,MAAM,MAAM,GAA+B,EAAE,CAAC;IAE9C,MAAM,MAAM,GAA+B;QACzC,GAAG,SAAS;QACZ,YAAY,EAAE,0BAA0B,CAAC,SAAS,CAAC,YAAY,CAAC;KACjE,CAAC;IAEF,IAAI,CAAC,YAAY,CAAC,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QAClE,MAAM,CAAC,IAAI,CAAC;YACV,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,2BAA2B;YACjC,OAAO,EAAE,GAAG,QAAQ,oCAAoC,MAAM,CAAC,YAAY,IAAI;SAChF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,KAAK,aAAa,IAAI,MAAM,CAAC,YAAY,KAAK,MAAM,EAAE,CAAC;QAC1E,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC;YACV,KAAK,EAAE,SAAS;YAChB,IAAI,EAAE,6BAA6B;YACnC,OAAO,EAAE,oFAAoF;SAC9F,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,KAAK,aAAa,IAAI,CAAC,YAAY,CAAC,6BAA6B,EAAE,CAAC;QACvF,MAAM,CAAC,IAAI,CAAC;YACV,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,oCAAoC;YAC1C,OAAO,EAAE,GAAG,QAAQ,4CAA4C;SACjE,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,GAAG,YAAY,CAAC,aAAa,EAAE,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC;YACV,KAAK,EAAE,SAAS;YAChB,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,GAAG,QAAQ,sBAAsB,YAAY,CAAC,aAAa,4BAA4B;SACjG,CAAC,CAAC;QACH,MAAM,CAAC,UAAU,GAAG,YAAY,CAAC,aAAa,CAAC;IACjD,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,YAAY,CAAC,WAAW,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/E,MAAM,CAAC,IAAI,CAAC;YACV,KAAK,EAAE,SAAS;YAChB,IAAI,EAAE,6BAA6B;YACnC,OAAO,EAAE,2DAA2D,MAAM,CAAC,UAAU,GAAG;SACzF,CAAC,CAAC;QACH,MAAM,CAAC,YAAY,CAAC,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;IACtD,CAAC;IAED,MAAM,CAAC,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAExF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,MAAqB;IAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;IACxC,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,8BAA8B;QAC7D,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI;QAC3C,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,UAAU,EAAE,MAAM,CAAC,UAAU;KAC9B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,GAAgB;IACrC,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;AACrD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type PromptSpec } from "./types-core.js";
2
+ export declare function normalizePromptSpec(spec: PromptSpec): PromptSpec;
3
+ export declare function buildStructuredPrompt(promptSpec: PromptSpec): string;