@fungi.computer/darkroom 0.4.0 → 0.5.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 +2 -3
- package/dist/cloudflare.d.ts +1 -0
- package/dist/execution-error.d.ts +1 -1
- package/dist/media-operation-do.d.ts +2 -0
- package/dist/media-operation-do.js +4 -0
- package/dist/media-operation-owner.d.ts +32 -0
- package/dist/media-operation-owner.js +26 -0
- package/docs/api/cloudflare.md +59 -0
- package/docs/api/server.md +38 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -113,9 +113,8 @@ save fails. An ambiguous provider execution is never silently dispatched again.
|
|
|
113
113
|
|
|
114
114
|
Declare `metering: "unmetered"` when your host pays its provider directly. A
|
|
115
115
|
metered host supplies idempotent `admit` and `settle` functions plus its own
|
|
116
|
-
`refusalMessages` for insufficient credit
|
|
117
|
-
|
|
118
|
-
settlement.
|
|
116
|
+
`refusalMessages` for insufficient credit and denied spending. Quotes are
|
|
117
|
+
estimates. Your metering owner decides the customer price and settlement.
|
|
119
118
|
|
|
120
119
|
A recognized provider safety refusal returns HTTP 400 with
|
|
121
120
|
`code: "SAFETY_FILTER_REFUSED"`, `stage: "provider"`, and `retryable: false`.
|
package/dist/cloudflare.d.ts
CHANGED
|
@@ -3,4 +3,5 @@ export { createWorkersAiMediaProvider, type MediaAiPort, } from "./cloudflare/pr
|
|
|
3
3
|
export type { MediaAiResult } from "./index.js";
|
|
4
4
|
export { createImagesReferenceFitter, createImagesViewFitter, type MediaImagePort, } from "./cloudflare/reference-images.js";
|
|
5
5
|
export { MediaOperationOwner } from "./media-operation-owner.js";
|
|
6
|
+
export type { MediaShareSource } from "./media-operation-owner.js";
|
|
6
7
|
export type { MediaOperationContext, MediaOperationStorage, MediaOperationBucket, MediaOperationObject, } from "./media-operation-storage.js";
|
|
@@ -51,7 +51,7 @@ export declare class MediaSafetyFilterRefusal extends MediaExecutionError {
|
|
|
51
51
|
constructor(options?: MediaExecutionErrorOptions);
|
|
52
52
|
}
|
|
53
53
|
/** Why the host's billing owner refused to admit a new generation. */
|
|
54
|
-
export type MediaBillingRefusalCode = "insufficient_credits" | "
|
|
54
|
+
export type MediaBillingRefusalCode = "insufficient_credits" | "denied";
|
|
55
55
|
/** A definitive billing refusal before dispatch; nothing was generated or charged. */
|
|
56
56
|
export declare class MediaBillingRefusal extends Error {
|
|
57
57
|
/** Bounded refusal or failure reason. */
|
|
@@ -20,6 +20,8 @@ export declare class MediaOperationDO extends DurableObject<MediaOperationCloudf
|
|
|
20
20
|
protected mediaProvider(): MediaProvider | undefined;
|
|
21
21
|
/** {@inheritDoc MediaOperationOwner.read} */
|
|
22
22
|
read(...input: Parameters<MediaOperationOwner["read"]>): ReturnType<MediaOperationOwner["read"]>;
|
|
23
|
+
/** {@inheritDoc MediaOperationOwner.readShare} */
|
|
24
|
+
readShare(...input: Parameters<MediaOperationOwner["readShare"]>): ReturnType<MediaOperationOwner["readShare"]>;
|
|
23
25
|
/** {@inheritDoc MediaOperationOwner.preflightErasure} */
|
|
24
26
|
preflightErasure(...input: Parameters<MediaOperationOwner["preflightErasure"]>): ReturnType<MediaOperationOwner["preflightErasure"]>;
|
|
25
27
|
/** {@inheritDoc MediaOperationOwner.erase} */
|
|
@@ -38,6 +38,10 @@ export class MediaOperationDO extends DurableObject {
|
|
|
38
38
|
read(...input) {
|
|
39
39
|
return this.owner.read(...input);
|
|
40
40
|
}
|
|
41
|
+
/** {@inheritDoc MediaOperationOwner.readShare} */
|
|
42
|
+
readShare(...input) {
|
|
43
|
+
return this.owner.readShare(...input);
|
|
44
|
+
}
|
|
41
45
|
/** {@inheritDoc MediaOperationOwner.preflightErasure} */
|
|
42
46
|
preflightErasure(...input) {
|
|
43
47
|
return this.owner.preflightErasure(...input);
|
|
@@ -94,6 +94,31 @@ export type MediaOperationProjection = Readonly<{
|
|
|
94
94
|
/** Last transition timestamp in milliseconds since the epoch. */
|
|
95
95
|
updatedAt: number;
|
|
96
96
|
}>;
|
|
97
|
+
/** What a host needs to serve one shared output: never references or receipts. */
|
|
98
|
+
export type MediaShareSource = Readonly<{
|
|
99
|
+
/** Retry identity of the generation; a Print's id. */
|
|
100
|
+
requestId: string;
|
|
101
|
+
/** The person whose request generated it. */
|
|
102
|
+
actorUserId: string;
|
|
103
|
+
/** Retained exact provider bytes in the host's artifacts bucket. */
|
|
104
|
+
outputKey: string;
|
|
105
|
+
/** Media type of the retained bytes. */
|
|
106
|
+
contentType: string;
|
|
107
|
+
/** Length of the retained bytes. */
|
|
108
|
+
bytes: number;
|
|
109
|
+
/** Whether the output is a still image or a video. */
|
|
110
|
+
kind: "image" | "video";
|
|
111
|
+
/** The generation prompt, as sent to the model. */
|
|
112
|
+
prompt: string;
|
|
113
|
+
/** Catalog model identifier. */
|
|
114
|
+
model: string;
|
|
115
|
+
/** Requested width in pixels. */
|
|
116
|
+
width: number;
|
|
117
|
+
/** Requested height in pixels. */
|
|
118
|
+
height: number;
|
|
119
|
+
/** Video length in whole seconds; null for an image. */
|
|
120
|
+
durationSeconds: number | null;
|
|
121
|
+
}>;
|
|
97
122
|
/** An admission or claim decision with a safe operation projection. */
|
|
98
123
|
export type MediaOperationDecision = Readonly<{
|
|
99
124
|
/** Admission or claim outcome. */
|
|
@@ -160,6 +185,13 @@ export declare class MediaOperationOwner {
|
|
|
160
185
|
private readRecord;
|
|
161
186
|
/** Read the safe persisted operation projection, or null before admission or after erasure. */
|
|
162
187
|
read(): MediaOperationProjection | null;
|
|
188
|
+
/**
|
|
189
|
+
* A settled operation's retained output and recipe, for a host that lets
|
|
190
|
+
* its owner share it publicly. Null before success or for another namespace,
|
|
191
|
+
* so a share can never reach another Team's output. References are never
|
|
192
|
+
* included.
|
|
193
|
+
*/
|
|
194
|
+
readShare(namespace: string): MediaShareSource | null;
|
|
163
195
|
/** Check host namespace, request identity and inactivity before erasure. */
|
|
164
196
|
preflightErasure(namespace: string, requestId: string): MediaErasurePreflight;
|
|
165
197
|
/** Erase inactive output and local storage, then retain the durable erasure marker. */
|
|
@@ -348,6 +348,32 @@ export class MediaOperationOwner {
|
|
|
348
348
|
const record = this.readRecord();
|
|
349
349
|
return record === null ? null : this.project(record);
|
|
350
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* A settled operation's retained output and recipe, for a host that lets
|
|
353
|
+
* its owner share it publicly. Null before success or for another namespace,
|
|
354
|
+
* so a share can never reach another Team's output. References are never
|
|
355
|
+
* included.
|
|
356
|
+
*/
|
|
357
|
+
readShare(namespace) {
|
|
358
|
+
const record = this.readRecord();
|
|
359
|
+
if (record?.namespace !== namespace ||
|
|
360
|
+
record.state !== "succeeded" ||
|
|
361
|
+
record.output === null)
|
|
362
|
+
return null;
|
|
363
|
+
return Object.freeze({
|
|
364
|
+
requestId: record.requestId,
|
|
365
|
+
actorUserId: record.actorUserId,
|
|
366
|
+
outputKey: record.output.key,
|
|
367
|
+
contentType: outputMime(record.output.format),
|
|
368
|
+
bytes: record.output.bytes,
|
|
369
|
+
kind: record.output.format === "mp4" ? "video" : "image",
|
|
370
|
+
prompt: record.input.prompt,
|
|
371
|
+
model: record.input.model,
|
|
372
|
+
width: record.input.width,
|
|
373
|
+
height: record.input.height,
|
|
374
|
+
durationSeconds: record.input.durationSeconds ?? null,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
351
377
|
/** Check host namespace, request identity and inactivity before erasure. */
|
|
352
378
|
preflightErasure(namespace, requestId) {
|
|
353
379
|
if (this.ctx.id.name !== `media:${requestId}`)
|
package/docs/api/cloudflare.md
CHANGED
|
@@ -110,6 +110,43 @@ erasure.
|
|
|
110
110
|
`string`; `bytes`: `number`; `format`: `string`; `costMilliunits`: `number`; \}
|
|
111
111
|
\| `null`; `createdAt`: `number`; `updatedAt`: `number`; \}\> \| `null`
|
|
112
112
|
|
|
113
|
+
##### readShare()
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
readShare(...input):
|
|
117
|
+
| Readonly<{
|
|
118
|
+
requestId: string;
|
|
119
|
+
actorUserId: string;
|
|
120
|
+
outputKey: string;
|
|
121
|
+
contentType: string;
|
|
122
|
+
bytes: number;
|
|
123
|
+
kind: "image" | "video";
|
|
124
|
+
prompt: string;
|
|
125
|
+
model: string;
|
|
126
|
+
width: number;
|
|
127
|
+
height: number;
|
|
128
|
+
durationSeconds: number | null;
|
|
129
|
+
}>
|
|
130
|
+
| null;
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
A settled operation's retained output and recipe, for a host that lets its owner
|
|
134
|
+
share it publicly. Null before success or for another namespace, so a share can
|
|
135
|
+
never reach another Team's output. References are never included.
|
|
136
|
+
|
|
137
|
+
###### Parameters
|
|
138
|
+
|
|
139
|
+
| Parameter | Type | Description |
|
|
140
|
+
| ---------- | ------------ | ----------- |
|
|
141
|
+
| ...`input` | \[`string`\] | - |
|
|
142
|
+
|
|
143
|
+
###### Returns
|
|
144
|
+
|
|
145
|
+
\| `Readonly`\<\{ `requestId`: `string`; `actorUserId`: `string`; `outputKey`:
|
|
146
|
+
`string`; `contentType`: `string`; `bytes`: `number`; `kind`: `"image"` \|
|
|
147
|
+
`"video"`; `prompt`: `string`; `model`: `string`; `width`: `number`; `height`:
|
|
148
|
+
`number`; `durationSeconds`: `number` \| `null`; \}\> \| `null`
|
|
149
|
+
|
|
113
150
|
##### preflightErasure()
|
|
114
151
|
|
|
115
152
|
```ts
|
|
@@ -572,6 +609,28 @@ type MediaOperationCloudflareEnvironment = MediaOperationEnvironment &
|
|
|
572
609
|
|
|
573
610
|
Retention storage and native background provider bindings for the operation DO.
|
|
574
611
|
|
|
612
|
+
---
|
|
613
|
+
|
|
614
|
+
### MediaShareSource
|
|
615
|
+
|
|
616
|
+
```ts
|
|
617
|
+
type MediaShareSource = Readonly<{
|
|
618
|
+
requestId: string;
|
|
619
|
+
actorUserId: string;
|
|
620
|
+
outputKey: string;
|
|
621
|
+
contentType: string;
|
|
622
|
+
bytes: number;
|
|
623
|
+
kind: "image" | "video";
|
|
624
|
+
prompt: string;
|
|
625
|
+
model: string;
|
|
626
|
+
width: number;
|
|
627
|
+
height: number;
|
|
628
|
+
durationSeconds: number | null;
|
|
629
|
+
}>;
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
What a host needs to serve one shared output: never references or receipts.
|
|
633
|
+
|
|
575
634
|
## Functions
|
|
576
635
|
|
|
577
636
|
### createWorkersAiMediaProvider()
|
package/docs/api/server.md
CHANGED
|
@@ -207,6 +207,43 @@ erasure.
|
|
|
207
207
|
`string`; `bytes`: `number`; `format`: `string`; `costMilliunits`: `number`; \}
|
|
208
208
|
\| `null`; `createdAt`: `number`; `updatedAt`: `number`; \}\> \| `null`
|
|
209
209
|
|
|
210
|
+
##### readShare()
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
readShare(namespace):
|
|
214
|
+
| Readonly<{
|
|
215
|
+
requestId: string;
|
|
216
|
+
actorUserId: string;
|
|
217
|
+
outputKey: string;
|
|
218
|
+
contentType: string;
|
|
219
|
+
bytes: number;
|
|
220
|
+
kind: "image" | "video";
|
|
221
|
+
prompt: string;
|
|
222
|
+
model: string;
|
|
223
|
+
width: number;
|
|
224
|
+
height: number;
|
|
225
|
+
durationSeconds: number | null;
|
|
226
|
+
}>
|
|
227
|
+
| null;
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
A settled operation's retained output and recipe, for a host that lets its owner
|
|
231
|
+
share it publicly. Null before success or for another namespace, so a share can
|
|
232
|
+
never reach another Team's output. References are never included.
|
|
233
|
+
|
|
234
|
+
###### Parameters
|
|
235
|
+
|
|
236
|
+
| Parameter | Type |
|
|
237
|
+
| ----------- | -------- |
|
|
238
|
+
| `namespace` | `string` |
|
|
239
|
+
|
|
240
|
+
###### Returns
|
|
241
|
+
|
|
242
|
+
\| `Readonly`\<\{ `requestId`: `string`; `actorUserId`: `string`; `outputKey`:
|
|
243
|
+
`string`; `contentType`: `string`; `bytes`: `number`; `kind`: `"image"` \|
|
|
244
|
+
`"video"`; `prompt`: `string`; `model`: `string`; `width`: `number`; `height`:
|
|
245
|
+
`number`; `durationSeconds`: `number` \| `null`; \}\> \| `null`
|
|
246
|
+
|
|
210
247
|
##### preflightErasure()
|
|
211
248
|
|
|
212
249
|
```ts
|
|
@@ -798,8 +835,7 @@ Private cause plus an independently decoded, safe provider diagnostic.
|
|
|
798
835
|
### MediaBillingRefusalCode
|
|
799
836
|
|
|
800
837
|
```ts
|
|
801
|
-
type MediaBillingRefusalCode =
|
|
802
|
-
"insufficient_credits" | "daily_limit_reached" | "denied";
|
|
838
|
+
type MediaBillingRefusalCode = "insufficient_credits" | "denied";
|
|
803
839
|
```
|
|
804
840
|
|
|
805
841
|
Why the host's billing owner refused to admit a new generation.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fungi.computer/darkroom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"author": "Levi <levi@technomancy.dev>",
|
|
5
5
|
"description": "Media generation, durable output retention and provenance with host-owned authority and billing",
|
|
6
6
|
"type": "module",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"exifreader": "4.46.0",
|
|
60
60
|
"@fungi.computer/ts-webp": "0.1.6",
|
|
61
61
|
"@xmldom/xmldom": "0.9.12",
|
|
62
|
-
"@fungi.computer/agar": "0.
|
|
62
|
+
"@fungi.computer/agar": "0.7.0",
|
|
63
63
|
"@fungi.computer/capnweb": "0.12.0"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|