@nodaro/shared 2.21.0 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +13 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -1
- package/dist/index.d.ts +21 -1
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/safety-retry-policy.test.ts +15 -0
- package/src/index.ts +1 -0
- package/src/model-catalog.ts +1 -0
- package/src/model-constants.ts +23 -0
- package/src/node-runtime-keys.ts +8 -0
package/package.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { T2I_TO_I2I_VARIANT } from "../model-constants.js"
|
|
1
2
|
import { describe, it, expect } from "vitest"
|
|
2
3
|
import { safetyRetryPolicy } from "../safety-retry-policy.js"
|
|
3
4
|
import { MODEL_CATALOG, getModel } from "../model-catalog.js"
|
|
@@ -45,3 +46,17 @@ describe("safetyRetryPolicy", () => {
|
|
|
45
46
|
}
|
|
46
47
|
})
|
|
47
48
|
})
|
|
49
|
+
|
|
50
|
+
describe("i2i variants inherit their base model's safety policy", () => {
|
|
51
|
+
it("resolves the referenced-request id (gpt-image-2-i2i) to the same policy as gpt-image-2", () => {
|
|
52
|
+
expect(safetyRetryPolicy("gpt-image-2-i2i")).toEqual({ maxAttempts: 2, fallback: "nano-banana-pro" })
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it("every T2I_TO_I2I_VARIANT pair declares the same safetyFilter on both sides", () => {
|
|
56
|
+
for (const [t2i, i2i] of Object.entries(T2I_TO_I2I_VARIANT)) {
|
|
57
|
+
const base = MODEL_CATALOG[t2i]?.safetyFilter ?? null
|
|
58
|
+
const twin = MODEL_CATALOG[i2i]?.safetyFilter ?? null
|
|
59
|
+
expect({ pair: `${t2i} -> ${i2i}`, twin }).toEqual({ pair: `${t2i} -> ${i2i}`, twin: base })
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
})
|
package/src/index.ts
CHANGED
package/src/model-catalog.ts
CHANGED
|
@@ -579,6 +579,7 @@ const IMAGE_MODELS: Record<string, ModelCatalogEntry> = {
|
|
|
579
579
|
label: "GPT Image 2 (I2I)",
|
|
580
580
|
series: "GPT Image",
|
|
581
581
|
description: "Image-to-image with GPT Image 2.",
|
|
582
|
+
safetyFilter: { stochastic: true, fallback: "nano-banana-pro" },
|
|
582
583
|
useCases: ["edit", "high-res"],
|
|
583
584
|
features: ["reference-image"],
|
|
584
585
|
aspectRatios: GPT_IMAGE_2_RATIOS,
|
package/src/model-constants.ts
CHANGED
|
@@ -2105,6 +2105,29 @@ export function videoProviderRequiresImage(provider: string | undefined): boolea
|
|
|
2105
2105
|
return !!provider && VIDEO_PROVIDERS_REQUIRING_IMAGE.has(provider)
|
|
2106
2106
|
}
|
|
2107
2107
|
|
|
2108
|
+
/**
|
|
2109
|
+
* True when the provider's image-to-video path FOLDS a lone closing frame into
|
|
2110
|
+
* its reference images — i.e. an end frame with no start frame is a reference
|
|
2111
|
+
* the model actually receives, not a half-formed frame pair.
|
|
2112
|
+
*
|
|
2113
|
+
* The Seedance 2.x, MiniMax Hailuo 3 and Wan 3 families all assemble their KIE
|
|
2114
|
+
* input through the shared `resolveSeedance2Inputs` (`@nodaro/prompts`), whose
|
|
2115
|
+
* reference mode takes a lone last frame as the sole reference image plus a
|
|
2116
|
+
* closing-frame prompt hint. NOTHING else does: VEO ships `[imageUrl,
|
|
2117
|
+
* endFrameUrl]` verbatim (a lone end frame would reach KIE as `[null, url]`),
|
|
2118
|
+
* the Gemini Omni branch drops the frame when there is no start frame, and the
|
|
2119
|
+
* generic KIE path sends `end_frame` with no image param at all. So the
|
|
2120
|
+
* exemption is keyed to the FOLD, not to "carries image references" — the
|
|
2121
|
+
* catalog has no capability for it, and these three family predicates are the
|
|
2122
|
+
* same membership the provider layer itself branches on (the backend's
|
|
2123
|
+
* `kie/video.ts::applySeedance2Params` / `applyMinimaxH3Params` / `runWan3`).
|
|
2124
|
+
* A ref-capable provider that grows the fold gets the exemption by joining a
|
|
2125
|
+
* family here; one that does not keeps the honest `image_required` 400.
|
|
2126
|
+
*/
|
|
2127
|
+
export function videoProviderFoldsLoneEndFrame(provider: string): boolean {
|
|
2128
|
+
return isSeedance2Provider(provider) || isMinimaxH3Provider(provider) || isWan3Provider(provider)
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2108
2131
|
/**
|
|
2109
2132
|
* Video models where enabling audio/sound incurs an additional cost.
|
|
2110
2133
|
* The audio addon is expressed as a separate composite identifier suffix.
|
package/src/node-runtime-keys.ts
CHANGED
|
@@ -21,6 +21,13 @@ export const EXECUTION_DATA_KEYS: ReadonlySet<string> = new Set([
|
|
|
21
21
|
// lifecycle as errorMessage: a RESULT the user expects to survive reload,
|
|
22
22
|
// never user-edited config.
|
|
23
23
|
"errorHint",
|
|
24
|
+
// A job policy registered by the deployment held this node's result for a
|
|
25
|
+
// human reviewer (`jobs.status = "pending_review"`). Pure run state, like
|
|
26
|
+
// executionStatus: the node is still "running" and the flag disappears the
|
|
27
|
+
// moment the review resolves — so it is ALSO in TRANSIENT_RUNTIME_KEYS
|
|
28
|
+
// below. Without the transient half, a flip into review marks a passive tab
|
|
29
|
+
// dirty and a preset captures "awaiting review".
|
|
30
|
+
"jobAwaitingReview",
|
|
24
31
|
"isStreaming",
|
|
25
32
|
"generatedImageUrl",
|
|
26
33
|
"generatedVideoUrl",
|
|
@@ -85,6 +92,7 @@ export const TRANSIENT_RUNTIME_KEYS: ReadonlySet<string> = new Set([
|
|
|
85
92
|
"executionStatus",
|
|
86
93
|
"currentJobId",
|
|
87
94
|
"currentJobProgress",
|
|
95
|
+
"jobAwaitingReview",
|
|
88
96
|
"isStreaming",
|
|
89
97
|
"subWorkflowProgress",
|
|
90
98
|
"__listTotal",
|