@melite/image-upscale-tools 0.1.4-alpha → 0.1.5-pre-alpha

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/README.md ADDED
@@ -0,0 +1,36 @@
1
+ ---
2
+ description: Hidden upscale card running SeedVR2 over an input image, with consumed fragment arms for resize, pixel-upscale, RTX VSR, and concat.
3
+ kind: package-library
4
+ ---
5
+
6
+ # @melite/image-upscale-tools
7
+
8
+ `@melite/image-upscale-tools` is the upscale card (`id: 'upscale-tools'`, stage row `generate`): SeedVR2-3B fp16 diffusion upscaling on a required `input_image`. It boards the `seedvr2_ema` family's declared `upscale` action and requires the `ComfyUI-SeedVR2_VideoUpscaler`, `ComfyUI-KJNodes`, and `Nvidia_RTX_Nodes_ComfyUI` packs. The package's single source module is the root face the cardPackages SSOT composes (`@melite/image-upscale-tools`); there is no tool or client face. The card is hidden from the sidebar (image order 16) and additionally serves the consumed tool fragments — `resize`, `pixel-upscale`, `rtx-vsr`, `concat`, and `input` — each with its own arm.
9
+
10
+ ## Contract
11
+
12
+ - `.` — the card definition and registration (the root module carries `inject = ['comfyui']`). Schema: `input_image` (required, path); ride keys with hint-only ranges and NO defaults — `resolution` (256..2160), `max_resolution` (512..4096), `batch_size` (1..16), where the model row owns the values (1080/4096/1); and `seed` (default −1). There are NO `dit_model`/`vae_model` knobs — weights ride the lane's `unet`/`vae` inputs. The `rtx-vsr` arm is compose-truth only: it emits the graph, while execution requires the NVIDIA SDK stack. `admits: ['filename_prefix']`; `spells: ['input_image']` — a `$spell` value (the `$image` form) names a wired stage input that rides verbatim. Estate-file contract: a file param must exist at compose (absolute mount path); a linked upstream output arrives as an asset URL (`/v1/assets/runs/...`) and the submit-time uploader stages it, refusing loudly on a dead URL.
13
+ - `./package.json` — the manifest.
14
+
15
+ ## Model Experience
16
+
17
+ ### Request context and condition
18
+
19
+ A run conditions the upscale graph only when the card composes; no agent tool face ships.
20
+
21
+ #### What the model sees
22
+
23
+ SeedVR2 receives the staged image plus the gated resolution, batch, and seed values as graph inputs.
24
+
25
+ #### Token effect
26
+
27
+ zero-direct — the package contributes no prompt or schema to any language-model context.
28
+
29
+ #### KV Cache effect
30
+
31
+ independent — nothing here appends to or reshapes a session cache.
32
+
33
+ ## Known Limitations and Deferred Work
34
+
35
+ - **rtx-vsr needs the NVIDIA SDK** — the arm composes anywhere but executes only where the RTX stack exists.
36
+ - **No dit/vae knobs** — weight selection rides the model row; a card-level override is not declared.
package/lib/card.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Context } from '@deepseek-ai/cordis';
1
+ import type { Context } from '@melite/comfyui-card-kit/card-definition';
2
2
  import type { ModelFacts } from '@melite/comfyui-card-kit/facts';
3
3
  import type { GraphBuilder } from '@melite/comfyui-card-kit/graph';
4
4
  export declare const ACTION_BINDINGS: Record<string, (p: Record<string, unknown>, model: ModelFacts, g: GraphBuilder, runId: string) => void>;
package/lib/card.js CHANGED
@@ -2,10 +2,11 @@ import { existsSync, statSync } from 'node:fs';
2
2
  import { resolve } from 'node:path';
3
3
  import z from '@deepseek-ai/schemastery';
4
4
  import { declaredAction, instantiateAction } from '@melite/comfyui-card-kit';
5
- import { resolveLinkedInput } from '@melite/comfyui-cordis/linked';
5
+ import { resolveLinkedInput, runMediaPrefix } from '@melite/comfyui-card-kit/linked';
6
6
  import { bag } from '@melite/contracts/extraKeys';
7
7
  import { DECL as seedvr2Decl } from '@melite/models-seedvr2_ema';
8
- import { gatedResolve } from '@melite/comfyui-cordis';
8
+ import { inputImageExtra, seedExtra } from '@melite/comfyui-card-kit/fields';
9
+ import { callableSchema, gatedResolve } from '@melite/comfyui-card-kit/admission';
9
10
  // THE FAMILY BINDINGS (the atom vocabulary, stroke 3): the declared
10
11
  // action composes; the legacy kit lane stays the declared fallback
11
12
  // (byte-oracle + unbound-row safety). Keyed by OWNING FAMILY
@@ -17,7 +18,7 @@ export const ACTION_BINDINGS = {
17
18
  },
18
19
  };
19
20
  const schema = z.object({
20
- input_image: z.string().role('path').description("Input image").extra('extra', bag({ order: 0, group: "input", width: 1, tooltip: "The frame to restore. Absolute mount path.", required: true, wtype: 'image', })),
21
+ input_image: z.string().role('path').description("Input image").extra('extra', bag(inputImageExtra({ tooltip: 'The frame to restore. Absolute mount path.' }))),
21
22
  // ride-the-model keys (ABSENT: no schema default — the
22
23
  // compose-door cascade overlays model defaults, then explicit
23
24
  // params): resolution/max_resolution/batch_size ride the seedvr2_ema
@@ -30,18 +31,13 @@ const schema = z.object({
30
31
  resolution: z.number().description("Target short side").min(256).max(2160).step(2).extra('extra', bag({ order: 0, group: "target", columns: 2, width: 1, tooltip: "1080 = FHD rail. SeedVR2 redraws detail at this size.", wtype: 'number' })),
31
32
  max_resolution: z.number().description("Max resolution").min(512).max(4096).step(64).extra('extra', bag({ order: 1, group: "target", columns: 2, width: 1, tooltip: "The hard ceiling — inputs already past it pass through.", wtype: 'number' })),
32
33
  batch_size: z.number().description("Batch size").min(1).max(16).step(1).extra('extra', bag({ order: 0, group: "run", width: 1, tooltip: "Video frames ride batches; images are batch 1.", wtype: 'number' })),
33
- seed: z.number().description("Seed").step(1).default(-1).extra('extra', bag({ order: 1, group: "run", width: 1 })),
34
+ seed: z.number().description("Seed").step(1).default(-1).extra('extra', bag(seedExtra({ order: 1, group: 'run', width: 1 }))),
34
35
  // NO dit_model/vae_model (card declares no such knobs — the
35
36
  // weights ride lane_inputs.unet/vae; old drafts naming them still
36
37
  // parse via the door's non-strict overlay but compose never reads
37
38
  // them).
38
39
  });
39
- /** The schema's callable face — ONE cast serving both seams (the
40
- * registration's schema carrier and the compose strict resolve's
41
- * judge): schemastery schemas are callable (Schema.resolve) but
42
- * carry a typed data parameter, while both card-seam consumers
43
- * take unknown. */
44
- const schemaFn = schema;
40
+ const schemaFn = callableSchema(schema);
45
41
  export const inject = ['comfyui'];
46
42
 
47
43
  // identity ring; the card owns its label/description/genre/icon).
@@ -58,6 +54,17 @@ export const identity = {
58
54
  'rtx-vsr is NVIDIA-SDK-only: the arm is compose-truth, execution needs the RTX stack',
59
55
  ],
60
56
  };
57
+ /** The estate's own tree for the linked-input rewrite — the
58
+ * compose call's manifest, first entry (the queue's own root).
59
+ * A root-relative ref with no manifest refuses LOUD (there is no
60
+ * cwd guess to fall back on — J12 killed it). */
61
+ function estateRoot(estate) {
62
+ const first = estate?.stateRoots[0];
63
+ if (first === undefined || first === '') {
64
+ throw new Error("linked input needs the estate state root — compose with the queue seat's roots manifest (a root-relative asset URL cannot be resolved from the cwd; it never guesses)");
65
+ }
66
+ return first;
67
+ }
61
68
  export function apply(ctx) {
62
69
  ctx.effect(() => ctx.comfyui.registerCard({
63
70
  id: 'upscale-tools',
@@ -82,7 +89,7 @@ export function apply(ctx) {
82
89
  admits: ['filename_prefix'],
83
90
  spells: ['input_image'],
84
91
  schema: schemaFn,
85
- compose(p, model, g, runId) {
92
+ compose(p, model, g, runId, estate) {
86
93
  // THE SCHEMA GATE (the audio-trio admission precedent — the
87
94
  // card's own declaration validates the last hop into the
88
95
  // engine): schemastery walk enforces declared types + bounds
@@ -109,7 +116,12 @@ export function apply(ctx) {
109
116
  // uploader fetches them); root-relative URLs rewrite to the
110
117
  // runs-root mount path (same estate, verified NOW).
111
118
  // Compile-time, never inference-time.
112
- const ref = resolveLinkedInput(String(doc.input_image).trim());
119
+ // J12: a root-relative asset URL resolves against the estate's
120
+ // config-named trees (the compose call's manifest — first tree
121
+ // is the queue's own root); every other spelling rides without
122
+ // a seat read. The retired env seam's cwd guess never returns.
123
+ const raw = String(doc.input_image).trim();
124
+ const ref = runMediaPrefix(raw) === '' ? raw : resolveLinkedInput(raw, estateRoot(estate));
113
125
  doc.input_image = ref;
114
126
  const lower = ref.toLowerCase();
115
127
  if (!ref.startsWith('$') && !lower.startsWith('http://') && !lower.startsWith('https://')) {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
- "version": "0.1.4-alpha",
2
+ "version": "0.1.5-pre-alpha",
3
3
  "license": "SSPL-1.0",
4
4
  "type": "module",
5
- "description": "the upscale-tools card (the image lane) — one card one package: card.ts host face + ui/ studio + agents/ context",
5
+ "description": "the upscale-tools card (the image lane) — one card one package: card.ts host face + agents/ context (no tool face, no ui/ — the view is constructed by @melite/card-base from the emission)",
6
6
  "exports": {
7
7
  ".": {
8
8
  "types": "./lib/card.d.ts",
@@ -12,10 +12,9 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@deepseek-ai/schemastery": "^3.18.4",
15
- "@melite/comfyui-card-kit": "0.1.4-alpha",
16
- "@melite/comfyui-cordis": "0.1.4-alpha",
17
- "@melite/contracts": "0.1.4-alpha",
18
- "@melite/models-seedvr2_ema": "0.1.4-alpha"
15
+ "@melite/comfyui-card-kit": "0.1.5-pre-alpha",
16
+ "@melite/contracts": "0.1.5-pre-alpha",
17
+ "@melite/models-seedvr2_ema": "0.1.5-pre-alpha"
19
18
  },
20
19
  "devDependencies": {
21
20
  "@types/node": "^22.20.0",