@cat-factory/contracts 0.211.0 → 0.212.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.
Files changed (58) hide show
  1. package/dist/binary-generators.d.ts +142 -0
  2. package/dist/binary-generators.d.ts.map +1 -0
  3. package/dist/binary-generators.js +143 -0
  4. package/dist/binary-generators.js.map +1 -0
  5. package/dist/binary-modalities.d.ts +36 -0
  6. package/dist/binary-modalities.d.ts.map +1 -0
  7. package/dist/binary-modalities.js +83 -0
  8. package/dist/binary-modalities.js.map +1 -0
  9. package/dist/binary-outputs.d.ts +61 -0
  10. package/dist/binary-outputs.d.ts.map +1 -1
  11. package/dist/binary-outputs.js +47 -0
  12. package/dist/binary-outputs.js.map +1 -1
  13. package/dist/entities.d.ts +12 -0
  14. package/dist/entities.d.ts.map +1 -1
  15. package/dist/entities.js +4 -0
  16. package/dist/entities.js.map +1 -1
  17. package/dist/errors.d.ts +1 -1
  18. package/dist/errors.d.ts.map +1 -1
  19. package/dist/errors.js +12 -0
  20. package/dist/errors.js.map +1 -1
  21. package/dist/execution.d.ts +10 -0
  22. package/dist/execution.d.ts.map +1 -1
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/notification-webhooks.d.ts +1 -1
  28. package/dist/notifications.d.ts +2 -2
  29. package/dist/observability.d.ts +17 -2
  30. package/dist/observability.d.ts.map +1 -1
  31. package/dist/observability.js +18 -0
  32. package/dist/observability.js.map +1 -1
  33. package/dist/public-api.d.ts +1 -1
  34. package/dist/requests.d.ts +4 -0
  35. package/dist/requests.d.ts.map +1 -1
  36. package/dist/routes/agent-runs.d.ts +10 -0
  37. package/dist/routes/agent-runs.d.ts.map +1 -1
  38. package/dist/routes/bug-hunt.d.ts +10 -0
  39. package/dist/routes/bug-hunt.d.ts.map +1 -1
  40. package/dist/routes/execution.d.ts +40 -0
  41. package/dist/routes/execution.d.ts.map +1 -1
  42. package/dist/routes/human-review.d.ts +5 -0
  43. package/dist/routes/human-review.d.ts.map +1 -1
  44. package/dist/routes/human-test.d.ts +25 -0
  45. package/dist/routes/human-test.d.ts.map +1 -1
  46. package/dist/routes/notifications.d.ts +3 -3
  47. package/dist/routes/pipelines.d.ts +16 -0
  48. package/dist/routes/pipelines.d.ts.map +1 -1
  49. package/dist/routes/public-api.d.ts +3 -3
  50. package/dist/routes/visual-confirm.d.ts +15 -0
  51. package/dist/routes/visual-confirm.d.ts.map +1 -1
  52. package/dist/routes/workspaces.d.ts +30 -2
  53. package/dist/routes/workspaces.d.ts.map +1 -1
  54. package/dist/snapshot.d.ts +25 -1
  55. package/dist/snapshot.d.ts.map +1 -1
  56. package/dist/snapshot.js +12 -0
  57. package/dist/snapshot.js.map +1 -1
  58. package/package.json +1 -1
@@ -0,0 +1,142 @@
1
+ import * as v from 'valibot';
2
+ /**
3
+ * A credential a generative integration needs, declared by NAME only — never a value.
4
+ *
5
+ * The value is resolved per dispatch through the facade-wired `ToolSecretResolver` port (the
6
+ * same port a tool server's credentials go through) and written straight onto the job body,
7
+ * where the harness injects it into THIS JOB's agent environment. It never reaches
8
+ * `AgentRunContext`, a prompt, or the telemetry snapshot — only the key NAME does, because the
9
+ * agent has to know which variable to read.
10
+ */
11
+ export declare const binaryGeneratorCredentialSchema: v.ObjectSchema<{
12
+ /**
13
+ * The credential's key. It is both what the secret resolver is asked for and the ENVIRONMENT
14
+ * VARIABLE the agent reads it from, so it must be a valid POSIX variable name — a generator
15
+ * declaring `x-rd-token` would resolve fine and then be dropped by the harness's env
16
+ * validation, which is a silent "the integration just 401s" at run time.
17
+ */
18
+ readonly key: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 128, undefined>, v.RegexAction<string, "must be a valid environment variable name">]>;
19
+ /**
20
+ * How the integration expects the credential to be presented (`X-RD-Token: <value>`,
21
+ * `Authorization: Bearer <value>`). Folded into the brief verbatim: the agent writes the
22
+ * request itself, and a key with no stated header is a key it has to guess the use of.
23
+ */
24
+ readonly usage: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MaxLengthAction<string, 400, undefined>]>, undefined>;
25
+ /**
26
+ * When true (the default), an integration whose credential does not resolve is reported to
27
+ * the agent as UNAVAILABLE rather than offered. Set false only for an endpoint that genuinely
28
+ * works unauthenticated — an agent handed an API whose first call 401s burns a run
29
+ * discovering it.
30
+ */
31
+ readonly required: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
32
+ }, undefined>;
33
+ export type BinaryGeneratorCredential = v.InferOutput<typeof binaryGeneratorCredentialSchema>;
34
+ /**
35
+ * A generative binary integration a deployment registers in code.
36
+ *
37
+ * Shaped like a foundational service on purpose — identity, prose, and API contracts in the
38
+ * SAME `uploadApiContractSchema` vocabulary — so one contract renderer serves both and a
39
+ * deployment writes one kind of definition. What it adds is what a GENERATOR has and a shared
40
+ * service does not: the content types it produces, and the credential it needs.
41
+ */
42
+ export declare const binaryGeneratorDefinitionSchema: v.ObjectSchema<{
43
+ /** Stable id, referenced by a step's `stepOptions.binaryOutput.generatorIds`. */
44
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 64, undefined>, v.RegexAction<string, "must be a lower-kebab slug">]>;
45
+ readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 200, undefined>]>;
46
+ /** One line, shown in the picker and the agent's brief. */
47
+ readonly summary: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 400, undefined>]>;
48
+ /**
49
+ * What it is good at and what it is NOT for — style, resolution/length limits, cost profile.
50
+ * The half a model needs to pick between two registered generators of the same modality.
51
+ */
52
+ readonly description: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MaxLengthAction<string, 20000, undefined>]>;
53
+ /**
54
+ * The content types it produces. At least one: a generator that produces nothing is not a
55
+ * generator, and an empty list would make it match every step's requirements by vacuity.
56
+ */
57
+ readonly modalities: v.SchemaWithPipe<readonly [v.ArraySchema<v.PicklistSchema<["image", "audio", "video", "3d", "document"], undefined>, undefined>, v.MinLengthAction<("3d" | "audio" | "document" | "image" | "video")[], 1, undefined>]>;
58
+ /**
59
+ * The concrete media types it can emit (`image/png`, `audio/mpeg`), when the integration
60
+ * pins them down. Absent ⇒ only the coarse {@link modalities} are known, which the brief
61
+ * states as such rather than implying every format of that modality is available.
62
+ */
63
+ readonly mediaTypes: v.OptionalSchema<v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.ToLowerCaseAction, v.MinLengthAction<string, 3, undefined>, v.MaxLengthAction<string, 128, undefined>, v.RegexAction<string, "must be a media type of the form type/subtype">]>, undefined>, undefined>;
64
+ /**
65
+ * The API's base URL. Stated to the agent so it does not have to infer one from the contract,
66
+ * and refused at registration unless it is `https` (or loopback) — the credential above rides
67
+ * this request.
68
+ */
69
+ readonly endpoint: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 2048, undefined>]>, undefined>;
70
+ /**
71
+ * Operating notes folded into the agent's brief verbatim — polling an async job, the shape of
72
+ * a returned payload (base64 vs a signed URL), a rate limit worth respecting. This is where a
73
+ * deployment puts the knowledge that would otherwise be discovered once per run.
74
+ */
75
+ readonly guidance: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MaxLengthAction<string, 20000, undefined>]>, undefined>;
76
+ readonly credential: v.OptionalSchema<v.ObjectSchema<{
77
+ /**
78
+ * The credential's key. It is both what the secret resolver is asked for and the ENVIRONMENT
79
+ * VARIABLE the agent reads it from, so it must be a valid POSIX variable name — a generator
80
+ * declaring `x-rd-token` would resolve fine and then be dropped by the harness's env
81
+ * validation, which is a silent "the integration just 401s" at run time.
82
+ */
83
+ readonly key: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 128, undefined>, v.RegexAction<string, "must be a valid environment variable name">]>;
84
+ /**
85
+ * How the integration expects the credential to be presented (`X-RD-Token: <value>`,
86
+ * `Authorization: Bearer <value>`). Folded into the brief verbatim: the agent writes the
87
+ * request itself, and a key with no stated header is a key it has to guess the use of.
88
+ */
89
+ readonly usage: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MaxLengthAction<string, 400, undefined>]>, undefined>;
90
+ /**
91
+ * When true (the default), an integration whose credential does not resolve is reported to
92
+ * the agent as UNAVAILABLE rather than offered. Set false only for an endpoint that genuinely
93
+ * works unauthenticated — an agent handed an API whose first call 401s burns a run
94
+ * discovering it.
95
+ */
96
+ readonly required: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
97
+ }, undefined>, undefined>;
98
+ /**
99
+ * The integration's API contract documents, in the same formats the foundational catalog
100
+ * accepts. Injected as `.cat-context/` files beside the brief, so the agent calls the
101
+ * operations the contract declares instead of inventing them.
102
+ */
103
+ readonly contracts: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
104
+ readonly contractId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 64, undefined>, v.RegexAction<string, "must be a lower-kebab slug">]>;
105
+ readonly format: v.PicklistSchema<["openapi", "toad-contract", "lokalise-api-contract"], undefined>;
106
+ readonly title: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 200, undefined>]>;
107
+ readonly body: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 1000000, undefined>]>;
108
+ }, undefined>, undefined>, undefined>;
109
+ }, undefined>;
110
+ export type BinaryGeneratorDefinition = v.InferOutput<typeof binaryGeneratorDefinitionSchema>;
111
+ /**
112
+ * The ways `definition` fails {@link binaryGeneratorDefinitionSchema}, as readable lines — empty
113
+ * when it would be accepted.
114
+ *
115
+ * Exists for the same reason `foundationalServiceDefinitionIssues` does: the backend layers that
116
+ * hold a deployment's CODE-registered definitions to this shape (kernel, orchestration's boot
117
+ * validation) cannot depend on valibot, and re-stating the rules in a second place is how a
118
+ * registration ends up accepted where an equivalent one is refused.
119
+ */
120
+ /**
121
+ * A registered integration as the WIRE carries it to the SPA (the workspace snapshot's
122
+ * `binaryGenerators`), so the pipeline builder can offer a step's `generatorIds` from the same
123
+ * set run admission validates against instead of asking a human to type an id.
124
+ *
125
+ * IDENTITY ONLY, and the omissions are the point. The credential's key NAME is left out — the
126
+ * picker has no use for it, and a workspace VIEWER has no business learning which environment
127
+ * variables the deployment sets. So are the contracts and the endpoint: they are the agent's
128
+ * interface to the integration, delivered as injected `.cat-context/` files at dispatch, and
129
+ * nothing a person picking from a list needs.
130
+ */
131
+ export declare const registeredBinaryGeneratorSchema: v.ObjectSchema<{
132
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 64, undefined>, v.RegexAction<string, "must be a lower-kebab slug">]>;
133
+ readonly name: v.StringSchema<undefined>;
134
+ readonly summary: v.StringSchema<undefined>;
135
+ /** What it produces — what the builder checks a step's declared content types against. */
136
+ readonly modalities: v.ArraySchema<v.PicklistSchema<["image", "audio", "video", "3d", "document"], undefined>, undefined>;
137
+ /** The concrete formats it pins down, when it declares any. Shown as detail, never a filter. */
138
+ readonly mediaTypes: v.OptionalSchema<v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.ToLowerCaseAction, v.MinLengthAction<string, 3, undefined>, v.MaxLengthAction<string, 128, undefined>, v.RegexAction<string, "must be a media type of the form type/subtype">]>, undefined>, undefined>;
139
+ }, undefined>;
140
+ export type RegisteredBinaryGenerator = v.InferOutput<typeof registeredBinaryGeneratorSchema>;
141
+ export declare function binaryGeneratorDefinitionIssues(definition: unknown): string[];
142
+ //# sourceMappingURL=binary-generators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binary-generators.d.ts","sourceRoot":"","sources":["../src/binary-generators.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAgC5B;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B;IAC1C;;;;;OAKG;;IAQH;;;;OAIG;;IAEH;;;;;OAKG;;aAEH,CAAA;AACF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,+BAA+B,CAAC,CAAA;AAE7F;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B;IAC1C,iFAAiF;;;IAGjF,2DAA2D;;IAE3D;;;OAGG;;IAEH;;;OAGG;;IAEH;;;;OAIG;;IAEH;;;;OAIG;;IAEH;;;;OAIG;;;QArEH;;;;;WAKG;;QAQH;;;;WAIG;;QAEH;;;;;WAKG;;;IAgDH;;;;OAIG;;;;;;;aAEH,CAAA;AACF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,+BAA+B,CAAC,CAAA;AAE7F;;;;;;;;GAQG;AACH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,+BAA+B;;;;IAI1C,0FAA0F;;IAE1F,gGAAgG;;aAEhG,CAAA;AACF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,+BAA+B,CAAC,CAAA;AAE7F,wBAAgB,+BAA+B,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,EAAE,CAO7E"}
@@ -0,0 +1,143 @@
1
+ import * as v from 'valibot';
2
+ import { binaryModalitySchema, mediaTypeSchema } from './binary-modalities.js';
3
+ import { uploadApiContractSchema } from './foundational-services.js';
4
+ // ---------------------------------------------------------------------------
5
+ // Wire vocabulary for GENERATIVE BINARY INTEGRATIONS — the third-party (or in-house) APIs a
6
+ // binary-generating agent kind calls to PRODUCE its deliverable: an image generator, a
7
+ // music/speech generator, a video generator.
8
+ //
9
+ // This is the missing half of `binary-outputs.ts`. That module answers "where does a generated
10
+ // artifact GO" (a foundational service the org runs, carrying the `asset-storage` capability);
11
+ // this one answers "what MAKES it". The two are deliberately separate registries because they
12
+ // are separate facts about an org: the storage estate is shared infrastructure every designed
13
+ // system consumes, while a generation integration is a vendor a deployment buys and points at
14
+ // specific steps. Modelling a generator as a foundational service would put a metered vendor
15
+ // API into the catalog an Architect designs AGAINST, where it would be offered to every design
16
+ // step as something to build on.
17
+ //
18
+ // A generator is registered in a deployment's CODE, on the app-owned `BinaryGeneratorRegistry`
19
+ // (kernel), exactly as it registers agent kinds, gates, pipelines or its foundational estate —
20
+ // so it needs no table, no migration and no UI, and both runtime facades get identical
21
+ // behaviour by building the same registry.
22
+ // ---------------------------------------------------------------------------
23
+ const slug = v.pipe(v.string(), v.trim(), v.minLength(1), v.maxLength(64), v.regex(/^[a-z0-9][a-z0-9-]*$/, 'must be a lower-kebab slug'));
24
+ /**
25
+ * A credential a generative integration needs, declared by NAME only — never a value.
26
+ *
27
+ * The value is resolved per dispatch through the facade-wired `ToolSecretResolver` port (the
28
+ * same port a tool server's credentials go through) and written straight onto the job body,
29
+ * where the harness injects it into THIS JOB's agent environment. It never reaches
30
+ * `AgentRunContext`, a prompt, or the telemetry snapshot — only the key NAME does, because the
31
+ * agent has to know which variable to read.
32
+ */
33
+ export const binaryGeneratorCredentialSchema = v.object({
34
+ /**
35
+ * The credential's key. It is both what the secret resolver is asked for and the ENVIRONMENT
36
+ * VARIABLE the agent reads it from, so it must be a valid POSIX variable name — a generator
37
+ * declaring `x-rd-token` would resolve fine and then be dropped by the harness's env
38
+ * validation, which is a silent "the integration just 401s" at run time.
39
+ */
40
+ key: v.pipe(v.string(), v.trim(), v.minLength(1), v.maxLength(128), v.regex(/^[A-Za-z_][A-Za-z0-9_]*$/, 'must be a valid environment variable name')),
41
+ /**
42
+ * How the integration expects the credential to be presented (`X-RD-Token: <value>`,
43
+ * `Authorization: Bearer <value>`). Folded into the brief verbatim: the agent writes the
44
+ * request itself, and a key with no stated header is a key it has to guess the use of.
45
+ */
46
+ usage: v.optional(v.pipe(v.string(), v.trim(), v.maxLength(400))),
47
+ /**
48
+ * When true (the default), an integration whose credential does not resolve is reported to
49
+ * the agent as UNAVAILABLE rather than offered. Set false only for an endpoint that genuinely
50
+ * works unauthenticated — an agent handed an API whose first call 401s burns a run
51
+ * discovering it.
52
+ */
53
+ required: v.optional(v.boolean()),
54
+ });
55
+ /**
56
+ * A generative binary integration a deployment registers in code.
57
+ *
58
+ * Shaped like a foundational service on purpose — identity, prose, and API contracts in the
59
+ * SAME `uploadApiContractSchema` vocabulary — so one contract renderer serves both and a
60
+ * deployment writes one kind of definition. What it adds is what a GENERATOR has and a shared
61
+ * service does not: the content types it produces, and the credential it needs.
62
+ */
63
+ export const binaryGeneratorDefinitionSchema = v.object({
64
+ /** Stable id, referenced by a step's `stepOptions.binaryOutput.generatorIds`. */
65
+ id: slug,
66
+ name: v.pipe(v.string(), v.trim(), v.minLength(1), v.maxLength(200)),
67
+ /** One line, shown in the picker and the agent's brief. */
68
+ summary: v.pipe(v.string(), v.trim(), v.minLength(1), v.maxLength(400)),
69
+ /**
70
+ * What it is good at and what it is NOT for — style, resolution/length limits, cost profile.
71
+ * The half a model needs to pick between two registered generators of the same modality.
72
+ */
73
+ description: v.pipe(v.string(), v.trim(), v.maxLength(20_000)),
74
+ /**
75
+ * The content types it produces. At least one: a generator that produces nothing is not a
76
+ * generator, and an empty list would make it match every step's requirements by vacuity.
77
+ */
78
+ modalities: v.pipe(v.array(binaryModalitySchema), v.minLength(1)),
79
+ /**
80
+ * The concrete media types it can emit (`image/png`, `audio/mpeg`), when the integration
81
+ * pins them down. Absent ⇒ only the coarse {@link modalities} are known, which the brief
82
+ * states as such rather than implying every format of that modality is available.
83
+ */
84
+ mediaTypes: v.optional(v.array(mediaTypeSchema)),
85
+ /**
86
+ * The API's base URL. Stated to the agent so it does not have to infer one from the contract,
87
+ * and refused at registration unless it is `https` (or loopback) — the credential above rides
88
+ * this request.
89
+ */
90
+ endpoint: v.optional(v.pipe(v.string(), v.trim(), v.minLength(1), v.maxLength(2048))),
91
+ /**
92
+ * Operating notes folded into the agent's brief verbatim — polling an async job, the shape of
93
+ * a returned payload (base64 vs a signed URL), a rate limit worth respecting. This is where a
94
+ * deployment puts the knowledge that would otherwise be discovered once per run.
95
+ */
96
+ guidance: v.optional(v.pipe(v.string(), v.trim(), v.maxLength(20_000))),
97
+ credential: v.optional(binaryGeneratorCredentialSchema),
98
+ /**
99
+ * The integration's API contract documents, in the same formats the foundational catalog
100
+ * accepts. Injected as `.cat-context/` files beside the brief, so the agent calls the
101
+ * operations the contract declares instead of inventing them.
102
+ */
103
+ contracts: v.optional(v.array(uploadApiContractSchema)),
104
+ });
105
+ /**
106
+ * The ways `definition` fails {@link binaryGeneratorDefinitionSchema}, as readable lines — empty
107
+ * when it would be accepted.
108
+ *
109
+ * Exists for the same reason `foundationalServiceDefinitionIssues` does: the backend layers that
110
+ * hold a deployment's CODE-registered definitions to this shape (kernel, orchestration's boot
111
+ * validation) cannot depend on valibot, and re-stating the rules in a second place is how a
112
+ * registration ends up accepted where an equivalent one is refused.
113
+ */
114
+ /**
115
+ * A registered integration as the WIRE carries it to the SPA (the workspace snapshot's
116
+ * `binaryGenerators`), so the pipeline builder can offer a step's `generatorIds` from the same
117
+ * set run admission validates against instead of asking a human to type an id.
118
+ *
119
+ * IDENTITY ONLY, and the omissions are the point. The credential's key NAME is left out — the
120
+ * picker has no use for it, and a workspace VIEWER has no business learning which environment
121
+ * variables the deployment sets. So are the contracts and the endpoint: they are the agent's
122
+ * interface to the integration, delivered as injected `.cat-context/` files at dispatch, and
123
+ * nothing a person picking from a list needs.
124
+ */
125
+ export const registeredBinaryGeneratorSchema = v.object({
126
+ id: slug,
127
+ name: v.string(),
128
+ summary: v.string(),
129
+ /** What it produces — what the builder checks a step's declared content types against. */
130
+ modalities: v.array(binaryModalitySchema),
131
+ /** The concrete formats it pins down, when it declares any. Shown as detail, never a filter. */
132
+ mediaTypes: v.optional(v.array(mediaTypeSchema)),
133
+ });
134
+ export function binaryGeneratorDefinitionIssues(definition) {
135
+ const parsed = v.safeParse(binaryGeneratorDefinitionSchema, definition);
136
+ if (parsed.success)
137
+ return [];
138
+ return parsed.issues.map((issue) => {
139
+ const path = issue.path?.map((segment) => String(segment.key)).join('.');
140
+ return path ? `${path}: ${issue.message}` : issue.message;
141
+ });
142
+ }
143
+ //# sourceMappingURL=binary-generators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binary-generators.js","sourceRoot":"","sources":["../src/binary-generators.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import * as v from 'valibot';
2
+ /**
3
+ * The CONTENT TYPE a generative integration produces, as a closed vocabulary.
4
+ *
5
+ * Closed, unlike the free-form capability tags on a foundational service, because this one is
6
+ * the platform's own: it decides which generator a step may be given for which deliverable, it
7
+ * groups the agent-facing brief, and the SPA renders a picker off it. A free-form tag would
8
+ * make `images` and `image` two different content types that look identical to a reader and
9
+ * silently fail to match — the exact failure `reservedCapabilityNearMiss` exists to catch for
10
+ * the tags that genuinely must stay free-form.
11
+ *
12
+ * The members are MODALITIES, not genres: music, speech and sound effects are all `audio`,
13
+ * because what differs between them is the prompt, while what differs between audio and video
14
+ * is the whole integration, its media types and what a step can do with the result. A
15
+ * deployment that must tell a music generator from a speech generator says so in the
16
+ * definition's `mediaTypes` and its description.
17
+ */
18
+ export declare const binaryModalitySchema: v.PicklistSchema<["image", "audio", "video", "3d", "document"], undefined>;
19
+ export type BinaryModality = v.InferOutput<typeof binaryModalitySchema>;
20
+ /**
21
+ * The {@link BinaryModality} a media type belongs to, or `null` when nothing here recognises it.
22
+ *
23
+ * `null` is a REAL answer and callers must keep it apart from a modality: it means the platform
24
+ * does not know what this content is, which is different from knowing it is not an image. It is
25
+ * what lets a registration's declared media types be checked against its declared modalities
26
+ * (a generator claiming `audio` while listing `image/png` is a configuration error, not a
27
+ * judgement call) and what lets a settled step's declared artifacts be CLASSIFIED in code rather
28
+ * than by asking the model what kind of thing it just made.
29
+ */
30
+ export declare function modalityOfMediaType(value: string): BinaryModality | null;
31
+ /**
32
+ * A media type as `type/subtype` (parameters are NOT accepted — a generator declares what it
33
+ * produces, not how one request happened to be encoded).
34
+ */
35
+ export declare const mediaTypeSchema: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.ToLowerCaseAction, v.MinLengthAction<string, 3, undefined>, v.MaxLengthAction<string, 128, undefined>, v.RegexAction<string, "must be a media type of the form type/subtype">]>;
36
+ //# sourceMappingURL=binary-modalities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binary-modalities.d.ts","sourceRoot":"","sources":["../src/binary-modalities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAY5B;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,4EAW/B,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEvE;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAoBxE;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,uPAU3B,CAAA"}
@@ -0,0 +1,83 @@
1
+ import * as v from 'valibot';
2
+ // ---------------------------------------------------------------------------
3
+ // The CONTENT-TYPE vocabulary shared by the two halves of a binary-output step: what a registered
4
+ // generative integration PRODUCES (`binary-generators.ts`) and what a step's stored artifacts
5
+ // turned out to BE (`binary-outputs.ts`).
6
+ //
7
+ // Its own leaf module — no imports beyond valibot — because both of those modules need it and one
8
+ // of them sits downstream of the entity schemas the other is reached through. A vocabulary this
9
+ // small has no business creating an import cycle.
10
+ // ---------------------------------------------------------------------------
11
+ /**
12
+ * The CONTENT TYPE a generative integration produces, as a closed vocabulary.
13
+ *
14
+ * Closed, unlike the free-form capability tags on a foundational service, because this one is
15
+ * the platform's own: it decides which generator a step may be given for which deliverable, it
16
+ * groups the agent-facing brief, and the SPA renders a picker off it. A free-form tag would
17
+ * make `images` and `image` two different content types that look identical to a reader and
18
+ * silently fail to match — the exact failure `reservedCapabilityNearMiss` exists to catch for
19
+ * the tags that genuinely must stay free-form.
20
+ *
21
+ * The members are MODALITIES, not genres: music, speech and sound effects are all `audio`,
22
+ * because what differs between them is the prompt, while what differs between audio and video
23
+ * is the whole integration, its media types and what a step can do with the result. A
24
+ * deployment that must tell a music generator from a speech generator says so in the
25
+ * definition's `mediaTypes` and its description.
26
+ */
27
+ export const binaryModalitySchema = v.picklist([
28
+ /** Still images — `image/png`, `image/webp`, `image/jpeg`, `image/svg+xml`. */
29
+ 'image',
30
+ /** Anything heard: music, speech/voice-over, sound effects — `audio/mpeg`, `audio/wav`. */
31
+ 'audio',
32
+ /** Moving pictures, with or without an audio track — `video/mp4`, `video/webm`. */
33
+ 'video',
34
+ /** 3D geometry — `model/gltf-binary`, `model/obj`. */
35
+ '3d',
36
+ /** A rendered, paginated document — `application/pdf`. */
37
+ 'document',
38
+ ]);
39
+ /**
40
+ * The {@link BinaryModality} a media type belongs to, or `null` when nothing here recognises it.
41
+ *
42
+ * `null` is a REAL answer and callers must keep it apart from a modality: it means the platform
43
+ * does not know what this content is, which is different from knowing it is not an image. It is
44
+ * what lets a registration's declared media types be checked against its declared modalities
45
+ * (a generator claiming `audio` while listing `image/png` is a configuration error, not a
46
+ * judgement call) and what lets a settled step's declared artifacts be CLASSIFIED in code rather
47
+ * than by asking the model what kind of thing it just made.
48
+ */
49
+ export function modalityOfMediaType(value) {
50
+ const type = value.trim().toLowerCase().split(';')[0]?.trim() ?? '';
51
+ const [top, subtype] = type.split('/');
52
+ if (!top || !subtype)
53
+ return null;
54
+ if (top === 'image')
55
+ return 'image';
56
+ if (top === 'audio')
57
+ return 'audio';
58
+ if (top === 'video')
59
+ return 'video';
60
+ if (top === 'model')
61
+ return '3d';
62
+ if (top === 'application') {
63
+ if (subtype === 'pdf')
64
+ return 'document';
65
+ // The 3D formats that predate `model/*` and are still what tooling emits: `sla` is STL, and
66
+ // `x-tgif` is what the shared mime database maps `.obj` to (an old collision with the TGIF
67
+ // drawing format, but it IS the type an OBJ file is served as, so recognising it is right).
68
+ // `octet-stream` stays null on purpose — it is the "no idea" type, and guessing `3d` from it
69
+ // would classify every unlabelled download as a model.
70
+ if (subtype === 'octet-stream')
71
+ return null;
72
+ if (['gltf+json', 'x-gltf', 'sla', 'x-tgif'].includes(subtype))
73
+ return '3d';
74
+ return null;
75
+ }
76
+ return null;
77
+ }
78
+ /**
79
+ * A media type as `type/subtype` (parameters are NOT accepted — a generator declares what it
80
+ * produces, not how one request happened to be encoded).
81
+ */
82
+ export const mediaTypeSchema = v.pipe(v.string(), v.trim(), v.toLowerCase(), v.minLength(3), v.maxLength(128), v.regex(/^[a-z0-9][a-z0-9!#$&^_.+-]*\/[a-z0-9][a-z0-9!#$&^_.+-]*$/, 'must be a media type of the form type/subtype'));
83
+ //# sourceMappingURL=binary-modalities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binary-modalities.js","sourceRoot":"","sources":["../src/binary-modalities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,8EAA8E;AAC9E,kGAAkG;AAClG,8FAA8F;AAC9F,0CAA0C;AAC1C,EAAE;AACF,kGAAkG;AAClG,gGAAgG;AAChG,kDAAkD;AAClD,8EAA8E;AAE9E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC7C,+EAA+E;IAC/E,OAAO;IACP,2FAA2F;IAC3F,OAAO;IACP,mFAAmF;IACnF,OAAO;IACP,sDAAsD;IACtD,IAAI;IACJ,0DAA0D;IAC1D,UAAU;CACX,CAAC,CAAA;AAGF;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;IACnE,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACtC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,OAAO,CAAA;IACnC,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,OAAO,CAAA;IACnC,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,OAAO,CAAA;IACnC,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,IAAI,CAAA;IAChC,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;QAC1B,IAAI,OAAO,KAAK,KAAK;YAAE,OAAO,UAAU,CAAA;QACxC,4FAA4F;QAC5F,2FAA2F;QAC3F,4FAA4F;QAC5F,6FAA6F;QAC7F,uDAAuD;QACvD,IAAI,OAAO,KAAK,cAAc;YAAE,OAAO,IAAI,CAAA;QAC3C,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAA;QAC3E,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CACnC,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,IAAI,EAAE,EACR,CAAC,CAAC,WAAW,EAAE,EACf,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACd,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,EAChB,CAAC,CAAC,KAAK,CACL,0DAA0D,EAC1D,+CAA+C,CAChD,CACF,CAAA"}
@@ -21,6 +21,29 @@ export declare const binaryOutputConfigSchema: v.ObjectSchema<{
21
21
  * context files are the whole scope.
22
22
  */
23
23
  readonly contextServiceIds: v.OptionalSchema<v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 64, undefined>, v.RegexAction<string, "must be a lower-kebab slug">]>, undefined>, undefined>;
24
+ /**
25
+ * The GENERATIVE INTEGRATIONS this step may call to produce its artifacts — ids from the
26
+ * deployment's code-registered `BinaryGeneratorRegistry` (see `binary-generators.ts`).
27
+ *
28
+ * A separate half of the selection from the two above, because it answers a different
29
+ * question: those say where an artifact GOES, this says what MAKES it. Absent ⇒ the step
30
+ * generates through whatever its agent already has (a model with native image output, a tool
31
+ * server), and its brief says so rather than naming an integration it does not have.
32
+ * Validated at run admission against the registry, never against a saved copy.
33
+ */
34
+ readonly generatorIds: v.OptionalSchema<v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 64, undefined>, v.RegexAction<string, "must be a lower-kebab slug">]>, undefined>, undefined>;
35
+ /**
36
+ * The CONTENT TYPES this step is expected to deliver. Every one of them must be covered by a
37
+ * selected generator, or the run is refused at admission — a step that must produce a theme
38
+ * song and selected only an image generator cannot do its job, and the failure would
39
+ * otherwise surface as an agent apologising at the end of a paid run.
40
+ *
41
+ * Absent ⇒ no requirement is imposed and the selected generators' own modalities are the
42
+ * whole story. It is deliberately NOT defaulted from the selection: "this step must produce
43
+ * audio" is a statement about the WORK, and deriving it from the current selection would make
44
+ * removing the audio generator look like a change of requirements rather than a break.
45
+ */
46
+ readonly modalities: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["image", "audio", "video", "3d", "document"], undefined>, undefined>, undefined>;
24
47
  }, undefined>;
25
48
  export type BinaryOutputConfig = v.InferOutput<typeof binaryOutputConfigSchema>;
26
49
  /** One stored artifact a binary-generating step declared in its reply's machine-read block. */
@@ -43,6 +66,21 @@ export declare const binaryOutputArtifactSchema: v.ObjectSchema<{
43
66
  readonly contentType: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
44
67
  /** A one-line description of what was generated. */
45
68
  readonly description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
69
+ /**
70
+ * The generative integration the agent says PRODUCED the artifact, lowercased on read-back
71
+ * like {@link service}. Optional because a step may generate without a registered integration
72
+ * (a model with native image output), and a claim of "no generator" is a different fact from
73
+ * a claim naming one the deployment does not register — which is why an unrecognised id is
74
+ * NAMED in the report rather than dropped.
75
+ */
76
+ readonly generator: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
77
+ /**
78
+ * The CONTENT TYPE of the artifact, DERIVED in code from {@link contentType} — never read off
79
+ * the model's prose. Absent when no media type was declared, or when the declared one is not
80
+ * one the platform recognises: "we do not know what this is" and "this is not an image" are
81
+ * different answers, and only the second could justify a warning.
82
+ */
83
+ readonly modality: v.OptionalSchema<v.PicklistSchema<["image", "audio", "video", "3d", "document"], undefined>, undefined>;
46
84
  }, undefined>;
47
85
  export type BinaryOutputArtifact = v.InferOutput<typeof binaryOutputArtifactSchema>;
48
86
  /**
@@ -80,9 +118,32 @@ export declare const binaryOutputReportSchema: v.ObjectSchema<{
80
118
  readonly contentType: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
81
119
  /** A one-line description of what was generated. */
82
120
  readonly description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
121
+ /**
122
+ * The generative integration the agent says PRODUCED the artifact, lowercased on read-back
123
+ * like {@link service}. Optional because a step may generate without a registered integration
124
+ * (a model with native image output), and a claim of "no generator" is a different fact from
125
+ * a claim naming one the deployment does not register — which is why an unrecognised id is
126
+ * NAMED in the report rather than dropped.
127
+ */
128
+ readonly generator: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
129
+ /**
130
+ * The CONTENT TYPE of the artifact, DERIVED in code from {@link contentType} — never read off
131
+ * the model's prose. Absent when no media type was declared, or when the declared one is not
132
+ * one the platform recognises: "we do not know what this is" and "this is not an image" are
133
+ * different answers, and only the second could justify a warning.
134
+ */
135
+ readonly modality: v.OptionalSchema<v.PicklistSchema<["image", "audio", "video", "3d", "document"], undefined>, undefined>;
83
136
  }, undefined>, undefined>;
84
137
  /** Distinct `service` ids named in entries that the resolved catalog does not contain. */
85
138
  readonly unknownServices: v.ArraySchema<v.StringSchema<undefined>, undefined>;
139
+ /**
140
+ * Distinct `generator` ids named in entries that the deployment does not register. Kept apart
141
+ * from {@link unknownServices} because they resolve against different registries and need
142
+ * different fixes — a storage id points at the workspace's foundational catalog, a generator
143
+ * id at the deployment's code. Entries are RETAINED either way: the platform records what the
144
+ * agent claimed and a reader judges it.
145
+ */
146
+ readonly unknownGenerators: v.ArraySchema<v.StringSchema<undefined>, undefined>;
86
147
  /** Entries dropped because they were not an object with `service` + `location` strings. */
87
148
  readonly invalidEntries: v.NumberSchema<undefined>;
88
149
  /** Valid entries dropped past the per-report cap. */
@@ -1 +1 @@
1
- {"version":3,"file":"binary-outputs.d.ts","sourceRoot":"","sources":["../src/binary-outputs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAkB5B;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB;IACnC;;;;OAIG;;IAEH;;;;;;OAMG;;aAEH,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAA;AAE/E,+FAA+F;AAC/F,eAAO,MAAM,0BAA0B;IACrC;;;;;OAKG;;IAEH;;;OAGG;;IAEH,8FAA8F;;IAE9F,uEAAuE;;IAEvE,oDAAoD;;aAEpD,CAAA;AACF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,0BAA0B,CAAC,CAAA;AAEnF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,wBAAwB;;QApCnC;;;;;WAKG;;QAEH;;;WAGG;;QAEH,8FAA8F;;QAE9F,uEAAuE;;QAEvE,oDAAoD;;;IAsBpD,0FAA0F;;IAE1F,2FAA2F;;IAE3F,qDAAqD;;IAErD,0FAA0F;;IAE1F,qEAAqE;;aAErE,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAA"}
1
+ {"version":3,"file":"binary-outputs.d.ts","sourceRoot":"","sources":["../src/binary-outputs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAmB5B;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB;IACnC;;;;OAIG;;IAEH;;;;;;OAMG;;IAEH;;;;;;;;;OASG;;IAEH;;;;;;;;;;OAUG;;aAEH,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAA;AAE/E,+FAA+F;AAC/F,eAAO,MAAM,0BAA0B;IACrC;;;;;OAKG;;IAEH;;;OAGG;;IAEH,8FAA8F;;IAE9F,uEAAuE;;IAEvE,oDAAoD;;IAEpD;;;;;;OAMG;;IAEH;;;;;OAKG;;aAEH,CAAA;AACF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,0BAA0B,CAAC,CAAA;AAEnF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,wBAAwB;;QAnDnC;;;;;WAKG;;QAEH;;;WAGG;;QAEH,8FAA8F;;QAE9F,uEAAuE;;QAEvE,oDAAoD;;QAEpD;;;;;;WAMG;;QAEH;;;;;WAKG;;;IAsBH,0FAA0F;;IAE1F;;;;;;OAMG;;IAEH,2FAA2F;;IAE3F,qDAAqD;;IAErD,0FAA0F;;IAE1F,qEAAqE;;aAErE,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import * as v from 'valibot';
2
+ import { binaryModalitySchema } from './binary-modalities.js';
2
3
  // Wire vocabulary for BINARY-OUTPUT agent steps (docs/initiatives/binary-output-foundational-storage.md):
3
4
  // a step whose kind GENERATES binary artifacts (image generation is the canonical example) and
4
5
  // stores them through a FOUNDATIONAL SERVICE the step selected from the workspace's catalog —
@@ -29,6 +30,29 @@ export const binaryOutputConfigSchema = v.object({
29
30
  * context files are the whole scope.
30
31
  */
31
32
  contextServiceIds: v.optional(v.array(serviceId)),
33
+ /**
34
+ * The GENERATIVE INTEGRATIONS this step may call to produce its artifacts — ids from the
35
+ * deployment's code-registered `BinaryGeneratorRegistry` (see `binary-generators.ts`).
36
+ *
37
+ * A separate half of the selection from the two above, because it answers a different
38
+ * question: those say where an artifact GOES, this says what MAKES it. Absent ⇒ the step
39
+ * generates through whatever its agent already has (a model with native image output, a tool
40
+ * server), and its brief says so rather than naming an integration it does not have.
41
+ * Validated at run admission against the registry, never against a saved copy.
42
+ */
43
+ generatorIds: v.optional(v.array(serviceId)),
44
+ /**
45
+ * The CONTENT TYPES this step is expected to deliver. Every one of them must be covered by a
46
+ * selected generator, or the run is refused at admission — a step that must produce a theme
47
+ * song and selected only an image generator cannot do its job, and the failure would
48
+ * otherwise surface as an agent apologising at the end of a paid run.
49
+ *
50
+ * Absent ⇒ no requirement is imposed and the selected generators' own modalities are the
51
+ * whole story. It is deliberately NOT defaulted from the selection: "this step must produce
52
+ * audio" is a statement about the WORK, and deriving it from the current selection would make
53
+ * removing the audio generator look like a change of requirements rather than a break.
54
+ */
55
+ modalities: v.optional(v.array(binaryModalitySchema)),
32
56
  });
33
57
  /** One stored artifact a binary-generating step declared in its reply's machine-read block. */
34
58
  export const binaryOutputArtifactSchema = v.object({
@@ -50,6 +74,21 @@ export const binaryOutputArtifactSchema = v.object({
50
74
  contentType: v.optional(v.string()),
51
75
  /** A one-line description of what was generated. */
52
76
  description: v.optional(v.string()),
77
+ /**
78
+ * The generative integration the agent says PRODUCED the artifact, lowercased on read-back
79
+ * like {@link service}. Optional because a step may generate without a registered integration
80
+ * (a model with native image output), and a claim of "no generator" is a different fact from
81
+ * a claim naming one the deployment does not register — which is why an unrecognised id is
82
+ * NAMED in the report rather than dropped.
83
+ */
84
+ generator: v.optional(v.string()),
85
+ /**
86
+ * The CONTENT TYPE of the artifact, DERIVED in code from {@link contentType} — never read off
87
+ * the model's prose. Absent when no media type was declared, or when the declared one is not
88
+ * one the platform recognises: "we do not know what this is" and "this is not an image" are
89
+ * different answers, and only the second could justify a warning.
90
+ */
91
+ modality: v.optional(binaryModalitySchema),
53
92
  });
54
93
  /**
55
94
  * What a settled binary-generating step DECLARED it stored, read back from the fenced
@@ -70,6 +109,14 @@ export const binaryOutputReportSchema = v.object({
70
109
  stored: v.array(binaryOutputArtifactSchema),
71
110
  /** Distinct `service` ids named in entries that the resolved catalog does not contain. */
72
111
  unknownServices: v.array(v.string()),
112
+ /**
113
+ * Distinct `generator` ids named in entries that the deployment does not register. Kept apart
114
+ * from {@link unknownServices} because they resolve against different registries and need
115
+ * different fixes — a storage id points at the workspace's foundational catalog, a generator
116
+ * id at the deployment's code. Entries are RETAINED either way: the platform records what the
117
+ * agent claimed and a reader judges it.
118
+ */
119
+ unknownGenerators: v.array(v.string()),
73
120
  /** Entries dropped because they were not an object with `service` + `location` strings. */
74
121
  invalidEntries: v.number(),
75
122
  /** Valid entries dropped past the per-report cap. */
@@ -1 +1 @@
1
- {"version":3,"file":"binary-outputs.js","sourceRoot":"","sources":["../src/binary-outputs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,0GAA0G;AAC1G,+FAA+F;AAC/F,8FAA8F;AAC9F,+FAA+F;AAC/F,gGAAgG;AAChG,gGAAgG;AAChG,6EAA6E;AAE7E,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CACtB,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,IAAI,EAAE,EACR,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACd,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,EACf,CAAC,CAAC,KAAK,CAAC,sBAAsB,EAAE,4BAA4B,CAAC,CAC9D,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C;;;;OAIG;IACH,gBAAgB,EAAE,SAAS;IAC3B;;;;;;OAMG;IACH,iBAAiB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;CAClD,CAAC,CAAA;AAGF,+FAA+F;AAC/F,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD;;;;;OAKG;IACH,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB;;;OAGG;IACH,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,8FAA8F;IAC9F,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC9B,uEAAuE;IACvE,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACnC,oDAAoD;IACpD,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CACpC,CAAC,CAAA;AAGF;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,0BAA0B,CAAC;IAC3C,0FAA0F;IAC1F,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACpC,2FAA2F;IAC3F,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;IAC1B,qDAAqD;IACrD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,0FAA0F;IAC1F,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACpC,qEAAqE;IACrE,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;CACpC,CAAC,CAAA"}
1
+ {"version":3,"file":"binary-outputs.js","sourceRoot":"","sources":["../src/binary-outputs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAE7D,0GAA0G;AAC1G,+FAA+F;AAC/F,8FAA8F;AAC9F,+FAA+F;AAC/F,gGAAgG;AAChG,gGAAgG;AAChG,6EAA6E;AAE7E,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CACtB,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,IAAI,EAAE,EACR,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACd,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,EACf,CAAC,CAAC,KAAK,CAAC,sBAAsB,EAAE,4BAA4B,CAAC,CAC9D,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C;;;;OAIG;IACH,gBAAgB,EAAE,SAAS;IAC3B;;;;;;OAMG;IACH,iBAAiB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACjD;;;;;;;;;OASG;IACH,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC5C;;;;;;;;;;OAUG;IACH,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;CACtD,CAAC,CAAA;AAGF,+FAA+F;AAC/F,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD;;;;;OAKG;IACH,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB;;;OAGG;IACH,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,8FAA8F;IAC9F,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC9B,uEAAuE;IACvE,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACnC,oDAAoD;IACpD,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACnC;;;;;;OAMG;IACH,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACjC;;;;;OAKG;IACH,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC;CAC3C,CAAC,CAAA;AAGF;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,0BAA0B,CAAC;IAC3C,0FAA0F;IAC1F,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACpC;;;;;;OAMG;IACH,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACtC,2FAA2F;IAC3F,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;IAC1B,qDAAqD;IACrD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,0FAA0F;IAC1F,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACpC,qEAAqE;IACrE,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;CACpC,CAAC,CAAA"}