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.
- package/CHANGELOG.md +87 -0
- package/README.md +764 -0
- package/bin/lootforge.js +28 -0
- package/dist/benchmarks/coarseToFineCost.d.ts +21 -0
- package/dist/benchmarks/coarseToFineCost.js +49 -0
- package/dist/benchmarks/coarseToFineCost.js.map +1 -0
- package/dist/checks/boundaryMetrics.d.ts +12 -0
- package/dist/checks/boundaryMetrics.js +102 -0
- package/dist/checks/boundaryMetrics.js.map +1 -0
- package/dist/checks/candidateScore.d.ts +11 -0
- package/dist/checks/candidateScore.js +462 -0
- package/dist/checks/candidateScore.js.map +1 -0
- package/dist/checks/commandParser.d.ts +5 -0
- package/dist/checks/commandParser.js +99 -0
- package/dist/checks/commandParser.js.map +1 -0
- package/dist/checks/consistencyOutliers.d.ts +42 -0
- package/dist/checks/consistencyOutliers.js +156 -0
- package/dist/checks/consistencyOutliers.js.map +1 -0
- package/dist/checks/imageAcceptance.d.ts +67 -0
- package/dist/checks/imageAcceptance.js +967 -0
- package/dist/checks/imageAcceptance.js.map +1 -0
- package/dist/checks/packInvariants.d.ts +56 -0
- package/dist/checks/packInvariants.js +1064 -0
- package/dist/checks/packInvariants.js.map +1 -0
- package/dist/checks/softAdapters.d.ts +25 -0
- package/dist/checks/softAdapters.js +275 -0
- package/dist/checks/softAdapters.js.map +1 -0
- package/dist/checks/vlmGate.d.ts +8 -0
- package/dist/checks/vlmGate.js +200 -0
- package/dist/checks/vlmGate.js.map +1 -0
- package/dist/cli/commands/atlas.d.ts +5 -0
- package/dist/cli/commands/atlas.js +18 -0
- package/dist/cli/commands/atlas.js.map +1 -0
- package/dist/cli/commands/eval.d.ts +6 -0
- package/dist/cli/commands/eval.js +23 -0
- package/dist/cli/commands/eval.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +18 -0
- package/dist/cli/commands/generate.js +66 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +15 -0
- package/dist/cli/commands/init.js +146 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/package.d.ts +6 -0
- package/dist/cli/commands/package.js +27 -0
- package/dist/cli/commands/package.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +16 -0
- package/dist/cli/commands/plan.js +49 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/process.d.ts +14 -0
- package/dist/cli/commands/process.js +29 -0
- package/dist/cli/commands/process.js.map +1 -0
- package/dist/cli/commands/regenerate.d.ts +29 -0
- package/dist/cli/commands/regenerate.js +244 -0
- package/dist/cli/commands/regenerate.js.map +1 -0
- package/dist/cli/commands/review.d.ts +5 -0
- package/dist/cli/commands/review.js +18 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/commands/select.d.ts +6 -0
- package/dist/cli/commands/select.js +21 -0
- package/dist/cli/commands/select.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +16 -0
- package/dist/cli/commands/serve.js +100 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +17 -0
- package/dist/cli/commands/validate.js +108 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +157 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/parseArgs.d.ts +3 -0
- package/dist/cli/parseArgs.js +37 -0
- package/dist/cli/parseArgs.js.map +1 -0
- package/dist/contracts/stageArtifacts.d.ts +4031 -0
- package/dist/contracts/stageArtifacts.js +663 -0
- package/dist/contracts/stageArtifacts.js.map +1 -0
- package/dist/manifest/load.d.ts +3 -0
- package/dist/manifest/load.js +50 -0
- package/dist/manifest/load.js.map +1 -0
- package/dist/manifest/normalize-palette.d.ts +17 -0
- package/dist/manifest/normalize-palette.js +235 -0
- package/dist/manifest/normalize-palette.js.map +1 -0
- package/dist/manifest/normalize-policy.d.ts +48 -0
- package/dist/manifest/normalize-policy.js +239 -0
- package/dist/manifest/normalize-policy.js.map +1 -0
- package/dist/manifest/normalize-prompt.d.ts +14 -0
- package/dist/manifest/normalize-prompt.js +73 -0
- package/dist/manifest/normalize-prompt.js.map +1 -0
- package/dist/manifest/normalize-target.d.ts +49 -0
- package/dist/manifest/normalize-target.js +542 -0
- package/dist/manifest/normalize-target.js.map +1 -0
- package/dist/manifest/schema.d.ts +7570 -0
- package/dist/manifest/schema.js +373 -0
- package/dist/manifest/schema.js.map +1 -0
- package/dist/manifest/semantic-validation.d.ts +4 -0
- package/dist/manifest/semantic-validation.js +526 -0
- package/dist/manifest/semantic-validation.js.map +1 -0
- package/dist/manifest/types.d.ts +263 -0
- package/dist/manifest/types.js +2 -0
- package/dist/manifest/types.js.map +1 -0
- package/dist/manifest/validate.d.ts +12 -0
- package/dist/manifest/validate.js +221 -0
- package/dist/manifest/validate.js.map +1 -0
- package/dist/output/assetPackManifest.d.ts +19 -0
- package/dist/output/assetPackManifest.js +20 -0
- package/dist/output/assetPackManifest.js.map +1 -0
- package/dist/output/catalog.d.ts +60 -0
- package/dist/output/catalog.js +107 -0
- package/dist/output/catalog.js.map +1 -0
- package/dist/output/contactSheet.d.ts +13 -0
- package/dist/output/contactSheet.js +124 -0
- package/dist/output/contactSheet.js.map +1 -0
- package/dist/output/phaserManifest.d.ts +8 -0
- package/dist/output/phaserManifest.js +25 -0
- package/dist/output/phaserManifest.js.map +1 -0
- package/dist/output/pixiManifest.d.ts +8 -0
- package/dist/output/pixiManifest.js +37 -0
- package/dist/output/pixiManifest.js.map +1 -0
- package/dist/output/provenance.d.ts +121 -0
- package/dist/output/provenance.js +10 -0
- package/dist/output/provenance.js.map +1 -0
- package/dist/output/runtimeManifests.d.ts +21 -0
- package/dist/output/runtimeManifests.js +82 -0
- package/dist/output/runtimeManifests.js.map +1 -0
- package/dist/output/unityImportManifest.d.ts +10 -0
- package/dist/output/unityImportManifest.js +58 -0
- package/dist/output/unityImportManifest.js.map +1 -0
- package/dist/output/zip.d.ts +5 -0
- package/dist/output/zip.js +68 -0
- package/dist/output/zip.js.map +1 -0
- package/dist/pipeline/atlas.d.ts +33 -0
- package/dist/pipeline/atlas.js +286 -0
- package/dist/pipeline/atlas.js.map +1 -0
- package/dist/pipeline/eval.d.ts +104 -0
- package/dist/pipeline/eval.js +246 -0
- package/dist/pipeline/eval.js.map +1 -0
- package/dist/pipeline/generate.d.ts +44 -0
- package/dist/pipeline/generate.js +1088 -0
- package/dist/pipeline/generate.js.map +1 -0
- package/dist/pipeline/package.d.ts +18 -0
- package/dist/pipeline/package.js +218 -0
- package/dist/pipeline/package.js.map +1 -0
- package/dist/pipeline/process.d.ts +15 -0
- package/dist/pipeline/process.js +776 -0
- package/dist/pipeline/process.js.map +1 -0
- package/dist/pipeline/review.d.ts +10 -0
- package/dist/pipeline/review.js +341 -0
- package/dist/pipeline/review.js.map +1 -0
- package/dist/pipeline/seamHeal.d.ts +2 -0
- package/dist/pipeline/seamHeal.js +70 -0
- package/dist/pipeline/seamHeal.js.map +1 -0
- package/dist/pipeline/select.d.ts +39 -0
- package/dist/pipeline/select.js +79 -0
- package/dist/pipeline/select.js.map +1 -0
- package/dist/providers/job.d.ts +29 -0
- package/dist/providers/job.js +113 -0
- package/dist/providers/job.js.map +1 -0
- package/dist/providers/localDiffusion.d.ts +28 -0
- package/dist/providers/localDiffusion.js +235 -0
- package/dist/providers/localDiffusion.js.map +1 -0
- package/dist/providers/nano.d.ts +36 -0
- package/dist/providers/nano.js +402 -0
- package/dist/providers/nano.js.map +1 -0
- package/dist/providers/openai.d.ts +37 -0
- package/dist/providers/openai.js +378 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/policy.d.ts +9 -0
- package/dist/providers/policy.js +192 -0
- package/dist/providers/policy.js.map +1 -0
- package/dist/providers/prompt.d.ts +3 -0
- package/dist/providers/prompt.js +63 -0
- package/dist/providers/prompt.js.map +1 -0
- package/dist/providers/registry.d.ts +24 -0
- package/dist/providers/registry.js +92 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/runtime.d.ts +15 -0
- package/dist/providers/runtime.js +101 -0
- package/dist/providers/runtime.js.map +1 -0
- package/dist/providers/runtimeConfig.d.ts +20 -0
- package/dist/providers/runtimeConfig.js +146 -0
- package/dist/providers/runtimeConfig.js.map +1 -0
- package/dist/providers/types-core.d.ts +514 -0
- package/dist/providers/types-core.js +60 -0
- package/dist/providers/types-core.js.map +1 -0
- package/dist/providers/types.d.ts +4 -0
- package/dist/providers/types.js +5 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/service/generationRequest.d.ts +58 -0
- package/dist/service/generationRequest.js +203 -0
- package/dist/service/generationRequest.js.map +1 -0
- package/dist/service/providerCapabilities.d.ts +40 -0
- package/dist/service/providerCapabilities.js +114 -0
- package/dist/service/providerCapabilities.js.map +1 -0
- package/dist/service/server.d.ts +31 -0
- package/dist/service/server.js +774 -0
- package/dist/service/server.js.map +1 -0
- package/dist/shared/errors.d.ts +13 -0
- package/dist/shared/errors.js +24 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/fs.d.ts +6 -0
- package/dist/shared/fs.js +30 -0
- package/dist/shared/fs.js.map +1 -0
- package/dist/shared/image.d.ts +25 -0
- package/dist/shared/image.js +136 -0
- package/dist/shared/image.js.map +1 -0
- package/dist/shared/paths.d.ts +30 -0
- package/dist/shared/paths.js +103 -0
- package/dist/shared/paths.js.map +1 -0
- package/dist/shared/schemas.d.ts +209 -0
- package/dist/shared/schemas.js +93 -0
- package/dist/shared/schemas.js.map +1 -0
- package/dist/shared/typeGuards.d.ts +1 -0
- package/dist/shared/typeGuards.js +4 -0
- package/dist/shared/typeGuards.js.map +1 -0
- package/dist/shared/zod.d.ts +1 -0
- package/dist/shared/zod.js +14 -0
- package/dist/shared/zod.js.map +1 -0
- package/dist/showcase/format.d.ts +9 -0
- package/dist/showcase/format.js +61 -0
- package/dist/showcase/format.js.map +1 -0
- package/dist/showcase/panelRenderer.d.ts +59 -0
- package/dist/showcase/panelRenderer.js +294 -0
- package/dist/showcase/panelRenderer.js.map +1 -0
- package/dist/showcase/releaseConfig.d.ts +233 -0
- package/dist/showcase/releaseConfig.js +75 -0
- package/dist/showcase/releaseConfig.js.map +1 -0
- package/dist/showcase/releaseEvidence.d.ts +25 -0
- package/dist/showcase/releaseEvidence.js +540 -0
- package/dist/showcase/releaseEvidence.js.map +1 -0
- package/dist/showcase/releaseEvidenceSchema.d.ts +1611 -0
- package/dist/showcase/releaseEvidenceSchema.js +165 -0
- package/dist/showcase/releaseEvidenceSchema.js.map +1 -0
- package/dist/showcase/scenarioRenderer.d.ts +19 -0
- package/dist/showcase/scenarioRenderer.js +488 -0
- package/dist/showcase/scenarioRenderer.js.map +1 -0
- package/docs/ADAPTER_CONTRACT.md +141 -0
- package/docs/ENGINE_TARGETING.md +86 -0
- package/docs/MANIFEST_POLICY_COVERAGE.md +130 -0
- package/docs/RELEASE_WORKFLOW.md +117 -0
- package/docs/ROADMAP.md +411 -0
- package/docs/ROADMAP_ISSUES.md +244 -0
- package/docs/SERVICE_MODE.md +137 -0
- package/docs/manifest-schema.md +254 -0
- package/package.json +70 -0
|
@@ -0,0 +1,402 @@
|
|
|
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, withCandidateSuffix, } from "./runtime.js";
|
|
4
|
+
import { createProviderJob, nowIso, ProviderError, PROVIDER_CAPABILITIES, } from "./types.js";
|
|
5
|
+
import { resolvePathWithinRoot } from "../shared/paths.js";
|
|
6
|
+
const GEMINI_API_BASE = "https://generativelanguage.googleapis.com/v1beta/models";
|
|
7
|
+
export const DEFAULT_NANO_MODEL = "gemini-2.5-flash-image";
|
|
8
|
+
const DEFAULT_EDIT_IMAGE_MIME_TYPE = "image/png";
|
|
9
|
+
export class NanoProvider {
|
|
10
|
+
name = "nano";
|
|
11
|
+
capabilities;
|
|
12
|
+
model;
|
|
13
|
+
apiBase;
|
|
14
|
+
timeoutMs;
|
|
15
|
+
maxRetries;
|
|
16
|
+
constructor(options = {}) {
|
|
17
|
+
const defaults = PROVIDER_CAPABILITIES.nano;
|
|
18
|
+
const model = options.model ?? DEFAULT_NANO_MODEL;
|
|
19
|
+
const supportsEdits = typeof options.supportsEdits === "boolean"
|
|
20
|
+
? options.supportsEdits
|
|
21
|
+
: supportsNanoImageEdits(model);
|
|
22
|
+
this.capabilities = {
|
|
23
|
+
...defaults,
|
|
24
|
+
supportsEdits,
|
|
25
|
+
defaultConcurrency: normalizePositiveInteger(options.defaultConcurrency, defaults.defaultConcurrency),
|
|
26
|
+
minDelayMs: normalizeNonNegativeInteger(options.minDelayMs, defaults.minDelayMs),
|
|
27
|
+
};
|
|
28
|
+
this.model = model;
|
|
29
|
+
this.apiBase = options.apiBase ?? GEMINI_API_BASE;
|
|
30
|
+
this.timeoutMs = normalizePositiveInteger(options.timeoutMs, DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS);
|
|
31
|
+
this.maxRetries = toOptionalNonNegativeInteger(options.maxRetries);
|
|
32
|
+
}
|
|
33
|
+
prepareJobs(targets, ctx) {
|
|
34
|
+
return targets.map((target) => createProviderJob({
|
|
35
|
+
provider: this.name,
|
|
36
|
+
target,
|
|
37
|
+
model: target.model ?? this.model,
|
|
38
|
+
imagesDir: ctx.imagesDir,
|
|
39
|
+
defaults: {
|
|
40
|
+
maxRetries: this.maxRetries,
|
|
41
|
+
},
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
supports(feature) {
|
|
45
|
+
if (feature === "image-generation")
|
|
46
|
+
return true;
|
|
47
|
+
if (feature === "transparent-background")
|
|
48
|
+
return false;
|
|
49
|
+
if (feature === "image-edits")
|
|
50
|
+
return this.capabilities.supportsEdits;
|
|
51
|
+
if (feature === "multi-candidate")
|
|
52
|
+
return true;
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
54
|
+
if (feature === "controlnet")
|
|
55
|
+
return false;
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
normalizeError(error) {
|
|
59
|
+
if (error instanceof ProviderError && error.provider === this.name) {
|
|
60
|
+
return error;
|
|
61
|
+
}
|
|
62
|
+
if (error instanceof Error) {
|
|
63
|
+
return new ProviderError({
|
|
64
|
+
provider: this.name,
|
|
65
|
+
code: "nano_request_failed",
|
|
66
|
+
message: error.message,
|
|
67
|
+
cause: error,
|
|
68
|
+
actionable: "Check GEMINI_API_KEY, selected model, and request payload compatibility.",
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return new ProviderError({
|
|
72
|
+
provider: this.name,
|
|
73
|
+
code: "nano_request_failed",
|
|
74
|
+
message: "Nano provider failed with a non-error throwable.",
|
|
75
|
+
cause: error,
|
|
76
|
+
actionable: "Check GEMINI_API_KEY, selected model, and request payload compatibility.",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async runJob(job, ctx) {
|
|
80
|
+
const startedAt = nowIso(ctx.now);
|
|
81
|
+
const fetchImpl = ctx.fetchImpl ?? globalThis.fetch;
|
|
82
|
+
const apiKey = process.env.GEMINI_API_KEY?.trim();
|
|
83
|
+
const useEdits = this.shouldUseEdits(job);
|
|
84
|
+
if (!apiKey) {
|
|
85
|
+
throw new ProviderError({
|
|
86
|
+
provider: this.name,
|
|
87
|
+
code: "missing_api_key",
|
|
88
|
+
message: "GEMINI_API_KEY is required for Nano provider generation.",
|
|
89
|
+
actionable: "Set GEMINI_API_KEY in the environment and rerun generate.",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
93
|
+
if (!fetchImpl) {
|
|
94
|
+
throw new ProviderError({
|
|
95
|
+
provider: this.name,
|
|
96
|
+
code: "missing_fetch",
|
|
97
|
+
message: "Global fetch is unavailable for Nano provider.",
|
|
98
|
+
actionable: "Use Node.js 18+ or pass a fetch implementation in the run context.",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (useEdits && !this.capabilities.supportsEdits) {
|
|
102
|
+
throw new ProviderError({
|
|
103
|
+
provider: this.name,
|
|
104
|
+
code: "nano_edit_unsupported_model",
|
|
105
|
+
message: `Nano provider model "${job.model}" does not advertise edit-first image support.`,
|
|
106
|
+
actionable: "Use an image-edit-capable Gemini image model (for example gemini-2.5-flash-image) or switch providers for edit-first targets.",
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
const endpoint = `${this.apiBase}/${encodeURIComponent(job.model)}:generateContent` +
|
|
110
|
+
`?key=${encodeURIComponent(apiKey)}`;
|
|
111
|
+
try {
|
|
112
|
+
const requestPayload = useEdits
|
|
113
|
+
? await this.buildEditRequestPayload(job, ctx)
|
|
114
|
+
: await this.buildTextRequestPayload(job, ctx);
|
|
115
|
+
const actualPrompt = this.extractPromptText(requestPayload);
|
|
116
|
+
const candidateOutputs = [];
|
|
117
|
+
const count = Math.max(job.candidateCount, 1);
|
|
118
|
+
for (let index = 0; index < count; index += 1) {
|
|
119
|
+
const response = await this.requestWithTimeout(fetchImpl, endpoint, {
|
|
120
|
+
method: "POST",
|
|
121
|
+
headers: {
|
|
122
|
+
"Content-Type": "application/json",
|
|
123
|
+
},
|
|
124
|
+
body: JSON.stringify(requestPayload),
|
|
125
|
+
});
|
|
126
|
+
if (!response.ok) {
|
|
127
|
+
const bodyText = await response.text();
|
|
128
|
+
throw new ProviderError({
|
|
129
|
+
provider: this.name,
|
|
130
|
+
code: "nano_http_error",
|
|
131
|
+
status: response.status,
|
|
132
|
+
message: `Nano provider request failed with status ${response.status}.`,
|
|
133
|
+
actionable: "Confirm GEMINI_API_KEY access and that the chosen model supports image output.",
|
|
134
|
+
cause: bodyText,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const payload = (await response.json());
|
|
138
|
+
const inlineData = this.findInlineImage(payload);
|
|
139
|
+
if (!inlineData?.data) {
|
|
140
|
+
throw new ProviderError({
|
|
141
|
+
provider: this.name,
|
|
142
|
+
code: "nano_missing_image",
|
|
143
|
+
message: "Nano provider response did not include image data. The selected Gemini model may not support image generation for this request.",
|
|
144
|
+
actionable: "Use an image-capable Gemini model and ensure generationConfig.responseModalities includes IMAGE.",
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
const imageBytes = Buffer.from(inlineData.data, "base64");
|
|
148
|
+
if (imageBytes.byteLength === 0) {
|
|
149
|
+
throw new ProviderError({
|
|
150
|
+
provider: this.name,
|
|
151
|
+
code: "nano_empty_image",
|
|
152
|
+
message: "Nano provider returned empty image bytes.",
|
|
153
|
+
actionable: "Retry with a simpler prompt and verify the model returns inlineData image payloads.",
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
if (imageBytes.byteLength > MAX_DECODED_IMAGE_BYTES) {
|
|
157
|
+
throw new ProviderError({
|
|
158
|
+
provider: this.name,
|
|
159
|
+
code: "nano_image_too_large",
|
|
160
|
+
message: `Decoded image exceeds ${MAX_DECODED_IMAGE_BYTES} byte safety limit.`,
|
|
161
|
+
actionable: "Request smaller images or adjust model settings.",
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
const outputPath = index === 0 ? job.outPath : withCandidateSuffix(job.outPath, index + 1);
|
|
165
|
+
await mkdir(path.dirname(outputPath), { recursive: true });
|
|
166
|
+
await writeFile(outputPath, imageBytes);
|
|
167
|
+
candidateOutputs.push({
|
|
168
|
+
outputPath,
|
|
169
|
+
bytesWritten: imageBytes.byteLength,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
jobId: job.id,
|
|
174
|
+
provider: this.name,
|
|
175
|
+
model: job.model,
|
|
176
|
+
targetId: job.targetId,
|
|
177
|
+
prompt: actualPrompt,
|
|
178
|
+
outputPath: candidateOutputs[0].outputPath,
|
|
179
|
+
bytesWritten: candidateOutputs[0].bytesWritten,
|
|
180
|
+
inputHash: job.inputHash,
|
|
181
|
+
startedAt,
|
|
182
|
+
finishedAt: nowIso(ctx.now),
|
|
183
|
+
candidateOutputs,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
throw this.normalizeError(error);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
shouldUseEdits(job) {
|
|
191
|
+
if (job.target.generationMode !== "edit-first") {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
return (job.target.edit?.inputs?.length ?? 0) > 0;
|
|
195
|
+
}
|
|
196
|
+
async buildTextRequestPayload(job, ctx) {
|
|
197
|
+
const parts = [
|
|
198
|
+
{
|
|
199
|
+
text: [
|
|
200
|
+
job.prompt,
|
|
201
|
+
"",
|
|
202
|
+
"Output requirements:",
|
|
203
|
+
`- image size: ${job.size}`,
|
|
204
|
+
`- image format: ${job.outputFormat}`,
|
|
205
|
+
`- background: ${job.background}`,
|
|
206
|
+
].join("\n"),
|
|
207
|
+
},
|
|
208
|
+
];
|
|
209
|
+
const styleRefs = job.target.styleReferenceImages ?? [];
|
|
210
|
+
if (styleRefs.length > 0) {
|
|
211
|
+
parts.push({ text: "\nStyle references to mimic:\n" });
|
|
212
|
+
for (const [index, styleRef] of styleRefs.entries()) {
|
|
213
|
+
const resolvedPath = this.resolveEditInputPath(styleRef, ctx.outDir, job.targetId);
|
|
214
|
+
const imageBytes = await this.readEditInputBytes(resolvedPath, job.targetId);
|
|
215
|
+
parts.push({ text: `Style Reference Image ${index + 1}:` });
|
|
216
|
+
parts.push({
|
|
217
|
+
inlineData: {
|
|
218
|
+
mimeType: this.mimeTypeForPath(resolvedPath),
|
|
219
|
+
data: imageBytes.toString("base64"),
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
contents: [
|
|
226
|
+
{
|
|
227
|
+
role: "user",
|
|
228
|
+
parts,
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
generationConfig: {
|
|
232
|
+
responseModalities: ["TEXT", "IMAGE"],
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
async buildEditRequestPayload(job, ctx) {
|
|
237
|
+
const editInputs = job.target.edit?.inputs ?? [];
|
|
238
|
+
const baseAndReferenceInputs = editInputs.filter((input) => input.role !== "mask");
|
|
239
|
+
if (baseAndReferenceInputs.length === 0) {
|
|
240
|
+
throw new ProviderError({
|
|
241
|
+
provider: this.name,
|
|
242
|
+
code: "nano_edit_missing_base_image",
|
|
243
|
+
message: `Target "${job.targetId}" requested edit-first mode but no base/reference inputs were provided.`,
|
|
244
|
+
actionable: "Add at least one edit input with role base/reference for generationMode=edit-first.",
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
const parts = [
|
|
248
|
+
{ text: this.buildEditPrompt(job, editInputs) },
|
|
249
|
+
];
|
|
250
|
+
for (const [index, input] of editInputs.entries()) {
|
|
251
|
+
const resolvedPath = this.resolveEditInputPath(input.path, ctx.outDir, job.targetId);
|
|
252
|
+
const imageBytes = await this.readEditInputBytes(resolvedPath, job.targetId);
|
|
253
|
+
parts.push({
|
|
254
|
+
text: this.describeEditInput(index + 1, input),
|
|
255
|
+
});
|
|
256
|
+
parts.push({
|
|
257
|
+
inlineData: {
|
|
258
|
+
mimeType: this.mimeTypeForPath(resolvedPath),
|
|
259
|
+
data: imageBytes.toString("base64"),
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
contents: [
|
|
265
|
+
{
|
|
266
|
+
role: "user",
|
|
267
|
+
parts,
|
|
268
|
+
},
|
|
269
|
+
],
|
|
270
|
+
generationConfig: {
|
|
271
|
+
responseModalities: ["TEXT", "IMAGE"],
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
buildEditPrompt(job, inputs) {
|
|
276
|
+
const instruction = job.target.edit?.instruction?.trim();
|
|
277
|
+
const preserveCompositionHint = job.target.edit?.preserveComposition
|
|
278
|
+
? "Preserve composition and camera framing unless the instruction explicitly changes them."
|
|
279
|
+
: "";
|
|
280
|
+
const hasMask = inputs.some((input) => input.role === "mask");
|
|
281
|
+
const maskHint = hasMask
|
|
282
|
+
? "If a mask input is provided, treat white/opaque regions as editable and preserve dark/transparent regions."
|
|
283
|
+
: "";
|
|
284
|
+
if (!instruction) {
|
|
285
|
+
return [
|
|
286
|
+
"Use the supplied edit input images to modify the asset.",
|
|
287
|
+
preserveCompositionHint,
|
|
288
|
+
maskHint,
|
|
289
|
+
"Target style/output requirements:",
|
|
290
|
+
job.prompt,
|
|
291
|
+
]
|
|
292
|
+
.filter(Boolean)
|
|
293
|
+
.join("\n\n");
|
|
294
|
+
}
|
|
295
|
+
return [
|
|
296
|
+
instruction,
|
|
297
|
+
preserveCompositionHint,
|
|
298
|
+
maskHint,
|
|
299
|
+
"Target style/output requirements:",
|
|
300
|
+
job.prompt,
|
|
301
|
+
]
|
|
302
|
+
.filter(Boolean)
|
|
303
|
+
.join("\n\n");
|
|
304
|
+
}
|
|
305
|
+
extractPromptText(payload) {
|
|
306
|
+
for (const content of payload.contents) {
|
|
307
|
+
for (const part of content.parts) {
|
|
308
|
+
if ("text" in part && typeof part.text === "string") {
|
|
309
|
+
return part.text;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return "";
|
|
314
|
+
}
|
|
315
|
+
describeEditInput(index, input) {
|
|
316
|
+
const role = input.role ?? "reference";
|
|
317
|
+
const fidelity = input.fidelity ?? "medium";
|
|
318
|
+
if (role === "mask") {
|
|
319
|
+
return `Input ${index}: role=mask, fidelity=${fidelity}. Use this as the edit mask guide.`;
|
|
320
|
+
}
|
|
321
|
+
if (role === "base") {
|
|
322
|
+
return `Input ${index}: role=base, fidelity=${fidelity}. Preserve identity and composition unless instructed otherwise.`;
|
|
323
|
+
}
|
|
324
|
+
return `Input ${index}: role=reference, fidelity=${fidelity}. Use this for style and detail guidance.`;
|
|
325
|
+
}
|
|
326
|
+
resolveEditInputPath(inputPath, outDir, targetId) {
|
|
327
|
+
try {
|
|
328
|
+
return resolvePathWithinRoot(outDir, inputPath, `edit input path for target "${targetId}"`);
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
throw new ProviderError({
|
|
332
|
+
provider: this.name,
|
|
333
|
+
code: "nano_edit_input_unsafe_path",
|
|
334
|
+
message: `Unsafe edit input path "${inputPath}" for target "${targetId}".`,
|
|
335
|
+
actionable: `Edit input paths must stay within the output root (${path.resolve(outDir)}).`,
|
|
336
|
+
cause: error,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
async readEditInputBytes(inputPath, targetId) {
|
|
341
|
+
try {
|
|
342
|
+
return await readFile(inputPath);
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
throw new ProviderError({
|
|
346
|
+
provider: this.name,
|
|
347
|
+
code: "nano_edit_input_unreadable",
|
|
348
|
+
message: `Failed to read edit input "${inputPath}" for target "${targetId}".`,
|
|
349
|
+
actionable: "Ensure edit input files exist and paths are correct relative to --out (or absolute).",
|
|
350
|
+
cause: error,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
mimeTypeForPath(filePath) {
|
|
355
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
356
|
+
if (ext === ".jpg" || ext === ".jpeg")
|
|
357
|
+
return "image/jpeg";
|
|
358
|
+
if (ext === ".webp")
|
|
359
|
+
return "image/webp";
|
|
360
|
+
if (ext === ".gif")
|
|
361
|
+
return "image/gif";
|
|
362
|
+
if (ext === ".bmp")
|
|
363
|
+
return "image/bmp";
|
|
364
|
+
if (ext === ".svg")
|
|
365
|
+
return "image/svg+xml";
|
|
366
|
+
return DEFAULT_EDIT_IMAGE_MIME_TYPE;
|
|
367
|
+
}
|
|
368
|
+
findInlineImage(payload) {
|
|
369
|
+
for (const candidate of payload.candidates ?? []) {
|
|
370
|
+
for (const part of candidate.content?.parts ?? []) {
|
|
371
|
+
if (part.inlineData?.data) {
|
|
372
|
+
return part.inlineData;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return undefined;
|
|
377
|
+
}
|
|
378
|
+
async requestWithTimeout(fetchImpl, input, init) {
|
|
379
|
+
try {
|
|
380
|
+
return await fetchWithTimeout(fetchImpl, input, init, this.timeoutMs);
|
|
381
|
+
}
|
|
382
|
+
catch (error) {
|
|
383
|
+
if (error instanceof ProviderRequestTimeoutError) {
|
|
384
|
+
throw new ProviderError({
|
|
385
|
+
provider: this.name,
|
|
386
|
+
code: "nano_request_timeout",
|
|
387
|
+
message: `Nano provider request timed out after ${error.timeoutMs}ms.`,
|
|
388
|
+
actionable: "Increase providers.nano.timeoutMs or LOOTFORGE_NANO_TIMEOUT_MS and retry.",
|
|
389
|
+
cause: error,
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
throw error;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
export function createNanoProvider(options = {}) {
|
|
397
|
+
return new NanoProvider(options);
|
|
398
|
+
}
|
|
399
|
+
function supportsNanoImageEdits(model) {
|
|
400
|
+
return model.toLowerCase().includes("image");
|
|
401
|
+
}
|
|
402
|
+
//# sourceMappingURL=nano.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nano.js","sourceRoot":"","sources":["../../src/providers/nano.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type GenerationProvider, type PlannedTarget, type ProviderCapabilities, ProviderError, type ProviderFeature, type ProviderJob, type ProviderPrepareContext, type ProviderRunContext, type ProviderRunResult } from "./types.js";
|
|
2
|
+
export declare const DEFAULT_OPENAI_MODEL = "gpt-image-1";
|
|
3
|
+
export interface OpenAIProviderOptions {
|
|
4
|
+
model?: string;
|
|
5
|
+
endpoint?: string;
|
|
6
|
+
editsEndpoint?: string;
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
maxRetries?: number;
|
|
9
|
+
minDelayMs?: number;
|
|
10
|
+
defaultConcurrency?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class OpenAIProvider implements GenerationProvider {
|
|
13
|
+
readonly name: "openai";
|
|
14
|
+
readonly capabilities: ProviderCapabilities;
|
|
15
|
+
private readonly model;
|
|
16
|
+
private readonly endpoint;
|
|
17
|
+
private readonly editsEndpoint;
|
|
18
|
+
private readonly timeoutMs;
|
|
19
|
+
private readonly maxRetries?;
|
|
20
|
+
constructor(options?: OpenAIProviderOptions);
|
|
21
|
+
prepareJobs(targets: PlannedTarget[], ctx: ProviderPrepareContext): ProviderJob[];
|
|
22
|
+
supports(feature: ProviderFeature): boolean;
|
|
23
|
+
normalizeError(error: unknown): ProviderError;
|
|
24
|
+
runJob(job: ProviderJob, ctx: ProviderRunContext): Promise<ProviderRunResult>;
|
|
25
|
+
private shouldUseEdits;
|
|
26
|
+
private runEditRequest;
|
|
27
|
+
private resolveEditInputPath;
|
|
28
|
+
private readEditInputBytes;
|
|
29
|
+
private buildEditPrompt;
|
|
30
|
+
private mimeTypeForPath;
|
|
31
|
+
private resolveImageBytes;
|
|
32
|
+
private buildHttpError;
|
|
33
|
+
private parseErrorPayload;
|
|
34
|
+
private httpErrorActionable;
|
|
35
|
+
private requestWithTimeout;
|
|
36
|
+
}
|
|
37
|
+
export declare function createOpenAIProvider(options?: OpenAIProviderOptions): OpenAIProvider;
|