@civitai/app-sdk 0.66.0 → 0.67.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 +52 -7
- package/dist/blocks/index.d.ts +6 -1
- package/dist/blocks/index.js +5 -0
- package/dist/blocks/messages.d.ts +15 -2
- package/dist/blocks/messages.js +1 -0
- package/dist/blocks/types.d.ts +243 -14
- package/dist/blocks/types.js +16 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -140,7 +140,7 @@ interface BlockInitPayload {
|
|
|
140
140
|
| `isModelSlotContext(ctx)` / `isPageSlotContext(ctx)` | Runtime narrowing for the `slotId`-discriminated `BlockContext` union. Real checks on a value that crossed a `postMessage` boundary — they verify every field they assert, not just `slotId`. |
|
|
141
141
|
| `fetchNestedDocument(opts)` | Embed one of your OWN bundled documents as an iframe `srcdoc`, because a nested `<iframe src>` of your own content **cannot load** — see [Nested documents](#nested-documents) below. `NestedDocumentError` carries a `.code` of `'invalid-url' \| 'http-error' \| 'network-error'`. |
|
|
142
142
|
| `isSignedIn(viewer)` | **The sign-in gate.** `isSignedIn(useBlockContext().viewer)` — do not open-code it as `viewer !== null` or `viewer?.signedIn === true`. Which of those is correct has already changed once with the host contract, and this is the one place it is decided. It reads neither `viewer.id` nor `viewer.username` (both `@deprecated`), so nothing written through it changes when those are removed. Need the identity rather than the presence? `useViewer()` — scope-gated and audited per call. |
|
|
143
|
-
| types | `BlockManifestV1`, `ManifestSettings` (+ field types), `BlockContext`, `ModelSlotContext`, `BlockCheckpointInfo`, `ShowcaseImage`, `BlockToken`, `WrappedToken`, `BlockSettings`, `ViewerInfo`, `Theme`, `WorkflowBody`, `BlockTextToImageParams`, `WorkflowBodyCustomComfy` (+ its two arms `WorkflowBodyCustomComfyRecipe` / `WorkflowBodyCustomComfyInline`, and `InlineComfyNode`), `WorkflowBodyStep` / `WorkflowBodyPassThroughStep` (the two arms of `kind: 'step'`), `WorkflowBodyTraining` (+ `AiToolkitTrainingParams`, `BlockTrainingQuote`, `BlockTrainingDatasetItem`, `BlockTrainingDatasetResult` and the `BLOCK_TRAINING_*` bounds), `WorkflowBodyWorkflow` (+ `WorkflowBodyWorkflowStep`, `WorkflowStepRef`, `WithWorkflowStepRefs`, `BlockWorkflowStepSnapshot` and `BLOCK_WORKFLOW_MAX_STEPS`), `BlockWorkflowSnapshot`, `WorkflowStatus`, `BlockInitPayload`, `ParentToBlockMessage`, `BlockToParentMessage`. |
|
|
143
|
+
| types | `BlockManifestV1`, `ManifestSettings` (+ field types), `BlockContext`, `ModelSlotContext`, `BlockCheckpointInfo`, `ShowcaseImage`, `BlockToken`, `WrappedToken`, `BlockSettings`, `ViewerInfo`, `Theme`, `WorkflowBody`, `BlockTextToImageParams`, `WorkflowBodyCustomComfy` (+ its two arms `WorkflowBodyCustomComfyRecipe` / `WorkflowBodyCustomComfyInline`, and `InlineComfyNode`), `WorkflowBodyStep` / `WorkflowBodyPassThroughStep` (the two arms of `kind: 'step'`), `WorkflowBodyTraining` (+ `AiToolkitTrainingParams`, `BlockTrainingQuote`, `BlockTrainingDatasetItem`, `BlockTrainingDatasetResult` and the `BLOCK_TRAINING_*` bounds), `WorkflowBodyWorkflow` (+ `WorkflowBodyWorkflowStep`, `WorkflowStepRef`, `WithWorkflowStepRefs`, `BlockWorkflowStepSnapshot` and `BLOCK_WORKFLOW_MAX_STEPS`), `BlockStepQuote` / `BlockRunConfirmedStepHostError` (+ `BLOCK_CONFIRMED_STEP_MAX_BUZZ_PER_JOB`, `BLOCK_STEP_QUOTE_ID_REGEX`), `BlockModel3dOutput`, `BlockWorkflowSnapshot`, `WorkflowStatus`, `BlockInitPayload`, `ParentToBlockMessage`, `BlockToParentMessage`. |
|
|
144
144
|
|
|
145
145
|
`WorkflowBody`'s `customComfy` member is a discriminated union on `mode`, mirroring
|
|
146
146
|
the host's `blockCustomComfyMemberSchema`. Narrow on the VALUE (`body.mode === 'inline'`),
|
|
@@ -209,6 +209,46 @@ const body: WorkflowBody = {
|
|
|
209
209
|
};
|
|
210
210
|
```
|
|
211
211
|
|
|
212
|
+
**Above the per-call budget: a confirmed step.** A pass-through job the per-call budget refuses
|
|
213
|
+
can still run when the **viewer confirms its exact price** in Civitai's own dialog
|
|
214
|
+
(civitai/civitai#5786). When the orchestrator quotes a **fixed** price (positive, not variable
|
|
215
|
+
or metered) above the token's per-call budget and at most `BLOCK_CONFIRMED_STEP_MAX_BUZZ_PER_JOB`
|
|
216
|
+
(5,000), the `estimate` reply carries `snapshot.stepQuote` (`quoteId`, `total`, `stepType`,
|
|
217
|
+
`expiresAt`). Send the same body back with that `quoteId` on the `RUN_CONFIRMED_STEP` bridge
|
|
218
|
+
(`CONFIRMED_STEP_RESULT`); a `quoteId` body sent as an ordinary submit is refused. A quote is
|
|
219
|
+
single-use and expires after 15 minutes. Only a **single** estimate carries `stepQuote` — a
|
|
220
|
+
batch estimate stores nothing, so its cells never do. Where a quote would be granted, the
|
|
221
|
+
estimate **fails instead** (`{ workflowId: 'failed', status: 'failed', error }`) for a training
|
|
222
|
+
`$type` in any casing (`a training step type cannot run as a confirmed step — use kind:'training'`) and for an
|
|
223
|
+
`input` that is not plain JSON (`a confirmed step needs plain JSON input (objects, arrays,
|
|
224
|
+
strings, finite numbers, booleans, null) — <path> is <what>`; the suffix varies, so match on
|
|
225
|
+
the text before the dash). Each confirmation is its own job, so a
|
|
226
|
+
`submission-unconfirmed` result — the outcome is unknown — must never be retried automatically:
|
|
227
|
+
a retry is a new, separately charged job. Page apps only, `ai:write:budgeted`, behind the host
|
|
228
|
+
flag `app-blocks-confirmed-step` (off by default), and refused for development, dev-tunnel and
|
|
229
|
+
review tokens — so it is exercised against the mock host, not `dev:live`. Use it through
|
|
230
|
+
`@civitai/blocks-react`'s `useRunConfirmedStep()`.
|
|
231
|
+
|
|
232
|
+
**3D outputs.** A step that produces 3D models (`polyGen`) still lists every model url in
|
|
233
|
+
`snapshot.imageUrls`; `snapshot.model3dOutputs` (and the same field on an `AppWorkflow` row)
|
|
234
|
+
labels them. Omitted when there are none.
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
import type { BlockModel3dOutput, BlockWorkflowSnapshot } from '@civitai/app-sdk/blocks';
|
|
238
|
+
|
|
239
|
+
// `format` is the model's file format; `variant` is the output it came from.
|
|
240
|
+
function pickModel(
|
|
241
|
+
snapshot: BlockWorkflowSnapshot,
|
|
242
|
+
format: string,
|
|
243
|
+
variant: string,
|
|
244
|
+
): BlockModel3dOutput | undefined {
|
|
245
|
+
return snapshot.model3dOutputs?.find((m) => m.format === format && m.variant === variant);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const mesh = pickModel(snapshot, 'glb', 'model');
|
|
249
|
+
const rigged = pickModel(snapshot, 'fbx', 'riggedFbxModel');
|
|
250
|
+
```
|
|
251
|
+
|
|
212
252
|
`WorkflowBodyTraining` (`kind: 'training'`) is the **quoted** way to train: an ai-toolkit LoRA
|
|
213
253
|
run on a dataset Civitai prepared from the viewer's own images, mirroring the host's
|
|
214
254
|
`blockTrainingBodySchema` (civitai/civitai#5434). There is no `maxBuzz` and no timeout — the
|
|
@@ -259,10 +299,15 @@ const body: WorkflowBody = {
|
|
|
259
299
|
|
|
260
300
|
- 🔴 **The estimate is not a maximum.** The orchestrator re-prices a step once the values it
|
|
261
301
|
references are known and charges the difference.
|
|
262
|
-
- **A workflow the host cannot price
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
`
|
|
302
|
+
- **A workflow the host cannot price has no estimate, but its submit still proceeds.** The
|
|
303
|
+
estimate (and a batch-estimate cell) fails with no `cost` and `snapshot.errorCode`
|
|
304
|
+
`workflow_quote_rejected` (the orchestrator refused the body; the same body will fail again),
|
|
305
|
+
`workflow_quote_unavailable` (no usable answer; the one a retry can clear) or
|
|
306
|
+
`workflow_quote_unpriced` (an answer without a price). The submit of the same body is reserved
|
|
307
|
+
at the ceiling above — unless it contains a training step (refused without a quote on both, as
|
|
308
|
+
on the single-step arm) or a `repeat` step at any depth (also refused on both, before any
|
|
309
|
+
reservation, as `workflow_repeat_unbounded`; its `error` states the cause). An older host
|
|
310
|
+
returns the ceiling as the estimate's `cost.total` instead of failing.
|
|
266
311
|
- **One author fee per workflow**, on the quoted base, itemised as `cost.authorFee` on the
|
|
267
312
|
estimate. If the workflow bills more, the fee charged is held to the fee shown; a workflow that
|
|
268
313
|
does not succeed has its whole fee reversed, even if earlier steps delivered output.
|
|
@@ -277,8 +322,8 @@ const body: WorkflowBody = {
|
|
|
277
322
|
- A refused body carries `snapshot.errorCode`: `workflow_step_denied` (a platform-internal
|
|
278
323
|
`$type`), `workflow_ref_invalid` (a reference to the step itself, a later step, or nothing, or a
|
|
279
324
|
step name that breaks the naming rules, or a malformed `repeat`/`merge`),
|
|
280
|
-
`workflow_repeat_unbounded` (a `repeat` not over an array in `arguments`, or over 16 iterations
|
|
281
|
-
or `workflow_too_many_steps`. The single-step pass-through arm refuses `repeat` outright.
|
|
325
|
+
`workflow_repeat_unbounded` (a `repeat` not over an array in `arguments`, or over 16 iterations,
|
|
326
|
+
or a `repeat` with no price quote) or `workflow_too_many_steps`. The single-step pass-through arm refuses `repeat` outright.
|
|
282
327
|
- Requires a host that knows the kind; an older host refuses the body.
|
|
283
328
|
|
|
284
329
|
### `defineBlock` validator rules
|
package/dist/blocks/index.d.ts
CHANGED
|
@@ -109,9 +109,14 @@ export { isModelSlotContext, isPageSlotContext } from './types.js';
|
|
|
109
109
|
* in `types.ts` for which of the two it uses and why.
|
|
110
110
|
*/
|
|
111
111
|
export { isSignedIn } from './types.js';
|
|
112
|
-
export type { BlockContext, KnownSlotId, ModelSlotId, PageSlotContext, PageSlotId, UnknownSlotContext, BlockAnalyticsDeclaration, BlockAnalyticsEventDeclaration, BlockAnalyticsPropertyDeclaration, BlockManifest, BlockManifestGood, BlockManifestV1, BlockSettings, BlockToken, ContentRating, ManifestBooleanField, ManifestIframe, ManifestNumberField, ManifestPage, ManifestPreview, ManifestSettingField, ManifestSettings, ManifestStringField, ManifestTarget, ModelSlotContext, SettingScope, SettingWidget, Theme, ViewerInfo, BlockCheckpointInfo, BlockResourceInfo, BlockResourcePickerType, BlockSourceImage, BlockUploadedImageInfo, BlockGenerationSourceImageInfo, BlockPendingImageInfo, BlockImageScanResult, BlockUploadPurpose, BlockNavigateScope, BlockTextToImageParams, BlockWorkflowSnapshot, BlockEstimateBatchAggregate, BlockModelSubstitution, ModelSubstitutionReason, KnownBlockWorkflowErrorCode, BlockStepToolCall, BlockTrainedEpoch, BlockPublishedModel, BuzzAccountType, ShowcaseImage, WorkflowBody, WorkflowBodyTextToImage, WorkflowBodyCustomComfy, WorkflowBodyCustomComfyRecipe, WorkflowBodyCustomComfyInline, InlineComfyNode, WorkflowBodyStep, WorkflowBodyPassThroughStep, WorkflowBodyWorkflow, WorkflowBodyWorkflowStep, WorkflowStepRef, WithWorkflowStepRefs, BlockWorkflowStepSnapshot, WorkflowStatus, BlockBuzzTransaction, BlockBuzzAccount, BlockDailyCompensationResource, BlockViewer, BlockWildcardPack, BlockWildcardPackErrorCode, AppWorkflow, AppWorkflowImage, BlockGatedImage, BlockCollectionFollowErrorCode, BlockCollectionFollowResult, BlockPostSource, BlockCreatePostRequest, BlockCreatePostResult, BlockCreatePostHostError, WorkflowBodyTraining, AiToolkitTrainingParams, AiToolkitTrainingParamsBase, AiToolkitPlainEcosystem, AiToolkitLrScheduler, AiToolkitOptimizerType, BlockTrainingQuote, BlockTrainingDatasetItem, BlockTrainingDatasetResult, BlockTrainingRejectionReason, BlockPrepareTrainingDatasetHostError, BlockRunTrainingHostError, } from './types.js';
|
|
112
|
+
export type { BlockContext, KnownSlotId, ModelSlotId, PageSlotContext, PageSlotId, UnknownSlotContext, BlockAnalyticsDeclaration, BlockAnalyticsEventDeclaration, BlockAnalyticsPropertyDeclaration, BlockManifest, BlockManifestGood, BlockManifestV1, BlockSettings, BlockToken, ContentRating, ManifestBooleanField, ManifestIframe, ManifestNumberField, ManifestPage, ManifestPreview, ManifestSettingField, ManifestSettings, ManifestStringField, ManifestTarget, ModelSlotContext, SettingScope, SettingWidget, Theme, ViewerInfo, BlockCheckpointInfo, BlockResourceInfo, BlockResourcePickerType, BlockSourceImage, BlockUploadedImageInfo, BlockGenerationSourceImageInfo, BlockPendingImageInfo, BlockImageScanResult, BlockUploadPurpose, BlockNavigateScope, BlockTextToImageParams, BlockWorkflowSnapshot, BlockEstimateBatchAggregate, BlockModelSubstitution, ModelSubstitutionReason, KnownBlockWorkflowErrorCode, BlockStepToolCall, BlockTrainedEpoch, BlockPublishedModel, BuzzAccountType, ShowcaseImage, WorkflowBody, WorkflowBodyTextToImage, WorkflowBodyCustomComfy, WorkflowBodyCustomComfyRecipe, WorkflowBodyCustomComfyInline, InlineComfyNode, WorkflowBodyStep, WorkflowBodyPassThroughStep, WorkflowBodyWorkflow, WorkflowBodyWorkflowStep, WorkflowStepRef, WithWorkflowStepRefs, BlockWorkflowStepSnapshot, WorkflowStatus, BlockBuzzTransaction, BlockBuzzAccount, BlockDailyCompensationResource, BlockViewer, BlockWildcardPack, BlockWildcardPackErrorCode, AppWorkflow, AppWorkflowImage, BlockGatedImage, BlockCollectionFollowErrorCode, BlockCollectionFollowResult, BlockPostSource, BlockCreatePostRequest, BlockCreatePostResult, BlockCreatePostHostError, WorkflowBodyTraining, AiToolkitTrainingParams, AiToolkitTrainingParamsBase, AiToolkitPlainEcosystem, AiToolkitLrScheduler, AiToolkitOptimizerType, BlockTrainingQuote, BlockTrainingDatasetItem, BlockTrainingDatasetResult, BlockTrainingRejectionReason, BlockPrepareTrainingDatasetHostError, BlockRunTrainingHostError, BlockStepQuote, BlockModel3dOutput, BlockRunConfirmedStepHostError, } from './types.js';
|
|
113
113
|
/** Host bound for the App Blocks `kind: 'workflow'` body — see `WorkflowBodyWorkflow`. */
|
|
114
114
|
export { BLOCK_WORKFLOW_MAX_STEPS, BLOCK_WORKFLOW_REPEAT_MAX_ITERATIONS } from './types.js';
|
|
115
|
+
/**
|
|
116
|
+
* Host bounds for a viewer-confirmed pass-through step, mirrored from
|
|
117
|
+
* civitai/civitai — see `BlockWorkflowSnapshot.stepQuote`.
|
|
118
|
+
*/
|
|
119
|
+
export { BLOCK_CONFIRMED_STEP_MAX_BUZZ_PER_JOB, BLOCK_STEP_QUOTE_ID_REGEX } from './types.js';
|
|
115
120
|
/**
|
|
116
121
|
* Host bounds for the App Blocks `kind: 'training'` flow, mirrored from
|
|
117
122
|
* civitai/civitai's zod — see `WorkflowBodyTraining`.
|
package/dist/blocks/index.js
CHANGED
|
@@ -110,6 +110,11 @@ export { isModelSlotContext, isPageSlotContext } from './types.js';
|
|
|
110
110
|
export { isSignedIn } from './types.js';
|
|
111
111
|
/** Host bound for the App Blocks `kind: 'workflow'` body — see `WorkflowBodyWorkflow`. */
|
|
112
112
|
export { BLOCK_WORKFLOW_MAX_STEPS, BLOCK_WORKFLOW_REPEAT_MAX_ITERATIONS } from './types.js';
|
|
113
|
+
/**
|
|
114
|
+
* Host bounds for a viewer-confirmed pass-through step, mirrored from
|
|
115
|
+
* civitai/civitai — see `BlockWorkflowSnapshot.stepQuote`.
|
|
116
|
+
*/
|
|
117
|
+
export { BLOCK_CONFIRMED_STEP_MAX_BUZZ_PER_JOB, BLOCK_STEP_QUOTE_ID_REGEX } from './types.js';
|
|
113
118
|
/**
|
|
114
119
|
* Host bounds for the App Blocks `kind: 'training'` flow, mirrored from
|
|
115
120
|
* civitai/civitai's zod — see `WorkflowBodyTraining`.
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Wire format: `window.postMessage({ type, payload }, targetOrigin)`.
|
|
9
9
|
*/
|
|
10
10
|
import type { ColorDomain } from './browsingLevel.js';
|
|
11
|
-
import type { BlockCheckpointInfo, BlockResourceInfo, BlockResourcePickerType, BlockUploadedImageInfo, BlockGenerationSourceImageInfo, BlockPendingImageInfo, BlockImageScanResult, BlockUploadPurpose, BlockNavigateScope, BlockContext, BlockSettings, Theme, ViewerInfo, WorkflowBody, BlockWorkflowSnapshot, BlockEstimateBatchAggregate, BlockBuzzTransaction, BlockBuzzAccount, BlockDailyCompensationResource, BlockViewer, BlockWildcardPack, BlockWildcardPackErrorCode, AppWorkflow, BlockGatedImage, BlockCollectionFollowErrorCode, BlockCollectionFollowResult, BlockPostSource, BlockCreatePostResult, BlockTrainingDatasetItem, BlockTrainingDatasetResult, WorkflowBodyTraining } from './types.js';
|
|
11
|
+
import type { BlockCheckpointInfo, BlockResourceInfo, BlockResourcePickerType, BlockUploadedImageInfo, BlockGenerationSourceImageInfo, BlockPendingImageInfo, BlockImageScanResult, BlockUploadPurpose, BlockNavigateScope, BlockContext, BlockSettings, Theme, ViewerInfo, WorkflowBody, BlockWorkflowSnapshot, BlockEstimateBatchAggregate, BlockBuzzTransaction, BlockBuzzAccount, BlockDailyCompensationResource, BlockViewer, BlockWildcardPack, BlockWildcardPackErrorCode, AppWorkflow, BlockGatedImage, BlockCollectionFollowErrorCode, BlockCollectionFollowResult, BlockPostSource, BlockCreatePostResult, BlockTrainingDatasetItem, BlockTrainingDatasetResult, WorkflowBodyTraining, WorkflowBodyPassThroughStep } from './types.js';
|
|
12
12
|
/**
|
|
13
13
|
* Filter params for `GET_BUZZ_TRANSACTIONS`. All optional; the host validates
|
|
14
14
|
* them server-side (they are NEVER trusted for auth — the account is self-bound
|
|
@@ -508,6 +508,13 @@ export type ParentToBlockMessage = {
|
|
|
508
508
|
snapshot?: BlockWorkflowSnapshot;
|
|
509
509
|
error?: string;
|
|
510
510
|
};
|
|
511
|
+
} | {
|
|
512
|
+
type: 'CONFIRMED_STEP_RESULT';
|
|
513
|
+
payload: {
|
|
514
|
+
requestId: string;
|
|
515
|
+
snapshot?: BlockWorkflowSnapshot;
|
|
516
|
+
error?: string;
|
|
517
|
+
};
|
|
511
518
|
} | {
|
|
512
519
|
type: 'IMAGES_RESULT';
|
|
513
520
|
payload: {
|
|
@@ -846,6 +853,12 @@ export type BlockToParentMessage = {
|
|
|
846
853
|
requestId: string;
|
|
847
854
|
body: WorkflowBodyTraining;
|
|
848
855
|
};
|
|
856
|
+
} | {
|
|
857
|
+
type: 'RUN_CONFIRMED_STEP';
|
|
858
|
+
payload: {
|
|
859
|
+
requestId: string;
|
|
860
|
+
body: WorkflowBodyPassThroughStep;
|
|
861
|
+
};
|
|
849
862
|
} | {
|
|
850
863
|
type: 'GET_IMAGES_BY_IDS';
|
|
851
864
|
payload: {
|
|
@@ -1093,7 +1106,7 @@ export type BlockToParentMessageType = BlockToParentMessage['type'];
|
|
|
1093
1106
|
* it is a measurement, not an invariant, and civitai's own compile-time gate
|
|
1094
1107
|
* (published SDK union ⊆ `keyof INVENTORY`) is what holds one direction of it.
|
|
1095
1108
|
*/
|
|
1096
|
-
export declare const BLOCK_TO_PARENT_MESSAGE_TYPES: readonly ["BLOCK_HELLO", "BLOCK_READY", "BLOCK_ERROR", "BLOCK_MESSAGE_REJECTED", "REQUEST_TOKEN", "RESIZE_IFRAME", "SUBMIT_WORKFLOW", "ESTIMATE_WORKFLOW", "ESTIMATE_WORKFLOW_BATCH", "POLL_WORKFLOW", "CANCEL_WORKFLOW", "OPEN_BUZZ_PURCHASE", "GET_BUZZ_BALANCE", "GET_VIEWER", "GET_BUZZ_TRANSACTIONS", "GET_BUZZ_ACCOUNTS", "GET_DAILY_COMPENSATION", "GET_WILDCARD_PACK", "QUERY_APP_WORKFLOWS", "PUBLISH_GENERATION_OUTPUTS", "CREATE_POST_FROM_APP", "PREPARE_TRAINING_DATASET", "RUN_TRAINING", "GET_IMAGES_BY_IDS", "CANCEL_APP_WORKFLOW", "OPEN_CHECKPOINT_PICKER", "OPEN_RESOURCE_PICKER", "OPEN_IMAGE_UPLOAD", "SET_USER_CHECKPOINT", "NAVIGATE", "REQUEST_SIGN_IN", "REQUEST_CONSENT", "TRACK_EVENT", "APP_STORAGE_GET", "APP_STORAGE_SET", "APP_STORAGE_DELETE", "APP_STORAGE_LIST", "APP_STORAGE_QUOTA", "SHARED_LIST", "SHARED_GET_COUNT", "SHARED_GET_COUNTS", "SHARED_APPEND", "SHARED_VOTE", "SHARED_UNVOTE", "SHARED_WITHDRAW", "SHARED_UPDATE", "SHARED_GET", "SHARED_REPORT", "SAVE_IMAGE", "SET_COLLECTION_FOLLOW"];
|
|
1109
|
+
export declare const BLOCK_TO_PARENT_MESSAGE_TYPES: readonly ["BLOCK_HELLO", "BLOCK_READY", "BLOCK_ERROR", "BLOCK_MESSAGE_REJECTED", "REQUEST_TOKEN", "RESIZE_IFRAME", "SUBMIT_WORKFLOW", "ESTIMATE_WORKFLOW", "ESTIMATE_WORKFLOW_BATCH", "POLL_WORKFLOW", "CANCEL_WORKFLOW", "OPEN_BUZZ_PURCHASE", "GET_BUZZ_BALANCE", "GET_VIEWER", "GET_BUZZ_TRANSACTIONS", "GET_BUZZ_ACCOUNTS", "GET_DAILY_COMPENSATION", "GET_WILDCARD_PACK", "QUERY_APP_WORKFLOWS", "PUBLISH_GENERATION_OUTPUTS", "CREATE_POST_FROM_APP", "PREPARE_TRAINING_DATASET", "RUN_TRAINING", "RUN_CONFIRMED_STEP", "GET_IMAGES_BY_IDS", "CANCEL_APP_WORKFLOW", "OPEN_CHECKPOINT_PICKER", "OPEN_RESOURCE_PICKER", "OPEN_IMAGE_UPLOAD", "SET_USER_CHECKPOINT", "NAVIGATE", "REQUEST_SIGN_IN", "REQUEST_CONSENT", "TRACK_EVENT", "APP_STORAGE_GET", "APP_STORAGE_SET", "APP_STORAGE_DELETE", "APP_STORAGE_LIST", "APP_STORAGE_QUOTA", "SHARED_LIST", "SHARED_GET_COUNT", "SHARED_GET_COUNTS", "SHARED_APPEND", "SHARED_VOTE", "SHARED_UNVOTE", "SHARED_WITHDRAW", "SHARED_UPDATE", "SHARED_GET", "SHARED_REPORT", "SAVE_IMAGE", "SET_COLLECTION_FOLLOW"];
|
|
1097
1110
|
/**
|
|
1098
1111
|
* The bucket a message type falls into when the protocol does not declare it.
|
|
1099
1112
|
*
|
package/dist/blocks/messages.js
CHANGED
package/dist/blocks/types.d.ts
CHANGED
|
@@ -1251,7 +1251,39 @@ export type WorkflowBodyPassThroughStep = {
|
|
|
1251
1251
|
* viewer as a maximum.
|
|
1252
1252
|
*/
|
|
1253
1253
|
maxBuzz: number;
|
|
1254
|
+
/**
|
|
1255
|
+
* The viewer-confirmable quote this job is charged against —
|
|
1256
|
+
* {@link BlockStepQuote.quoteId} from this body's own estimate
|
|
1257
|
+
* (`sq_` + 32 lowercase hex characters, {@link BLOCK_STEP_QUOTE_ID_REGEX}).
|
|
1258
|
+
*
|
|
1259
|
+
* OMIT it everywhere except a CONFIRMED run: an estimate never carries it,
|
|
1260
|
+
* and neither does an ordinary submit. It is REQUIRED on
|
|
1261
|
+
* `RUN_CONFIRMED_STEP` (`useRunConfirmedStep()` in `@civitai/blocks-react`),
|
|
1262
|
+
* the only message that can run a job priced above the token's per-call
|
|
1263
|
+
* budget — see {@link BlockWorkflowSnapshot.stepQuote} for the flow.
|
|
1264
|
+
*
|
|
1265
|
+
* 🔴 A body carrying it is NOT runnable through `SUBMIT_WORKFLOW`. The server
|
|
1266
|
+
* charges a confirmed job only against a quote the viewer confirmed in
|
|
1267
|
+
* Civitai's own dialog from a signed-in session, so the same body sent as a
|
|
1268
|
+
* plain submit is refused. Change nothing else in the body between the
|
|
1269
|
+
* estimate and the run: the server checks it against the quoted one
|
|
1270
|
+
* (`quoteId` itself is excluded from that comparison).
|
|
1271
|
+
*/
|
|
1272
|
+
quoteId?: string;
|
|
1254
1273
|
};
|
|
1274
|
+
/**
|
|
1275
|
+
* Ceiling on what ONE viewer-confirmed pass-through job may cost, in Buzz. Host
|
|
1276
|
+
* constant `BLOCK_CONFIRMED_STEP_MAX_BUZZ_PER_JOB`. A fixed price above it gets
|
|
1277
|
+
* no {@link BlockWorkflowSnapshot.stepQuote} and cannot be run from an app.
|
|
1278
|
+
*/
|
|
1279
|
+
export declare const BLOCK_CONFIRMED_STEP_MAX_BUZZ_PER_JOB = 5000;
|
|
1280
|
+
/**
|
|
1281
|
+
* The shape of a confirmed-step quote id ({@link BlockStepQuote.quoteId}): `sq_`
|
|
1282
|
+
* followed by 32 lowercase hex characters. Host constant
|
|
1283
|
+
* `BLOCK_STEP_QUOTE_ID_REGEX`. Disjoint from the training quote's `tq_` shape,
|
|
1284
|
+
* so neither kind's id can name the other's quote.
|
|
1285
|
+
*/
|
|
1286
|
+
export declare const BLOCK_STEP_QUOTE_ID_REGEX: RegExp;
|
|
1255
1287
|
/**
|
|
1256
1288
|
* The most steps one `kind: 'workflow'` body may carry. The host refuses a
|
|
1257
1289
|
* longer list with `errorCode: 'workflow_too_many_steps'`; an empty list is
|
|
@@ -1386,12 +1418,21 @@ export type WorkflowBodyWorkflowStep = {
|
|
|
1386
1418
|
* earlier step, the orchestrator re-prices that step once the referenced
|
|
1387
1419
|
* values are known and charges the difference. Show the estimate as an
|
|
1388
1420
|
* estimate; never as "you will pay at most".
|
|
1389
|
-
* 2. **A workflow the host cannot price
|
|
1390
|
-
*
|
|
1391
|
-
*
|
|
1392
|
-
*
|
|
1393
|
-
*
|
|
1394
|
-
* `
|
|
1421
|
+
* 2. **A workflow the host cannot price has no estimate, but its submit still
|
|
1422
|
+
* proceeds.** `estimate()` (and that body's cell in a batch estimate) FAILS
|
|
1423
|
+
* with no `cost` and `errorCode` `'workflow_quote_rejected'`,
|
|
1424
|
+
* `'workflow_quote_unavailable'` or `'workflow_quote_unpriced'` — see
|
|
1425
|
+
* {@link BlockWorkflowSnapshot.errorCode} for which of them a retry can
|
|
1426
|
+
* clear. `submit()` of the same body is NOT refused: it is reserved at the
|
|
1427
|
+
* ceiling above instead of at a quote. So a failed estimate does not predict
|
|
1428
|
+
* a refused submit. Two exceptions are refused on BOTH, before any
|
|
1429
|
+
* reservation: a workflow containing a training step, exactly as on the
|
|
1430
|
+
* single-step arm (a `training-quote-*` `errorCode`), and one with a
|
|
1431
|
+
* `repeat` step at any depth (`errorCode: 'workflow_repeat_unbounded'`).
|
|
1432
|
+
* Their `error` states the cause; only "none could be obtained; try again"
|
|
1433
|
+
* is one a retry of the same body can clear.
|
|
1434
|
+
* (An OLDER host returns the ceiling as the estimate's `cost.total` instead
|
|
1435
|
+
* of failing, so there a total equal to the ceiling may be unpriced.)
|
|
1395
1436
|
* 3. **One author fee per workflow**, not one per step, computed on the
|
|
1396
1437
|
* QUOTED base. The estimate's `cost.authorFee` is that single fee, already
|
|
1397
1438
|
* inside `cost.total`. If the workflow bills more than the quote, the fee
|
|
@@ -1700,15 +1741,21 @@ export interface BlockWorkflowSnapshot {
|
|
|
1700
1741
|
*
|
|
1701
1742
|
* WHERE IT APPEARS today: the refusal for a pass-through `step` body
|
|
1702
1743
|
* ({@link WorkflowBodyPassThroughStep}) whose `$type` is a training type
|
|
1703
|
-
* (`'training'` or `'imageResourceTraining'
|
|
1744
|
+
* (`'training'` or `'imageResourceTraining'`, in any casing — the host
|
|
1745
|
+
* compares `$type` case-insensitively) when the host could not get a
|
|
1704
1746
|
* price quote for it. That refusal is `{ workflowId: 'failed', status:
|
|
1705
1747
|
* 'failed', error, errorCode }` with no `cost`, and it is the reply to
|
|
1706
1748
|
* `estimate()` (which rejects with `WorkflowEstimateError`), to `submit()`
|
|
1707
1749
|
* (which rejects with `WorkflowSubmitError`, before anything is reserved or
|
|
1708
1750
|
* charged), and to that body's cell in a batch estimate. Read it from the
|
|
1709
|
-
* error's `.snapshot.errorCode`.
|
|
1751
|
+
* error's `.snapshot.errorCode`. A `kind: 'training'` ESTIMATE does not set
|
|
1752
|
+
* it. The confirmed SUBMIT of a training run or a confirmed step can — see
|
|
1753
|
+
* `'daily-limit-exceeded'` below.
|
|
1710
1754
|
* A refused `kind: 'workflow'` body ({@link WorkflowBodyWorkflow}) sets it in
|
|
1711
|
-
* the same shape, on the same three replies
|
|
1755
|
+
* the same shape, on the same three replies — except the three
|
|
1756
|
+
* `workflow_quote_*` codes, which are ESTIMATE-ONLY (`estimate()` and a
|
|
1757
|
+
* batch-estimate cell): `submit()` of the same body defines no such refusal
|
|
1758
|
+
* and proceeds, reserved at the ceiling.
|
|
1712
1759
|
*
|
|
1713
1760
|
* The values the host sends today ({@link KnownBlockWorkflowErrorCode}):
|
|
1714
1761
|
* - `'training-quote-rejected'` — the orchestrator refused the request
|
|
@@ -1717,6 +1764,15 @@ export interface BlockWorkflowSnapshot {
|
|
|
1717
1764
|
* - `'training-quote-unavailable'` — no usable answer (an outage, a timeout,
|
|
1718
1765
|
* a rate limit, insufficient funds, …). Retrying later may succeed.
|
|
1719
1766
|
* - `'training-quote-unpriced'` — the orchestrator answered without a price.
|
|
1767
|
+
* - `'daily-limit-exceeded'` — a viewer-confirmed job (a `kind: 'training'`
|
|
1768
|
+
* run or a confirmed step) would exceed what remains today of the daily
|
|
1769
|
+
* Buzz limit THE VIEWER set for this app. Nothing was charged and no job
|
|
1770
|
+
* was started; the confirm cannot override it, and only the viewer can
|
|
1771
|
+
* raise the limit. This one arrives on the failed snapshot a confirmed
|
|
1772
|
+
* SUBMIT resolves (`{ workflowId: 'failed', status: 'failed', cost, error,
|
|
1773
|
+
* errorCode }`), not on an estimate. On a confirmed step the host also
|
|
1774
|
+
* reports it as the `error` code of `CONFIRMED_STEP_RESULT` — see
|
|
1775
|
+
* {@link BlockRunConfirmedStepHostError}.
|
|
1720
1776
|
* - `'workflow_step_denied'` — a step of a `kind: 'workflow'` body names a
|
|
1721
1777
|
* platform-internal `$type`. Remove or replace that step.
|
|
1722
1778
|
* - `'workflow_ref_invalid'` — a {@link WorkflowStepRef} in a step's `input`
|
|
@@ -1728,10 +1784,30 @@ export interface BlockWorkflowSnapshot {
|
|
|
1728
1784
|
* - `'workflow_repeat_unbounded'` — a `repeat` step iterates something other
|
|
1729
1785
|
* than an array in the body's `arguments`, or more than
|
|
1730
1786
|
* {@link BLOCK_WORKFLOW_REPEAT_MAX_ITERATIONS} times, nested repeats
|
|
1731
|
-
* multiplied; or the workflow has a `repeat` and the host
|
|
1732
|
-
*
|
|
1733
|
-
* a price quote and
|
|
1734
|
-
*
|
|
1787
|
+
* multiplied; or the workflow has a `repeat` and the host has no price
|
|
1788
|
+
* quote for it. `error` then reads `workflow step N: a workflow with a
|
|
1789
|
+
* repeat needs a price quote and <cause>`, where `<cause>` is one of the
|
|
1790
|
+
* three in the `workflow_quote_*` messages below. A retry of the same body
|
|
1791
|
+
* can succeed only when the cause is `none could be obtained; try again`;
|
|
1792
|
+
* otherwise the body is what has to change.
|
|
1793
|
+
* - `'workflow_quote_rejected'` — ESTIMATE only. The orchestrator refused
|
|
1794
|
+
* the body, so there is no price to show; resending the same body will not
|
|
1795
|
+
* help. `error` reads `No price quote for this workflow: the orchestrator
|
|
1796
|
+
* rejected the request: <reason>` when the reason is safe to show, else
|
|
1797
|
+
* `No price quote for this workflow: the orchestrator rejected the request;
|
|
1798
|
+
* check the step inputs and references (retrying the same body will not
|
|
1799
|
+
* help)`.
|
|
1800
|
+
* - `'workflow_quote_unavailable'` — ESTIMATE only. No usable answer (an
|
|
1801
|
+
* outage, a timeout, a rate limit, …). The one `workflow_quote_*` code a
|
|
1802
|
+
* retry of the same body can clear. `error` reads `No price quote for this
|
|
1803
|
+
* workflow: none could be obtained; try again`.
|
|
1804
|
+
* - `'workflow_quote_unpriced'` — ESTIMATE only. The orchestrator answered
|
|
1805
|
+
* without a price. `error` reads `No price quote for this workflow: the
|
|
1806
|
+
* orchestrator answered without one`.
|
|
1807
|
+
*
|
|
1808
|
+
* Each `workflow_quote_*` reply is `{ workflowId: 'failed', status: 'failed',
|
|
1809
|
+
* error, errorCode }` with NO `cost`. A host that predates these codes
|
|
1810
|
+
* resolves the estimate instead, with the spend ceiling as `cost.total`.
|
|
1735
1811
|
*
|
|
1736
1812
|
* 🔴 AN UNKNOWN VALUE IS POSSIBLE: the host may add codes, and the SDK's
|
|
1737
1813
|
* inbound validator accepts any string here. Handle an unrecognised code as a
|
|
@@ -1939,6 +2015,84 @@ export interface BlockWorkflowSnapshot {
|
|
|
1939
2015
|
* that predate civitai/civitai#5434.
|
|
1940
2016
|
*/
|
|
1941
2017
|
trainingQuote?: BlockTrainingQuote;
|
|
2018
|
+
/**
|
|
2019
|
+
* The viewer-confirmable quote a pass-through `step` ESTIMATE
|
|
2020
|
+
* ({@link WorkflowBodyPassThroughStep}) produced, when the job costs more than
|
|
2021
|
+
* the app may spend without asking. Its presence means: this job cannot run
|
|
2022
|
+
* through `submit()`, and CAN run through `useRunConfirmedStep()` once the
|
|
2023
|
+
* viewer confirms `stepQuote.total` in Civitai's own dialog.
|
|
2024
|
+
*
|
|
2025
|
+
* THE FLOW, mirroring a training run's:
|
|
2026
|
+
* 1. `useBuzzWorkflow().estimate(body)` — the reply carries `stepQuote`.
|
|
2027
|
+
* 2. `useRunConfirmedStep().runConfirmedStep({ ...body, quoteId:
|
|
2028
|
+
* stepQuote.quoteId })` — Civitai shows the viewer the price (read back
|
|
2029
|
+
* from the server, never from the body) and submits on their confirm.
|
|
2030
|
+
* 3. `useBuzzWorkflow().watch(snapshot.workflowId)`.
|
|
2031
|
+
*
|
|
2032
|
+
* WHEN THE HOST SENDS IT — all of these, decided server-side:
|
|
2033
|
+
* - the orchestrator quoted a **FIXED** price for exactly this step:
|
|
2034
|
+
* positive, and not a variable or metered one. The viewer confirms what
|
|
2035
|
+
* they are charged, so a price that may move is never confirmable;
|
|
2036
|
+
* - that price is ABOVE the token's per-call budget and at most
|
|
2037
|
+
* {@link BLOCK_CONFIRMED_STEP_MAX_BUZZ_PER_JOB} (5,000 Buzz);
|
|
2038
|
+
* - the block runs in a page app for a signed-in viewer on an ordinary
|
|
2039
|
+
* token. Development, dev-tunnel and review sessions never get one, and
|
|
2040
|
+
* neither does the model slot.
|
|
2041
|
+
* Everywhere else the field is ABSENT and the estimate is exactly what it was.
|
|
2042
|
+
* Absent is therefore not an error — it is also what every host that
|
|
2043
|
+
* predates civitai/civitai#5786 sends.
|
|
2044
|
+
*
|
|
2045
|
+
* 🔴 ONLY A SINGLE ESTIMATE CARRIES IT. A batch estimate
|
|
2046
|
+
* (`ESTIMATE_WORKFLOW_BATCH`, `useBatchEstimate()`) stores nothing, so its
|
|
2047
|
+
* cells never have a `stepQuote`, whatever they cost. Price a grid in a batch,
|
|
2048
|
+
* then estimate the one body you want to run on its own.
|
|
2049
|
+
*
|
|
2050
|
+
* 🔴 TWO BODIES MAKE THAT ESTIMATE FAIL INSTEAD OF RETURNING A PRICE — only
|
|
2051
|
+
* where a quote would otherwise have been granted (so not below the budget,
|
|
2052
|
+
* and not in a batch). The reply is the failure snapshot `{ workflowId:
|
|
2053
|
+
* 'failed', status: 'failed', error }`, which `estimate()` rejects with; the
|
|
2054
|
+
* same text arrives as `CONFIRMED_STEP_RESULT`'s `error` if such a body is
|
|
2055
|
+
* run. Neither has an {@link BlockWorkflowSnapshot.errorCode}; they are
|
|
2056
|
+
* server messages, so match on the text and keep a generic branch:
|
|
2057
|
+
* - `a training step type cannot run as a confirmed step — use
|
|
2058
|
+
* kind:'training'` — `$type` is `training` or `imageResourceTraining`, in
|
|
2059
|
+
* any casing.
|
|
2060
|
+
* Training has its own kind ({@link WorkflowBodyTraining}).
|
|
2061
|
+
* - `a confirmed step needs plain JSON input (objects, arrays, strings,
|
|
2062
|
+
* finite numbers, booleans, null) — <path> is <what>` — `input` holds a
|
|
2063
|
+
* `Date`, `Map`, `Set`, class instance, `BigInt`, `NaN`/`Infinity`, an
|
|
2064
|
+
* `undefined` array element or an empty slot in a sparse array
|
|
2065
|
+
* (`… — body.input.list[1] is an empty array slot`). The quote is bound to the exact body, so the
|
|
2066
|
+
* body must be exactly representable. The part after the dash names the
|
|
2067
|
+
* offending path (`body.input.when is a Date`) and varies: match on the
|
|
2068
|
+
* text BEFORE the dash.
|
|
2069
|
+
*
|
|
2070
|
+
* `total` is the price the viewer confirms and is charged. 🔴 It can differ
|
|
2071
|
+
* from `cost.total` on the same snapshot, which stays what an UNCONFIRMED
|
|
2072
|
+
* submit would reserve (`max(maxBuzz, quote)`); show `stepQuote.total` on a
|
|
2073
|
+
* confirm button. `expiresAt` is an ISO-8601 timestamp 15 minutes out; after
|
|
2074
|
+
* it the run is refused and you estimate again. A quote is single-use.
|
|
2075
|
+
*/
|
|
2076
|
+
stepQuote?: BlockStepQuote;
|
|
2077
|
+
/**
|
|
2078
|
+
* What each 3D model in {@link BlockWorkflowSnapshot.imageUrls} IS — one label
|
|
2079
|
+
* per model a pass-through step produced (e.g. `polyGen`).
|
|
2080
|
+
*
|
|
2081
|
+
* Every model url is still listed in `imageUrls`, unchanged and in the same
|
|
2082
|
+
* order as before the field existed; this only says which entry is which.
|
|
2083
|
+
* Match on `url`:
|
|
2084
|
+
*
|
|
2085
|
+
* ```ts
|
|
2086
|
+
* const glb = snapshot.model3dOutputs?.find(
|
|
2087
|
+
* (m) => m.format === 'glb' && m.variant === 'model',
|
|
2088
|
+
* );
|
|
2089
|
+
* if (glb) viewer.load(glb.url);
|
|
2090
|
+
* ```
|
|
2091
|
+
*
|
|
2092
|
+
* OMITTED when the workflow produced no 3D model, and on hosts that predate
|
|
2093
|
+
* civitai/civitai#5786 — in which case `imageUrls` is all there is.
|
|
2094
|
+
*/
|
|
2095
|
+
model3dOutputs?: BlockModel3dOutput[];
|
|
1942
2096
|
/**
|
|
1943
2097
|
* The steps of a `kind: 'workflow'` run ({@link WorkflowBodyWorkflow}), in
|
|
1944
2098
|
* the orchestrator's order, each with its own status and results. The steps a
|
|
@@ -2014,6 +2168,42 @@ export interface BlockTrainingQuote {
|
|
|
2014
2168
|
/** ISO-8601. The quote cannot be run after this. */
|
|
2015
2169
|
expiresAt: string;
|
|
2016
2170
|
}
|
|
2171
|
+
/** {@link BlockWorkflowSnapshot.stepQuote}. */
|
|
2172
|
+
export interface BlockStepQuote {
|
|
2173
|
+
/**
|
|
2174
|
+
* `sq_` + 32 lowercase hex characters ({@link BLOCK_STEP_QUOTE_ID_REGEX}).
|
|
2175
|
+
* Opaque — pass it back verbatim as the body's `quoteId`.
|
|
2176
|
+
*/
|
|
2177
|
+
quoteId: string;
|
|
2178
|
+
/** The exact price the viewer confirms and is charged, in Buzz. */
|
|
2179
|
+
total: number;
|
|
2180
|
+
/** The orchestrator `$type` that was priced — the body's own `$type`. */
|
|
2181
|
+
stepType: string;
|
|
2182
|
+
/** ISO-8601. The quote cannot be run after this. */
|
|
2183
|
+
expiresAt: string;
|
|
2184
|
+
}
|
|
2185
|
+
/**
|
|
2186
|
+
* One entry of {@link BlockWorkflowSnapshot.model3dOutputs} /
|
|
2187
|
+
* {@link AppWorkflow.model3dOutputs} — the label for one 3D model url.
|
|
2188
|
+
*/
|
|
2189
|
+
export interface BlockModel3dOutput {
|
|
2190
|
+
/** The model's url. Also present in the snapshot's `imageUrls` (an `AppWorkflow`'s `images`). */
|
|
2191
|
+
url: string;
|
|
2192
|
+
/**
|
|
2193
|
+
* The model's own file format as the orchestrator reports it — `'glb'`,
|
|
2194
|
+
* `'fbx'`, …. An open set: compare against the formats your viewer loads and
|
|
2195
|
+
* ignore the rest.
|
|
2196
|
+
*/
|
|
2197
|
+
format: string;
|
|
2198
|
+
/**
|
|
2199
|
+
* Which output of the step this model is: the output field it came from,
|
|
2200
|
+
* dot-joined when nested — `'model'`, `'riggedFbxModel'`,
|
|
2201
|
+
* `'basicAnimations.walkingModel'`, …. An array index is a segment
|
|
2202
|
+
* (`'models.0'`), and it is `''` when the step's whole output is the model.
|
|
2203
|
+
* The names are the orchestrator's, per `$type`; nothing here lists them.
|
|
2204
|
+
*/
|
|
2205
|
+
variant: string;
|
|
2206
|
+
}
|
|
2017
2207
|
/**
|
|
2018
2208
|
* Why the host substituted a checkpoint version — see
|
|
2019
2209
|
* {@link BlockWorkflowSnapshot.modelSubstitutions}.
|
|
@@ -2040,7 +2230,7 @@ export type ModelSubstitutionReason = 'wrong-workflow' | 'unrecognized' | 'gated
|
|
|
2040
2230
|
* and the SDK's inbound validator accepts any string. Handle an unrecognised
|
|
2041
2231
|
* code as a generic failure.
|
|
2042
2232
|
*/
|
|
2043
|
-
export type KnownBlockWorkflowErrorCode = 'training-quote-rejected' | 'training-quote-unavailable' | 'training-quote-unpriced' | 'workflow_step_denied' | 'workflow_ref_invalid' | 'workflow_too_many_steps' | 'workflow_repeat_unbounded';
|
|
2233
|
+
export type KnownBlockWorkflowErrorCode = 'training-quote-rejected' | 'training-quote-unavailable' | 'training-quote-unpriced' | 'daily-limit-exceeded' | 'workflow_step_denied' | 'workflow_ref_invalid' | 'workflow_too_many_steps' | 'workflow_repeat_unbounded' | 'workflow_quote_rejected' | 'workflow_quote_unavailable' | 'workflow_quote_unpriced';
|
|
2044
2234
|
/** One entry of {@link BlockWorkflowSnapshot.modelSubstitutions}. */
|
|
2045
2235
|
export interface BlockModelSubstitution {
|
|
2046
2236
|
/** The checkpoint version id the block asked for. */
|
|
@@ -2696,6 +2886,13 @@ export interface AppWorkflow {
|
|
|
2696
2886
|
* absence as "unknown", not as "no checkpoint".
|
|
2697
2887
|
*/
|
|
2698
2888
|
trainedEpochs?: BlockTrainedEpoch[];
|
|
2889
|
+
/**
|
|
2890
|
+
* Labels for the 3D models among this workflow's {@link AppWorkflow.images} —
|
|
2891
|
+
* same shape and rule as {@link BlockWorkflowSnapshot.model3dOutputs}: every
|
|
2892
|
+
* labelled `url` is also an entry of `images`, and the field is OMITTED when
|
|
2893
|
+
* there are none (and on hosts that predate it).
|
|
2894
|
+
*/
|
|
2895
|
+
model3dOutputs?: BlockModel3dOutput[];
|
|
2699
2896
|
}
|
|
2700
2897
|
/**
|
|
2701
2898
|
* Per-viewer gated projection of ONE image returned by `GET_IMAGES_BY_IDS`
|
|
@@ -3013,5 +3210,37 @@ export type BlockPrepareTrainingDatasetHostError = 'review-mode' | 'block is not
|
|
|
3013
3210
|
* run is a SECOND, separately charged run.
|
|
3014
3211
|
*/
|
|
3015
3212
|
export type BlockRunTrainingHostError = 'review-mode' | 'block is not ready' | 'sign in to train' | 'invalid training request' | 'no block token' | 'declined' | 'submission-unconfirmed';
|
|
3213
|
+
/**
|
|
3214
|
+
* The HOST'S OWN refusal codes on a `CONFIRMED_STEP_RESULT`'s `error`. Mirrors
|
|
3215
|
+
* civitai/civitai's `RUN_CONFIRMED_STEP_HOST_ERRORS`
|
|
3216
|
+
* (`src/components/AppBlocks/runConfirmedStepGate.ts`, civitai/civitai#5786).
|
|
3217
|
+
*
|
|
3218
|
+
* 🔴 THE SET A BLOCK MAY RELY ON, NOT THE SET IT MAY RECEIVE: server messages
|
|
3219
|
+
* (an expired or already-used quote, a body that differs from the quoted one, a
|
|
3220
|
+
* price that changed, `confirmed steps from apps are not enabled`) arrive
|
|
3221
|
+
* verbatim in the same field.
|
|
3222
|
+
*
|
|
3223
|
+
* - `review-mode` — a mod-review sandbox with "run for real" off.
|
|
3224
|
+
* - `block is not ready` — the host handshake has not completed.
|
|
3225
|
+
* - `sign in to run` — anonymous viewer; there is no account to charge.
|
|
3226
|
+
* - `invalid confirmed step request` — the body is not a pass-through
|
|
3227
|
+
* `kind: 'step'` body naming an `sq_`-shaped `quoteId`.
|
|
3228
|
+
* - `no block token` — the host holds no block token yet.
|
|
3229
|
+
* - `declined` — the viewer dismissed the confirm. 🔴 GUARANTEED to mean NO JOB
|
|
3230
|
+
* WAS SUBMITTED. The quote is untouched and can still be run before it
|
|
3231
|
+
* expires.
|
|
3232
|
+
* - `daily-limit-exceeded` — the job would exceed what remains today of the
|
|
3233
|
+
* daily Buzz limit the VIEWER set for this app. NO job was submitted and
|
|
3234
|
+
* nothing was charged. The host has already told the viewer, in its own
|
|
3235
|
+
* chrome, and pointed them at where to raise the limit; there is no confirm
|
|
3236
|
+
* to click and nothing the app can do about it. Do not retry.
|
|
3237
|
+
* - `submission-unconfirmed` — the submit was SENT but its outcome is unknown.
|
|
3238
|
+
* 🔴 The job MAY BE RUNNING AND CHARGED. Every confirmation is its own job,
|
|
3239
|
+
* so a retry (which needs a new estimate and a new confirmation) starts a
|
|
3240
|
+
* SECOND, separately charged job if the first one did start. Check the
|
|
3241
|
+
* viewer's generations (`useAppWorkflows()`) before offering one, and never
|
|
3242
|
+
* retry automatically.
|
|
3243
|
+
*/
|
|
3244
|
+
export type BlockRunConfirmedStepHostError = 'review-mode' | 'block is not ready' | 'sign in to run' | 'invalid confirmed step request' | 'no block token' | 'declined' | 'daily-limit-exceeded' | 'submission-unconfirmed';
|
|
3016
3245
|
export {};
|
|
3017
3246
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/blocks/types.js
CHANGED
|
@@ -115,6 +115,22 @@ export function isSignedIn(viewer) {
|
|
|
115
115
|
return viewer !== null && viewer !== undefined;
|
|
116
116
|
}
|
|
117
117
|
// ============================================================
|
|
118
|
+
// Confirmed steps (a pass-through job above the per-call budget)
|
|
119
|
+
// ============================================================
|
|
120
|
+
/**
|
|
121
|
+
* Ceiling on what ONE viewer-confirmed pass-through job may cost, in Buzz. Host
|
|
122
|
+
* constant `BLOCK_CONFIRMED_STEP_MAX_BUZZ_PER_JOB`. A fixed price above it gets
|
|
123
|
+
* no {@link BlockWorkflowSnapshot.stepQuote} and cannot be run from an app.
|
|
124
|
+
*/
|
|
125
|
+
export const BLOCK_CONFIRMED_STEP_MAX_BUZZ_PER_JOB = 5000;
|
|
126
|
+
/**
|
|
127
|
+
* The shape of a confirmed-step quote id ({@link BlockStepQuote.quoteId}): `sq_`
|
|
128
|
+
* followed by 32 lowercase hex characters. Host constant
|
|
129
|
+
* `BLOCK_STEP_QUOTE_ID_REGEX`. Disjoint from the training quote's `tq_` shape,
|
|
130
|
+
* so neither kind's id can name the other's quote.
|
|
131
|
+
*/
|
|
132
|
+
export const BLOCK_STEP_QUOTE_ID_REGEX = /^sq_[a-f0-9]{32}$/;
|
|
133
|
+
// ============================================================
|
|
118
134
|
// App Blocks MULTI-STEP kind (`kind: 'workflow'`)
|
|
119
135
|
// ============================================================
|
|
120
136
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
*
|
|
26
26
|
* - **`./blocks`** — importing it RUNS `./safe-storage` for its side effect
|
|
27
27
|
* (repairing `localStorage`/`sessionStorage` at an opaque origin). Folding
|
|
28
|
-
*
|
|
28
|
+
* 172 symbols and that side effect into the root would make every OAuth app
|
|
29
29
|
* that writes `import { exchangeCode } from '@civitai/app-sdk'` pay for the
|
|
30
30
|
* Civitai-Apps contract it does not use. Blocks and OAuth apps are disjoint
|
|
31
31
|
* audiences; see this package's README.
|
|
32
|
-
* 🔴 That
|
|
32
|
+
* 🔴 That 172 is ASSERTED, not merely quoted — by
|
|
33
33
|
* `packages/civitai-app-sdk/test/export-surface.test.ts`, which pins
|
|
34
34
|
* `surface.get('./blocks').size`. It said 119 here against a real 125 until
|
|
35
35
|
* 2026-10-04, because the existing checks pin the root as an exact union and
|
package/dist/index.js
CHANGED
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
*
|
|
26
26
|
* - **`./blocks`** — importing it RUNS `./safe-storage` for its side effect
|
|
27
27
|
* (repairing `localStorage`/`sessionStorage` at an opaque origin). Folding
|
|
28
|
-
*
|
|
28
|
+
* 172 symbols and that side effect into the root would make every OAuth app
|
|
29
29
|
* that writes `import { exchangeCode } from '@civitai/app-sdk'` pay for the
|
|
30
30
|
* Civitai-Apps contract it does not use. Blocks and OAuth apps are disjoint
|
|
31
31
|
* audiences; see this package's README.
|
|
32
|
-
* 🔴 That
|
|
32
|
+
* 🔴 That 172 is ASSERTED, not merely quoted — by
|
|
33
33
|
* `packages/civitai-app-sdk/test/export-surface.test.ts`, which pins
|
|
34
34
|
* `surface.get('./blocks').size`. It said 119 here against a real 125 until
|
|
35
35
|
* 2026-10-04, because the existing checks pin the root as an exact union and
|
package/package.json
CHANGED