@fungi.computer/agar 0.0.0-stage → 0.0.1

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.
Files changed (159) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +766 -2
  3. package/dist/agent-message-meta.d.ts +74 -0
  4. package/dist/agent-message-meta.js +63 -0
  5. package/dist/agents.d.ts +170 -0
  6. package/dist/agents.js +218 -0
  7. package/dist/app-build-contract.d.ts +43 -0
  8. package/dist/app-build-contract.js +24 -0
  9. package/dist/apps.d.ts +66 -0
  10. package/dist/apps.js +47 -0
  11. package/dist/backend-declaration.d.ts +6 -0
  12. package/dist/backend-declaration.js +65 -0
  13. package/dist/backend-definition.d.ts +88 -0
  14. package/dist/backend-definition.js +158 -0
  15. package/dist/backend-refusal.d.ts +10 -0
  16. package/dist/backend-refusal.js +10 -0
  17. package/dist/backend.d.ts +30 -0
  18. package/dist/backend.js +28 -0
  19. package/dist/capabilities.d.ts +30 -0
  20. package/dist/capabilities.js +50 -0
  21. package/dist/channels.d.ts +142 -0
  22. package/dist/channels.js +97 -0
  23. package/dist/commands.d.ts +33 -0
  24. package/dist/commands.js +46 -0
  25. package/dist/computer-contracts.d.ts +73 -0
  26. package/dist/computer-contracts.js +57 -0
  27. package/dist/computer.d.ts +294 -0
  28. package/dist/computer.js +319 -0
  29. package/dist/connect.d.ts +11 -0
  30. package/dist/connect.js +211 -0
  31. package/dist/errors.d.ts +34 -0
  32. package/dist/errors.js +106 -0
  33. package/dist/failure.d.ts +2 -0
  34. package/dist/failure.js +9 -0
  35. package/dist/files.d.ts +25 -0
  36. package/dist/files.js +84 -0
  37. package/dist/game-servers.d.ts +530 -0
  38. package/dist/game-servers.js +244 -0
  39. package/dist/gills.d.ts +43 -0
  40. package/dist/gills.js +174 -0
  41. package/dist/git-commit.d.ts +143 -0
  42. package/dist/git-commit.js +251 -0
  43. package/dist/git-rpc.d.ts +310 -0
  44. package/dist/git-rpc.js +166 -0
  45. package/dist/git-steps.d.ts +579 -0
  46. package/dist/git-steps.js +804 -0
  47. package/dist/git-wire.d.ts +33 -0
  48. package/dist/git-wire.js +240 -0
  49. package/dist/git.d.ts +322 -0
  50. package/dist/git.js +98 -0
  51. package/dist/host.d.ts +97 -0
  52. package/dist/host.js +732 -0
  53. package/dist/inbox.d.ts +99 -0
  54. package/dist/inbox.js +184 -0
  55. package/dist/index.d.ts +31 -0
  56. package/dist/index.js +15 -0
  57. package/dist/inference.d.ts +17 -0
  58. package/dist/inference.js +115 -0
  59. package/dist/internal/app-error.d.ts +8 -0
  60. package/dist/internal/app-error.js +36 -0
  61. package/dist/internal/app-session.d.ts +8 -0
  62. package/dist/internal/app-session.js +551 -0
  63. package/dist/internal/back-inputs.d.ts +22 -0
  64. package/dist/internal/back-inputs.js +93 -0
  65. package/dist/internal/browser-bridge.d.ts +30 -0
  66. package/dist/internal/browser-bridge.js +203 -0
  67. package/dist/internal/capabilities.d.ts +13 -0
  68. package/dist/internal/capabilities.js +138 -0
  69. package/dist/internal/commands.d.ts +9 -0
  70. package/dist/internal/commands.js +257 -0
  71. package/dist/internal/disconnect-host.d.ts +7 -0
  72. package/dist/internal/disconnect-host.js +19 -0
  73. package/dist/internal/git-edit-tree.d.ts +6 -0
  74. package/dist/internal/git-edit-tree.js +46 -0
  75. package/dist/internal/memory-fs.d.ts +39 -0
  76. package/dist/internal/memory-fs.js +154 -0
  77. package/dist/internal/protocol.d.ts +116 -0
  78. package/dist/internal/protocol.js +6 -0
  79. package/dist/internal/query-feed.d.ts +23 -0
  80. package/dist/internal/query-feed.js +111 -0
  81. package/dist/internal/result.d.ts +22 -0
  82. package/dist/internal/result.js +61 -0
  83. package/dist/internal/rpc-contract.d.ts +24 -0
  84. package/dist/internal/rpc-contract.js +78 -0
  85. package/dist/internal/schemas.d.ts +307 -0
  86. package/dist/internal/schemas.js +524 -0
  87. package/dist/internal/store.d.ts +8 -0
  88. package/dist/internal/store.js +30 -0
  89. package/dist/internal/terminal-gate.d.ts +17 -0
  90. package/dist/internal/terminal-gate.js +94 -0
  91. package/dist/lifecycle.d.ts +44 -0
  92. package/dist/lifecycle.js +1 -0
  93. package/dist/marketplace.d.ts +159 -0
  94. package/dist/marketplace.js +102 -0
  95. package/dist/media-json.d.ts +181 -0
  96. package/dist/media-json.js +204 -0
  97. package/dist/media-library.d.ts +11 -0
  98. package/dist/media-library.js +15 -0
  99. package/dist/media-request-id.d.ts +7 -0
  100. package/dist/media-request-id.js +16 -0
  101. package/dist/media.d.ts +354 -0
  102. package/dist/media.js +654 -0
  103. package/dist/method-refusal.d.ts +64 -0
  104. package/dist/method-refusal.js +48 -0
  105. package/dist/pending.d.ts +10 -0
  106. package/dist/pending.js +10 -0
  107. package/dist/query.d.ts +76 -0
  108. package/dist/query.js +195 -0
  109. package/dist/react-mount.d.ts +23 -0
  110. package/dist/react-mount.js +108 -0
  111. package/dist/react.d.ts +41 -0
  112. package/dist/react.js +111 -0
  113. package/dist/read-copy.d.ts +103 -0
  114. package/dist/read-copy.js +195 -0
  115. package/dist/roles/files.d.ts +295 -0
  116. package/dist/roles/files.js +184 -0
  117. package/dist/root.d.ts +21 -0
  118. package/dist/root.js +1 -0
  119. package/dist/rpc.d.ts +1 -0
  120. package/dist/rpc.js +1 -0
  121. package/dist/status.d.ts +17 -0
  122. package/dist/status.js +50 -0
  123. package/dist/storage-wire.d.ts +167 -0
  124. package/dist/storage-wire.js +115 -0
  125. package/dist/storage.d.ts +72 -0
  126. package/dist/storage.js +143 -0
  127. package/dist/store.d.ts +11 -0
  128. package/dist/store.js +1 -0
  129. package/dist/test-kit/git.d.ts +31 -0
  130. package/dist/test-kit/git.js +174 -0
  131. package/dist/ui.d.ts +169 -0
  132. package/dist/ui.js +10 -0
  133. package/dist/window.d.ts +41 -0
  134. package/dist/window.js +15 -0
  135. package/dist/world.d.ts +16 -0
  136. package/dist/world.js +17 -0
  137. package/docs/api/README.md +28 -0
  138. package/docs/api/app-build-contract.md +113 -0
  139. package/docs/api/backend-declaration.md +62 -0
  140. package/docs/api/backend-definition.md +215 -0
  141. package/docs/api/backend.md +269 -0
  142. package/docs/api/errors.md +169 -0
  143. package/docs/api/files.md +91 -0
  144. package/docs/api/gills.md +164 -0
  145. package/docs/api/git-commit.md +279 -0
  146. package/docs/api/git-rpc.md +243 -0
  147. package/docs/api/git-steps.md +1010 -0
  148. package/docs/api/git-wire.md +197 -0
  149. package/docs/api/git.md +579 -0
  150. package/docs/api/index.md +2880 -0
  151. package/docs/api/media-json.md +507 -0
  152. package/docs/api/media-request-id.md +32 -0
  153. package/docs/api/modules.md +32 -0
  154. package/docs/api/query.md +253 -0
  155. package/docs/api/react.md +216 -0
  156. package/docs/api/read-copy.md +204 -0
  157. package/docs/api/rpc.md +128 -0
  158. package/docs/api/storage.md +620 -0
  159. package/package.json +197 -3
package/dist/media.js ADDED
@@ -0,0 +1,654 @@
1
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
2
+ if (value !== null && value !== void 0) {
3
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
4
+ var dispose, inner;
5
+ if (async) {
6
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
7
+ dispose = value[Symbol.asyncDispose];
8
+ }
9
+ if (dispose === void 0) {
10
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
11
+ dispose = value[Symbol.dispose];
12
+ if (async) inner = dispose;
13
+ }
14
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
15
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
16
+ env.stack.push({ value: value, dispose: dispose, async: async });
17
+ }
18
+ else if (async) {
19
+ env.stack.push({ async: true });
20
+ }
21
+ return value;
22
+ };
23
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
24
+ return function (env) {
25
+ function fail(e) {
26
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
+ env.hasError = true;
28
+ }
29
+ var r, s = 0;
30
+ function next() {
31
+ while (r = env.stack.pop()) {
32
+ try {
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
39
+ }
40
+ catch (e) {
41
+ fail(e);
42
+ }
43
+ }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
45
+ if (env.hasError) throw env.error;
46
+ }
47
+ return next();
48
+ };
49
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
50
+ var e = new Error(message);
51
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
+ });
53
+ import * as z from "zod";
54
+ import { defineCapability } from "./capabilities.js";
55
+ import { rpcDataSchema, rpcHandleSchema, rpcMethod, rpcVoid, } from "./internal/rpc-contract.js";
56
+ import * as Schema from "effect/Schema";
57
+ export { mediaLibraryRequestSchema, mediaLibraryPathSchema, mediaLibraryResponseSchema, } from "./media-library.js";
58
+ import { AppError } from "./errors.js";
59
+ import { ownedRpcValue } from "./internal/capabilities.js";
60
+ /** A decoded Media failure; null stage means the host could not identify it. */
61
+ export class MediaGenerationError extends AppError {
62
+ stage;
63
+ constructor(failure) {
64
+ super(failure.message, {
65
+ code: failure.code,
66
+ retryable: failure.retryable,
67
+ });
68
+ this.stage = failure.stage ?? null;
69
+ }
70
+ }
71
+ /** One narrow Media capability: discover the retained catalog and generate. */
72
+ const text = (maximum) => Schema.String.pipe(Schema.check(Schema.isMinLength(1)), Schema.check(Schema.isMaxLength(maximum)));
73
+ /** A replay identity, never an authorization capability. */
74
+ export const mediaGenerationReferenceSchema = Schema.Struct({
75
+ requestId: text(256),
76
+ computerId: text(256),
77
+ });
78
+ const safeInteger = Schema.Number.pipe(Schema.check(Schema.isInt()), Schema.check(Schema.makeFilter(Number.isSafeInteger, {
79
+ message: "Expected a safe integer",
80
+ })));
81
+ const positiveInteger = safeInteger.pipe(Schema.check(Schema.isGreaterThan(0)));
82
+ const nonNegativeInteger = safeInteger.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(0)));
83
+ /** Video frame/reference role, interpreted by the host's model catalog. */
84
+ export const mediaVideoReferenceRoleSchema = Schema.Literals([
85
+ "first-frame",
86
+ "last-frame",
87
+ "reference",
88
+ ]);
89
+ /** A supported wire resolution. The host refines it against the chosen model. */
90
+ export const mediaVideoResolutionSchema = Schema.Literals([
91
+ "480p",
92
+ "720p",
93
+ "768p",
94
+ "1080p",
95
+ "4k",
96
+ ]);
97
+ /** A supported wire aspect. The host refines it against the chosen model. */
98
+ export const mediaVideoAspectRatioSchema = Schema.Literals([
99
+ "16:9",
100
+ "4:3",
101
+ "1:1",
102
+ "3:4",
103
+ "9:16",
104
+ "21:9",
105
+ "9:21",
106
+ ]);
107
+ const referenceSchema = Schema.Struct({
108
+ path: text(4_096),
109
+ role: Schema.optional(mediaVideoReferenceRoleSchema),
110
+ });
111
+ /** Path-only video reference. The host supplies Computer authority. */
112
+ export const mediaVideoReferenceSchema = Schema.Struct({
113
+ /** Computer-relative image path. */
114
+ path: text(4_096),
115
+ /** First frame, last frame or reference-image mode. */
116
+ role: mediaVideoReferenceRoleSchema,
117
+ });
118
+ const resultReferenceSchema = Schema.Struct({
119
+ computerId: text(256),
120
+ path: text(4_096),
121
+ });
122
+ const modelInputSchema = Schema.Struct({
123
+ defaultHeight: positiveInteger,
124
+ defaultSteps: Schema.NullOr(nonNegativeInteger),
125
+ defaultWidth: positiveInteger,
126
+ dimensions: Schema.Literals(["none", "own"]),
127
+ maxDimension: Schema.NullOr(positiveInteger),
128
+ maxReferences: nonNegativeInteger,
129
+ maxSteps: Schema.NullOr(positiveInteger),
130
+ referenceField: Schema.NullOr(text(256)),
131
+ steps: Schema.Literals(["steps", "num_steps", "fixed"]),
132
+ transport: Schema.Literals(["json", "multipart"]),
133
+ });
134
+ /** Host-described video capabilities and costs. This is wire grammar, not a catalog. */
135
+ export const mediaVideoModelSchema = Schema.Struct({
136
+ /** Smallest duration; the durations list owns exact membership. */
137
+ minSeconds: positiveInteger,
138
+ /** Largest duration. */
139
+ maxSeconds: positiveInteger,
140
+ /** Default whole seconds. */
141
+ defaultSeconds: positiveInteger,
142
+ /** Exact admitted duration values. */
143
+ durations: Schema.Array(positiveInteger),
144
+ /** Provider translation family. */
145
+ provider: Schema.Literals(["seedance", "veo", "minimax"]),
146
+ /** Resolution/aspect selectors and nominal dimensions. */
147
+ formats: Schema.Array(Schema.Struct({
148
+ /** Provider resolution selector. */
149
+ resolution: mediaVideoResolutionSchema,
150
+ /** Requested aspect selector. */
151
+ aspectRatio: mediaVideoAspectRatioSchema,
152
+ /** Nominal width, not measured MP4 dimensions. */
153
+ width: positiveInteger,
154
+ /** Nominal height, not measured MP4 dimensions. */
155
+ height: positiveInteger,
156
+ })),
157
+ /** Default resolution. */
158
+ defaultResolution: mediaVideoResolutionSchema,
159
+ /** Default requested aspect. */
160
+ defaultAspectRatio: mediaVideoAspectRatioSchema,
161
+ /** Audio default, or null when the provider default is undocumented. */
162
+ defaultGenerateAudio: Schema.NullOr(Schema.Boolean),
163
+ /** Host/provider prompt bound. */
164
+ maxPromptLength: positiveInteger,
165
+ /** Roles admitted by this model. */
166
+ referenceRoles: Schema.Array(mediaVideoReferenceRoleSchema),
167
+ /** Maximum images in reference-image mode. */
168
+ maxReferenceImages: nonNegativeInteger,
169
+ /** Resolutions admitting reference-image mode. */
170
+ referenceResolutions: Schema.Array(mediaVideoResolutionSchema),
171
+ /** Host-described costs, where 1 USD is 100,000 milliunits. */
172
+ prices: Schema.Array(Schema.Struct({
173
+ /** Billed provider resolution. */
174
+ resolution: mediaVideoResolutionSchema,
175
+ /** Provider milliunits per silent output second. */
176
+ silentMilliunitsPerSecond: positiveInteger,
177
+ /** Provider milliunits per output second with audio. */
178
+ audioMilliunitsPerSecond: positiveInteger,
179
+ })),
180
+ });
181
+ /** Validates one model row of the host's Media catalog. */
182
+ export const mediaModelSchema = Schema.Struct({
183
+ id: text(256),
184
+ input: modelInputSchema,
185
+ kind: Schema.Literals(["image", "video"]),
186
+ label: text(512),
187
+ tier: Schema.Literals(["draft", "balanced", "premium", "max"]),
188
+ outputFormats: Schema.Array(Schema.Literals(["png", "jpeg", "webp"])).pipe(Schema.check(Schema.isMaxLength(3))),
189
+ sizes: Schema.NullOr(Schema.Array(Schema.String.pipe(Schema.check(Schema.isPattern(/^\d+x\d+$/u))))),
190
+ video: Schema.NullOr(mediaVideoModelSchema),
191
+ });
192
+ const modelsSchema = Schema.Array(mediaModelSchema);
193
+ const descriptionSchema = Schema.Struct({
194
+ [Symbol.dispose]: Schema.optional(Schema.Unknown),
195
+ computerId: text(256),
196
+ models: modelsSchema,
197
+ canGenerate: Schema.Boolean,
198
+ });
199
+ /** The most reference images one generation request may name. */
200
+ export const MAX_MEDIA_REFERENCES = 4;
201
+ /**
202
+ * Validates the shape of an App's generation settings. Model-specific limits
203
+ * (sizes, steps, durations, reference counts) and defaults are the host's:
204
+ * it checks the selection against its catalog when it accepts a generation.
205
+ */
206
+ export const mediaGenerationSelectionSchema = Schema.Struct({
207
+ model: text(256),
208
+ prompt: text(2_048),
209
+ width: positiveInteger.pipe(Schema.check(Schema.isLessThanOrEqualTo(5_040))),
210
+ height: positiveInteger.pipe(Schema.check(Schema.isLessThanOrEqualTo(5_040))),
211
+ steps: Schema.optional(positiveInteger),
212
+ durationSeconds: Schema.optional(positiveInteger),
213
+ resolution: Schema.optional(mediaVideoResolutionSchema),
214
+ aspectRatio: Schema.optional(mediaVideoAspectRatioSchema),
215
+ generateAudio: Schema.optional(Schema.Boolean),
216
+ references: Schema.optional(Schema.Array(referenceSchema).pipe(Schema.check(Schema.isMaxLength(MAX_MEDIA_REFERENCES)))),
217
+ });
218
+ /** Path-only video selection. Model defaults and combination refinements remain host-owned. */
219
+ export const mediaVideoSelectionSchema = Schema.Struct({
220
+ /** Host catalog model identifier. */
221
+ model: text(256),
222
+ /** Host-bounded prompt. */
223
+ prompt: text(2_048),
224
+ /** Optional provider resolution selector. */
225
+ resolution: Schema.optional(mediaVideoResolutionSchema),
226
+ /** Optional requested aspect selector. */
227
+ aspectRatio: Schema.optional(mediaVideoAspectRatioSchema),
228
+ /** Whole seconds, 4 through 15; the host checks exact model membership. */
229
+ durationSeconds: Schema.optional(positiveInteger.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(4)), Schema.check(Schema.isLessThanOrEqualTo(15)))),
230
+ /** Explicit audio choice. The host owns omitted defaults. */
231
+ generateAudio: Schema.optional(Schema.Boolean),
232
+ /** At most four paths with explicit frame/reference roles. */
233
+ references: Schema.optional(Schema.Array(mediaVideoReferenceSchema).pipe(Schema.check(Schema.isMaxLength(MAX_MEDIA_REFERENCES)))),
234
+ });
235
+ /** Public diagnostic stages a host may name when a generation fails. */
236
+ export const mediaFailureStages = [
237
+ "admission",
238
+ "generation-authorization",
239
+ "settings",
240
+ "estimate",
241
+ "billing",
242
+ "operation",
243
+ "provider",
244
+ "normalization",
245
+ "artifact",
246
+ "destination-authorization",
247
+ "destination-write",
248
+ ];
249
+ /** Validates a generation input envelope; settings are parsed separately. */
250
+ export const mediaGenerationInputWireSchema = Schema.Struct({
251
+ destination: Schema.Struct({ path: text(4_096) }),
252
+ settings: Schema.Unknown,
253
+ });
254
+ /** Completed image or video metadata saved to a host-admitted destination. */
255
+ export const mediaGenerationResultSchema = Schema.Struct({
256
+ // Cap'n Web decorates returned object envelopes with a disposal owner.
257
+ [Symbol.dispose]: Schema.optional(Schema.Unknown),
258
+ bytes: positiveInteger,
259
+ costMilliunits: nonNegativeInteger,
260
+ destination: resultReferenceSchema,
261
+ format: Schema.Literals(["png", "jpeg", "gif", "webp", "mp4"]),
262
+ height: positiveInteger,
263
+ model: text(256),
264
+ width: positiveInteger,
265
+ });
266
+ /** Completed native MEDIA video result, with a host-admitted destination. */
267
+ export const mediaVideoResultSchema = Schema.Struct({
268
+ ...mediaGenerationResultSchema.fields,
269
+ /** Bounded fetched video encoding. */
270
+ format: Schema.Literal("mp4"),
271
+ });
272
+ /** Validates the typed failure a host reports for a generation attempt. */
273
+ export const mediaGenerationFailureSchema = Schema.Struct({
274
+ message: text(512),
275
+ stage: Schema.optional(Schema.Literals(mediaFailureStages)),
276
+ code: Schema.Literals([
277
+ "CANCELLED",
278
+ "CAPABILITY_DENIED",
279
+ "CAPABILITY_REVOKED",
280
+ "DISCONNECTED",
281
+ "HOST_FAILURE",
282
+ "IDENTITY",
283
+ "INSUFFICIENT_CREDIT",
284
+ "INVALID_ARGUMENT",
285
+ "PROTOCOL",
286
+ "SAFETY_FILTER_REFUSED",
287
+ "TIMEOUT",
288
+ ]),
289
+ retryable: Schema.Boolean,
290
+ });
291
+ const outcomeSchema = Schema.Union([
292
+ Schema.Struct({
293
+ [Symbol.dispose]: Schema.optional(Schema.Unknown),
294
+ kind: Schema.Literal("succeeded"),
295
+ result: mediaGenerationResultSchema,
296
+ }),
297
+ Schema.Struct({
298
+ [Symbol.dispose]: Schema.optional(Schema.Unknown),
299
+ kind: Schema.Literal("failed"),
300
+ failure: mediaGenerationFailureSchema,
301
+ }),
302
+ ]);
303
+ const mediaAttemptHandleSchema = rpcHandleSchema({
304
+ reference: rpcMethod(rpcDataSchema(z
305
+ .unknown()
306
+ .transform((value) => Schema.decodeUnknownSync(mediaGenerationReferenceSchema)(value)))),
307
+ generate: rpcMethod(rpcDataSchema(z.unknown().transform((value) => {
308
+ const outcome = Schema.decodeUnknownSync(outcomeSchema, {
309
+ onExcessProperty: "error",
310
+ })(value);
311
+ return outcome.kind === "succeeded"
312
+ ? {
313
+ kind: outcome.kind,
314
+ result: {
315
+ bytes: outcome.result.bytes,
316
+ costMilliunits: outcome.result.costMilliunits,
317
+ destination: outcome.result.destination,
318
+ format: outcome.result.format,
319
+ height: outcome.result.height,
320
+ model: outcome.result.model,
321
+ width: outcome.result.width,
322
+ },
323
+ }
324
+ : { kind: outcome.kind, failure: outcome.failure };
325
+ }))),
326
+ });
327
+ /** Capability contract for generating Media (images or video). Apps
328
+ * declare it to request access; openMediaGeneration uses it to obtain
329
+ * the host's handle. */
330
+ export const mediaGeneration = defineCapability("media.generation", 5, rpcHandleSchema({
331
+ describe: rpcMethod(rpcDataSchema(z.unknown().transform((value) => {
332
+ const { computerId, canGenerate, models } = Schema.decodeUnknownSync(descriptionSchema, {
333
+ onExcessProperty: "error",
334
+ })(value);
335
+ return { computerId, canGenerate, models };
336
+ }))),
337
+ createAttempt: rpcMethod(mediaAttemptHandleSchema),
338
+ restoreAttempt: rpcMethod(mediaAttemptHandleSchema),
339
+ cancelAttempt: rpcVoid,
340
+ }));
341
+ /** Parse a value received from the host and turn schema failures into the
342
+ * transport-safe Agar error used by the other capability helpers. */
343
+ function decode(schema, value) {
344
+ try {
345
+ return Schema.decodeUnknownSync(schema, {
346
+ onExcessProperty: "error",
347
+ })(value);
348
+ }
349
+ catch (cause) {
350
+ throw new AppError("The Media capability returned malformed data", {
351
+ cause,
352
+ code: "PROTOCOL",
353
+ retryable: false,
354
+ });
355
+ }
356
+ }
357
+ function capabilityFailure(cause) {
358
+ if (cause instanceof AppError)
359
+ return cause;
360
+ return new AppError("The Media capability failed", {
361
+ cause,
362
+ code: "HOST_FAILURE",
363
+ retryable: true,
364
+ });
365
+ }
366
+ function throwIfCancelled(signal) {
367
+ if (!signal?.aborted)
368
+ return;
369
+ throw new AppError("Media generation was cancelled", {
370
+ code: "CANCELLED",
371
+ retryable: false,
372
+ });
373
+ }
374
+ /** Decode and normalize a typed input envelope; storage parses the envelope first. */
375
+ export function parseMediaGenerationInput(input) {
376
+ let parsed;
377
+ try {
378
+ parsed = Schema.decodeUnknownSync(mediaGenerationInputWireSchema, {
379
+ onExcessProperty: "error",
380
+ })(input);
381
+ }
382
+ catch (cause) {
383
+ throw new AppError("Media generation input is invalid", {
384
+ cause,
385
+ code: "INVALID_ARGUMENT",
386
+ retryable: false,
387
+ });
388
+ }
389
+ let settings;
390
+ try {
391
+ settings = normalizeSelection(Schema.decodeUnknownSync(mediaGenerationSelectionSchema, {
392
+ onExcessProperty: "error",
393
+ })(parsed.settings));
394
+ }
395
+ catch (cause) {
396
+ throw new AppError("Media generation settings are invalid", {
397
+ cause,
398
+ code: "INVALID_ARGUMENT",
399
+ retryable: false,
400
+ });
401
+ }
402
+ const destination = { path: parsed.destination.path.trim() };
403
+ if (destination.path.length === 0)
404
+ throw new AppError("Media generation destination is invalid", {
405
+ code: "INVALID_ARGUMENT",
406
+ retryable: false,
407
+ });
408
+ return Object.freeze({
409
+ destination: Object.freeze(destination),
410
+ settings,
411
+ });
412
+ }
413
+ /** Trim the text fields the host compares; blank text is invalid. */
414
+ function normalizeSelection(selection) {
415
+ const trimmed = (value, name) => {
416
+ const result = value.trim();
417
+ if (result.length === 0)
418
+ throw new Error(`${name} must not be blank`);
419
+ return result;
420
+ };
421
+ const normalized = {
422
+ model: trimmed(selection.model, "model"),
423
+ prompt: trimmed(selection.prompt, "prompt"),
424
+ width: selection.width,
425
+ height: selection.height,
426
+ };
427
+ if (selection.steps !== undefined)
428
+ normalized.steps = selection.steps;
429
+ if (selection.durationSeconds !== undefined)
430
+ normalized.durationSeconds = selection.durationSeconds;
431
+ if (selection.resolution !== undefined)
432
+ normalized.resolution = selection.resolution;
433
+ if (selection.aspectRatio !== undefined)
434
+ normalized.aspectRatio = selection.aspectRatio;
435
+ if (selection.generateAudio !== undefined)
436
+ normalized.generateAudio = selection.generateAudio;
437
+ if (selection.references !== undefined)
438
+ normalized.references = Object.freeze(selection.references.map((reference) => Object.freeze({
439
+ ...reference,
440
+ path: trimmed(reference.path, "reference"),
441
+ })));
442
+ return Object.freeze(normalized);
443
+ }
444
+ /** The host owns the catalog; Agar checks only its shape and identity. */
445
+ function parseModels(value) {
446
+ const models = decode(modelsSchema, value);
447
+ const seen = new Set();
448
+ for (const model of models) {
449
+ if (seen.has(model.id))
450
+ throw new AppError("The Media capability repeated a model", {
451
+ code: "PROTOCOL",
452
+ retryable: false,
453
+ });
454
+ seen.add(model.id);
455
+ }
456
+ return Object.freeze(models.map((model) => Object.freeze(model)));
457
+ }
458
+ function parseResult(value, request, computerId) {
459
+ const result = decode(mediaGenerationResultSchema, value);
460
+ if (result.model !== request.settings.model ||
461
+ result.destination.computerId !== computerId ||
462
+ result.destination.path !== request.destination.path ||
463
+ result.width !== request.settings.width ||
464
+ result.height !== request.settings.height)
465
+ throw new AppError("The Media capability returned an unrelated result", {
466
+ code: "PROTOCOL",
467
+ retryable: false,
468
+ });
469
+ return Object.freeze({
470
+ bytes: result.bytes,
471
+ costMilliunits: result.costMilliunits,
472
+ destination: Object.freeze({ ...result.destination }),
473
+ format: result.format,
474
+ height: result.height,
475
+ model: result.model,
476
+ width: result.width,
477
+ });
478
+ }
479
+ /** Discover the exact retained model catalog surfaced by the owner. */
480
+ export async function openMediaGeneration(capabilities) {
481
+ try {
482
+ const handle = capabilities.require(mediaGeneration);
483
+ {
484
+ const env_1 = { stack: [], error: void 0, hasError: false };
485
+ try {
486
+ const response = __addDisposableResource(env_1, ownedRpcValue(await handle.describe()), false);
487
+ const description = decode(descriptionSchema, response.value);
488
+ const computerId = description.computerId.trim();
489
+ if (computerId.length === 0)
490
+ throw new AppError("The Media capability returned no Computer", {
491
+ code: "PROTOCOL",
492
+ retryable: false,
493
+ });
494
+ const models = parseModels(description.models);
495
+ const wrapAttempt = async (remote) => {
496
+ const owner = ownedRpcValue(remote);
497
+ let reference;
498
+ try {
499
+ {
500
+ const env_2 = { stack: [], error: void 0, hasError: false };
501
+ try {
502
+ const response = __addDisposableResource(env_2, ownedRpcValue(await remote.reference()), false);
503
+ const parsed = decode(Schema.Struct({
504
+ ...mediaGenerationReferenceSchema.fields,
505
+ [Symbol.dispose]: Schema.optional(Schema.Unknown),
506
+ }), response.value);
507
+ reference = {
508
+ requestId: parsed.requestId,
509
+ computerId: parsed.computerId,
510
+ };
511
+ if (reference.computerId !== computerId)
512
+ throw new AppError("Media attempt belongs to another Computer", {
513
+ code: "IDENTITY",
514
+ retryable: false,
515
+ });
516
+ }
517
+ catch (e_2) {
518
+ env_2.error = e_2;
519
+ env_2.hasError = true;
520
+ }
521
+ finally {
522
+ __disposeResources(env_2);
523
+ }
524
+ }
525
+ }
526
+ catch (cause) {
527
+ owner[Symbol.dispose]();
528
+ throw capabilityFailure(cause);
529
+ }
530
+ let disposed = false;
531
+ return {
532
+ reference: Object.freeze(reference),
533
+ async generate(input, options = {}) {
534
+ if (disposed)
535
+ throw new AppError("Media generation attempt is closed", {
536
+ code: "CAPABILITY_DENIED",
537
+ retryable: false,
538
+ });
539
+ throwIfCancelled(options.signal);
540
+ const request = parseMediaGenerationInput(input);
541
+ const signal = options.signal;
542
+ let onAbort;
543
+ let cancellation;
544
+ const requestCancellation = () => {
545
+ cancellation ??= handle.cancelAttempt(reference);
546
+ return cancellation;
547
+ };
548
+ try {
549
+ const generation = remote.generate(request);
550
+ const response = signal === undefined
551
+ ? await generation
552
+ : await Promise.race([
553
+ generation,
554
+ new Promise((_resolve, reject) => {
555
+ onAbort = () => {
556
+ void requestCancellation().then(() => {
557
+ reject(new AppError("Media generation was cancelled", {
558
+ code: "CANCELLED",
559
+ retryable: false,
560
+ }));
561
+ }, reject);
562
+ };
563
+ signal.addEventListener("abort", onAbort, {
564
+ once: true,
565
+ });
566
+ if (signal.aborted)
567
+ onAbort();
568
+ }),
569
+ ]);
570
+ if (signal?.aborted) {
571
+ await requestCancellation();
572
+ throwIfCancelled(signal);
573
+ }
574
+ throwIfCancelled(signal);
575
+ {
576
+ const env_3 = { stack: [], error: void 0, hasError: false };
577
+ try {
578
+ const owned = __addDisposableResource(env_3, ownedRpcValue(response), false);
579
+ const outcome = decode(outcomeSchema, owned.value);
580
+ if (outcome.kind === "failed")
581
+ throw new MediaGenerationError(outcome.failure);
582
+ return parseResult(outcome.result, request, computerId);
583
+ }
584
+ catch (e_3) {
585
+ env_3.error = e_3;
586
+ env_3.hasError = true;
587
+ }
588
+ finally {
589
+ __disposeResources(env_3);
590
+ }
591
+ }
592
+ }
593
+ catch (cause) {
594
+ if (signal?.aborted) {
595
+ await requestCancellation();
596
+ throwIfCancelled(signal);
597
+ }
598
+ throw capabilityFailure(cause);
599
+ }
600
+ finally {
601
+ if (onAbort !== undefined)
602
+ signal?.removeEventListener("abort", onAbort);
603
+ }
604
+ },
605
+ [Symbol.dispose]() {
606
+ if (disposed)
607
+ return;
608
+ disposed = true;
609
+ owner[Symbol.dispose]();
610
+ },
611
+ };
612
+ };
613
+ return Object.freeze({
614
+ computerId,
615
+ canGenerate: description.canGenerate,
616
+ models,
617
+ /** Start a fresh attempt scoped to this session's Computer. */
618
+ async createAttempt() {
619
+ return wrapAttempt(await handle.createAttempt());
620
+ },
621
+ /** Resume an attempt using a reference returned earlier in this
622
+ * session; the reference must match this session's Computer. */
623
+ async restoreAttempt(reference) {
624
+ const parsed = decode(mediaGenerationReferenceSchema, reference);
625
+ if (parsed.computerId !== computerId)
626
+ throw new AppError("Select the original Computer to retry this generation", {
627
+ code: "IDENTITY",
628
+ retryable: false,
629
+ });
630
+ const attempt = await wrapAttempt(await handle.restoreAttempt(parsed));
631
+ if (attempt.reference.requestId !== parsed.requestId) {
632
+ attempt[Symbol.dispose]();
633
+ throw new AppError("Media restore changed the request identity", {
634
+ code: "PROTOCOL",
635
+ retryable: false,
636
+ });
637
+ }
638
+ return attempt;
639
+ },
640
+ });
641
+ }
642
+ catch (e_1) {
643
+ env_1.error = e_1;
644
+ env_1.hasError = true;
645
+ }
646
+ finally {
647
+ __disposeResources(env_1);
648
+ }
649
+ }
650
+ }
651
+ catch (cause) {
652
+ throw capabilityFailure(cause);
653
+ }
654
+ }