@fungi.computer/agar 0.5.0 → 0.6.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.
@@ -47,6 +47,7 @@ export declare const FungiMessageMetaSchema: z.ZodObject<{
47
47
  ancestors: z.ZodArray<z.ZodLazy<z.ZodString>>;
48
48
  maxDepth: z.ZodNumber;
49
49
  steer: z.ZodOptional<z.ZodLiteral<true>>;
50
+ goal: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<false>]>>;
50
51
  reply: z.ZodOptional<z.ZodLazy<z.ZodObject<{
51
52
  agentId: z.ZodLazy<z.ZodString>;
52
53
  sessionId: z.ZodLazy<z.ZodString>;
@@ -56,6 +56,10 @@ export const FungiMessageMetaSchema = z.strictObject({
56
56
  maxDepth: z.number().int().min(1).max(8),
57
57
  /** The sender asked to steer the recipient's running turn, not queue behind it. */
58
58
  steer: z.literal(true).optional(),
59
+ /** A new recipient Session's objective; false opts out of an automatic goal. */
60
+ goal: z
61
+ .union([z.string().min(1).max(4_000), z.literal(false)])
62
+ .optional(),
59
63
  /**
60
64
  * Present only on a line the host admitted as an authenticated reply;
61
65
  * a line's text never sets it.
package/dist/agents.js CHANGED
@@ -150,13 +150,22 @@ async function openOperationHandles(openRead, openWrite) {
150
150
  return {
151
151
  fetch: async (request) => {
152
152
  ensureOpen();
153
+ request.signal.throwIfAborted();
153
154
  const handle = request.method === "GET" ||
154
155
  request.method === "HEAD" ||
155
156
  openRead === openWrite
156
157
  ? read
157
158
  : await (write ??= openWrite());
158
159
  ensureOpen();
159
- return decodeResponse(await handle.fetch(request));
160
+ request.signal.throwIfAborted();
161
+ const response = decodeResponse(await handle.fetch(request));
162
+ if (response.body === null)
163
+ return response;
164
+ // Request signals do not cross Cap'n Web. Cancelling the local response
165
+ // pipeline cancels its remote body, including EventSource's locked reader.
166
+ return new Response(response.body.pipeThrough(new TransformStream(), {
167
+ signal: request.signal,
168
+ }), response);
160
169
  },
161
170
  close: () => {
162
171
  if (!closing) {
@@ -3,7 +3,7 @@ import * as Schema from "effect/Schema";
3
3
  import { appApiSchema, appDeclarationSchema, } from "@fungi.computer/puffball/app";
4
4
  /** Build-only API projection from the schemas used by runtime calls. */
5
5
  export function buildAppApi(backend) {
6
- let api = {
6
+ const api = {
7
7
  methods: Object.fromEntries(Object.entries(backend.methods).map(([name, method]) => [
8
8
  name,
9
9
  {
@@ -14,8 +14,7 @@ export function buildAppApi(backend) {
14
14
  ])),
15
15
  };
16
16
  if (backend.events !== undefined)
17
- api = {
18
- ...api,
17
+ Object.assign(api, {
19
18
  events: Object.fromEntries(Object.entries(backend.events).map(([name, event]) => [
20
19
  name,
21
20
  {
@@ -23,9 +22,9 @@ export function buildAppApi(backend) {
23
22
  payload: z.toJSONSchema(event.payload, { io: "output" }),
24
23
  },
25
24
  ])),
26
- };
25
+ });
27
26
  if (backend.toolFamily !== undefined)
28
- api = { ...api, toolFamily: backend.toolFamily };
27
+ Object.assign(api, { toolFamily: backend.toolFamily });
29
28
  return Schema.decodeUnknownSync(appApiSchema)(api);
30
29
  }
31
30
  /** Strict build-only declaration generation; Workers never import this module. */
@@ -23,8 +23,6 @@ export type MethodPolicy = Readonly<{
23
23
  requires: readonly AppCapabilityId[];
24
24
  /** Omit this method from Workflow and tool discovery; direct calls keep their validators. */
25
25
  hidden?: true;
26
- /** Request anonymous read admission; hosts still require explicit installer approval. */
27
- anonymous?: true;
28
26
  /** Allow the shared Pending result while this method is still working. */
29
27
  pending?: true;
30
28
  /** Past tense for timelines ("made", "wrote"); the row itself comes from {@link MethodPresentation}. */
@@ -26,8 +26,6 @@ export function defineAppMethod(method) {
26
26
  policy = { ...policy, pending: true };
27
27
  if (method.hidden === true)
28
28
  policy = { ...policy, hidden: true };
29
- if (method.anonymous === true)
30
- policy = { ...policy, anonymous: true };
31
29
  const call = async (rawInput, context, rawCaller) => {
32
30
  const caller = parseAppMethodCallContext(rawCaller);
33
31
  const parsed = method.input.parse(rawInput);
package/dist/backend.d.ts CHANGED
@@ -10,8 +10,7 @@ export declare const appBackend: CapabilityContract<{
10
10
  /**
11
11
  * Call one of this App's declared, typed methods through its host. Unlike
12
12
  * `appBackend`, the host knows which method is called, so it can apply the
13
- * method's declared effect (for example, allow only `read` methods to a
14
- * visitor of a public App).
13
+ * method's declared effect.
15
14
  */
16
15
  export declare const appMethods: CapabilityContract<{
17
16
  /** Call the named method with JSON-encoded `input`; resolves with its JSON result. */
package/dist/backend.js CHANGED
@@ -9,8 +9,7 @@ export const appBackend = defineCapability("app.backend", 1, z.lazy(() => rpcHan
9
9
  /**
10
10
  * Call one of this App's declared, typed methods through its host. Unlike
11
11
  * `appBackend`, the host knows which method is called, so it can apply the
12
- * method's declared effect (for example, allow only `read` methods to a
13
- * visitor of a public App).
12
+ * method's declared effect.
14
13
  */
15
14
  export const appMethods = defineCapability("app.methods", 1, z.lazy(() => rpcHandleSchema({
16
15
  call: rpcMethod(rpcDataSchema(z.unknown().transform((value) => parseJsonValue(value)))),
package/dist/errors.d.ts CHANGED
@@ -5,6 +5,8 @@ export type MediaProviderDiagnostic = Readonly<{
5
5
  category: "InferenceUpstreamError" | "AiInternalError" | "TypeError" | "AbortError" | "TimeoutError" | "Error";
6
6
  /** Four- or five-digit provider prefix, or null when absent. */
7
7
  code: number | null;
8
+ /** Host-classified provider refusal, independent of public error prose. */
9
+ reason?: "credits_exhausted";
8
10
  }> | Readonly<{
9
11
  /** A completed video result could not be downloaded. */
10
12
  category: "result_download";
@@ -15,25 +17,15 @@ export type MediaProviderDiagnostic = Readonly<{
15
17
  export declare function decodeMediaProviderDiagnostic(input: unknown): MediaProviderDiagnostic;
16
18
  /**
17
19
  * Documentable wire projection of the canonical diagnostic grammar.
18
- * Maintained converters preserve its closed objects and numeric bounds;
19
- * decoding still returns the declaration-safe public diagnostic type.
20
+ * Its owner supplies the native Zod dialect so output declarations remain
21
+ * documentable without transforms, coercions or an unchecked type assertion.
20
22
  */
21
- export declare const mediaProviderDiagnosticWireSchema: z.ZodPipe<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, z.ZodTransform<Readonly<{
22
- /** Allowlisted Workers AI category; never a provider message. */
23
- category: "InferenceUpstreamError" | "AiInternalError" | "TypeError" | "AbortError" | "TimeoutError" | "Error";
24
- /** Four- or five-digit provider prefix, or null when absent. */
25
- code: number | null;
26
- }> | Readonly<{
27
- /** A completed video result could not be downloaded. */
28
- category: "result_download";
29
- /** Native Response status, including zero. */
30
- status: number;
31
- }>, unknown>>;
23
+ export declare const mediaProviderDiagnosticWireSchema: z.ZodType<MediaProviderDiagnostic>;
32
24
  /** Decode an ordinary Error name without retaining arbitrary upstream text. */
33
25
  export declare function decodeMediaProviderErrorCategory(input: string | undefined): Exclude<MediaProviderDiagnostic["category"], "result_download">;
34
26
  /** The closed set of reasons an AppError can state; every SDK and
35
27
  * host-reported failure is tagged with exactly one of these codes. */
36
- export declare const appErrorCodes: readonly ["CANCELLED", "CAPABILITY_DENIED", "CAPABILITY_REVOKED", "COMMAND_NOT_DECLARED", "CONFLICT", "DELIVERY_PENDING", "DISCONNECTED", "FILE_TOO_LARGE", "HOST_FAILURE", "IDENTITY", "INSUFFICIENT_CREDIT", "INVALID_ARGUMENT", "PROTOCOL", "SAFETY_FILTER_REFUSED", "SELECTION_CHANGED", "TIMEOUT"];
28
+ export declare const appErrorCodes: readonly ["CANCELLED", "CAPABILITY_DENIED", "CAPABILITY_REVOKED", "COMMAND_NOT_DECLARED", "CONFLICT", "DELIVERY_PENDING", "DISCONNECTED", "FILE_TOO_LARGE", "HOST_FAILURE", "IDENTITY", "INSUFFICIENT_CREDIT", "INVALID_ARGUMENT", "MEDIA_PROVIDER_FAILURE", "MEDIA_PROVIDER_FAILURE_UNCHARGED", "PROTOCOL", "SAFETY_FILTER_REFUSED", "SELECTION_CHANGED", "TIMEOUT"];
37
29
  /** One closed App error code from `appErrorCodes`. */
38
30
  export type AppErrorCode = (typeof appErrorCodes)[number];
39
31
  /** One pending-delivery refusal shared by admission and the shell. */
package/dist/errors.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as Schema from "effect/Schema";
2
2
  import * as Option from "effect/Option";
3
3
  import * as z from "zod";
4
- import { mediaProviderDiagnosticSchema, mediaProviderErrorCategorySchema, } from "./internal/media-diagnostic.js";
4
+ import { mediaProviderDiagnosticSchema, mediaProviderDiagnosticZodSchema, mediaProviderErrorCategorySchema, } from "./internal/media-diagnostic.js";
5
5
  /** Decode only safe provider facts, rejecting unmodeled private fields. */
6
6
  export function decodeMediaProviderDiagnostic(input) {
7
7
  // Bidirectional projection check, erased from the Promise declaration graph.
@@ -11,14 +11,10 @@ export function decodeMediaProviderDiagnostic(input) {
11
11
  }
12
12
  /**
13
13
  * Documentable wire projection of the canonical diagnostic grammar.
14
- * Maintained converters preserve its closed objects and numeric bounds;
15
- * decoding still returns the declaration-safe public diagnostic type.
14
+ * Its owner supplies the native Zod dialect so output declarations remain
15
+ * documentable without transforms, coercions or an unchecked type assertion.
16
16
  */
17
- export const mediaProviderDiagnosticWireSchema = z
18
- .fromJSONSchema(Schema.toJsonSchemaDocument(mediaProviderDiagnosticSchema, {
19
- onExcessProperty: "error",
20
- }).schema)
21
- .transform(decodeMediaProviderDiagnostic);
17
+ export const mediaProviderDiagnosticWireSchema = mediaProviderDiagnosticZodSchema;
22
18
  /** Decode an ordinary Error name without retaining arbitrary upstream text. */
23
19
  export function decodeMediaProviderErrorCategory(input) {
24
20
  return (Option.getOrUndefined(Schema.decodeUnknownOption(mediaProviderErrorCategorySchema)(input)) ?? "Error");
@@ -38,6 +34,8 @@ export const appErrorCodes = [
38
34
  "IDENTITY",
39
35
  "INSUFFICIENT_CREDIT",
40
36
  "INVALID_ARGUMENT",
37
+ "MEDIA_PROVIDER_FAILURE",
38
+ "MEDIA_PROVIDER_FAILURE_UNCHARGED",
41
39
  "PROTOCOL",
42
40
  "SAFETY_FILTER_REFUSED",
43
41
  "SELECTION_CHANGED",
@@ -116,13 +114,21 @@ const errorCopy = {
116
114
  title: "Request not accepted",
117
115
  message: "The App couldn't use the details in this request.",
118
116
  },
117
+ MEDIA_PROVIDER_FAILURE: {
118
+ title: "Generation failed",
119
+ message: "The model couldn't complete this generation. Change the prompt or model and send again.",
120
+ },
121
+ MEDIA_PROVIDER_FAILURE_UNCHARGED: {
122
+ title: "Generation failed",
123
+ message: "The model couldn't complete this generation. You weren't charged. Change the prompt or model and send again.",
124
+ },
119
125
  PROTOCOL: {
120
126
  title: "Couldn't read the response",
121
127
  message: "The App received a response it couldn't use.",
122
128
  },
123
129
  SAFETY_FILTER_REFUSED: {
124
- title: "Safety filter refused this prompt",
125
- message: "The model's safety filter refused this prompt — try rewording.",
130
+ title: "Generation refused",
131
+ message: "The model refused this generation. Change the prompt or reference image and send again.",
126
132
  },
127
133
  SELECTION_CHANGED: {
128
134
  title: "Selection changed",
@@ -1,11 +1,29 @@
1
1
  import * as Schema from "effect/Schema";
2
+ import * as z from "zod";
2
3
  /** Names emitted by the maintained Workers AI boundary, never arbitrary names. */
3
4
  export declare const mediaProviderErrorCategorySchema: Schema.Literals<readonly ["InferenceUpstreamError", "AiInternalError", "TypeError", "AbortError", "TimeoutError", "Error"]>;
4
5
  /** One canonical grammar for safe provider facts across Media transports. */
5
6
  export declare const mediaProviderDiagnosticSchema: Schema.Union<readonly [Schema.Struct<{
6
7
  readonly category: Schema.Literals<readonly ["InferenceUpstreamError", "AiInternalError", "TypeError", "AbortError", "TimeoutError", "Error"]>;
7
8
  readonly code: Schema.NullOr<Schema.Int>;
9
+ readonly reason: Schema.optionalKey<Schema.Literal<"credits_exhausted">>;
8
10
  }>, Schema.Struct<{
9
11
  readonly category: Schema.Literal<"result_download">;
10
12
  readonly status: Schema.Int;
11
13
  }>]>;
14
+ /** Documentable Promise transport grammar; this module owns both schema dialects. */
15
+ export declare const mediaProviderDiagnosticZodSchema: z.ZodUnion<readonly [z.ZodObject<{
16
+ category: z.ZodEnum<{
17
+ InferenceUpstreamError: "InferenceUpstreamError";
18
+ AiInternalError: "AiInternalError";
19
+ TypeError: "TypeError";
20
+ AbortError: "AbortError";
21
+ TimeoutError: "TimeoutError";
22
+ Error: "Error";
23
+ }>;
24
+ code: z.ZodNullable<z.ZodNumber>;
25
+ reason: z.ZodOptional<z.ZodLiteral<"credits_exhausted">>;
26
+ }, z.core.$strict>, z.ZodObject<{
27
+ category: z.ZodLiteral<"result_download">;
28
+ status: z.ZodNumber;
29
+ }, z.core.$strict>]>;
@@ -1,21 +1,47 @@
1
1
  import * as Schema from "effect/Schema";
2
- /** Names emitted by the maintained Workers AI boundary, never arbitrary names. */
3
- export const mediaProviderErrorCategorySchema = Schema.Literals([
2
+ import * as z from "zod";
3
+ const categories = [
4
4
  "InferenceUpstreamError",
5
5
  "AiInternalError",
6
6
  "TypeError",
7
7
  "AbortError",
8
8
  "TimeoutError",
9
9
  "Error",
10
- ]);
10
+ ];
11
+ const providerCodeBounds = { minimum: 0, maximum: 99_999 };
12
+ const responseStatusBounds = { minimum: 0, maximum: 599 };
13
+ /** Names emitted by the maintained Workers AI boundary, never arbitrary names. */
14
+ export const mediaProviderErrorCategorySchema = Schema.Literals(categories);
11
15
  /** One canonical grammar for safe provider facts across Media transports. */
12
16
  export const mediaProviderDiagnosticSchema = Schema.Union([
13
17
  Schema.Struct({
14
18
  category: mediaProviderErrorCategorySchema,
15
- code: Schema.NullOr(Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 99_999 }))),
19
+ code: Schema.NullOr(Schema.Int.check(Schema.isBetween(providerCodeBounds))),
20
+ reason: Schema.optionalKey(Schema.Literal("credits_exhausted")),
16
21
  }),
17
22
  Schema.Struct({
18
23
  category: Schema.Literal("result_download"),
19
- status: Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 599 })),
24
+ status: Schema.Int.check(Schema.isBetween(responseStatusBounds)),
25
+ }),
26
+ ]);
27
+ /** Documentable Promise transport grammar; this module owns both schema dialects. */
28
+ export const mediaProviderDiagnosticZodSchema = z.union([
29
+ z.strictObject({
30
+ category: z.enum(categories),
31
+ code: z
32
+ .number()
33
+ .int()
34
+ .min(providerCodeBounds.minimum)
35
+ .max(providerCodeBounds.maximum)
36
+ .nullable(),
37
+ reason: z.literal("credits_exhausted").optional(),
38
+ }),
39
+ z.strictObject({
40
+ category: z.literal("result_download"),
41
+ status: z
42
+ .number()
43
+ .int()
44
+ .min(responseStatusBounds.minimum)
45
+ .max(responseStatusBounds.maximum),
20
46
  }),
21
47
  ]);
@@ -75,6 +75,7 @@ export declare const mediaGenerationJsonRequestSchema: Schema.Struct<{
75
75
  readonly aspectRatio: Schema.optional<Schema.Literals<readonly ["16:9", "4:3", "1:1", "3:4", "9:16", "21:9", "9:21"]>>;
76
76
  readonly generateAudio: Schema.optional<Schema.Boolean>;
77
77
  readonly references: Schema.optional<Schema.$Array<Schema.Struct<{
78
+ readonly computerId: Schema.optional<Schema.String>;
78
79
  readonly path: Schema.String;
79
80
  readonly role: Schema.optional<Schema.Literals<readonly ["first-frame", "last-frame", "reference"]>>;
80
81
  }>>>;
@@ -115,11 +116,12 @@ export declare const mediaGenerationJsonOutcomeSchema: Schema.Union<readonly [Sc
115
116
  readonly provider: Schema.optional<Schema.Union<readonly [Schema.Struct<{
116
117
  readonly category: Schema.Literals<readonly ["InferenceUpstreamError", "AiInternalError", "TypeError", "AbortError", "TimeoutError", "Error"]>;
117
118
  readonly code: Schema.NullOr<Schema.Int>;
119
+ readonly reason: Schema.optionalKey<Schema.Literal<"credits_exhausted">>;
118
120
  }>, Schema.Struct<{
119
121
  readonly category: Schema.Literal<"result_download">;
120
122
  readonly status: Schema.Int;
121
123
  }>]>>;
122
- readonly code: Schema.Literals<readonly ["CANCELLED", "CAPABILITY_DENIED", "CAPABILITY_REVOKED", "DISCONNECTED", "HOST_FAILURE", "IDENTITY", "INSUFFICIENT_CREDIT", "INVALID_ARGUMENT", "PROTOCOL", "SAFETY_FILTER_REFUSED", "TIMEOUT"]>;
124
+ readonly code: Schema.Literals<readonly ["CANCELLED", "CAPABILITY_DENIED", "CAPABILITY_REVOKED", "DISCONNECTED", "HOST_FAILURE", "IDENTITY", "INSUFFICIENT_CREDIT", "INVALID_ARGUMENT", "MEDIA_PROVIDER_FAILURE", "MEDIA_PROVIDER_FAILURE_UNCHARGED", "PROTOCOL", "SAFETY_FILTER_REFUSED", "TIMEOUT"]>;
123
125
  readonly retryable: Schema.Boolean;
124
126
  }>;
125
127
  }>]>;
@@ -151,11 +153,12 @@ export declare const mediaGenerationJsonReplySchema: Schema.Union<readonly [Sche
151
153
  readonly provider: Schema.optional<Schema.Union<readonly [Schema.Struct<{
152
154
  readonly category: Schema.Literals<readonly ["InferenceUpstreamError", "AiInternalError", "TypeError", "AbortError", "TimeoutError", "Error"]>;
153
155
  readonly code: Schema.NullOr<Schema.Int>;
156
+ readonly reason: Schema.optionalKey<Schema.Literal<"credits_exhausted">>;
154
157
  }>, Schema.Struct<{
155
158
  readonly category: Schema.Literal<"result_download">;
156
159
  readonly status: Schema.Int;
157
160
  }>]>>;
158
- readonly code: Schema.Literals<readonly ["CANCELLED", "CAPABILITY_DENIED", "CAPABILITY_REVOKED", "DISCONNECTED", "HOST_FAILURE", "IDENTITY", "INSUFFICIENT_CREDIT", "INVALID_ARGUMENT", "PROTOCOL", "SAFETY_FILTER_REFUSED", "TIMEOUT"]>;
161
+ readonly code: Schema.Literals<readonly ["CANCELLED", "CAPABILITY_DENIED", "CAPABILITY_REVOKED", "DISCONNECTED", "HOST_FAILURE", "IDENTITY", "INSUFFICIENT_CREDIT", "INVALID_ARGUMENT", "MEDIA_PROVIDER_FAILURE", "MEDIA_PROVIDER_FAILURE_UNCHARGED", "PROTOCOL", "SAFETY_FILTER_REFUSED", "TIMEOUT"]>;
159
162
  readonly retryable: Schema.Boolean;
160
163
  }>;
161
164
  }>]>, Schema.declare<Readonly<{
package/dist/media.d.ts CHANGED
@@ -278,6 +278,8 @@ export declare const mediaGenerationSelectionSchema: Schema.Struct<{
278
278
  readonly aspectRatio: Schema.optional<Schema.Literals<readonly ["16:9", "4:3", "1:1", "3:4", "9:16", "21:9", "9:21"]>>;
279
279
  readonly generateAudio: Schema.optional<Schema.Boolean>;
280
280
  readonly references: Schema.optional<Schema.$Array<Schema.Struct<{
281
+ /** Omit for the selected Computer; a named Computer requires its own authorization. */
282
+ readonly computerId: Schema.optional<Schema.String>;
281
283
  readonly path: Schema.String;
282
284
  readonly role: Schema.optional<Schema.Literals<readonly ["first-frame", "last-frame", "reference"]>>;
283
285
  }>>>;
@@ -357,11 +359,12 @@ export declare const mediaGenerationFailureSchema: Schema.Struct<{
357
359
  readonly provider: Schema.optional<Schema.Union<readonly [Schema.Struct<{
358
360
  readonly category: Schema.Literals<readonly ["InferenceUpstreamError", "AiInternalError", "TypeError", "AbortError", "TimeoutError", "Error"]>;
359
361
  readonly code: Schema.NullOr<Schema.Int>;
362
+ readonly reason: Schema.optionalKey<Schema.Literal<"credits_exhausted">>;
360
363
  }>, Schema.Struct<{
361
364
  readonly category: Schema.Literal<"result_download">;
362
365
  readonly status: Schema.Int;
363
366
  }>]>>;
364
- readonly code: Schema.Literals<readonly ["CANCELLED", "CAPABILITY_DENIED", "CAPABILITY_REVOKED", "DISCONNECTED", "HOST_FAILURE", "IDENTITY", "INSUFFICIENT_CREDIT", "INVALID_ARGUMENT", "PROTOCOL", "SAFETY_FILTER_REFUSED", "TIMEOUT"]>;
367
+ readonly code: Schema.Literals<readonly ["CANCELLED", "CAPABILITY_DENIED", "CAPABILITY_REVOKED", "DISCONNECTED", "HOST_FAILURE", "IDENTITY", "INSUFFICIENT_CREDIT", "INVALID_ARGUMENT", "MEDIA_PROVIDER_FAILURE", "MEDIA_PROVIDER_FAILURE_UNCHARGED", "PROTOCOL", "SAFETY_FILTER_REFUSED", "TIMEOUT"]>;
365
368
  readonly retryable: Schema.Boolean;
366
369
  }>;
367
370
  /** Capability contract for generating Media (images or video). Apps
package/dist/media.js CHANGED
@@ -109,6 +109,8 @@ export const mediaVideoAspectRatioSchema = Schema.Literals([
109
109
  "9:21",
110
110
  ]);
111
111
  const referenceSchema = Schema.Struct({
112
+ /** Omit for the selected Computer; a named Computer requires its own authorization. */
113
+ computerId: Schema.optional(text(256)),
112
114
  path: text(4_096),
113
115
  role: Schema.optional(mediaVideoReferenceRoleSchema),
114
116
  });
@@ -297,6 +299,8 @@ export const mediaGenerationFailureSchema = Schema.Struct({
297
299
  "IDENTITY",
298
300
  "INSUFFICIENT_CREDIT",
299
301
  "INVALID_ARGUMENT",
302
+ "MEDIA_PROVIDER_FAILURE",
303
+ "MEDIA_PROVIDER_FAILURE_UNCHARGED",
300
304
  "PROTOCOL",
301
305
  "SAFETY_FILTER_REFUSED",
302
306
  "TIMEOUT",
@@ -28,7 +28,6 @@ type MethodPolicy = Readonly<{
28
28
  effect: "read" | "write" | "external";
29
29
  requires: readonly AppCapabilityId[];
30
30
  hidden?: true;
31
- anonymous?: true;
32
31
  pending?: true;
33
32
  present?: Readonly<{
34
33
  verb: string;
@@ -229,9 +228,9 @@ Define a typed method once; neither discovery nor builds execute its handler.
229
228
 
230
229
  #### Parameters
231
230
 
232
- | Parameter | Type |
233
- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
234
- | `method` | `Omit`\<`Readonly`\<\{ `description`: `string`; `effect`: `"external"` \| `"read"` \| `"write"`; `requires`: readonly ( \| `"agent.list"` \| `"agent.manage"` \| `"agent.read"` \| `"agent.send"` \| `"computer.list"` \| `"computer.readFile"` \| `"computer.writeFile"` \| `"computer.execute"` \| `"agent.rename"` \| `"agent.avatar"` \| `"agent.toolPolicy"` \| `"approvals"` \| `"apps.open"` \| `"apps.call"` \| `"llm.generation"` \| `"media.generation"` \| `"games:servers"` \| `"git.repository"` \| `"app.storage"` \| `"app.events.emit"` \| `"team.workbenchHost"` \| `"marketplace.browse"` \| `"marketplace.purchase"` \| `"workflow.run"` \| `"workflow.publish"` \| `"workflow.arm"` \| `"world"` \| `"channels.read"` \| `"channels.personal.manage"`)[]; `hidden?`: `true`; `anonymous?`: `true`; `pending?`: `true`; `present?`: `Readonly`\<\{ `verb`: `string`; \}\>; \}\>, `"present"`\> & \{ input: I; output: O; present?: Readonly\<\{ verb: string; row: (call: Readonly\<\{ input: output\<I\>; output: output\<O\>; \}\>) =\> \{ readonly id: string; readonly title: string; ... 4 more ...; readonly media?: \{ ...; \} \| undefined; \}; rows: Readonly\<...\>; \}\> \| undefined; \} & (\{ ...; \} \| \{ ...; \}) |
231
+ | Parameter | Type |
232
+ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
233
+ | `method` | `Omit`\<`Readonly`\<\{ `description`: `string`; `effect`: `"external"` \| `"read"` \| `"write"`; `requires`: readonly ( \| `"agent.list"` \| `"agent.manage"` \| `"agent.read"` \| `"agent.send"` \| `"computer.list"` \| `"computer.readFile"` \| `"computer.writeFile"` \| `"computer.execute"` \| `"agent.rename"` \| `"agent.avatar"` \| `"agent.toolPolicy"` \| `"approvals"` \| `"apps.open"` \| `"apps.call"` \| `"llm.generation"` \| `"media.generation"` \| `"games:servers"` \| `"git.repository"` \| `"app.storage"` \| `"app.events.emit"` \| `"team.workbenchHost"` \| `"marketplace.browse"` \| `"marketplace.purchase"` \| `"workflow.run"` \| `"workflow.publish"` \| `"workflow.arm"` \| `"world"` \| `"channels.read"` \| `"channels.personal.manage"`)[]; `hidden?`: `true`; `pending?`: `true`; `present?`: `Readonly`\<\{ `verb`: `string`; \}\>; \}\>, `"present"`\> & \{ input: I; output: O; present?: Readonly\<\{ verb: string; row: (call: Readonly\<\{ input: output\<I\>; output: output\<O\>; \}\>) =\> \{ readonly id: string; readonly title: string; ... 4 more ...; readonly media?: \{ ...; \} \| undefined; \}; rows: Readonly\<...\>; \}\> \| undefined; \} & (\{ ...; \} \| \{ ...; \}) |
235
234
 
236
235
  #### Returns
237
236
 
@@ -135,8 +135,7 @@ const appMethods: CapabilityContract<{
135
135
 
136
136
  Call one of this App's declared, typed methods through its host. Unlike
137
137
  `appBackend`, the host knows which method is called, so it can apply the
138
- method's declared effect (for example, allow only `read` methods to a visitor of
139
- a public App).
138
+ method's declared effect.
140
139
 
141
140
  ---
142
141
 
@@ -63,6 +63,8 @@ readonly code:
63
63
  | "IDENTITY"
64
64
  | "INSUFFICIENT_CREDIT"
65
65
  | "INVALID_ARGUMENT"
66
+ | "MEDIA_PROVIDER_FAILURE"
67
+ | "MEDIA_PROVIDER_FAILURE_UNCHARGED"
66
68
  | "PROTOCOL"
67
69
  | "SAFETY_FILTER_REFUSED"
68
70
  | "SELECTION_CHANGED"
@@ -90,6 +92,7 @@ type MediaProviderDiagnostic =
90
92
  | "TimeoutError"
91
93
  | "Error";
92
94
  code: number | null;
95
+ reason?: "credits_exhausted";
93
96
  }>
94
97
  | Readonly<{
95
98
  category: "result_download";
@@ -186,31 +189,13 @@ automatically.
186
189
  ### mediaProviderDiagnosticWireSchema
187
190
 
188
191
  ```ts
189
- const mediaProviderDiagnosticWireSchema: ZodPipe<
190
- ZodType<unknown, unknown, $ZodTypeInternals<unknown, unknown>>,
191
- ZodTransform<
192
- | Readonly<{
193
- category:
194
- | "InferenceUpstreamError"
195
- | "AiInternalError"
196
- | "TypeError"
197
- | "AbortError"
198
- | "TimeoutError"
199
- | "Error";
200
- code: number | null;
201
- }>
202
- | Readonly<{
203
- category: "result_download";
204
- status: number;
205
- }>,
206
- unknown
207
- >
208
- >;
192
+ const mediaProviderDiagnosticWireSchema: z.ZodType<MediaProviderDiagnostic> =
193
+ mediaProviderDiagnosticZodSchema;
209
194
  ```
210
195
 
211
- Documentable wire projection of the canonical diagnostic grammar. Maintained
212
- converters preserve its closed objects and numeric bounds; decoding still
213
- returns the declaration-safe public diagnostic type.
196
+ Documentable wire projection of the canonical diagnostic grammar. Its owner
197
+ supplies the native Zod dialect so output declarations remain documentable
198
+ without transforms, coercions or an unchecked type assertion.
214
199
 
215
200
  ---
216
201
 
@@ -230,6 +215,8 @@ const appErrorCodes: readonly [
230
215
  "IDENTITY",
231
216
  "INSUFFICIENT_CREDIT",
232
217
  "INVALID_ARGUMENT",
218
+ "MEDIA_PROVIDER_FAILURE",
219
+ "MEDIA_PROVIDER_FAILURE_UNCHARGED",
233
220
  "PROTOCOL",
234
221
  "SAFETY_FILTER_REFUSED",
235
222
  "SELECTION_CHANGED",
@@ -303,10 +290,10 @@ prerequisites, so they can accompany a non-retryable operation.
303
290
 
304
291
  #### Parameters
305
292
 
306
- | Parameter | Type |
307
- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
308
- | `cause` | `unknown` |
309
- | `overrides?` | `Partial`\<`Record`\< \| `"CANCELLED"` \| `"CAPABILITY_DENIED"` \| `"CAPABILITY_REVOKED"` \| `"COMMAND_NOT_DECLARED"` \| `"CONFLICT"` \| `"DELIVERY_PENDING"` \| `"DISCONNECTED"` \| `"FILE_TOO_LARGE"` \| `"HOST_FAILURE"` \| `"IDENTITY"` \| `"INSUFFICIENT_CREDIT"` \| `"INVALID_ARGUMENT"` \| `"PROTOCOL"` \| `"SAFETY_FILTER_REFUSED"` \| `"SELECTION_CHANGED"` \| `"TIMEOUT"`, `Readonly`\<\{ `title`: `string`; `message`: `string`; \}\>\>\> |
293
+ | Parameter | Type |
294
+ | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
295
+ | `cause` | `unknown` |
296
+ | `overrides?` | `Partial`\<`Record`\< \| `"CANCELLED"` \| `"CAPABILITY_DENIED"` \| `"CAPABILITY_REVOKED"` \| `"COMMAND_NOT_DECLARED"` \| `"CONFLICT"` \| `"DELIVERY_PENDING"` \| `"DISCONNECTED"` \| `"FILE_TOO_LARGE"` \| `"HOST_FAILURE"` \| `"IDENTITY"` \| `"INSUFFICIENT_CREDIT"` \| `"INVALID_ARGUMENT"` \| `"MEDIA_PROVIDER_FAILURE"` \| `"MEDIA_PROVIDER_FAILURE_UNCHARGED"` \| `"PROTOCOL"` \| `"SAFETY_FILTER_REFUSED"` \| `"SELECTION_CHANGED"` \| `"TIMEOUT"`, `Readonly`\<\{ `title`: `string`; `message`: `string`; \}\>\>\> |
310
297
 
311
298
  #### Returns
312
299
 
package/docs/api/index.md CHANGED
@@ -2111,6 +2111,7 @@ const FungiMessageMetaSchema: ZodObject<{
2111
2111
  ancestors: ZodArray<ZodLazy<ZodString>>;
2112
2112
  maxDepth: ZodNumber;
2113
2113
  steer: ZodOptional<ZodLiteral<true>>;
2114
+ goal: ZodOptional<ZodUnion<readonly [ZodString, ZodLiteral<false>]>>;
2114
2115
  reply: ZodOptional<ZodLazy<ZodObject<{
2115
2116
  agentId: ZodLazy<ZodString>;
2116
2117
  sessionId: ZodLazy<ZodString>;
@@ -2708,6 +2709,7 @@ const mediaGenerationSelectionSchema: Struct<{
2708
2709
  references: optional<
2709
2710
  $Array<
2710
2711
  Struct<{
2712
+ computerId: optional<String>;
2711
2713
  path: String;
2712
2714
  role: optional<
2713
2715
  Literals<readonly ["first-frame", "last-frame", "reference"]>
@@ -2761,6 +2763,7 @@ const mediaGenerationFailureSchema: Struct<{
2761
2763
  ]
2762
2764
  >;
2763
2765
  code: NullOr<Int>;
2766
+ reason: optionalKey<Literal<"credits_exhausted">>;
2764
2767
  }>,
2765
2768
  Struct<{
2766
2769
  category: Literal<"result_download">;
@@ -2779,6 +2782,8 @@ const mediaGenerationFailureSchema: Struct<{
2779
2782
  "IDENTITY",
2780
2783
  "INSUFFICIENT_CREDIT",
2781
2784
  "INVALID_ARGUMENT",
2785
+ "MEDIA_PROVIDER_FAILURE",
2786
+ "MEDIA_PROVIDER_FAILURE_UNCHARGED",
2782
2787
  "PROTOCOL",
2783
2788
  "SAFETY_FILTER_REFUSED",
2784
2789
  "TIMEOUT",
@@ -385,6 +385,7 @@ const mediaGenerationJsonRequestSchema: Struct<{
385
385
  aspectRatio: optional<Literals<readonly ["16:9", "4:3", "1:1", "3:4", "9:16", "21:9", "9:21"]>>;
386
386
  generateAudio: optional<Boolean>;
387
387
  references: optional<$Array<Struct<{
388
+ computerId: optional<String>;
388
389
  path: String;
389
390
  role: optional<Literals<readonly [..., ..., ...]>>;
390
391
  }>>>;
@@ -425,11 +426,12 @@ const mediaGenerationJsonOutcomeSchema: Union<readonly [Struct<{
425
426
  provider: optional<Union<readonly [Struct<{
426
427
  category: ...;
427
428
  code: ...;
429
+ reason: ...;
428
430
  }>, Struct<{
429
431
  category: ...;
430
432
  status: ...;
431
433
  }>]>>;
432
- code: Literals<readonly ["CANCELLED", "CAPABILITY_DENIED", "CAPABILITY_REVOKED", "DISCONNECTED", "HOST_FAILURE", "IDENTITY", "INSUFFICIENT_CREDIT", "INVALID_ARGUMENT", "PROTOCOL", "SAFETY_FILTER_REFUSED", "TIMEOUT"]>;
434
+ code: Literals<readonly ["CANCELLED", "CAPABILITY_DENIED", "CAPABILITY_REVOKED", "DISCONNECTED", "HOST_FAILURE", "IDENTITY", "INSUFFICIENT_CREDIT", "INVALID_ARGUMENT", "MEDIA_PROVIDER_FAILURE", "MEDIA_PROVIDER_FAILURE_UNCHARGED", "PROTOCOL", "SAFETY_FILTER_REFUSED", "TIMEOUT"]>;
433
435
  retryable: Boolean;
434
436
  }>;
435
437
  }>]>;
@@ -463,7 +465,7 @@ const mediaGenerationJsonReplySchema: Union<readonly [Union<readonly [Struct<{
463
465
  message: String;
464
466
  stage: optional<Literals<readonly [..., ..., ..., ..., ..., ..., ..., ..., ..., ..., ...]>>;
465
467
  provider: optional<Union<readonly [..., ...]>>;
466
- code: Literals<readonly ["CANCELLED", "CAPABILITY_DENIED", "CAPABILITY_REVOKED", "DISCONNECTED", "HOST_FAILURE", "IDENTITY", "INSUFFICIENT_CREDIT", "INVALID_ARGUMENT", "PROTOCOL", "SAFETY_FILTER_REFUSED", "TIMEOUT"]>;
468
+ code: Literals<readonly ["CANCELLED", "CAPABILITY_DENIED", "CAPABILITY_REVOKED", "DISCONNECTED", "HOST_FAILURE", "IDENTITY", "INSUFFICIENT_CREDIT", "INVALID_ARGUMENT", "MEDIA_PROVIDER_FAILURE", "MEDIA_PROVIDER_FAILURE_UNCHARGED", "PROTOCOL", "SAFETY_FILTER_REFUSED", "TIMEOUT"]>;
467
469
  retryable: Boolean;
468
470
  }>;
469
471
  }>]>, declare<Readonly<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fungi.computer/agar",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "author": "Levi <levi@technomancy.dev>",
5
5
  "description": "App contract for fungi.computer: typed backend methods, host capabilities and the App frontend connection",
6
6
  "type": "module",
@@ -168,7 +168,7 @@
168
168
  }
169
169
  },
170
170
  "dependencies": {
171
- "@fungi.computer/puffball": "0.2.0",
171
+ "@fungi.computer/puffball": "0.3.0",
172
172
  "@fungi.computer/whistle": "0.3.0",
173
173
  "@opentui/keymap": "0.5.10",
174
174
  "@fungi.computer/capnweb": "0.12.0",