@nodetool-ai/project-services 0.8.9-beta.2 → 0.8.9-beta.5
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/.nodetool-build-stamp +1 -1
- package/dist/asset-autosave.d.ts +80 -0
- package/dist/asset-autosave.d.ts.map +1 -0
- package/dist/asset-autosave.js +456 -0
- package/dist/asset-autosave.js.map +1 -0
- package/dist/example-catalog.d.ts +11 -0
- package/dist/example-catalog.d.ts.map +1 -0
- package/dist/example-catalog.js +154 -0
- package/dist/example-catalog.js.map +1 -0
- package/dist/example-thumbnail.d.ts +21 -0
- package/dist/example-thumbnail.d.ts.map +1 -0
- package/dist/example-thumbnail.js +50 -0
- package/dist/example-thumbnail.js.map +1 -0
- package/dist/example-workflows.d.ts +22 -0
- package/dist/example-workflows.d.ts.map +1 -0
- package/dist/example-workflows.js +141 -0
- package/dist/example-workflows.js.map +1 -0
- package/dist/examples/nodetool-base/50 Ad Variants Overnight.json +270 -0
- package/dist/examples/nodetool-base/A Campaign Concept from a Brief.json +135 -0
- package/dist/examples/nodetool-base/A Gradient Card as PNG.json +128 -0
- package/dist/examples/nodetool-base/A Poster in Portrait.json +129 -0
- package/dist/examples/nodetool-base/A Repeating Texture Tile.json +129 -0
- package/dist/examples/nodetool-base/A Run Button for Any Job.json +152 -0
- package/dist/examples/nodetool-base/A Webhook That Answers.json +170 -0
- package/dist/examples/nodetool-base/AI Spokesperson.json +328 -0
- package/dist/examples/nodetool-base/Action Items from a Meeting Recording.json +198 -0
- package/dist/examples/nodetool-base/Ad Copy in Three Registers.json +135 -0
- package/dist/examples/nodetool-base/Ad Loop from a Product Photo.json +277 -0
- package/dist/examples/nodetool-base/Add Reverb to a Voice.json +125 -0
- package/dist/examples/nodetool-base/Album Art from a Mood.json +129 -0
- package/dist/examples/nodetool-base/Assemble a UGC Product Video.json +158 -0
- package/dist/examples/nodetool-base/Audio To Image.json +184 -0
- package/dist/examples/nodetool-base/B-Roll Reel from a Brief.json +339 -0
- package/dist/examples/nodetool-base/Batch a List.json +171 -0
- package/dist/examples/nodetool-base/Black and White, Hard.json +147 -0
- package/dist/examples/nodetool-base/Blog Post to Social Thread.json +135 -0
- package/dist/examples/nodetool-base/Blur a Channel.json +205 -0
- package/dist/examples/nodetool-base/Blur an Image.json +179 -0
- package/dist/examples/nodetool-base/Boost Saturation.json +178 -0
- package/dist/examples/nodetool-base/Brand Asset Generator.json +585 -0
- package/dist/examples/nodetool-base/Brand a UGC Product Video.json +402 -0
- package/dist/examples/nodetool-base/Bring a Still to Life.json +250 -0
- package/dist/examples/nodetool-base/Bullet Points to Press Release.json +135 -0
- package/dist/examples/nodetool-base/Camera Move Contact Sheet.json +210 -0
- package/dist/examples/nodetool-base/Camera Move.json +257 -0
- package/dist/examples/nodetool-base/Chapter Markers for a Long Recording.json +198 -0
- package/dist/examples/nodetool-base/Character in Any Scene.json +276 -0
- package/dist/examples/nodetool-base/Chat With Your Documents.json +569 -0
- package/dist/examples/nodetool-base/Chunk a Transcript for Indexing.json +202 -0
- package/dist/examples/nodetool-base/Circles and Lines.json +126 -0
- package/dist/examples/nodetool-base/Clean Up a Rough Voice Recording.json +208 -0
- package/dist/examples/nodetool-base/Clip on Kie.json +173 -0
- package/dist/examples/nodetool-base/Cold Outreach Co-Pilot.json +423 -0
- package/dist/examples/nodetool-base/Color Boost Video.json +250 -0
- package/dist/examples/nodetool-base/Compose Directed Campaign Formats.json +764 -0
- package/dist/examples/nodetool-base/Concept Art Iteration Board.json +439 -0
- package/dist/examples/nodetool-base/Concept Art, Then a Moving Version.json +173 -0
- package/dist/examples/nodetool-base/Conditional Logic Engine.json +535 -0
- package/dist/examples/nodetool-base/Consistent Cast Storyboard.json +330 -0
- package/dist/examples/nodetool-base/Count a List.json +168 -0
- package/dist/examples/nodetool-base/Count to Three with a Loop.json +157 -0
- package/dist/examples/nodetool-base/Crop an Image.json +181 -0
- package/dist/examples/nodetool-base/Crop then Fit.json +208 -0
- package/dist/examples/nodetool-base/Crush It to 8 Bits.json +123 -0
- package/dist/examples/nodetool-base/Cut Out the Subject.json +184 -0
- package/dist/examples/nodetool-base/Cut a Landscape Clip for Vertical.json +123 -0
- package/dist/examples/nodetool-base/Cut a Product Out of Its Background.json +238 -0
- package/dist/examples/nodetool-base/Data Generator.json +216 -0
- package/dist/examples/nodetool-base/Denoise Footage.json +178 -0
- package/dist/examples/nodetool-base/Direct a Short Film.json +305 -0
- package/dist/examples/nodetool-base/Directed Film to Timeline.json +385 -0
- package/dist/examples/nodetool-base/Does This Text Mention the Deadline.json +130 -0
- package/dist/examples/nodetool-base/Draft Answers for an FAQ.json +135 -0
- package/dist/examples/nodetool-base/Draw a Badge in SVG.json +126 -0
- package/dist/examples/nodetool-base/Drop Duplicates.json +170 -0
- package/dist/examples/nodetool-base/Drop the First Few.json +148 -0
- package/dist/examples/nodetool-base/Dub a Video into 5 Languages.json +285 -0
- package/dist/examples/nodetool-base/Dungeon and Ruins Starter Pack.json +786 -0
- package/dist/examples/nodetool-base/Edit a Still with Words.json +284 -0
- package/dist/examples/nodetool-base/Editorial Still from a Line.json +197 -0
- package/dist/examples/nodetool-base/Effects Gallery.json +189 -0
- package/dist/examples/nodetool-base/Emboss a Still.json +120 -0
- package/dist/examples/nodetool-base/Every Combination.json +225 -0
- package/dist/examples/nodetool-base/Every Hour, On the Hour.json +162 -0
- package/dist/examples/nodetool-base/Executive Summary of a Long Document.json +135 -0
- package/dist/examples/nodetool-base/Explainer Clip from a Paragraph.json +244 -0
- package/dist/examples/nodetool-base/Extract the Claims Worth Checking.json +135 -0
- package/dist/examples/nodetool-base/Fade Audio In and Out.json +203 -0
- package/dist/examples/nodetool-base/Fade Audio Out.json +202 -0
- package/dist/examples/nodetool-base/Fill a Template.json +149 -0
- package/dist/examples/nodetool-base/Find Every Number in a Sentence.json +127 -0
- package/dist/examples/nodetool-base/Find and Replace.json +224 -0
- package/dist/examples/nodetool-base/Find the Edges.json +123 -0
- package/dist/examples/nodetool-base/Fit an Image.json +179 -0
- package/dist/examples/nodetool-base/Five Headlines for a Landing Page.json +135 -0
- package/dist/examples/nodetool-base/Flashcard Generator.json +297 -0
- package/dist/examples/nodetool-base/Gate Out the Room Noise.json +124 -0
- package/dist/examples/nodetool-base/Generate a Native-Audio UGC Testimonial.json +276 -0
- package/dist/examples/nodetool-base/Generate a Silent Bed.json +126 -0
- package/dist/examples/nodetool-base/Generate then Upscale a Poster.json +164 -0
- package/dist/examples/nodetool-base/Hacker News Agent.json +183 -0
- package/dist/examples/nodetool-base/Hook & Thumbnail Factory.json +498 -0
- package/dist/examples/nodetool-base/How Long Is This Transcript.json +185 -0
- package/dist/examples/nodetool-base/Image Enhance.json +272 -0
- package/dist/examples/nodetool-base/Image To Audio Story.json +180 -0
- package/dist/examples/nodetool-base/Image to Video Animation.json +346 -0
- package/dist/examples/nodetool-base/Inspect a Clip's Audio.json +187 -0
- package/dist/examples/nodetool-base/Inspect a Clip.json +163 -0
- package/dist/examples/nodetool-base/Invert a Still.json +120 -0
- package/dist/examples/nodetool-base/Keep Only the Long Lines.json +220 -0
- package/dist/examples/nodetool-base/Keep Only the Matches.json +148 -0
- package/dist/examples/nodetool-base/Key Out a Green Screen.json +124 -0
- package/dist/examples/nodetool-base/Last One Wins.json +144 -0
- package/dist/examples/nodetool-base/Lens and Look.json +327 -0
- package/dist/examples/nodetool-base/Lip-sync a Clip to a Voice Track.json +313 -0
- package/dist/examples/nodetool-base/Localise a Product Listing.json +135 -0
- package/dist/examples/nodetool-base/Localise a Script and Revoice It.json +242 -0
- package/dist/examples/nodetool-base/Localized Explainer.json +430 -0
- package/dist/examples/nodetool-base/Low-poly Adventure Starter Pack.json +786 -0
- package/dist/examples/nodetool-base/Low-poly Seaside Starter Pack.json +786 -0
- package/dist/examples/nodetool-base/Master a Voice Track.json +180 -0
- package/dist/examples/nodetool-base/Meeting Transcript Summarizer.json +524 -0
- package/dist/examples/nodetool-base/Model Arena.json +550 -0
- package/dist/examples/nodetool-base/Moodboard Frame from a Theme.json +129 -0
- package/dist/examples/nodetool-base/Movie Posters.json +660 -0
- package/dist/examples/nodetool-base/Movie Trailer Generator.json +418 -0
- package/dist/examples/nodetool-base/Music Video Visualizer.json +720 -0
- package/dist/examples/nodetool-base/Name a File from Its Narration.json +231 -0
- package/dist/examples/nodetool-base/Narrate a Script.json +169 -0
- package/dist/examples/nodetool-base/Narration with a Music Bed.json +360 -0
- package/dist/examples/nodetool-base/Normalize a Clip's Audio.json +201 -0
- package/dist/examples/nodetool-base/One Tagline, Six Markets.json +135 -0
- package/dist/examples/nodetool-base/Pad a Canvas.json +188 -0
- package/dist/examples/nodetool-base/Per-SKU Ad Factory.json +511 -0
- package/dist/examples/nodetool-base/Photo Enhancement Suite.json +417 -0
- package/dist/examples/nodetool-base/Picture in Picture.json +231 -0
- package/dist/examples/nodetool-base/Pitch a Voice Up.json +122 -0
- package/dist/examples/nodetool-base/Pixelate a Still.json +122 -0
- package/dist/examples/nodetool-base/Platformer Playground Starter Pack.json +786 -0
- package/dist/examples/nodetool-base/Podcast Episode to Show Notes.json +198 -0
- package/dist/examples/nodetool-base/Podcast Repurposing Studio.json +745 -0
- package/dist/examples/nodetool-base/Pokemon Maker.json +282 -0
- package/dist/examples/nodetool-base/Poster on Kie.json +172 -0
- package/dist/examples/nodetool-base/Posterize to Four Bits.json +122 -0
- package/dist/examples/nodetool-base/Private Assistant.json +236 -0
- package/dist/examples/nodetool-base/Product Mockup Generator.json +608 -0
- package/dist/examples/nodetool-base/Product Spot from Text.json +330 -0
- package/dist/examples/nodetool-base/Product URL to CGI Commercial.json +289 -0
- package/dist/examples/nodetool-base/Product URL to UGC Ad.json +298 -0
- package/dist/examples/nodetool-base/Product Video Generator.json +344 -0
- package/dist/examples/nodetool-base/Prompt Template.json +221 -0
- package/dist/examples/nodetool-base/Propose Three Campaign Directions.json +614 -0
- package/dist/examples/nodetool-base/Pull a Field out of JSON Text.json +128 -0
- package/dist/examples/nodetool-base/Pull a Still from a Clip.json +179 -0
- package/dist/examples/nodetool-base/Pull the Quotable Lines Out of an Interview.json +198 -0
- package/dist/examples/nodetool-base/Put a Product on a Studio Backdrop.json +252 -0
- package/dist/examples/nodetool-base/Put a Voice Over a Music Bed.json +358 -0
- package/dist/examples/nodetool-base/README_EXAMPLES.md +59 -0
- package/dist/examples/nodetool-base/Re-delimit a List.json +199 -0
- package/dist/examples/nodetool-base/Read a Clip's Frame Rate.json +120 -0
- package/dist/examples/nodetool-base/Redact Email Addresses.json +129 -0
- package/dist/examples/nodetool-base/Redact and Tidy a Log Line.json +266 -0
- package/dist/examples/nodetool-base/Relight a Product for a Seasonal Campaign.json +131 -0
- package/dist/examples/nodetool-base/Render a Directed Campaign Hero.json +338 -0
- package/dist/examples/nodetool-base/Reopen a Directed Campaign.json +1748 -0
- package/dist/examples/nodetool-base/Research Agent.json +231 -0
- package/dist/examples/nodetool-base/Research a Brand from Its Website.json +445 -0
- package/dist/examples/nodetool-base/Restyle a Photo as an Illustration.json +136 -0
- package/dist/examples/nodetool-base/Reverse Audio.json +201 -0
- package/dist/examples/nodetool-base/Reverse a Clip.json +176 -0
- package/dist/examples/nodetool-base/Revise an Accepted Campaign Hero.json +486 -0
- package/dist/examples/nodetool-base/Rewrite This So a Customer Understands It.json +135 -0
- package/dist/examples/nodetool-base/Rotate Footage.json +178 -0
- package/dist/examples/nodetool-base/SEO Content Engine.json +708 -0
- package/dist/examples/nodetool-base/SEO Title and Meta Description.json +135 -0
- package/dist/examples/nodetool-base/Sci-fi Game Model Starter Pack.json +693 -0
- package/dist/examples/nodetool-base/Sci-fi Outpost Expansion.json +601 -0
- package/dist/examples/nodetool-base/Score a Clip from Its Own Mood.json +229 -0
- package/dist/examples/nodetool-base/Score a Silent Clip.json +382 -0
- package/dist/examples/nodetool-base/Script to Narrated Clip.json +224 -0
- package/dist/examples/nodetool-base/Script to Screen.json +940 -0
- package/dist/examples/nodetool-base/Sharpen Footage.json +179 -0
- package/dist/examples/nodetool-base/Shot List from a Synopsis.json +136 -0
- package/dist/examples/nodetool-base/Single Shot from a Line.json +199 -0
- package/dist/examples/nodetool-base/Slice Text.json +159 -0
- package/dist/examples/nodetool-base/Slow a Clip Without Dropping Pitch.json +122 -0
- package/dist/examples/nodetool-base/Soften a Plate.json +178 -0
- package/dist/examples/nodetool-base/Solarize a Still.json +122 -0
- package/dist/examples/nodetool-base/Speak a Line, Then Trim the Silence.json +157 -0
- package/dist/examples/nodetool-base/Spin a Packshot into a Turntable Clip.json +137 -0
- package/dist/examples/nodetool-base/Split a Channel.json +178 -0
- package/dist/examples/nodetool-base/Split a Log into Records.json +128 -0
- package/dist/examples/nodetool-base/Stabilize Handheld.json +179 -0
- package/dist/examples/nodetool-base/Still on Replicate.json +172 -0
- package/dist/examples/nodetool-base/Subject Lines Worth Testing.json +135 -0
- package/dist/examples/nodetool-base/Subtitle Lines from a Script.json +170 -0
- package/dist/examples/nodetool-base/Subtitle Text from a Recording.json +198 -0
- package/dist/examples/nodetool-base/Summarise a Recorded Call.json +198 -0
- package/dist/examples/nodetool-base/Swirl and Echo.json +154 -0
- package/dist/examples/nodetool-base/Take While the Numbers Are Small.json +148 -0
- package/dist/examples/nodetool-base/Take a Product Shot to Print Resolution.json +209 -0
- package/dist/examples/nodetool-base/Take the First Few Seconds of a Bed.json +127 -0
- package/dist/examples/nodetool-base/Take the First Few.json +170 -0
- package/dist/examples/nodetool-base/Talking Avatar from a Photo and a Script.json +252 -0
- package/dist/examples/nodetool-base/Telephone Voice.json +174 -0
- package/dist/examples/nodetool-base/Themes Across Customer Feedback.json +135 -0
- package/dist/examples/nodetool-base/Three Ratios.json +315 -0
- package/dist/examples/nodetool-base/Tidy Up Messy Text.json +199 -0
- package/dist/examples/nodetool-base/Top-down Native Asset Pack.json +955 -0
- package/dist/examples/nodetool-base/Trailer Beats from a Premise.json +136 -0
- package/dist/examples/nodetool-base/Train a Character.json +243 -0
- package/dist/examples/nodetool-base/Transcribe Audio.json +138 -0
- package/dist/examples/nodetool-base/Transcribe a Clip.json +198 -0
- package/dist/examples/nodetool-base/Translate Marketing Copy to German.json +135 -0
- package/dist/examples/nodetool-base/Translate a Script for Dubbing.json +224 -0
- package/dist/examples/nodetool-base/Trim Audio to a Range.json +203 -0
- package/dist/examples/nodetool-base/Trim a Blurb to Length.json +128 -0
- package/dist/examples/nodetool-base/Trim a Clip.json +180 -0
- package/dist/examples/nodetool-base/Turn Research Notes into a Comparison Table.json +136 -0
- package/dist/examples/nodetool-base/Turn Specs into Product Copy.json +135 -0
- package/dist/examples/nodetool-base/Turn a Changelog into Release Notes.json +135 -0
- package/dist/examples/nodetool-base/Turn a Logo into Print-Ready Vector.json +126 -0
- package/dist/examples/nodetool-base/Turn a Support Thread into a Bug Report.json +135 -0
- package/dist/examples/nodetool-base/Turn a Talk into a Blog Post.json +198 -0
- package/dist/examples/nodetool-base/Upscale a Still.json +186 -0
- package/dist/examples/nodetool-base/Vectorize a Generated Logo.json +162 -0
- package/dist/examples/nodetool-base/Video Restyle Studio.json +281 -0
- package/dist/examples/nodetool-base/Vignette a Portrait.json +124 -0
- package/dist/examples/nodetool-base/Voice a Script in Two Voices.json +217 -0
- package/dist/examples/nodetool-base/Warm Up a Cold Clip.json +124 -0
- package/dist/examples/nodetool-base/Watch a Folder, Act on What Lands.json +177 -0
- package/dist/examples/nodetool-base/Widen a Mono Voice.json +151 -0
- package/dist/examples/nodetool-base/Workflow As A Tool.json +257 -0
- package/dist/examples/nodetool-base/Write a Listing from the Product Photo.json +139 -0
- package/dist/examples/nodetool-base/Write the Prompt, Then Make the Image.json +200 -0
- package/dist/examples/nodetool-base/gallery_thumbnail_generator.ts +384 -0
- package/dist/mcp-tool-host-deps.d.ts +29 -0
- package/dist/mcp-tool-host-deps.d.ts.map +1 -0
- package/dist/mcp-tool-host-deps.js +69 -0
- package/dist/mcp-tool-host-deps.js.map +1 -0
- package/dist/package-assets.d.ts +41 -0
- package/dist/package-assets.d.ts.map +1 -0
- package/dist/package-assets.js +155 -0
- package/dist/package-assets.js.map +1 -0
- package/dist/project-delete.d.ts +14 -0
- package/dist/project-delete.d.ts.map +1 -0
- package/dist/project-delete.js +66 -0
- package/dist/project-delete.js.map +1 -0
- package/dist/worker-settings-env.d.ts +23 -0
- package/dist/worker-settings-env.d.ts.map +1 -0
- package/dist/worker-settings-env.js +47 -0
- package/dist/worker-settings-env.js.map +1 -0
- package/dist/workflow-runtime-environment.d.ts +20 -0
- package/dist/workflow-runtime-environment.d.ts.map +1 -0
- package/dist/workflow-runtime-environment.js +137 -0
- package/dist/workflow-runtime-environment.js.map +1 -0
- package/package.json +12 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
2026-10-
|
|
1
|
+
2026-10-31T20:31:01.131Z
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export declare function getAssetStoragePath(): string;
|
|
2
|
+
/**
|
|
3
|
+
* Resolve a node's primary output name when it is a text/str type, so its value
|
|
4
|
+
* can be persisted as a text generation. Mirrors the frontend's
|
|
5
|
+
* `getPrimaryOutput` (honor `primary_output`, else first output). Returns
|
|
6
|
+
* undefined for non-text primaries (media, structured data, …).
|
|
7
|
+
*/
|
|
8
|
+
export declare function primaryTextOutputName(meta: {
|
|
9
|
+
outputs?: Array<{
|
|
10
|
+
name: string;
|
|
11
|
+
type?: {
|
|
12
|
+
type?: string;
|
|
13
|
+
};
|
|
14
|
+
}>;
|
|
15
|
+
primary_output?: string;
|
|
16
|
+
} | undefined): string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Replace native-Float32Array chunk payloads in an outgoing message with
|
|
19
|
+
* their base64 wire form. Chunks appear as the message itself (chat
|
|
20
|
+
* streaming), as `value` (output_update), or as `result`/array elements
|
|
21
|
+
* (node_update); nested generic walks are deliberately avoided — this runs
|
|
22
|
+
* per message on the hot streaming path.
|
|
23
|
+
*/
|
|
24
|
+
export declare function encodeNativeAudioChunks(message: Record<string, unknown>): Record<string, unknown>;
|
|
25
|
+
/**
|
|
26
|
+
* Pull image bytes (+mime) out of an embedded image payload — `{ data, mimeType }`
|
|
27
|
+
* or `{ uri }` — so it can be materialized into a temp asset. A non-data
|
|
28
|
+
* remote/storage URI is surfaced as a passthrough handle (view_image fetches it).
|
|
29
|
+
*/
|
|
30
|
+
export declare function extractEmbeddedImage(source: {
|
|
31
|
+
data?: unknown;
|
|
32
|
+
uri?: unknown;
|
|
33
|
+
mimeType?: unknown;
|
|
34
|
+
}): {
|
|
35
|
+
bytes: Uint8Array;
|
|
36
|
+
mimeType: string;
|
|
37
|
+
} | {
|
|
38
|
+
uri: string;
|
|
39
|
+
} | null;
|
|
40
|
+
/**
|
|
41
|
+
* Recursively find asset-like values in a result object and persist them as
|
|
42
|
+
* Asset records in the database + on disk.
|
|
43
|
+
*
|
|
44
|
+
* Mutates the result in-place: sets `asset_id` and updates `uri` to
|
|
45
|
+
* `asset://{id}.{ext}`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function autoSaveAssets(result: Record<string, unknown>, opts: {
|
|
48
|
+
userId: string;
|
|
49
|
+
workflowId: string | null;
|
|
50
|
+
jobId: string;
|
|
51
|
+
nodeId: string;
|
|
52
|
+
/**
|
|
53
|
+
* Name of the node's primary output when it is a text/str type. When set and
|
|
54
|
+
* the result carries a non-empty string there, it is persisted as a
|
|
55
|
+
* `text/plain` asset so text content-card nodes (Agent, Summarizer,
|
|
56
|
+
* Classifier) get the same reload-surviving, browsable generation history as
|
|
57
|
+
* media nodes.
|
|
58
|
+
*/
|
|
59
|
+
textOutputName?: string;
|
|
60
|
+
/**
|
|
61
|
+
* The relay-stamped arrival `index` of the `generation_complete` event that
|
|
62
|
+
* triggered this save (RFC Decision 8 `(job_id, node_id, index)` key).
|
|
63
|
+
* Stamped onto each created asset's `metadata.generation_index` so a replay
|
|
64
|
+
* can dedupe by the exact slot — independent of how many assets a single
|
|
65
|
+
* event yields (a `list[image]` output, or media + text together, persists
|
|
66
|
+
* several rows for ONE arrival index).
|
|
67
|
+
*/
|
|
68
|
+
generationIndex?: number;
|
|
69
|
+
/**
|
|
70
|
+
* Input properties from the `generation_complete` event (the actor's
|
|
71
|
+
* resolved declared/dynamic/edge inputs, filtered to scalars and model
|
|
72
|
+
* refs). The prompt and the settings are persisted into each saved media
|
|
73
|
+
* asset's metadata so the asset viewer can show what produced the
|
|
74
|
+
* image/audio/video, and so the same settings can seed a variant.
|
|
75
|
+
*/
|
|
76
|
+
properties?: Record<string, unknown>;
|
|
77
|
+
/** Node type that produced the result, recorded alongside the settings. */
|
|
78
|
+
nodeType?: string;
|
|
79
|
+
}): Promise<void>;
|
|
80
|
+
//# sourceMappingURL=asset-autosave.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-autosave.d.ts","sourceRoot":"","sources":["../src/asset-autosave.ts"],"names":[],"mappings":"AAsBA,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAgDD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EACA;IACE,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACD,SAAS,GACZ,MAAM,GAAG,SAAS,CAQpB;AAmDD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzB;AA6BD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiCnE;AAmCD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE;IACJ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,OAAO,CAAC,IAAI,CAAC,CA4Pf"}
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
import { generationsForNode, linkGenerationAssets } from "@nodetool-ai/execution";
|
|
2
|
+
import { createLogger, getDefaultAssetsPath } from "@nodetool-ai/config";
|
|
3
|
+
import { Asset } from "@nodetool-ai/models";
|
|
4
|
+
import { buildAssetGenerationMetadata, isRawRgbaImage } from "@nodetool-ai/protocol";
|
|
5
|
+
import { encodeRawRgbaToPng, fetchExternalMedia } from "@nodetool-ai/runtime";
|
|
6
|
+
import { getAssetFileName } from "@nodetool-ai/asset-services/asset-paths";
|
|
7
|
+
import { storeAssetWithThumbnail } from "@nodetool-ai/asset-services/thumbnail";
|
|
8
|
+
import { isNonEmptyString, isObjectLike, isRecord, isString } from "@nodetool-ai/protocol";
|
|
9
|
+
const log = createLogger("nodetool.websocket.runner");
|
|
10
|
+
export function getAssetStoragePath() {
|
|
11
|
+
return getDefaultAssetsPath();
|
|
12
|
+
}
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Auto-save assets — persists generated media as Asset records
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
const ASSET_MEDIA_TYPES = new Set(["image", "audio", "video"]);
|
|
17
|
+
/** Byte cap for inline-preview text stored in a text generation's asset metadata. */
|
|
18
|
+
const TEXT_GENERATION_PREVIEW_CAP = 200_000;
|
|
19
|
+
/**
|
|
20
|
+
* The model property a generative node ran with, as the actor forwards it:
|
|
21
|
+
* `{type: "image_model", id, name, provider}`. Which key holds it varies by
|
|
22
|
+
* node, so the first model-shaped property wins.
|
|
23
|
+
*/
|
|
24
|
+
function modelProperty(properties) {
|
|
25
|
+
for (const value of Object.values(properties ?? {})) {
|
|
26
|
+
if (!isRecord(value))
|
|
27
|
+
continue;
|
|
28
|
+
if (isString(value.type) && value.type.endsWith("_model") && isString(value.id)) {
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Lift the prompt and the generation settings out of a generation's input
|
|
36
|
+
* properties into asset metadata, so the asset says what produced it and can
|
|
37
|
+
* seed a variant later. Returns `{}` when nothing worth keeping is present.
|
|
38
|
+
*/
|
|
39
|
+
function generationMetadata(properties, nodeType) {
|
|
40
|
+
const model = modelProperty(properties);
|
|
41
|
+
return buildAssetGenerationMetadata({
|
|
42
|
+
prompt: properties?.prompt,
|
|
43
|
+
provider: model?.provider,
|
|
44
|
+
model: model?.id,
|
|
45
|
+
modelName: model?.name,
|
|
46
|
+
nodeType,
|
|
47
|
+
params: properties ?? null
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Resolve a node's primary output name when it is a text/str type, so its value
|
|
52
|
+
* can be persisted as a text generation. Mirrors the frontend's
|
|
53
|
+
* `getPrimaryOutput` (honor `primary_output`, else first output). Returns
|
|
54
|
+
* undefined for non-text primaries (media, structured data, …).
|
|
55
|
+
*/
|
|
56
|
+
export function primaryTextOutputName(meta) {
|
|
57
|
+
const outputs = meta?.outputs ?? [];
|
|
58
|
+
if (outputs.length === 0)
|
|
59
|
+
return undefined;
|
|
60
|
+
const named = meta?.primary_output;
|
|
61
|
+
const primary = (named && outputs.find((o) => o.name === named)) || outputs[0];
|
|
62
|
+
const t = primary?.type?.type;
|
|
63
|
+
return t === "str" || t === "text" ? primary.name : undefined;
|
|
64
|
+
}
|
|
65
|
+
const ASSET_TYPE_MIME = {
|
|
66
|
+
image: "image/png",
|
|
67
|
+
audio: "audio/wav",
|
|
68
|
+
video: "video/mp4"
|
|
69
|
+
};
|
|
70
|
+
function isAssetLikeValue(value) {
|
|
71
|
+
if (!isRecord(value))
|
|
72
|
+
return false;
|
|
73
|
+
const v = value;
|
|
74
|
+
return (isString(v.type) &&
|
|
75
|
+
ASSET_MEDIA_TYPES.has(v.type) &&
|
|
76
|
+
("data" in v || "uri" in v));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A chunk whose content is the native in-process `Float32Array` sample
|
|
80
|
+
* payload (see protocol `Chunk.content`). Must be encoded before crossing
|
|
81
|
+
* the websocket: msgpack/JSON would mangle the typed array.
|
|
82
|
+
*/
|
|
83
|
+
function isNativeAudioChunk(value) {
|
|
84
|
+
if (!isObjectLike(value))
|
|
85
|
+
return false;
|
|
86
|
+
const v = value;
|
|
87
|
+
return v.type === "chunk" && v.content instanceof Float32Array;
|
|
88
|
+
}
|
|
89
|
+
/** Encode a native audio chunk's samples to base64 f32le for the wire. */
|
|
90
|
+
function encodeAudioChunkForWire(chunk) {
|
|
91
|
+
const samples = chunk.content;
|
|
92
|
+
const bytes = Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength);
|
|
93
|
+
return {
|
|
94
|
+
...chunk,
|
|
95
|
+
content: bytes.toString("base64"),
|
|
96
|
+
content_metadata: {
|
|
97
|
+
...chunk.content_metadata,
|
|
98
|
+
encoding: "f32le"
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Replace native-Float32Array chunk payloads in an outgoing message with
|
|
104
|
+
* their base64 wire form. Chunks appear as the message itself (chat
|
|
105
|
+
* streaming), as `value` (output_update), or as `result`/array elements
|
|
106
|
+
* (node_update); nested generic walks are deliberately avoided — this runs
|
|
107
|
+
* per message on the hot streaming path.
|
|
108
|
+
*/
|
|
109
|
+
export function encodeNativeAudioChunks(message) {
|
|
110
|
+
if (isNativeAudioChunk(message))
|
|
111
|
+
return encodeAudioChunkForWire(message);
|
|
112
|
+
let out = message;
|
|
113
|
+
for (const key of ["value", "result", "chunk"]) {
|
|
114
|
+
const v = out[key];
|
|
115
|
+
if (isNativeAudioChunk(v)) {
|
|
116
|
+
out = { ...out, [key]: encodeAudioChunkForWire(v) };
|
|
117
|
+
}
|
|
118
|
+
else if (Array.isArray(v) && v.some(isNativeAudioChunk)) {
|
|
119
|
+
out = {
|
|
120
|
+
...out,
|
|
121
|
+
[key]: v.map((item) => isNativeAudioChunk(item) ? encodeAudioChunkForWire(item) : item)
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return out;
|
|
126
|
+
}
|
|
127
|
+
function decodeAssetBytes(data) {
|
|
128
|
+
if (data === null || data === undefined)
|
|
129
|
+
return null;
|
|
130
|
+
if (data instanceof Uint8Array)
|
|
131
|
+
return data;
|
|
132
|
+
if (Buffer.isBuffer(data))
|
|
133
|
+
return new Uint8Array(data);
|
|
134
|
+
if (Array.isArray(data) && data.every((v) => Number.isInteger(v))) {
|
|
135
|
+
return new Uint8Array(data);
|
|
136
|
+
}
|
|
137
|
+
if (isString(data)) {
|
|
138
|
+
return Uint8Array.from(Buffer.from(data, "base64"));
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
/** Parse a `data:` URI into its mime type and decoded bytes. */
|
|
143
|
+
function parseImageDataUri(uri) {
|
|
144
|
+
const match = /^data:([^;,]+)?(;base64)?,([\s\S]*)$/.exec(uri);
|
|
145
|
+
if (!match)
|
|
146
|
+
return null;
|
|
147
|
+
const mimeType = match[1] || "image/png";
|
|
148
|
+
const payload = match[3] ?? "";
|
|
149
|
+
const bytes = match[2]
|
|
150
|
+
? Uint8Array.from(Buffer.from(payload, "base64"))
|
|
151
|
+
: new TextEncoder().encode(decodeURIComponent(payload));
|
|
152
|
+
return { bytes, mimeType };
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Pull image bytes (+mime) out of an embedded image payload — `{ data, mimeType }`
|
|
156
|
+
* or `{ uri }` — so it can be materialized into a temp asset. A non-data
|
|
157
|
+
* remote/storage URI is surfaced as a passthrough handle (view_image fetches it).
|
|
158
|
+
*/
|
|
159
|
+
export function extractEmbeddedImage(source) {
|
|
160
|
+
const declaredMime = isString(source.mimeType) ? source.mimeType : undefined;
|
|
161
|
+
const data = isString(source.data) ? source.data : undefined;
|
|
162
|
+
const uri = isString(source.uri) ? source.uri : undefined;
|
|
163
|
+
if (data) {
|
|
164
|
+
if (data.startsWith("data:")) {
|
|
165
|
+
const parsed = parseImageDataUri(data);
|
|
166
|
+
if (parsed) {
|
|
167
|
+
return {
|
|
168
|
+
bytes: parsed.bytes,
|
|
169
|
+
mimeType: declaredMime ?? parsed.mimeType
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
const bytes = decodeAssetBytes(data);
|
|
175
|
+
if (bytes)
|
|
176
|
+
return { bytes, mimeType: declaredMime ?? "image/png" };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (uri) {
|
|
180
|
+
if (uri.startsWith("data:")) {
|
|
181
|
+
const parsed = parseImageDataUri(uri);
|
|
182
|
+
if (parsed) {
|
|
183
|
+
return {
|
|
184
|
+
bytes: parsed.bytes,
|
|
185
|
+
mimeType: declaredMime ?? parsed.mimeType
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
return { uri };
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
async function readBytesFromUri(uri) {
|
|
196
|
+
if (!uri)
|
|
197
|
+
return null;
|
|
198
|
+
try {
|
|
199
|
+
if (uri.startsWith("file://")) {
|
|
200
|
+
const { readFile } = await import("node:fs/promises");
|
|
201
|
+
const { fileURLToPath } = await import("node:url");
|
|
202
|
+
return new Uint8Array(await readFile(fileURLToPath(uri)));
|
|
203
|
+
}
|
|
204
|
+
if (uri.startsWith("data:")) {
|
|
205
|
+
const commaIdx = uri.indexOf(",");
|
|
206
|
+
if (commaIdx < 0)
|
|
207
|
+
return null;
|
|
208
|
+
return Uint8Array.from(Buffer.from(uri.slice(commaIdx + 1), "base64"));
|
|
209
|
+
}
|
|
210
|
+
if (uri.startsWith("http://") || uri.startsWith("https://")) {
|
|
211
|
+
// The uri comes from a user-authored workflow's output, so it is fetched
|
|
212
|
+
// under the media-ref egress policy — otherwise an auto-save node could
|
|
213
|
+
// make the server read cloud-metadata / internal services. A refusal
|
|
214
|
+
// throws; the catch below reports it and answers "no bytes".
|
|
215
|
+
const resp = await fetchExternalMedia(uri);
|
|
216
|
+
if (!resp.ok)
|
|
217
|
+
return null;
|
|
218
|
+
return new Uint8Array(await resp.arrayBuffer());
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
catch (err) {
|
|
222
|
+
// Failed to read bytes — non-fatal, but say which uri and why: a refused
|
|
223
|
+
// URL and a dead host are different problems for whoever reads the log.
|
|
224
|
+
log.warn("readBytesFromUri failed", {
|
|
225
|
+
uri,
|
|
226
|
+
error: err instanceof Error ? err.message : String(err)
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Recursively find asset-like values in a result object and persist them as
|
|
233
|
+
* Asset records in the database + on disk.
|
|
234
|
+
*
|
|
235
|
+
* Mutates the result in-place: sets `asset_id` and updates `uri` to
|
|
236
|
+
* `asset://{id}.{ext}`.
|
|
237
|
+
*/
|
|
238
|
+
export async function autoSaveAssets(result, opts) {
|
|
239
|
+
// Prompt + settings lifted into each media asset's metadata: what produced
|
|
240
|
+
// this, and what to re-run to get another one like it.
|
|
241
|
+
const generationMeta = generationMetadata(opts.properties, opts.nodeType);
|
|
242
|
+
// Generations the seam opened for this node that no asset names yet: the
|
|
243
|
+
// node returned an inline ref, so the link is made here, on save
|
|
244
|
+
// (docs/media-generation-tracking-design.md § 8, S3).
|
|
245
|
+
const generationIds = generationsForNode(opts.jobId, opts.nodeId);
|
|
246
|
+
const savedAssetIds = [];
|
|
247
|
+
// Each entry keeps the top-level output handle it was found under, so a node
|
|
248
|
+
// with several media outputs (a video and its last frame, say) persists
|
|
249
|
+
// assets that name which handle produced them. Without it, a reloaded
|
|
250
|
+
// Preview wired to one handle cannot tell the node's saved assets apart and
|
|
251
|
+
// shows whichever one its priority order happens to pick — for every handle.
|
|
252
|
+
const queue = [];
|
|
253
|
+
// Collect all asset-like values from the result (may be nested)
|
|
254
|
+
function collect(value, outputName) {
|
|
255
|
+
if (value === null || value === undefined)
|
|
256
|
+
return;
|
|
257
|
+
if (Array.isArray(value)) {
|
|
258
|
+
for (const item of value)
|
|
259
|
+
collect(item, outputName);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
if (isAssetLikeValue(value)) {
|
|
263
|
+
queue.push({ value, outputName });
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
if (isRecord(value)) {
|
|
267
|
+
for (const v of Object.values(value)) {
|
|
268
|
+
collect(v, outputName);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
for (const [outputName, value] of Object.entries(result)) {
|
|
273
|
+
collect(value, outputName);
|
|
274
|
+
}
|
|
275
|
+
// Whether this result carries media at all — used to gate the structured
|
|
276
|
+
// (JSON) generation fallback below so a media node never also persists a
|
|
277
|
+
// redundant JSON copy of its output dict (true even on replay, where the
|
|
278
|
+
// media value already carries an asset_id and is skipped by the save loop).
|
|
279
|
+
const hasMedia = queue.length > 0;
|
|
280
|
+
for (const { value: assetValue, outputName } of queue) {
|
|
281
|
+
// Skip if already saved
|
|
282
|
+
if (assetValue.asset_id)
|
|
283
|
+
continue;
|
|
284
|
+
const assetType = String(assetValue.type);
|
|
285
|
+
// Get bytes. Raw in-flight RGBA is encoded to PNG first so the stored
|
|
286
|
+
// asset (and its thumbnail) is a real image.
|
|
287
|
+
const isRaw = isRawRgbaImage(assetValue);
|
|
288
|
+
let bytes;
|
|
289
|
+
if (isRaw) {
|
|
290
|
+
bytes = await encodeRawRgbaToPng(assetValue.data, assetValue.width, assetValue.height);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
bytes = decodeAssetBytes(assetValue.data);
|
|
294
|
+
if (!bytes && isString(assetValue.uri)) {
|
|
295
|
+
bytes = await readBytesFromUri(assetValue.uri);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (!bytes)
|
|
299
|
+
continue;
|
|
300
|
+
// Determine mime/ext, preferring explicit content_type.
|
|
301
|
+
const explicitMime = isRaw
|
|
302
|
+
? "image/png"
|
|
303
|
+
: (assetValue.mime_type ?? assetValue.content_type);
|
|
304
|
+
const contentType = isString(explicitMime) && explicitMime
|
|
305
|
+
? explicitMime
|
|
306
|
+
: (ASSET_TYPE_MIME[assetType] ?? "application/octet-stream");
|
|
307
|
+
// Create Asset record
|
|
308
|
+
const asset = new Asset({
|
|
309
|
+
user_id: opts.userId,
|
|
310
|
+
workflow_id: opts.workflowId ?? null,
|
|
311
|
+
node_id: opts.nodeId,
|
|
312
|
+
job_id: opts.jobId,
|
|
313
|
+
name: `${assetType}_${opts.nodeId.slice(0, 8)}`,
|
|
314
|
+
content_type: contentType,
|
|
315
|
+
parent_id: null
|
|
316
|
+
});
|
|
317
|
+
const mediaMeta = { ...generationMeta };
|
|
318
|
+
if (opts.generationIndex != null) {
|
|
319
|
+
mediaMeta.generation_index = opts.generationIndex;
|
|
320
|
+
}
|
|
321
|
+
if (generationIds.length > 0) {
|
|
322
|
+
mediaMeta.generation_ids = generationIds;
|
|
323
|
+
}
|
|
324
|
+
if (outputName) {
|
|
325
|
+
mediaMeta.output_name = outputName;
|
|
326
|
+
}
|
|
327
|
+
if (Object.keys(mediaMeta).length > 0) {
|
|
328
|
+
asset.metadata = mediaMeta;
|
|
329
|
+
}
|
|
330
|
+
const fileName = getAssetFileName(asset.id, contentType);
|
|
331
|
+
try {
|
|
332
|
+
await storeAssetWithThumbnail(asset.user_id, asset.id, fileName, bytes, contentType);
|
|
333
|
+
asset.size = bytes.length;
|
|
334
|
+
await asset.save();
|
|
335
|
+
savedAssetIds.push(asset.id);
|
|
336
|
+
// Mutate the result value in-place. For raw assets, also drop the raw
|
|
337
|
+
// pixels and fix the mime so later normalization treats it as the saved
|
|
338
|
+
// PNG, not raw RGBA.
|
|
339
|
+
assetValue.asset_id = asset.id;
|
|
340
|
+
assetValue.uri = `asset://${fileName}`;
|
|
341
|
+
if (isRaw) {
|
|
342
|
+
const mutable = assetValue;
|
|
343
|
+
mutable.data = undefined;
|
|
344
|
+
mutable.mimeType = "image/png";
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
catch (err) {
|
|
348
|
+
log.warn("Auto-save asset failed", {
|
|
349
|
+
nodeId: opts.nodeId,
|
|
350
|
+
error: String(err)
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
// Persist the primary text output as a generation (a text/plain asset), so
|
|
355
|
+
// text content-card nodes get the same reload-surviving, browsable generation
|
|
356
|
+
// history as media nodes. The text is stored both as the asset bytes and
|
|
357
|
+
if (generationIds.length > 0 && savedAssetIds.length > 0) {
|
|
358
|
+
await linkGenerationAssets(generationIds, savedAssetIds);
|
|
359
|
+
}
|
|
360
|
+
// (capped) inline in metadata so the UI can preview it without a fetch.
|
|
361
|
+
let savedText = false;
|
|
362
|
+
const textKey = opts.textOutputName;
|
|
363
|
+
if (textKey) {
|
|
364
|
+
const textVal = result[textKey];
|
|
365
|
+
if (isNonEmptyString(textVal)) {
|
|
366
|
+
savedText = true;
|
|
367
|
+
const bytes = new TextEncoder().encode(textVal);
|
|
368
|
+
const previewText = new TextDecoder().decode(bytes.slice(0, TEXT_GENERATION_PREVIEW_CAP));
|
|
369
|
+
const asset = new Asset({
|
|
370
|
+
user_id: opts.userId,
|
|
371
|
+
workflow_id: opts.workflowId ?? null,
|
|
372
|
+
node_id: opts.nodeId,
|
|
373
|
+
job_id: opts.jobId,
|
|
374
|
+
name: `text_${opts.nodeId.slice(0, 8)}`,
|
|
375
|
+
content_type: "text/plain",
|
|
376
|
+
parent_id: null
|
|
377
|
+
});
|
|
378
|
+
asset.metadata =
|
|
379
|
+
opts.generationIndex != null
|
|
380
|
+
? { text: previewText, generation_index: opts.generationIndex }
|
|
381
|
+
: { text: previewText };
|
|
382
|
+
const fileName = `${asset.id}.txt`;
|
|
383
|
+
try {
|
|
384
|
+
await storeAssetWithThumbnail(asset.user_id, asset.id, fileName, bytes, "text/plain");
|
|
385
|
+
asset.size = bytes.length;
|
|
386
|
+
await asset.save();
|
|
387
|
+
}
|
|
388
|
+
catch (err) {
|
|
389
|
+
log.warn("Auto-save text generation failed", {
|
|
390
|
+
nodeId: opts.nodeId,
|
|
391
|
+
error: String(err)
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
// Structured (JSON) generation fallback. Nodes whose primary output is neither
|
|
397
|
+
// media nor a plain string — the generator family (List/Data/Chart/SVG/
|
|
398
|
+
// StructuredOutput), which emit lists, dicts, dataframes, chart configs, etc.
|
|
399
|
+
// — persist their whole output dict as an `application/json` asset so they get
|
|
400
|
+
// the same reload-surviving, browsable generation history as media/text nodes.
|
|
401
|
+
// The full value lives in the asset bytes; a copy is stored inline in
|
|
402
|
+
// `metadata.json` (when small enough) for fetch-free reload. Gated on
|
|
403
|
+
// !hasMedia && !savedText so media/text nodes never double-persist.
|
|
404
|
+
if (!hasMedia && !savedText) {
|
|
405
|
+
const structured = {};
|
|
406
|
+
for (const [key, value] of Object.entries(result)) {
|
|
407
|
+
if (value !== null && value !== undefined)
|
|
408
|
+
structured[key] = value;
|
|
409
|
+
}
|
|
410
|
+
if (Object.keys(structured).length > 0) {
|
|
411
|
+
let serialized = null;
|
|
412
|
+
try {
|
|
413
|
+
serialized = JSON.stringify(structured);
|
|
414
|
+
}
|
|
415
|
+
catch {
|
|
416
|
+
serialized = null;
|
|
417
|
+
}
|
|
418
|
+
if (serialized) {
|
|
419
|
+
const bytes = new TextEncoder().encode(serialized);
|
|
420
|
+
const asset = new Asset({
|
|
421
|
+
user_id: opts.userId,
|
|
422
|
+
workflow_id: opts.workflowId ?? null,
|
|
423
|
+
node_id: opts.nodeId,
|
|
424
|
+
job_id: opts.jobId,
|
|
425
|
+
name: `json_${opts.nodeId.slice(0, 8)}`,
|
|
426
|
+
content_type: "application/json",
|
|
427
|
+
parent_id: null
|
|
428
|
+
});
|
|
429
|
+
// Inline the full value only when it fits — a truncated JSON string
|
|
430
|
+
// would not parse on reload. Oversized values reload from the bytes.
|
|
431
|
+
const inline = bytes.length <= TEXT_GENERATION_PREVIEW_CAP ? structured : undefined;
|
|
432
|
+
const metadata = {};
|
|
433
|
+
if (inline !== undefined) {
|
|
434
|
+
metadata.json = inline;
|
|
435
|
+
}
|
|
436
|
+
if (opts.generationIndex != null) {
|
|
437
|
+
metadata.generation_index = opts.generationIndex;
|
|
438
|
+
}
|
|
439
|
+
asset.metadata = metadata;
|
|
440
|
+
const fileName = `${asset.id}.json`;
|
|
441
|
+
try {
|
|
442
|
+
await storeAssetWithThumbnail(asset.user_id, asset.id, fileName, bytes, "application/json");
|
|
443
|
+
asset.size = bytes.length;
|
|
444
|
+
await asset.save();
|
|
445
|
+
}
|
|
446
|
+
catch (err) {
|
|
447
|
+
log.warn("Auto-save JSON generation failed", {
|
|
448
|
+
nodeId: opts.nodeId,
|
|
449
|
+
error: String(err)
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
//# sourceMappingURL=asset-autosave.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-autosave.js","sourceRoot":"","sources":["../src/asset-autosave.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type NodeRegistry } from "@nodetool-ai/node-sdk";
|
|
2
|
+
/** Where the examples come from. The server passes its HTTP options. */
|
|
3
|
+
export interface ExampleSourceOptions {
|
|
4
|
+
examplesDir?: string;
|
|
5
|
+
examplesAssetsFallbackDir?: string;
|
|
6
|
+
registry?: NodeRegistry;
|
|
7
|
+
metadataRoots?: string[];
|
|
8
|
+
metadataMaxDepth?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildExampleWorkflows(options: ExampleSourceOptions): unknown[];
|
|
11
|
+
//# sourceMappingURL=example-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example-catalog.d.ts","sourceRoot":"","sources":["../src/example-catalog.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAY/B,wEAAwE;AACxE,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAoGD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,EAAE,CAgEX"}
|