@cat-factory/kernel 0.279.3 → 0.281.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/domain/binary-candidates.d.ts +103 -0
- package/dist/domain/binary-candidates.d.ts.map +1 -0
- package/dist/domain/binary-candidates.js +283 -0
- package/dist/domain/binary-candidates.js.map +1 -0
- package/dist/domain/binary-generator-registry.d.ts +8 -1
- package/dist/domain/binary-generator-registry.d.ts.map +1 -1
- package/dist/domain/binary-generator-registry.js +1 -0
- package/dist/domain/binary-generator-registry.js.map +1 -1
- package/dist/domain/binary-generators.d.ts +31 -1
- package/dist/domain/binary-generators.d.ts.map +1 -1
- package/dist/domain/binary-generators.js +147 -1
- package/dist/domain/binary-generators.js.map +1 -1
- package/dist/domain/binary-outputs.d.ts +11 -1
- package/dist/domain/binary-outputs.d.ts.map +1 -1
- package/dist/domain/binary-outputs.js +78 -1
- package/dist/domain/binary-outputs.js.map +1 -1
- package/dist/domain/seed.d.ts +16 -21
- package/dist/domain/seed.d.ts.map +1 -1
- package/dist/domain/seed.js +182 -151
- package/dist/domain/seed.js.map +1 -1
- package/dist/domain/types.d.ts +1 -1
- package/dist/domain/types.d.ts.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { BinaryCandidate, BinaryCandidateComparison, BinaryCandidateStepState } from '@cat-factory/contracts';
|
|
2
|
+
import type { BinaryGeneratorView } from './binary-generator-registry.js';
|
|
3
|
+
/** The fenced block a comparison step's FIRST phase ends its reply with. */
|
|
4
|
+
export declare const BINARY_CANDIDATE_DECLARATION_TAG = "binary-candidates";
|
|
5
|
+
/**
|
|
6
|
+
* How many candidates ride ONE step's comparison.
|
|
7
|
+
*
|
|
8
|
+
* A hard bound on a surface a human has to look at, not merely on a row size: forty images side
|
|
9
|
+
* by side is not a comparison, and a step that generated that many has misread its own brief.
|
|
10
|
+
* Everything past it is COUNTED (`omitted`) rather than silently dropped, so the surface can say
|
|
11
|
+
* the list is a prefix.
|
|
12
|
+
*/
|
|
13
|
+
export declare const MAX_BINARY_CANDIDATES = 24;
|
|
14
|
+
/**
|
|
15
|
+
* What a first-phase reply declared it staged, before the engine mints ids and records it.
|
|
16
|
+
*
|
|
17
|
+
* Every loss is bookkept exactly as `parseBinaryOutputDeclaration` does it, and the two extra
|
|
18
|
+
* fields are the ones this surface needs and that one does not: an unusable preview is a
|
|
19
|
+
* candidate that renders as metadata rather than a candidate that failed, and `undeclared` /
|
|
20
|
+
* `parseFailed` are what turn a comparison into a stated `no_choice` rather than a wedged run.
|
|
21
|
+
*/
|
|
22
|
+
export interface BinaryCandidateDeclaration {
|
|
23
|
+
candidates: Omit<BinaryCandidate, 'id'>[];
|
|
24
|
+
invalidEntries: number;
|
|
25
|
+
omitted: number;
|
|
26
|
+
unusablePreviews: number;
|
|
27
|
+
parseFailed: boolean;
|
|
28
|
+
undeclared: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Read the candidates a comparison step staged out of its reply.
|
|
32
|
+
*
|
|
33
|
+
* The contract is a fenced ```binary-candidates block holding a JSON array of
|
|
34
|
+
* `{ generator?, subject?, service, location, contentType?, previewUrl?, label?, note? }`. The
|
|
35
|
+
* LAST block wins, like every other declaration in this feature, because the guidance asks the
|
|
36
|
+
* agent to END its reply with it and models illustrate the shape first.
|
|
37
|
+
*
|
|
38
|
+
* Ids are NOT read from the reply and are minted by the caller instead. The id is what a human's
|
|
39
|
+
* choice names and what the second phase resolves against, so a model that repeats one, omits
|
|
40
|
+
* one, or writes a paragraph into one would break the decision rather than its own bookkeeping.
|
|
41
|
+
* The agent's own name for a candidate is kept as `label`, so its prose can still be lined up
|
|
42
|
+
* with the rows.
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseBinaryCandidateDeclaration(output: string | undefined): BinaryCandidateDeclaration;
|
|
45
|
+
/**
|
|
46
|
+
* Whether a declared preview URL may be put in an `<img src>` on the board.
|
|
47
|
+
*
|
|
48
|
+
* `https` and nothing else. This string is written by a MODEL and rendered in a human's browser,
|
|
49
|
+
* which is the one place in this feature where a declaration is not merely recorded, so the rule
|
|
50
|
+
* is a whitelist rather than a blacklist: `javascript:` and `data:` are the obvious refusals, but
|
|
51
|
+
* so is plain `http` (a mixed-content image silently fails to load, which reads as a broken
|
|
52
|
+
* candidate rather than a refused link) and so is loopback (the browser's own machine is not the
|
|
53
|
+
* container's, so such a link points at whatever happens to be listening on the reader's laptop).
|
|
54
|
+
*
|
|
55
|
+
* Deliberately NOT `isAllowedMcpHttpUrl`, whose own note says it is not a guard for untrusted
|
|
56
|
+
* input: that predicate judges deployment-authored composition-root data and allows cleartext
|
|
57
|
+
* loopback precisely because the caller is a sidecar-hosting container. Both facts are wrong here,
|
|
58
|
+
* and reusing it because the shapes match is how a rule's rationale gets left behind.
|
|
59
|
+
*
|
|
60
|
+
* A refused URL costs the candidate its picture, never its row: the location, the generator and
|
|
61
|
+
* the note are what the comparison is anchored on, and dropping the whole entry over a bad link
|
|
62
|
+
* would remove a real generation from a decision.
|
|
63
|
+
*/
|
|
64
|
+
export declare function isRenderablePreviewUrl(raw: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* The FIRST-PHASE brief section: generate candidates, stage them, declare them, store nothing as
|
|
67
|
+
* final.
|
|
68
|
+
*
|
|
69
|
+
* The whole section exists because the default behaviour of a competent agent is the wrong one
|
|
70
|
+
* here. Handed two image APIs and a subject, it picks one, generates once, stores the result and
|
|
71
|
+
* reports success, which is exactly the unobserved choice this feature exists to surface. So the
|
|
72
|
+
* instruction is explicit on all four counts: generate from EVERY integration, do not treat any
|
|
73
|
+
* of it as a deliverable, put them somewhere a person can look at them, and stop.
|
|
74
|
+
*
|
|
75
|
+
* How to get several candidates from ONE integration is the one place the capability vocabulary
|
|
76
|
+
* changes the instruction rather than a control: an integration declaring `candidate-batch`
|
|
77
|
+
* returns them from a single call, and one that does not has to be called again with a different
|
|
78
|
+
* seed. Getting that backwards either multiplies the bill or sends a parameter the endpoint
|
|
79
|
+
* rejects, and no description could have said which.
|
|
80
|
+
*/
|
|
81
|
+
export declare function renderBinaryCandidateSection(input: {
|
|
82
|
+
comparison: BinaryCandidateComparison;
|
|
83
|
+
selected: readonly BinaryGeneratorView[];
|
|
84
|
+
/** Whether the step also fixes a seed, which changes what "vary the seed" can mean. */
|
|
85
|
+
fixedSeed?: number;
|
|
86
|
+
}): string[];
|
|
87
|
+
/**
|
|
88
|
+
* The SECOND-PHASE brief section: what the human kept, under which ids, and what to do with the
|
|
89
|
+
* rest.
|
|
90
|
+
*
|
|
91
|
+
* The decision is DATA and this is where it becomes work. The platform recorded which candidates
|
|
92
|
+
* survive; the agent is the party that can move a file, so it is told to promote exactly those
|
|
93
|
+
* and nothing else. Two instructions carry the weight:
|
|
94
|
+
*
|
|
95
|
+
* - **Every kept candidate is named with its own id when there is more than one.** Two survivors
|
|
96
|
+
* stored at one address is one artifact, and the ALTERNATE ID is the entire mechanism by which
|
|
97
|
+
* keeping two is a real outcome.
|
|
98
|
+
* - **The discarded candidates are named, and clearing them up is asked for explicitly.** The
|
|
99
|
+
* staged files exist; a pass that promotes one and forgets the other three leaves an asset
|
|
100
|
+
* store with four sprites in it, of which one is the sprite.
|
|
101
|
+
*/
|
|
102
|
+
export declare function renderBinaryCandidateChoiceSection(state: BinaryCandidateStepState): string[];
|
|
103
|
+
//# sourceMappingURL=binary-candidates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binary-candidates.d.ts","sourceRoot":"","sources":["../../src/domain/binary-candidates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AAezE,4EAA4E;AAC5E,eAAO,MAAM,gCAAgC,sBAAsB,CAAA;AAEnE;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAA;AAQvC;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,EAAE,CAAA;IACzC,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,gBAAgB,EAAE,MAAM,CAAA;IACxB,WAAW,EAAE,OAAO,CAAA;IACpB,UAAU,EAAE,OAAO,CAAA;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,0BAA0B,CAoD5B;AA6BD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAe3D;AAoBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAClD,UAAU,EAAE,yBAAyB,CAAA;IACrC,QAAQ,EAAE,SAAS,mBAAmB,EAAE,CAAA;IACxC,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GAAG,MAAM,EAAE,CAsCX;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,wBAAwB,GAAG,MAAM,EAAE,CA6C5F"}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { extractFencedDeclaration } from './fenced-declaration.js';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Pure logic for the CANDIDATE-COMPARISON half of a binary-output step
|
|
4
|
+
// (docs/initiatives/binary-output-foundational-storage.md): the phase-A brief that asks an agent
|
|
5
|
+
// for comparable candidates, the read-back of what it staged, and the phase-B brief that tells it
|
|
6
|
+
// which candidates a human kept and under which ids.
|
|
7
|
+
//
|
|
8
|
+
// A sibling of `binary-generators.ts` rather than more of it, because the two answer different
|
|
9
|
+
// questions at different moments: that module is about WHICH integrations a step may call, this
|
|
10
|
+
// one is about a step calling SEVERAL of them on purpose and handing the choice to a person. No
|
|
11
|
+
// I/O, so admission, the dispatch brief and the settlement read-back all apply identical rules.
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
/** The fenced block a comparison step's FIRST phase ends its reply with. */
|
|
14
|
+
export const BINARY_CANDIDATE_DECLARATION_TAG = 'binary-candidates';
|
|
15
|
+
/**
|
|
16
|
+
* How many candidates ride ONE step's comparison.
|
|
17
|
+
*
|
|
18
|
+
* A hard bound on a surface a human has to look at, not merely on a row size: forty images side
|
|
19
|
+
* by side is not a comparison, and a step that generated that many has misread its own brief.
|
|
20
|
+
* Everything past it is COUNTED (`omitted`) rather than silently dropped, so the surface can say
|
|
21
|
+
* the list is a prefix.
|
|
22
|
+
*/
|
|
23
|
+
export const MAX_BINARY_CANDIDATES = 24;
|
|
24
|
+
/** Longest `service`/`location` accepted per candidate; beyond it the entry is INVALID. */
|
|
25
|
+
const MAX_IDENTITY_CHARS = 512;
|
|
26
|
+
/** Longest optional display field retained per candidate; the excess is elided with a marker. */
|
|
27
|
+
const MAX_DISPLAY_CHARS = 300;
|
|
28
|
+
/**
|
|
29
|
+
* Read the candidates a comparison step staged out of its reply.
|
|
30
|
+
*
|
|
31
|
+
* The contract is a fenced ```binary-candidates block holding a JSON array of
|
|
32
|
+
* `{ generator?, subject?, service, location, contentType?, previewUrl?, label?, note? }`. The
|
|
33
|
+
* LAST block wins, like every other declaration in this feature, because the guidance asks the
|
|
34
|
+
* agent to END its reply with it and models illustrate the shape first.
|
|
35
|
+
*
|
|
36
|
+
* Ids are NOT read from the reply and are minted by the caller instead. The id is what a human's
|
|
37
|
+
* choice names and what the second phase resolves against, so a model that repeats one, omits
|
|
38
|
+
* one, or writes a paragraph into one would break the decision rather than its own bookkeeping.
|
|
39
|
+
* The agent's own name for a candidate is kept as `label`, so its prose can still be lined up
|
|
40
|
+
* with the rows.
|
|
41
|
+
*/
|
|
42
|
+
export function parseBinaryCandidateDeclaration(output) {
|
|
43
|
+
const empty = {
|
|
44
|
+
candidates: [],
|
|
45
|
+
invalidEntries: 0,
|
|
46
|
+
omitted: 0,
|
|
47
|
+
unusablePreviews: 0,
|
|
48
|
+
parseFailed: false,
|
|
49
|
+
undeclared: false,
|
|
50
|
+
};
|
|
51
|
+
const body = extractFencedDeclaration(output, BINARY_CANDIDATE_DECLARATION_TAG);
|
|
52
|
+
if (body === null)
|
|
53
|
+
return { ...empty, undeclared: true };
|
|
54
|
+
// `none` is accepted and means the same thing an empty array does: the agent staged nothing.
|
|
55
|
+
// It is a legitimate answer (every generation failed, or the scope turned out to be empty) and
|
|
56
|
+
// it resolves to `too_few` rather than to an error, so the run advances and the step's report
|
|
57
|
+
// says what happened.
|
|
58
|
+
if (body.toLowerCase() === 'none')
|
|
59
|
+
return empty;
|
|
60
|
+
let parsed;
|
|
61
|
+
try {
|
|
62
|
+
parsed = JSON.parse(body);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// silent-catch-ok: an unparseable body is a REPORTED state (`parseFailed` → a `no_choice`
|
|
66
|
+
// the surface names) rather than an error: the generation itself already happened.
|
|
67
|
+
return { ...empty, parseFailed: true };
|
|
68
|
+
}
|
|
69
|
+
const entries = Array.isArray(parsed) ? parsed : [parsed];
|
|
70
|
+
const candidates = [];
|
|
71
|
+
let invalidEntries = 0;
|
|
72
|
+
let omitted = 0;
|
|
73
|
+
let unusablePreviews = 0;
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
const coerced = coerceCandidate(entry);
|
|
76
|
+
if (!coerced) {
|
|
77
|
+
invalidEntries++;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (candidates.length >= MAX_BINARY_CANDIDATES) {
|
|
81
|
+
omitted++;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (coerced.previewRefused)
|
|
85
|
+
unusablePreviews++;
|
|
86
|
+
candidates.push(coerced.candidate);
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
candidates,
|
|
90
|
+
invalidEntries,
|
|
91
|
+
omitted,
|
|
92
|
+
unusablePreviews,
|
|
93
|
+
parseFailed: false,
|
|
94
|
+
undeclared: false,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function coerceCandidate(entry) {
|
|
98
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry))
|
|
99
|
+
return null;
|
|
100
|
+
const record = entry;
|
|
101
|
+
const service = identityField(record.service)?.toLowerCase();
|
|
102
|
+
const location = identityField(record.location);
|
|
103
|
+
if (!service || !location)
|
|
104
|
+
return null;
|
|
105
|
+
const candidate = { service, location };
|
|
106
|
+
// Lowercased like `service` and for the same reason: registry ids are lower-kebab slugs, so a
|
|
107
|
+
// model that capitalises one means the registered integration.
|
|
108
|
+
const generator = identityField(record.generator)?.toLowerCase();
|
|
109
|
+
const label = displayField(record.label);
|
|
110
|
+
const subject = displayField(record.subject);
|
|
111
|
+
const contentType = displayField(record.contentType);
|
|
112
|
+
const note = displayField(record.note);
|
|
113
|
+
if (generator)
|
|
114
|
+
candidate.generator = generator;
|
|
115
|
+
if (label)
|
|
116
|
+
candidate.label = label;
|
|
117
|
+
if (subject)
|
|
118
|
+
candidate.subject = subject;
|
|
119
|
+
if (contentType)
|
|
120
|
+
candidate.contentType = contentType;
|
|
121
|
+
if (note)
|
|
122
|
+
candidate.note = note;
|
|
123
|
+
const rawPreview = typeof record.previewUrl === 'string' ? record.previewUrl.trim() : '';
|
|
124
|
+
const previewUrl = rawPreview && isRenderablePreviewUrl(rawPreview) ? rawPreview : undefined;
|
|
125
|
+
if (previewUrl)
|
|
126
|
+
candidate.previewUrl = previewUrl;
|
|
127
|
+
return { candidate, previewRefused: rawPreview !== '' && previewUrl === undefined };
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Whether a declared preview URL may be put in an `<img src>` on the board.
|
|
131
|
+
*
|
|
132
|
+
* `https` and nothing else. This string is written by a MODEL and rendered in a human's browser,
|
|
133
|
+
* which is the one place in this feature where a declaration is not merely recorded, so the rule
|
|
134
|
+
* is a whitelist rather than a blacklist: `javascript:` and `data:` are the obvious refusals, but
|
|
135
|
+
* so is plain `http` (a mixed-content image silently fails to load, which reads as a broken
|
|
136
|
+
* candidate rather than a refused link) and so is loopback (the browser's own machine is not the
|
|
137
|
+
* container's, so such a link points at whatever happens to be listening on the reader's laptop).
|
|
138
|
+
*
|
|
139
|
+
* Deliberately NOT `isAllowedMcpHttpUrl`, whose own note says it is not a guard for untrusted
|
|
140
|
+
* input: that predicate judges deployment-authored composition-root data and allows cleartext
|
|
141
|
+
* loopback precisely because the caller is a sidecar-hosting container. Both facts are wrong here,
|
|
142
|
+
* and reusing it because the shapes match is how a rule's rationale gets left behind.
|
|
143
|
+
*
|
|
144
|
+
* A refused URL costs the candidate its picture, never its row: the location, the generator and
|
|
145
|
+
* the note are what the comparison is anchored on, and dropping the whole entry over a bad link
|
|
146
|
+
* would remove a real generation from a decision.
|
|
147
|
+
*/
|
|
148
|
+
export function isRenderablePreviewUrl(raw) {
|
|
149
|
+
// The WHATWG parser, reached through `globalThis` because kernel compiles against the ES2022
|
|
150
|
+
// lib alone: the same trade `agent-capabilities.ts` makes, and made here for the stronger of
|
|
151
|
+
// its two reasons: the string is rendered by a BROWSER, so the only parser whose verdict is
|
|
152
|
+
// binding is the one the browser uses. A runtime without it REFUSES rather than falling back to
|
|
153
|
+
// a regex, since a hand-written scheme scan is exactly how `javascript:` survives an escape.
|
|
154
|
+
const parser = globalThis.URL;
|
|
155
|
+
if (!parser)
|
|
156
|
+
return false;
|
|
157
|
+
try {
|
|
158
|
+
return new parser(raw).protocol === 'https:';
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// silent-catch-ok: an unparseable URL is simply not renderable, and the caller COUNTS the
|
|
162
|
+
// refusal (`unusablePreviews`) rather than dropping it silently.
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/** A field that IDENTIFIES something: non-empty and within the cap, or the entry is invalid. */
|
|
167
|
+
function identityField(value) {
|
|
168
|
+
if (typeof value !== 'string')
|
|
169
|
+
return null;
|
|
170
|
+
const trimmed = value.trim();
|
|
171
|
+
if (!trimmed || trimmed.length > MAX_IDENTITY_CHARS)
|
|
172
|
+
return null;
|
|
173
|
+
return trimmed;
|
|
174
|
+
}
|
|
175
|
+
/** A field that DESCRIBES something: kept best-effort, elided past the cap with a marker. */
|
|
176
|
+
function displayField(value) {
|
|
177
|
+
if (typeof value !== 'string')
|
|
178
|
+
return undefined;
|
|
179
|
+
const trimmed = value.trim();
|
|
180
|
+
if (!trimmed)
|
|
181
|
+
return undefined;
|
|
182
|
+
return trimmed.length > MAX_DISPLAY_CHARS ? `${trimmed.slice(0, MAX_DISPLAY_CHARS)}…` : trimmed;
|
|
183
|
+
}
|
|
184
|
+
// --- agent-facing rendering -------------------------------------------------
|
|
185
|
+
/**
|
|
186
|
+
* The FIRST-PHASE brief section: generate candidates, stage them, declare them, store nothing as
|
|
187
|
+
* final.
|
|
188
|
+
*
|
|
189
|
+
* The whole section exists because the default behaviour of a competent agent is the wrong one
|
|
190
|
+
* here. Handed two image APIs and a subject, it picks one, generates once, stores the result and
|
|
191
|
+
* reports success, which is exactly the unobserved choice this feature exists to surface. So the
|
|
192
|
+
* instruction is explicit on all four counts: generate from EVERY integration, do not treat any
|
|
193
|
+
* of it as a deliverable, put them somewhere a person can look at them, and stop.
|
|
194
|
+
*
|
|
195
|
+
* How to get several candidates from ONE integration is the one place the capability vocabulary
|
|
196
|
+
* changes the instruction rather than a control: an integration declaring `candidate-batch`
|
|
197
|
+
* returns them from a single call, and one that does not has to be called again with a different
|
|
198
|
+
* seed. Getting that backwards either multiplies the bill or sends a parameter the endpoint
|
|
199
|
+
* rejects, and no description could have said which.
|
|
200
|
+
*/
|
|
201
|
+
export function renderBinaryCandidateSection(input) {
|
|
202
|
+
const perGenerator = input.comparison.perGenerator ?? 1;
|
|
203
|
+
const batched = input.selected.filter((g) => g.capabilities.includes('candidate-batch'));
|
|
204
|
+
const lines = [
|
|
205
|
+
'## Candidates for review',
|
|
206
|
+
'',
|
|
207
|
+
'This step does NOT deliver its artifacts directly. A person compares candidates and decides which survive, so your job in this pass is to produce the choices and stop.',
|
|
208
|
+
'',
|
|
209
|
+
];
|
|
210
|
+
if (input.selected.length > 1) {
|
|
211
|
+
lines.push(`- Generate ${perGenerator === 1 ? 'one candidate' : `${perGenerator} candidates`} per subject from EVERY integration listed above, not from whichever one you would have picked. The comparison is between them; a subject missing an integration's candidate cannot be judged.`);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
lines.push(`- Generate ${perGenerator} candidate${perGenerator === 1 ? '' : 's'} per subject. Make them meaningfully different from each other, and say how in each candidate's \`note\`.`);
|
|
215
|
+
}
|
|
216
|
+
if (perGenerator > 1) {
|
|
217
|
+
lines.push(batched.length > 0
|
|
218
|
+
? `- ${joinIds(batched.map((g) => g.id))} can return several candidates from ONE call: ask for ${perGenerator} that way rather than repeating the request. For any other integration, repeat the call with a different seed.`
|
|
219
|
+
: '- No selected integration returns several candidates from one call, so repeat the request with a different seed for each candidate rather than looking for a count parameter.');
|
|
220
|
+
}
|
|
221
|
+
if (input.fixedSeed !== undefined && perGenerator > 1) {
|
|
222
|
+
lines.push(`- This step fixes a seed (${input.fixedSeed}). Use it for the FIRST candidate of each subject and vary it for the rest, so one candidate stays reproducible and the others are genuinely different.`);
|
|
223
|
+
}
|
|
224
|
+
lines.push('- Stage every candidate through the storage service below, clearly marked as a candidate rather than a deliverable. Do NOT store anything at its final location, delete anything, or overwrite an existing asset in this pass.', `- End your reply with a fenced \`\`\`${BINARY_CANDIDATE_DECLARATION_TAG} block: a JSON array of \`{ generator, subject, service, location, contentType, previewUrl, label, note }\`. \`generator\` and \`subject\` are what the comparison is grouped and labelled by, so omitting them makes the candidates unreadable to whoever decides.`, "- `previewUrl` must be an https URL the storage service issued for the candidate. If it issues none, leave it out rather than constructing one: the reviewer is shown the candidate's details instead, which is honest, and a broken image is not.", '- Then STOP. Do not declare `binary-outputs` in this pass; you will be run again with the decision.', '');
|
|
225
|
+
return lines;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* The SECOND-PHASE brief section: what the human kept, under which ids, and what to do with the
|
|
229
|
+
* rest.
|
|
230
|
+
*
|
|
231
|
+
* The decision is DATA and this is where it becomes work. The platform recorded which candidates
|
|
232
|
+
* survive; the agent is the party that can move a file, so it is told to promote exactly those
|
|
233
|
+
* and nothing else. Two instructions carry the weight:
|
|
234
|
+
*
|
|
235
|
+
* - **Every kept candidate is named with its own id when there is more than one.** Two survivors
|
|
236
|
+
* stored at one address is one artifact, and the ALTERNATE ID is the entire mechanism by which
|
|
237
|
+
* keeping two is a real outcome.
|
|
238
|
+
* - **The discarded candidates are named, and clearing them up is asked for explicitly.** The
|
|
239
|
+
* staged files exist; a pass that promotes one and forgets the other three leaves an asset
|
|
240
|
+
* store with four sprites in it, of which one is the sprite.
|
|
241
|
+
*/
|
|
242
|
+
export function renderBinaryCandidateChoiceSection(state) {
|
|
243
|
+
const choice = state.choice;
|
|
244
|
+
if (!choice)
|
|
245
|
+
return [];
|
|
246
|
+
const byId = new Map(state.candidates.map((candidate) => [candidate.id, candidate]));
|
|
247
|
+
const lines = [
|
|
248
|
+
'## The candidate decision',
|
|
249
|
+
'',
|
|
250
|
+
'You generated candidates in an earlier pass and a person has now chosen. Deliver exactly what was kept.',
|
|
251
|
+
'',
|
|
252
|
+
];
|
|
253
|
+
for (const kept of choice.kept) {
|
|
254
|
+
const candidate = byId.get(kept.candidateId);
|
|
255
|
+
if (!candidate)
|
|
256
|
+
continue;
|
|
257
|
+
const identity = [
|
|
258
|
+
candidate.generator ? `from \`${candidate.generator}\`` : 'from an unattributed generator',
|
|
259
|
+
candidate.subject ? `for ${candidate.subject}` : null,
|
|
260
|
+
]
|
|
261
|
+
.filter(Boolean)
|
|
262
|
+
.join(' ');
|
|
263
|
+
lines.push(`- KEEP the candidate staged at \`${candidate.location}\` in \`${candidate.service}\` (${identity}).` +
|
|
264
|
+
(kept.storeAs
|
|
265
|
+
? ` Store it as \`${kept.storeAs}\`: that id is what distinguishes it from the other kept candidates, so use it exactly.`
|
|
266
|
+
: " Store it under this step's ordinary naming."));
|
|
267
|
+
}
|
|
268
|
+
const discarded = choice.discarded.flatMap((id) => byId.get(id) ?? []);
|
|
269
|
+
if (discarded.length > 0) {
|
|
270
|
+
lines.push(`- DISCARD the ${discarded.length} candidate${discarded.length === 1 ? '' : 's'} that were not kept, and remove the staged file${discarded.length === 1 ? '' : 's'} where the storage service allows it: ${discarded.map((c) => `\`${c.location}\``).join(', ')}. If it does not, say so in your report rather than leaving it unsaid.`);
|
|
271
|
+
}
|
|
272
|
+
if (choice.note) {
|
|
273
|
+
lines.push('', `The person who chose added: ${choice.note}`, 'Apply it to what you store. If it asks for a change the kept candidate does not already have, regenerate that artifact with the change rather than storing the candidate as-is.');
|
|
274
|
+
}
|
|
275
|
+
lines.push('', 'Do NOT generate a new set of candidates and do NOT declare `binary-candidates` again. Store what was kept and declare it in the `binary-outputs` block as usual.', '');
|
|
276
|
+
return lines;
|
|
277
|
+
}
|
|
278
|
+
/** `` `a` and `b` ``; `` `a`, `b` and `c` ``. Total for any length, including the empty list. */
|
|
279
|
+
function joinIds(ids) {
|
|
280
|
+
const quoted = ids.map((id) => `\`${id}\``);
|
|
281
|
+
return [quoted.slice(0, -1).join(', '), ...quoted.slice(-1)].filter(Boolean).join(' and ');
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=binary-candidates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binary-candidates.js","sourceRoot":"","sources":["../../src/domain/binary-candidates.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ApiContractDocument, ApiContractSummary, BinaryGeneratorCredential, BinaryGeneratorDefinition, BinaryModality } from '@cat-factory/contracts';
|
|
1
|
+
import type { ApiContractDocument, ApiContractSummary, BinaryGeneratorCapability, BinaryGeneratorCredential, BinaryGeneratorDefinition, BinaryModality } from '@cat-factory/contracts';
|
|
2
2
|
/**
|
|
3
3
|
* The wire definition verbatim, re-exported so a deployment registering an integration imports
|
|
4
4
|
* one name from the layer it is already wiring against (the same courtesy
|
|
@@ -21,6 +21,13 @@ export interface BinaryGeneratorView {
|
|
|
21
21
|
description: string;
|
|
22
22
|
modalities: BinaryModality[];
|
|
23
23
|
mediaTypes: string[];
|
|
24
|
+
/**
|
|
25
|
+
* What it can be ASKED FOR while generating. EMPTY means the definition declared none, which
|
|
26
|
+
* the coverage rule reads as "only the coarse facts are known" rather than as a denial: the
|
|
27
|
+
* same reading an empty {@link mediaTypes} gets, and the reason both are projected as arrays
|
|
28
|
+
* here while the wire form omits them.
|
|
29
|
+
*/
|
|
30
|
+
capabilities: BinaryGeneratorCapability[];
|
|
24
31
|
endpoint?: string;
|
|
25
32
|
guidance?: string;
|
|
26
33
|
credential?: BinaryGeneratorCredential;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binary-generator-registry.d.ts","sourceRoot":"","sources":["../../src/domain/binary-generator-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,yBAAyB,EACzB,yBAAyB,EACzB,cAAc,EACf,MAAM,wBAAwB,CAAA;AAG/B;;;;GAIG;AACH,YAAY,EAAE,yBAAyB,EAAE,CAAA;AAqBzC;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,cAAc,EAAE,CAAA;IAC5B,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,yBAAyB,CAAA;IACtC,SAAS,EAAE,kBAAkB,EAAE,CAAA;CAChC;AAED;;;;GAIG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+C;IAC3E;;;;;;OAMG;IACH,OAAO,CAAC,UAAU,CAGH;IAEf,2FAA2F;IAC3F,QAAQ,CAAC,UAAU,EAAE,yBAAyB,GAAG,IAAI,CAGpD;IAED,6CAA6C;IAC7C,WAAW,CAAC,WAAW,EAAE,QAAQ,CAAC,yBAAyB,CAAC,GAAG,IAAI,CAElE;IAED,iFAAiF;IACjF,GAAG,IAAI,yBAAyB,EAAE,CAEjC;IAED,sGAAsG;IACtG,GAAG,IAAI,MAAM,EAAE,CAEd;IAED,yFAAyF;IACzF,KAAK,IAAI,mBAAmB,EAAE,CAE7B;IAED,gGAAgG;IAChG,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAE9C;IAED,OAAO,CAAC,KAAK;
|
|
1
|
+
{"version":3,"file":"binary-generator-registry.d.ts","sourceRoot":"","sources":["../../src/domain/binary-generator-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,cAAc,EACf,MAAM,wBAAwB,CAAA;AAG/B;;;;GAIG;AACH,YAAY,EAAE,yBAAyB,EAAE,CAAA;AAqBzC;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,cAAc,EAAE,CAAA;IAC5B,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB;;;;;OAKG;IACH,YAAY,EAAE,yBAAyB,EAAE,CAAA;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,yBAAyB,CAAA;IACtC,SAAS,EAAE,kBAAkB,EAAE,CAAA;CAChC;AAED;;;;GAIG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+C;IAC3E;;;;;;OAMG;IACH,OAAO,CAAC,UAAU,CAGH;IAEf,2FAA2F;IAC3F,QAAQ,CAAC,UAAU,EAAE,yBAAyB,GAAG,IAAI,CAGpD;IAED,6CAA6C;IAC7C,WAAW,CAAC,WAAW,EAAE,QAAQ,CAAC,yBAAyB,CAAC,GAAG,IAAI,CAElE;IAED,iFAAiF;IACjF,GAAG,IAAI,yBAAyB,EAAE,CAEjC;IAED,sGAAsG;IACtG,GAAG,IAAI,MAAM,EAAE,CAEd;IAED,yFAAyF;IACzF,KAAK,IAAI,mBAAmB,EAAE,CAE7B;IAED,gGAAgG;IAChG,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAE9C;IAED,OAAO,CAAC,KAAK;CAyCd;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,IAAI,uBAAuB,CAExE"}
|
|
@@ -65,6 +65,7 @@ export class BinaryGeneratorRegistry {
|
|
|
65
65
|
description: definition.description,
|
|
66
66
|
modalities: [...definition.modalities],
|
|
67
67
|
mediaTypes: [...(definition.mediaTypes ?? [])],
|
|
68
|
+
capabilities: [...(definition.capabilities ?? [])],
|
|
68
69
|
...(definition.endpoint ? { endpoint: definition.endpoint } : {}),
|
|
69
70
|
...(definition.guidance ? { guidance: definition.guidance } : {}),
|
|
70
71
|
...(definition.credential ? { credential: definition.credential } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binary-generator-registry.js","sourceRoot":"","sources":["../../src/domain/binary-generator-registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"binary-generator-registry.js","sourceRoot":"","sources":["../../src/domain/binary-generator-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BinaryModality, BinaryOutputConfig } from '@cat-factory/contracts';
|
|
1
|
+
import type { BinaryGenerationOptions, BinaryGeneratorCapability, BinaryModality, BinaryOutputConfig } from '@cat-factory/contracts';
|
|
2
2
|
import type { BinaryGeneratorView } from './binary-generator-registry.js';
|
|
3
3
|
import { BINARY_GENERATOR_CONTEXT_DIR, binaryGeneratorContextFileFor } from './binary-output-paths.js';
|
|
4
4
|
export { BINARY_GENERATOR_CONTEXT_DIR, binaryGeneratorContextFileFor };
|
|
@@ -68,6 +68,24 @@ export type BinaryGeneratorSelectionIssue =
|
|
|
68
68
|
| {
|
|
69
69
|
problem: 'media_type_uncovered';
|
|
70
70
|
mediaType: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* A per-step GENERATION OPTION whose capability no selected integration declares: a reference
|
|
74
|
+
* image handed to an endpoint that takes no image input, a mask edit asked of an API that only
|
|
75
|
+
* rewrites whole pictures, a seed asked of one that has none.
|
|
76
|
+
*
|
|
77
|
+
* The third axis of the same rule the two above enforce, and refused for the same reason: an
|
|
78
|
+
* unsupported parameter is not a thinner generation. Either the call is rejected, which burns
|
|
79
|
+
* the run, or it succeeds having silently ignored the one input that made the step's output
|
|
80
|
+
* correct, which is worse because every downstream check passes.
|
|
81
|
+
*
|
|
82
|
+
* Only ever raised against integrations that DECLARED their capabilities. The third outcome
|
|
83
|
+
* ({@link binaryCapabilityCoverage}'s `unverifiable`) is not an issue, which is what keeps
|
|
84
|
+
* every integration registered before this axis existed running unchanged.
|
|
85
|
+
*/
|
|
86
|
+
| {
|
|
87
|
+
problem: 'capability_unsupported';
|
|
88
|
+
capability: BinaryGeneratorCapability;
|
|
71
89
|
};
|
|
72
90
|
/** A step's selection, resolved against the registry's views. */
|
|
73
91
|
export interface ResolvedBinaryGeneratorSelection {
|
|
@@ -102,6 +120,16 @@ export declare function resolveBinaryGeneratorSelection(config: BinaryOutputConf
|
|
|
102
120
|
* step that lost three integrations instead of three refuse-fix-restart rounds.
|
|
103
121
|
*/
|
|
104
122
|
export declare function binaryGeneratorSelectionIssues(config: BinaryOutputConfig | undefined, generators: readonly BinaryGeneratorView[]): BinaryGeneratorSelectionIssue[];
|
|
123
|
+
/**
|
|
124
|
+
* A capability in words, for a message a human reads.
|
|
125
|
+
*
|
|
126
|
+
* The `default` is here for the reason {@link describeModality}'s is, minus the persistence: this
|
|
127
|
+
* vocabulary is not stored on a step, but a MOTHERSHIP-MODE node resolves its integrations from a
|
|
128
|
+
* process that may be a build AHEAD of it, so a capability this build has never defined arrives
|
|
129
|
+
* over `/internal/binary-generators` and reaches this switch. Falling off the end would render it
|
|
130
|
+
* `undefined` inside the one sentence whose job is to say what a selection cannot do.
|
|
131
|
+
*/
|
|
132
|
+
export declare function describeCapability(capability: BinaryGeneratorCapability): string;
|
|
105
133
|
/**
|
|
106
134
|
* The content type in words, for a message a human reads.
|
|
107
135
|
*
|
|
@@ -144,5 +172,7 @@ export declare function renderBinaryGeneratorSection(input: {
|
|
|
144
172
|
requestedModalities: BinaryModality[];
|
|
145
173
|
/** The concrete formats it must deliver (`stepOptions.binaryOutput.mediaTypes`). */
|
|
146
174
|
requestedMediaTypes?: string[];
|
|
175
|
+
/** The parameters every generation carries (`stepOptions.binaryOutput.generation`). */
|
|
176
|
+
generation?: BinaryGenerationOptions;
|
|
147
177
|
}): string[];
|
|
148
178
|
//# sourceMappingURL=binary-generators.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binary-generators.d.ts","sourceRoot":"","sources":["../../src/domain/binary-generators.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"binary-generators.d.ts","sourceRoot":"","sources":["../../src/domain/binary-generators.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,uBAAuB,EACvB,yBAAyB,EACzB,cAAc,EACd,kBAAkB,EACnB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AACzE,OAAO,EACL,4BAA4B,EAC5B,6BAA6B,EAC9B,MAAM,0BAA0B,CAAA;AAsBjC,OAAO,EAAE,4BAA4B,EAAE,6BAA6B,EAAE,CAAA;AAEtE;;;;;;;;GAQG;AACH,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,cAAc,EAAE,CAAA;IAM5B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,6FAA6F;IAC7F,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED;;kGAEkG;AAClG,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,gCAAgC,GAC1C,uBAAuB,EAAE,CAS3B;AAED,oFAAoF;AACpF,MAAM,MAAM,6BAA6B;AACvC,0DAA0D;AACxD;IAAE,OAAO,EAAE,mBAAmB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE;AACvD;;;;GAIG;GACD;IAAE,OAAO,EAAE,oBAAoB,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAE;AAC7D;;;;;;;;GAQG;GACD;IAAE,OAAO,EAAE,sBAAsB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE;AACxD;;;;;;;;;;;;;GAaG;GACD;IAAE,OAAO,EAAE,wBAAwB,CAAC;IAAC,UAAU,EAAE,yBAAyB,CAAA;CAAE,CAAA;AAEhF,iEAAiE;AACjE,MAAM,WAAW,gCAAgC;IAC/C,0DAA0D;IAC1D,QAAQ,EAAE,mBAAmB,EAAE,CAAA;IAC/B,wEAAwE;IACxE,aAAa,EAAE,MAAM,EAAE,CAAA;CACxB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,kBAAkB,GAAG,SAAS,EACtC,UAAU,EAAE,SAAS,mBAAmB,EAAE,GACzC,gCAAgC,CAalC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,kBAAkB,GAAG,SAAS,EACtC,UAAU,EAAE,SAAS,mBAAmB,EAAE,GACzC,6BAA6B,EAAE,CA0BjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,yBAAyB,GAAG,MAAM,CA6BhF;AAcD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAiBjE;AAcD;;;;;;;GAOG;AACH,wBAAgB,sCAAsC,CACpD,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,6BAA6B,EAAE,GAC/C,MAAM,CAmBR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAClD,SAAS,EAAE,gCAAgC,CAAA;IAC3C,mGAAmG;IACnG,mBAAmB,EAAE,cAAc,EAAE,CAAA;IACrC,oFAAoF;IACpF,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC9B,uFAAuF;IACvF,UAAU,CAAC,EAAE,uBAAuB,CAAA;CACrC,GAAG,MAAM,EAAE,CA4CX"}
|