@civitai/app-sdk 0.59.0 → 0.61.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/README.md CHANGED
@@ -528,7 +528,7 @@ The starters in `civitai/civitai-app-starters` wire this into framework-specific
528
528
 
529
529
  ## Choosing a workflow step type
530
530
 
531
- The orchestrator is a workflow API: each request submits a list of typed steps. `WORKFLOW_STEP_TYPES` is the in-code catalog of every step `$type` it accepts, with a one-line description for each — `textToImage`, `imageGen`, `videoGen`, `comfy`, `customComfy`, `textToSpeech`, `aceStepAudio`, `transcription`, `imageUpscaler` among them (53 in total).
531
+ The orchestrator is a workflow API: each request submits a list of typed steps. `WORKFLOW_STEP_TYPES` is the in-code catalog of every step `$type` it accepts, with a one-line description for each — `textToImage`, `imageGen`, `videoGen`, `comfy`, `customComfy`, `textToSpeech`, `aceStepAudio`, `transcription`, `imageUpscaler` among them (55 in total).
532
532
 
533
533
  The catalog is pinned to the orchestrator's published OpenAPI spec two ways — an offline unit test against a transcribed copy of the spec's `WorkflowStepTemplate` discriminator mapping, and a CI job (`pnpm check:catalogs`) that re-fetches the live spec and diffs it. If a `$type` is listed here, the orchestrator accepts it.
534
534
 
@@ -603,15 +603,15 @@ What it exports:
603
603
 
604
604
  | Export | What |
605
605
  |---|---|
606
- | `WorkflowStepTemplates` | `$type` → template type, for 47 of the catalog's 53 step types. Keyed by the WIRE name, which the generated type names don't always match (`model3DPreview` → `Model3dPreviewStepTemplate`). |
606
+ | `WorkflowStepTemplates` | `$type` → template type, for 47 of the catalog's 55 step types. Keyed by the WIRE name, which the generated type names don't always match (`model3DPreview` → `Model3dPreviewStepTemplate`). |
607
607
  | `WorkflowStepTemplateFor<'videoGen'>` | One step's template. |
608
608
  | `WorkflowStepInputFor<'videoGen'>` | One step's `input` shape, without needing the generated `*Input` name. |
609
609
  | `AnyWorkflowStepTemplate` | Discriminated union of all 47 mapped templates — `Extract<…, { $type: 'comfy' }>` and exhaustive `switch` work. `@civitai/client`'s base `WorkflowStepTemplate` has `$type` as a bare `string`, so it narrows nothing. |
610
610
  | `TypedWorkflowTemplate` | The submit envelope with `steps` narrowed to that union. Pass it straight to `submitWorkflow` / `estimateWorkflow`. |
611
611
 
612
- > 🔴 **The map is not total over the catalog, and that is the expected state.** `WORKFLOW_STEP_TYPES` documents 53 `$type`s; this map covers 47. The 6 with no generated template in the pinned `@civitai/client` are `imageScanning`, `liveTranscription`, `merge`, `preprocessVideo`, `soniloAudioGen`, `yuE2`, and `WorkflowStepTemplateFor<…>` is a compile error for each of them.
612
+ > 🔴 **The map is not total over the catalog, and that is the expected state.** `WORKFLOW_STEP_TYPES` documents 55 `$type`s; this map covers 47. The 8 with no generated template in the pinned `@civitai/client` are `imageScanning`, `liveTextToSpeech`, `liveTranscription`, `merge`, `preprocessVideo`, `promptModeration`, `soniloAudioGen`, `yuE2`, and `WorkflowStepTemplateFor<…>` is a compile error for each of them.
613
613
  >
614
- > The two surfaces move independently on purpose: the catalog tracks the **live** orchestrator spec (a daily job syncs it), while these types track whatever `@civitai/client` was last published from. So the catalog runs ahead and the client catches up. The gap is never silent — `test/orchestrator/step-templates.test-d.ts` carries it as a `never` ledger plus one `@ts-expect-error` per gap `$type`, and `test/orchestrator/step-count-prose.test.ts` derives all four numbers (53, 47, 6, and the names) from `WORKFLOW_STEP_TYPES` and the map's own AST, then fails if this paragraph or its twin in `src/orchestrator/steps.ts` disagrees by one character.
614
+ > The two surfaces move independently on purpose: the catalog tracks the **live** orchestrator spec (a daily job syncs it), while these types track whatever `@civitai/client` was last published from. So the catalog runs ahead and the client catches up. The gap is never silent — `test/orchestrator/step-templates.test-d.ts` carries it as a `never` ledger plus one `@ts-expect-error` per gap `$type`, and `test/orchestrator/step-count-prose.test.ts` derives all four numbers (55, 47, 8, and the names) from `WORKFLOW_STEP_TYPES` and the map's own AST, then fails if this paragraph or its twin in `src/orchestrator/steps.ts` disagrees by one character.
615
615
 
616
616
  The generated `*StepTemplate` and `*Input` types are **not** re-exported individually. Using this subpath already requires `@civitai/client` installed, so if you want one by name, import it straight from there — `import type { TextToImageStepTemplate } from '@civitai/client'`.
617
617
 
@@ -650,7 +650,7 @@ Several of the 47 exist to serve Civitai's own pipelines rather than third-party
650
650
 
651
651
  `training` and `imageResourceTraining` are the exception: an App Block's host explicitly **allows** them on the pass-through arm (see `WorkflowBodyPassThroughStep` under Primitives above for the `maxBuzz` bound, and how a trained epoch is published). For a standalone app, the orchestrator's own authorization still decides.
652
652
 
653
- Note that `WORKFLOW_STEP_TYPES` does **not** mark most of them: of its 53 entries exactly two — `comfyNodepackSnapshot` and `qwenImageBench` — sit under its "Platform internals" heading, and the rest are ordinary documented entries (`webScrape` even carries usage notes). The reason the platform steps are typed anyway is not that the catalog flags them as internal; it's that the catalog *documents* them, so skipping them would make `WorkflowStepTemplateFor<'training'>` a compile error for a step type the SDK documents — which is exactly what is live today for the 3 `$type`s the pinned client cannot type, and is why that gap is spelled out above rather than left to be discovered.
653
+ Note that `WORKFLOW_STEP_TYPES` does **not** mark most of them: of its 55 entries exactly three — `comfyNodepackSnapshot`, `qwenImageBench` and `promptModeration` — sit under its "Platform internals" heading, and the rest are ordinary documented entries (`webScrape` even carries usage notes). The reason the platform steps are typed anyway is not that the catalog flags them as internal; it's that the catalog *documents* them, so skipping them would make `WorkflowStepTemplateFor<'training'>` a compile error for a step type the SDK documents — which is exactly what is live today for each `$type` the pinned client cannot type, and is why that gap is spelled out above rather than left to be discovered.
654
654
 
655
655
  ## Public vs. confidential clients
656
656
 
@@ -966,11 +966,20 @@ export type BlockToParentMessage = {
966
966
  type: 'SAVE_IMAGE';
967
967
  payload: {
968
968
  requestId: string;
969
- /** Own-output URL — origin-allowlisted host-side. Mutually exclusive with `imageId`. */
969
+ /** Own-output URL — origin-allowlisted host-side. Mutually exclusive with `imageId` / `bytes`. */
970
970
  url?: string;
971
- /** Cross-user image id — routed through the gated per-viewer read. Mutually exclusive with `url`. */
971
+ /** Cross-user image id — routed through the gated per-viewer read. Mutually exclusive with `url` / `bytes`. */
972
972
  imageId?: number;
973
- /** Optional download filename (host-sanitized). */
973
+ /**
974
+ * In-tab file bytes — classified by CONTENT host-side, size-capped host-side.
975
+ * Page apps only. Mutually exclusive with `url` / `imageId`.
976
+ */
977
+ bytes?: ArrayBuffer;
978
+ /**
979
+ * Optional download filename (host-sanitized). For `bytes`, a `.json`
980
+ * name selects JSON for text that parses as JSON, and the extension is
981
+ * forced from the classified type.
982
+ */
974
983
  filename?: string;
975
984
  };
976
985
  } | {
@@ -113,6 +113,15 @@ export declare const WORKFLOW_STEP_TYPES: {
113
113
  readonly transcode: "Audio/video transcoding";
114
114
  /** Text-to-speech (multi-voice, multi-language). */
115
115
  readonly textToSpeech: "Text-to-speech synthesis";
116
+ /**
117
+ * Streaming text-to-speech. Inputs mirror `textToSpeech`, restricted to voices
118
+ * that stream with low first-audio latency. The output hands back an
119
+ * `inputUrl` you POST UTF-8 text chunks to (`?seq=0,1,…`, `final=true` on the
120
+ * last) and one continuous `audioUrl` stream (`pcm` s16le 24 kHz mono, or
121
+ * `ogg` Opus). The session ends at `maxCharacters` or after
122
+ * `idleTimeoutSeconds` without input, and is billed on characters spoken.
123
+ */
124
+ readonly liveTextToSpeech: "Streaming text-to-speech — post text in chunks, read back one continuous audio stream";
116
125
  /** Music generation via ACE Step 1.5 (lyrics + style → song). */
117
126
  readonly aceStepAudio: "Music generation (ACE Step 1.5)";
118
127
  /**
@@ -139,6 +148,8 @@ export declare const WORKFLOW_STEP_TYPES: {
139
148
  readonly soniloAudioGen: "Music or a sound effect from a text prompt (Sonilo)";
140
149
  /** Speech-to-text transcription. */
141
150
  readonly transcription: "Speech-to-text transcription";
151
+ /** Speech-to-text over audio streamed in while the user is still talking. */
152
+ readonly liveTranscription: "Live speech-to-text from audio streamed while the user talks";
142
153
  /** Generate captions from audio. */
143
154
  readonly audioCaptioning: "Caption generation from audio";
144
155
  /**
@@ -215,12 +226,14 @@ export declare const WORKFLOW_STEP_TYPES: {
215
226
  readonly echo: "Echo step — round-trip the input for testing";
216
227
  /** Package multiple blobs into a zip archive. */
217
228
  readonly blobArchive: "Zip multiple blobs into an archive";
229
+ /** Combine fields from earlier steps' outputs into a single result. */
230
+ readonly merge: "Merge — combine fields from earlier steps' outputs into one result";
218
231
  /** Snapshot the installed ComfyUI custom-node packs on a worker. */
219
232
  readonly comfyNodepackSnapshot: "Snapshot a worker’s installed ComfyUI node packs (internal)";
220
233
  /** Qwen image benchmarking harness. */
221
234
  readonly qwenImageBench: "Qwen image benchmarking (internal)";
222
- readonly liveTranscription: "Live speech-to-text from audio streamed while the user talks";
223
- readonly merge: "Merge — combine fields from earlier steps' outputs into one result";
235
+ /** Per-label scores and flags for a positive / negative prompt pair, under a versioned policy. */
236
+ readonly promptModeration: "Prompt moderation — per-label scores and flags for a prompt pair (internal)";
224
237
  };
225
238
  export type WorkflowStepType = keyof typeof WORKFLOW_STEP_TYPES;
226
239
  /**
@@ -117,6 +117,15 @@ export const WORKFLOW_STEP_TYPES = {
117
117
  // ----- Audio -------------------------------------------------------------
118
118
  /** Text-to-speech (multi-voice, multi-language). */
119
119
  textToSpeech: 'Text-to-speech synthesis',
120
+ /**
121
+ * Streaming text-to-speech. Inputs mirror `textToSpeech`, restricted to voices
122
+ * that stream with low first-audio latency. The output hands back an
123
+ * `inputUrl` you POST UTF-8 text chunks to (`?seq=0,1,…`, `final=true` on the
124
+ * last) and one continuous `audioUrl` stream (`pcm` s16le 24 kHz mono, or
125
+ * `ogg` Opus). The session ends at `maxCharacters` or after
126
+ * `idleTimeoutSeconds` without input, and is billed on characters spoken.
127
+ */
128
+ liveTextToSpeech: 'Streaming text-to-speech — post text in chunks, read back one continuous audio stream',
120
129
  /** Music generation via ACE Step 1.5 (lyrics + style → song). */
121
130
  aceStepAudio: 'Music generation (ACE Step 1.5)',
122
131
  /**
@@ -143,6 +152,8 @@ export const WORKFLOW_STEP_TYPES = {
143
152
  soniloAudioGen: 'Music or a sound effect from a text prompt (Sonilo)',
144
153
  /** Speech-to-text transcription. */
145
154
  transcription: 'Speech-to-text transcription',
155
+ /** Speech-to-text over audio streamed in while the user is still talking. */
156
+ liveTranscription: 'Live speech-to-text from audio streamed while the user talks',
146
157
  /** Generate captions from audio. */
147
158
  audioCaptioning: 'Caption generation from audio',
148
159
  // ----- Media composition -------------------------------------------------
@@ -226,6 +237,8 @@ export const WORKFLOW_STEP_TYPES = {
226
237
  echo: 'Echo step — round-trip the input for testing',
227
238
  /** Package multiple blobs into a zip archive. */
228
239
  blobArchive: 'Zip multiple blobs into an archive',
240
+ /** Combine fields from earlier steps' outputs into a single result. */
241
+ merge: "Merge — combine fields from earlier steps' outputs into one result",
229
242
  // ----- Platform internals ------------------------------------------------
230
243
  // Present in the consumer spec, so listed here for completeness — but these
231
244
  // exist to serve Civitai's own pipelines. A third-party app has no reason to
@@ -234,15 +247,8 @@ export const WORKFLOW_STEP_TYPES = {
234
247
  comfyNodepackSnapshot: 'Snapshot a worker’s installed ComfyUI node packs (internal)',
235
248
  /** Qwen image benchmarking harness. */
236
249
  qwenImageBench: 'Qwen image benchmarking (internal)',
237
- // ----- Auto-added 2026-10-06 from the orchestrator spec ----------------------
238
- // Added by scripts/sync-orchestrator-catalogs.mjs: the live spec accepts
239
- // these and this catalog did not list them. MOVE each entry into the right
240
- // section above, and replace any TODO(catalog) line with a real one-line
241
- // description — `pnpm check:catalogs` names every placeholder that is left.
242
- // (That check is advisory, so it will not stop this merging. It is a
243
- // reminder, not a gate.)
244
- liveTranscription: 'Live speech-to-text from audio streamed while the user talks',
245
- merge: "Merge — combine fields from earlier steps' outputs into one result",
250
+ /** Per-label scores and flags for a positive / negative prompt pair, under a versioned policy. */
251
+ promptModeration: 'Prompt moderation — per-label scores and flags for a prompt pair (internal)',
246
252
  };
247
253
  /**
248
254
  * Engines that the `imageGen` step accepts. Each one has its own input shape;
@@ -3,7 +3,7 @@
3
3
  * own generated client (`@civitai/client`).
4
4
  *
5
5
  * The sibling `@civitai/app-sdk/orchestrator` module gives you the *catalog*
6
- * (`WORKFLOW_STEP_TYPES` — 53 `$type` names and what each one does) and the
6
+ * (`WORKFLOW_STEP_TYPES` — 55 `$type` names and what each one does) and the
7
7
  * fetch helpers (`submitWorkflow`, `estimateWorkflow`, …), but its body
8
8
  * builders take `input: unknown`. This module is the missing half: the actual
9
9
  * per-step input shapes, tracked against the orchestrator's OpenAPI spec by
@@ -78,9 +78,9 @@
78
78
  * orchestrator's own authorization still decides.
79
79
  *
80
80
  * ⚠️ `WORKFLOW_STEP_TYPES` does NOT mark most of them. Counted at this commit:
81
- * of its 53 entries, exactly TWO sit under its "Platform internals" heading —
82
- * `comfyNodepackSnapshot` and `qwenImageBench`. `training`, `webScrape`,
83
- * `xGuardModeration`, `modelPickleScan` and the `model*` / `media*` steps are
81
+ * of its 55 entries, exactly THREE sit under its "Platform internals" heading —
82
+ * `comfyNodepackSnapshot`, `qwenImageBench` and `promptModeration`. `training`,
83
+ * `webScrape`, `xGuardModeration`, `modelPickleScan` and the `model*` / `media*` steps are
84
84
  * ordinary documented entries under ordinary headings, and `webScrape` carries
85
85
  * consumer-facing usage notes. So "the catalog already flags these as internal"
86
86
  * is not a reason this map types them, and an earlier version of this docblock
@@ -97,9 +97,10 @@
97
97
  * (#315) without anything going red. The measured state, derived rather than
98
98
  * typed:
99
99
  *
100
- * `WORKFLOW_STEP_TYPES` documents 53 `$type`s; this map covers 47. The 6 with
100
+ * `WORKFLOW_STEP_TYPES` documents 55 `$type`s; this map covers 47. The 8 with
101
101
  * no generated template in the pinned `@civitai/client` are `imageScanning`,
102
- * `liveTranscription`, `merge`, `preprocessVideo`, `soniloAudioGen`, `yuE2`, and
102
+ * `liveTextToSpeech`, `liveTranscription`, `merge`, `preprocessVideo`,
103
+ * `promptModeration`, `soniloAudioGen`, `yuE2`, and
103
104
  * `WorkflowStepTemplateFor<…>` is a compile error for each of them.
104
105
  *
105
106
  * That gap is EXPECTED and is not a defect in either surface. The catalog
@@ -110,7 +111,7 @@
110
111
  * stated: it is spelled as a `never` ledger in
111
112
  * `test/orchestrator/step-templates.test-d.ts` (which also pins the compile
112
113
  * error above, one `@ts-expect-error` per gap `$type`), and the sentence naming
113
- * the 3 is pinned character for character — here and in the README — by
114
+ * the gap is pinned character for character — here and in the README — by
114
115
  * `test/orchestrator/step-count-prose.test.ts`, which derives all four numbers
115
116
  * from `WORKFLOW_STEP_TYPES` and this file's own AST. Both go red when the gap
116
117
  * moves in either direction.
@@ -308,7 +309,7 @@ interface StepTemplateMap {
308
309
  xGuardModeration: XGuardModerationStepTemplate;
309
310
  }
310
311
  /**
311
- * `$type` → its step-template type, for 47 of the catalog's 53 step types.
312
+ * `$type` → its step-template type, for 47 of the catalog's 55 step types.
312
313
  *
313
314
  * Keyed by the WIRE name rather than the generated type name, because the wire
314
315
  * name is what you actually have in hand and the generator does not always
@@ -3,7 +3,7 @@
3
3
  * own generated client (`@civitai/client`).
4
4
  *
5
5
  * The sibling `@civitai/app-sdk/orchestrator` module gives you the *catalog*
6
- * (`WORKFLOW_STEP_TYPES` — 53 `$type` names and what each one does) and the
6
+ * (`WORKFLOW_STEP_TYPES` — 55 `$type` names and what each one does) and the
7
7
  * fetch helpers (`submitWorkflow`, `estimateWorkflow`, …), but its body
8
8
  * builders take `input: unknown`. This module is the missing half: the actual
9
9
  * per-step input shapes, tracked against the orchestrator's OpenAPI spec by
@@ -78,9 +78,9 @@
78
78
  * orchestrator's own authorization still decides.
79
79
  *
80
80
  * ⚠️ `WORKFLOW_STEP_TYPES` does NOT mark most of them. Counted at this commit:
81
- * of its 53 entries, exactly TWO sit under its "Platform internals" heading —
82
- * `comfyNodepackSnapshot` and `qwenImageBench`. `training`, `webScrape`,
83
- * `xGuardModeration`, `modelPickleScan` and the `model*` / `media*` steps are
81
+ * of its 55 entries, exactly THREE sit under its "Platform internals" heading —
82
+ * `comfyNodepackSnapshot`, `qwenImageBench` and `promptModeration`. `training`,
83
+ * `webScrape`, `xGuardModeration`, `modelPickleScan` and the `model*` / `media*` steps are
84
84
  * ordinary documented entries under ordinary headings, and `webScrape` carries
85
85
  * consumer-facing usage notes. So "the catalog already flags these as internal"
86
86
  * is not a reason this map types them, and an earlier version of this docblock
@@ -97,9 +97,10 @@
97
97
  * (#315) without anything going red. The measured state, derived rather than
98
98
  * typed:
99
99
  *
100
- * `WORKFLOW_STEP_TYPES` documents 53 `$type`s; this map covers 47. The 6 with
100
+ * `WORKFLOW_STEP_TYPES` documents 55 `$type`s; this map covers 47. The 8 with
101
101
  * no generated template in the pinned `@civitai/client` are `imageScanning`,
102
- * `liveTranscription`, `merge`, `preprocessVideo`, `soniloAudioGen`, `yuE2`, and
102
+ * `liveTextToSpeech`, `liveTranscription`, `merge`, `preprocessVideo`,
103
+ * `promptModeration`, `soniloAudioGen`, `yuE2`, and
103
104
  * `WorkflowStepTemplateFor<…>` is a compile error for each of them.
104
105
  *
105
106
  * That gap is EXPECTED and is not a defect in either surface. The catalog
@@ -110,7 +111,7 @@
110
111
  * stated: it is spelled as a `never` ledger in
111
112
  * `test/orchestrator/step-templates.test-d.ts` (which also pins the compile
112
113
  * error above, one `@ts-expect-error` per gap `$type`), and the sentence naming
113
- * the 3 is pinned character for character — here and in the README — by
114
+ * the gap is pinned character for character — here and in the README — by
114
115
  * `test/orchestrator/step-count-prose.test.ts`, which derives all four numbers
115
116
  * from `WORKFLOW_STEP_TYPES` and this file's own AST. Both go red when the gap
116
117
  * moves in either direction.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@civitai/app-sdk",
3
- "version": "0.59.0",
3
+ "version": "0.61.0",
4
4
  "description": "OAuth + PKCE, encrypted-cookie sessions, scopes, and orchestrator helpers for building third-party Civitai apps.",
5
5
  "license": "MIT",
6
6
  "type": "module",