@happyvertical/smrt-ingestion 0.57.45 → 0.57.47
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/FEEDBACK.md +30 -0
- package/PROPOSALS.md +29 -0
- package/REVIEW.md +79 -0
- package/agents/execution.md +3 -1
- package/dist/chunks/{execution-DKWz2cz0.js → execution-Clcmi0sj.js} +2 -2
- package/dist/chunks/{execution-DKWz2cz0.js.map → execution-Clcmi0sj.js.map} +1 -1
- package/dist/chunks/{feedback-DHcSKgVU.js → feedback-hDSMYjiG.js} +94 -34
- package/dist/chunks/feedback-hDSMYjiG.js.map +1 -0
- package/dist/chunks/{proposal-contracts-CPH3ckgH.js → proposal-contracts-DREPLG56.js} +75 -2
- package/dist/chunks/proposal-contracts-DREPLG56.js.map +1 -0
- package/dist/chunks/{reviewer-instruction-Deoe4NPv.js → reviewer-instruction-BeOYVCVk.js} +2 -2
- package/dist/chunks/{reviewer-instruction-Deoe4NPv.js.map → reviewer-instruction-BeOYVCVk.js.map} +1 -1
- package/dist/execution-contracts.d.ts +7 -0
- package/dist/execution-contracts.d.ts.map +1 -1
- package/dist/execution.js +1 -1
- package/dist/feedback-contracts.d.ts +32 -3
- package/dist/feedback-contracts.d.ts.map +1 -1
- package/dist/feedback.d.ts +28 -0
- package/dist/feedback.d.ts.map +1 -1
- package/dist/generation-retry.d.ts +45 -0
- package/dist/generation-retry.d.ts.map +1 -0
- package/dist/manifest.json +1 -1
- package/dist/models.js +1 -1
- package/dist/models.js.map +1 -1
- package/dist/proposal-contracts.d.ts +15 -0
- package/dist/proposal-contracts.d.ts.map +1 -1
- package/dist/proposal-dto.d.ts +6 -0
- package/dist/proposal-dto.d.ts.map +1 -1
- package/dist/proposals.d.ts +7 -0
- package/dist/proposals.d.ts.map +1 -1
- package/dist/proposals.js +61 -18
- package/dist/proposals.js.map +1 -1
- package/dist/review-dto.d.ts +56 -0
- package/dist/review-dto.d.ts.map +1 -1
- package/dist/review-host.d.ts +14 -1
- package/dist/review-host.d.ts.map +1 -1
- package/dist/server.d.ts +27 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +127 -5
- package/dist/server.js.map +1 -1
- package/dist/smrt-knowledge.json +16 -16
- package/dist/svelte/argument-fields.d.ts +48 -0
- package/dist/svelte/argument-fields.d.ts.map +1 -0
- package/dist/svelte/argument-fields.js +96 -0
- package/dist/svelte/components/ActionReview.svelte +81 -11
- package/dist/svelte/components/ActionReview.svelte.d.ts +30 -1
- package/dist/svelte/components/ActionReview.svelte.d.ts.map +1 -1
- package/dist/svelte/components/ArgumentFields.svelte +176 -0
- package/dist/svelte/components/ArgumentFields.svelte.d.ts +27 -0
- package/dist/svelte/components/ArgumentFields.svelte.d.ts.map +1 -0
- package/dist/svelte/components/InboxView.svelte +137 -17
- package/dist/svelte/components/InboxView.svelte.d.ts +17 -0
- package/dist/svelte/components/InboxView.svelte.d.ts.map +1 -1
- package/dist/svelte/components/IntakeInbox.svelte +26 -2
- package/dist/svelte/components/IntakeInbox.svelte.d.ts +10 -1
- package/dist/svelte/components/IntakeInbox.svelte.d.ts.map +1 -1
- package/dist/svelte/components/IntakeWorkspace.svelte +23 -1
- package/dist/svelte/components/IntakeWorkspace.svelte.d.ts +13 -1
- package/dist/svelte/components/IntakeWorkspace.svelte.d.ts.map +1 -1
- package/dist/svelte/components/ReviewView.svelte +88 -10
- package/dist/svelte/components/ReviewView.svelte.d.ts.map +1 -1
- package/dist/svelte/components/TriageView.svelte +43 -3
- package/dist/svelte/components/TriageView.svelte.d.ts +10 -1
- package/dist/svelte/components/TriageView.svelte.d.ts.map +1 -1
- package/dist/svelte/i18n.d.ts +33 -0
- package/dist/svelte/i18n.d.ts.map +1 -1
- package/dist/svelte/i18n.js +36 -0
- package/dist/svelte/index.d.ts +2 -1
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +1 -0
- package/dist/svelte/upload-refusal.d.ts +25 -0
- package/dist/svelte/upload-refusal.d.ts.map +1 -0
- package/dist/svelte/upload-refusal.js +40 -0
- package/dist/svelte/view-utils.d.ts +8 -0
- package/dist/svelte/view-utils.d.ts.map +1 -1
- package/dist/svelte/view-utils.js +36 -0
- package/package.json +17 -17
- package/dist/chunks/feedback-DHcSKgVU.js.map +0 -1
- package/dist/chunks/proposal-contracts-CPH3ckgH.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as intakeBindingDigest, k as __exportAll, n as IntakeExecutionService, o as feedbackActionTransaction, s as feedbackDiscoveryContext } from "./execution-
|
|
2
|
-
import { i as reviewerInstructionView } from "./reviewer-instruction-
|
|
1
|
+
import { i as intakeBindingDigest, k as __exportAll, n as IntakeExecutionService, o as feedbackActionTransaction, s as feedbackDiscoveryContext } from "./execution-Clcmi0sj.js";
|
|
2
|
+
import { i as reviewerInstructionView } from "./reviewer-instruction-BeOYVCVk.js";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
//#region src/feedback.ts
|
|
5
5
|
var feedback_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -54,6 +54,7 @@ var IntakeFeedbackService = class {
|
|
|
54
54
|
[this.config.maxScan, 1e3],
|
|
55
55
|
[this.config.maxBytes, 1e6]
|
|
56
56
|
]) if (!Number.isSafeInteger(value) || value < 1 || value > max) throw new Error("Invalid feedback limits");
|
|
57
|
+
if (this.config.onRecorded !== void 0 && typeof this.config.onRecorded !== "function") throw new Error("Invalid feedback hook");
|
|
57
58
|
if (!Number.isFinite(this.config.minimumSimilarity) || this.config.minimumSimilarity < .2 || this.config.minimumSimilarity > 1) throw new Error("Invalid feedback similarity");
|
|
58
59
|
}
|
|
59
60
|
options;
|
|
@@ -116,13 +117,28 @@ var IntakeFeedbackService = class {
|
|
|
116
117
|
const scope = this.scope();
|
|
117
118
|
return (await db.query(`SELECT * FROM intake_feedback WHERE tenant_id=? AND confidential_scope_id=? AND ${where}`, scope.tenantId, scope.confidentialScopeId, ...params)).rows;
|
|
118
119
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Ask the host. `verify` (re-checking stored lineage) falls back to
|
|
122
|
+
* `retrieve` when refused, so an authorizer that predates `verify` keeps
|
|
123
|
+
* today's answer; only a refusal of both denies.
|
|
124
|
+
*/
|
|
125
|
+
async permits(db, itemId, operation) {
|
|
126
|
+
const scope = this.scope();
|
|
127
|
+
if (await this.config.authorize({
|
|
128
|
+
db,
|
|
129
|
+
scope,
|
|
130
|
+
itemId,
|
|
124
131
|
operation
|
|
125
|
-
}))
|
|
132
|
+
})) return true;
|
|
133
|
+
return operation === "verify" && await this.config.authorize({
|
|
134
|
+
db,
|
|
135
|
+
scope,
|
|
136
|
+
itemId,
|
|
137
|
+
operation: "retrieve"
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
async authorize(ctx, operation) {
|
|
141
|
+
if (!await this.permits(ctx.db, ctx.itemId, operation)) throw new Error("Feedback unavailable");
|
|
126
142
|
}
|
|
127
143
|
checkBinding(input, ctx) {
|
|
128
144
|
if (input.itemId !== ctx.itemId || input.actionId !== ctx.review.actionId || input.expectedRevision !== ctx.review.revision || input.expectedReviewVersion !== ctx.review.reviewVersion || input.bindingHash !== ctx.review.bindingHash) throw new Error("Stale feedback binding");
|
|
@@ -169,7 +185,7 @@ var IntakeFeedbackService = class {
|
|
|
169
185
|
if (this.lineage.has(key) || this.lineage.size >= 8) throw new Error("Feedback lineage unavailable");
|
|
170
186
|
this.lineage.add(key);
|
|
171
187
|
try {
|
|
172
|
-
await this.
|
|
188
|
+
await this.checkSelection({
|
|
173
189
|
itemId: ctx.itemId,
|
|
174
190
|
query: String(inherited.query),
|
|
175
191
|
offered: generation.offered,
|
|
@@ -177,7 +193,7 @@ var IntakeFeedbackService = class {
|
|
|
177
193
|
configurationVersion: String(provenance.configurationVersion),
|
|
178
194
|
model: provenance.generative,
|
|
179
195
|
providers: [String(object(provenance.generative).provider), ...object(provenance.decision).configured ? [String(object(provenance.decision).provider)] : []]
|
|
180
|
-
}, inherited.selection, ctx.db);
|
|
196
|
+
}, inherited.selection, ctx.db, "verify");
|
|
181
197
|
} finally {
|
|
182
198
|
this.lineage.delete(key);
|
|
183
199
|
}
|
|
@@ -265,6 +281,43 @@ var IntakeFeedbackService = class {
|
|
|
265
281
|
};
|
|
266
282
|
}
|
|
267
283
|
/** Internal saved-action gate; the execution owner supplies its transaction. */
|
|
284
|
+
/**
|
|
285
|
+
* The caller's own current interpretation judgment per displayed action
|
|
286
|
+
* (#4503): not superseded, recorded by this actor, bound to the action's
|
|
287
|
+
* displayed revision and binding, integrity-checked. Presentation only;
|
|
288
|
+
* the caller has already read these actions under review authority.
|
|
289
|
+
*/
|
|
290
|
+
async ownJudgments(itemId, actions) {
|
|
291
|
+
const result = /* @__PURE__ */ new Map();
|
|
292
|
+
if (!actions.length) return result;
|
|
293
|
+
const wanted = new Map(actions.map((action) => [action.actionId, action]));
|
|
294
|
+
const rows = await this.rows(this.options.db, "item_id=? AND kind='interpretation' AND NOT EXISTS (SELECT 1 FROM intake_feedback successor WHERE successor.tenant_id=intake_feedback.tenant_id AND successor.confidential_scope_id=intake_feedback.confidential_scope_id AND successor.supersedes_id=intake_feedback.id)", [itemId]);
|
|
295
|
+
const newest = /* @__PURE__ */ new Map();
|
|
296
|
+
for (const row of rows) {
|
|
297
|
+
let data;
|
|
298
|
+
try {
|
|
299
|
+
data = object(row.data);
|
|
300
|
+
} catch {
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
const { digest: stored, ...body } = data;
|
|
304
|
+
const action = typeof data.actionId === "string" ? wanted.get(data.actionId) : void 0;
|
|
305
|
+
if (!action || typeof stored !== "string" || intakeBindingDigest(body) !== stored || data.reviewer !== this.scope().actorId || data.revision !== action.revision || data.bindingHash !== action.bindingHash || !["correct", "incorrect"].includes(String(data.judgment))) continue;
|
|
306
|
+
const previous = newest.get(action.actionId);
|
|
307
|
+
const at = (value) => new Date(value.created_at).getTime();
|
|
308
|
+
if (!previous || at(row) > at(previous) || at(row) === at(previous) && String(row.id) > String(previous.id)) newest.set(action.actionId, row);
|
|
309
|
+
}
|
|
310
|
+
for (const [actionId, row] of newest) {
|
|
311
|
+
const data = object(row.data);
|
|
312
|
+
result.set(actionId, {
|
|
313
|
+
id: String(row.id),
|
|
314
|
+
judgment: data.judgment,
|
|
315
|
+
...typeof data.comment === "string" && data.comment ? { comment: data.comment } : {},
|
|
316
|
+
recordedAt: new Date(row.created_at).toISOString()
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
return result;
|
|
320
|
+
}
|
|
268
321
|
async assertActionLineage(actionId, db, proposalId) {
|
|
269
322
|
await this.execution[feedbackActionTransaction](actionId, false, async (ctx) => {
|
|
270
323
|
await this.provenance(ctx);
|
|
@@ -325,9 +378,16 @@ var IntakeFeedbackService = class {
|
|
|
325
378
|
};
|
|
326
379
|
if (Buffer.byteLength(JSON.stringify(selection)) > Math.min(this.config.maxBytes, ctx.context.policy.maxBytes)) throw new Error("Feedback instruction exceeds retrieval budget");
|
|
327
380
|
}
|
|
381
|
+
const receipt = this.receipt(row);
|
|
382
|
+
await this.config.onRecorded?.({
|
|
383
|
+
db: ctx.db,
|
|
384
|
+
scope: this.scope(),
|
|
385
|
+
receipt: structuredClone(receipt),
|
|
386
|
+
input: structuredClone(frozen)
|
|
387
|
+
});
|
|
328
388
|
await this.authorize(ctx, "capture");
|
|
329
389
|
if (intakeBindingDigest(routing) !== intakeBindingDigest(this.routing(ctx))) throw new Error("Routing projection changed");
|
|
330
|
-
return
|
|
390
|
+
return receipt;
|
|
331
391
|
});
|
|
332
392
|
}
|
|
333
393
|
/** Consume a durable owner event idempotently. Never derive correctness from these signals. */
|
|
@@ -372,13 +432,13 @@ var IntakeFeedbackService = class {
|
|
|
372
432
|
return this.receipt(row);
|
|
373
433
|
});
|
|
374
434
|
}
|
|
375
|
-
async example(row, input, executor) {
|
|
435
|
+
async example(row, input, executor, operation = "retrieve") {
|
|
376
436
|
if (++this.exampleChecks > this.config.maxScan) return void 0;
|
|
377
437
|
try {
|
|
378
438
|
const candidate = object(row.data);
|
|
379
439
|
if (typeof candidate.actionId !== "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(candidate.actionId)) return void 0;
|
|
380
440
|
return await this.execution[feedbackActionTransaction](candidate.actionId, false, async (ctx) => {
|
|
381
|
-
await this.authorize(ctx,
|
|
441
|
+
await this.authorize(ctx, operation);
|
|
382
442
|
await this.provenance(ctx);
|
|
383
443
|
const guidance = this.instructionFor(ctx);
|
|
384
444
|
const [current] = await this.rows(ctx.db, "id=? AND kind=? AND NOT EXISTS (SELECT 1 FROM intake_feedback successor WHERE successor.tenant_id=intake_feedback.tenant_id AND successor.confidential_scope_id=intake_feedback.confidential_scope_id AND successor.supersedes_id=intake_feedback.id)", [row.id, "interpretation"]);
|
|
@@ -400,7 +460,7 @@ var IntakeFeedbackService = class {
|
|
|
400
460
|
}
|
|
401
461
|
}
|
|
402
462
|
/** Reviewer routing choice, reusable without a model suggestion; fails closed like `example`. */
|
|
403
|
-
async routingExample(row, input, executor, lineage = false) {
|
|
463
|
+
async routingExample(row, input, executor, lineage = false, operation = "retrieve") {
|
|
404
464
|
if (++this.exampleChecks > this.config.maxScan) return void 0;
|
|
405
465
|
try {
|
|
406
466
|
const data = object(row.data);
|
|
@@ -419,12 +479,7 @@ var IntakeFeedbackService = class {
|
|
|
419
479
|
const providers = input.providers ?? [input.model.provider];
|
|
420
480
|
const scope = this.scope();
|
|
421
481
|
const current = async (db) => {
|
|
422
|
-
if (!await this.
|
|
423
|
-
db,
|
|
424
|
-
scope,
|
|
425
|
-
itemId,
|
|
426
|
-
operation: "retrieve"
|
|
427
|
-
})) throw new Error("Feedback unavailable");
|
|
482
|
+
if (!await this.permits(db, itemId, operation)) throw new Error("Feedback unavailable");
|
|
428
483
|
const [attempt] = (await db.query("SELECT output_digest FROM intake_analysis_attempts WHERE tenant_id=? AND confidential_scope_id=? AND item_id=? AND id=?", scope.tenantId, scope.confidentialScopeId, itemId, data.attemptId)).rows;
|
|
429
484
|
if (!attempt || attempt.output_digest !== data.attemptDigest) throw new Error("Feedback source unavailable");
|
|
430
485
|
const evidence = data.evidence;
|
|
@@ -537,31 +592,36 @@ var IntakeFeedbackService = class {
|
|
|
537
592
|
return this.receivingContext(input, executor, work);
|
|
538
593
|
}
|
|
539
594
|
async assertSelection(input, selection, executor) {
|
|
595
|
+
await this.checkSelection(input, selection, executor, "retrieve");
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Re-verify the stored selection an existing generation was produced with
|
|
599
|
+
* (#4504): the same checks as `assertSelection`, asked as `verify` (which
|
|
600
|
+
* falls back to `retrieve` for authorizers that predate it).
|
|
601
|
+
*/
|
|
602
|
+
async verifySelection(input, selection, executor) {
|
|
603
|
+
await this.checkSelection(input, selection, executor, "verify");
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* `retrieve` revalidates a selection before provider disclosure; `verify`
|
|
607
|
+
* re-checks the stored lineage of an existing generation (#4504).
|
|
608
|
+
*/
|
|
609
|
+
async checkSelection(input, selection, executor, operation) {
|
|
540
610
|
if (selection.version !== this.config.version || selection.configurationDigest !== this.configurationDigest() || !Array.isArray(selection.examples) || selection.examples.length > this.config.maxExamples || new Set(selection.examples.map((example) => example.feedbackId)).size !== selection.examples.length || Buffer.byteLength(JSON.stringify(selection)) > this.config.maxBytes) throw new Error("Feedback eligibility changed");
|
|
541
611
|
if (!input.offered[0]) {
|
|
542
612
|
if (selection.examples.length) throw new Error("Feedback eligibility changed");
|
|
543
613
|
return;
|
|
544
614
|
}
|
|
545
615
|
const work = async (context) => {
|
|
546
|
-
if (!await this.
|
|
547
|
-
db: context.db,
|
|
548
|
-
scope: this.scope(),
|
|
549
|
-
itemId: input.itemId,
|
|
550
|
-
operation: "retrieve"
|
|
551
|
-
})) throw new Error("Feedback unavailable");
|
|
616
|
+
if (!await this.permits(context.db, input.itemId, operation)) throw new Error("Feedback unavailable");
|
|
552
617
|
const examples = [];
|
|
553
618
|
for (const expected of selection.examples) {
|
|
554
619
|
const [row] = await this.rows(context.db, "id=? AND kind IN ('interpretation','reviewer_routing')", [expected.feedbackId]);
|
|
555
|
-
const current = !row ? void 0 : row.kind === "reviewer_routing" ? await this.routingExample(row, input, context.db, true) : await this.example(row, input, context.db);
|
|
620
|
+
const current = !row ? void 0 : row.kind === "reviewer_routing" ? await this.routingExample(row, input, context.db, true, operation) : await this.example(row, input, context.db, operation);
|
|
556
621
|
if (!current || current.digest !== expected.digest || feedbackSimilarity(input.query, current.query) < this.config.minimumSimilarity) throw new Error("Feedback eligibility changed");
|
|
557
622
|
examples.push(current);
|
|
558
623
|
}
|
|
559
|
-
if (!await this.
|
|
560
|
-
db: context.db,
|
|
561
|
-
scope: this.scope(),
|
|
562
|
-
itemId: input.itemId,
|
|
563
|
-
operation: "retrieve"
|
|
564
|
-
})) throw new Error("Feedback unavailable");
|
|
624
|
+
if (!await this.permits(context.db, input.itemId, operation)) throw new Error("Feedback unavailable");
|
|
565
625
|
return {
|
|
566
626
|
...selection,
|
|
567
627
|
examples
|
|
@@ -771,4 +831,4 @@ var IntakeFeedbackService = class {
|
|
|
771
831
|
//#endregion
|
|
772
832
|
export { IntakeFeedbackService as n, feedback_exports as r, FeedbackRetrievalDeniedError as t };
|
|
773
833
|
|
|
774
|
-
//# sourceMappingURL=feedback-
|
|
834
|
+
//# sourceMappingURL=feedback-hDSMYjiG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback-hDSMYjiG.js","names":["handler","reference","candidate","row","digest","id"],"sources":["../../src/feedback.ts"],"sourcesContent":["/** Initial optional-example denial; revocation after selection must remain fatal. */\nexport class FeedbackRetrievalDeniedError extends Error {\n constructor() {\n super('Feedback unavailable');\n this.name = 'FeedbackRetrievalDeniedError';\n }\n}\n\nimport { randomUUID } from 'node:crypto';\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport {\n intakeBindingDigest as digest,\n IntakeExecutionService,\n} from './execution.js';\nimport type {\n FeedbackConfiguration,\n FeedbackOperation,\n} from './feedback-contracts.js';\nimport type {\n AdoptRuleInput,\n FeedbackBinding,\n FeedbackExample,\n FeedbackReceipt,\n FeedbackReferences,\n FeedbackSelection,\n ObserveFeedbackInput,\n ReadRuleInput,\n RecordFeedbackInput,\n RoutingRule,\n RuleAdoption,\n RuleSuggestion,\n SuggestRuleInput,\n} from './feedback-dto.js';\nimport {\n type FeedbackActionContext,\n feedbackActionTransaction,\n feedbackDiscoveryContext,\n} from './feedback-internal.js';\nimport type { GenerationOutput } from './proposal-dto.js';\nimport { reviewerInstructionView } from './reviewer-instruction.js';\nimport type { IngestionOptions } from './server.js';\n\ntype Row = Record<string, unknown>;\nfunction object(value: unknown): Row {\n const result = typeof value === 'string' ? JSON.parse(value) : value;\n if (!result || typeof result !== 'object' || Array.isArray(result))\n throw new Error('Feedback unavailable');\n return result as Row;\n}\nfunction text(value: unknown, max = 512): asserts value is string {\n if (typeof value !== 'string' || !value.trim() || value.length > max)\n throw new Error('Invalid feedback');\n}\nfunction resultData(data: Row): Row {\n return {\n status: data.status,\n provider: data.provider,\n model: data.model,\n version: data.version,\n output: data.output,\n usage: data.usage,\n ...(Object.hasOwn(data, 'error') ? { error: data.error } : {}),\n ...(Object.hasOwn(data, 'confidence')\n ? { confidence: data.confidence }\n : {}),\n };\n}\nexport function feedbackTerms(value: string): string[] {\n return [\n ...new Set(value.toLowerCase().match(/[\\p{L}\\p{N}]+/gu) ?? []),\n ].sort();\n}\nexport function feedbackSimilarity(left: string, right: string): number {\n const a = new Set(feedbackTerms(left)),\n b = new Set(feedbackTerms(right));\n const union = new Set([...a, ...b]);\n return union.size\n ? [...a].filter((value) => b.has(value)).length / union.size\n : 0;\n}\nexport interface RetrieveFeedbackInput {\n itemId: string;\n query: string;\n offered: GenerationOutput['offered'];\n promptVersion: string;\n configurationVersion: string;\n model: { provider: string; model: string; version: string };\n providers?: string[];\n}\n/** Owning ingestion ledger. Generic LearningMemory's success/ancestor fallback semantics are deliberately not used. */\nexport class IntakeFeedbackService {\n private readonly execution: IntakeExecutionService;\n private readonly config: FeedbackConfiguration;\n private readonly lineage = new Set<string>();\n private exampleChecks = 0;\n constructor(\n private readonly options: IngestionOptions,\n execution?: IntakeExecutionService,\n ) {\n if (!options.execution || !options.feedback)\n throw new Error('Feedback not configured');\n this.config = { ...options.feedback };\n this.execution =\n execution ?? new IntakeExecutionService(options, options.execution);\n text(this.config.version);\n for (const [value, max] of [\n [this.config.maxExamples, 20],\n [this.config.maxScan, 1000],\n [this.config.maxBytes, 1000000],\n ])\n if (!Number.isSafeInteger(value) || value < 1 || value > max)\n throw new Error('Invalid feedback limits');\n if (\n this.config.onRecorded !== undefined &&\n typeof this.config.onRecorded !== 'function'\n )\n throw new Error('Invalid feedback hook');\n if (\n !Number.isFinite(this.config.minimumSimilarity) ||\n this.config.minimumSimilarity < 0.2 ||\n this.config.minimumSimilarity > 1\n )\n throw new Error('Invalid feedback similarity');\n }\n private configurationDigest() {\n const { version, maxExamples, maxScan, maxBytes, minimumSimilarity } =\n this.config;\n return digest({\n version,\n maxExamples,\n maxScan,\n maxBytes,\n minimumSimilarity,\n });\n }\n private routing(\n ctx: FeedbackActionContext,\n ): Pick<RoutingRule, 'args' | 'projection'> {\n // Read live trusted configuration again at publication/replay boundaries.\n const declarations = this.options.feedback?.routing;\n if (declarations === undefined) return { args: ctx.args };\n if (!Array.isArray(declarations))\n throw new Error('Invalid routing projection');\n const seen = new Set<string>();\n for (const declaration of declarations) {\n const entry = object(declaration);\n text(entry.handlerId);\n text(entry.handlerVersion);\n text(entry.version);\n const key = digest([entry.handlerId, entry.handlerVersion]);\n const handler = this.options.execution!.handlers.find(\n (handler) =>\n handler.id === entry.handlerId &&\n handler.version === entry.handlerVersion,\n );\n if (!handler || seen.has(key))\n throw new Error('Invalid routing projection');\n seen.add(key);\n const properties = object(handler.argsSchema.properties);\n if (\n !Array.isArray(entry.fields) ||\n !entry.fields.length ||\n entry.fields.length > 64 ||\n new Set(entry.fields).size !== entry.fields.length\n )\n throw new Error('Invalid routing projection');\n for (const field of entry.fields) {\n text(field);\n if (\n ['__proto__', 'prototype', 'constructor'].includes(field) ||\n !Object.hasOwn(properties, field)\n )\n throw new Error('Invalid routing projection');\n }\n }\n const selected = declarations.find(\n (entry) =>\n entry.handlerId === ctx.handlerId &&\n entry.handlerVersion === ctx.handlerVersion,\n );\n if (!selected) return { args: ctx.args };\n const fields = [...selected.fields].sort();\n const args = Object.fromEntries(\n fields\n .filter((field) => Object.hasOwn(ctx.args, field))\n .map((field) => [field, structuredClone(ctx.args[field])]),\n );\n if (!Object.keys(args).length)\n throw new Error('Routing values unavailable');\n return { args, projection: { version: selected.version, fields } };\n }\n private scope() {\n return this.options.scope;\n }\n private async rows(\n db: DatabaseInterface,\n where: string,\n params: unknown[] = [],\n ): Promise<Row[]> {\n const scope = this.scope();\n return (\n await db.query(\n `SELECT * FROM intake_feedback WHERE tenant_id=? AND confidential_scope_id=? AND ${where}`,\n scope.tenantId,\n scope.confidentialScopeId,\n ...params,\n )\n ).rows;\n }\n /**\n * Ask the host. `verify` (re-checking stored lineage) falls back to\n * `retrieve` when refused, so an authorizer that predates `verify` keeps\n * today's answer; only a refusal of both denies.\n */\n private async permits(\n db: DatabaseInterface,\n itemId: string,\n operation: FeedbackOperation,\n ): Promise<boolean> {\n const scope = this.scope();\n if (await this.config.authorize({ db, scope, itemId, operation }))\n return true;\n return (\n operation === 'verify' &&\n (await this.config.authorize({\n db,\n scope,\n itemId,\n operation: 'retrieve',\n }))\n );\n }\n private async authorize(\n ctx: FeedbackActionContext,\n operation: FeedbackOperation,\n ) {\n if (!(await this.permits(ctx.db, ctx.itemId, operation)))\n throw new Error('Feedback unavailable');\n }\n private checkBinding(input: FeedbackBinding, ctx: FeedbackActionContext) {\n if (\n input.itemId !== ctx.itemId ||\n input.actionId !== ctx.review.actionId ||\n input.expectedRevision !== ctx.review.revision ||\n input.expectedReviewVersion !== ctx.review.reviewVersion ||\n input.bindingHash !== ctx.review.bindingHash\n )\n throw new Error('Stale feedback binding');\n }\n private async insert(\n ctx: FeedbackActionContext,\n key: string,\n kind: string,\n data: Row,\n supersedesId: string | null = null,\n ): Promise<Row> {\n const serialized = JSON.stringify(data);\n if (\n Buffer.byteLength(serialized) >\n Math.min(this.config.maxBytes, ctx.context.policy.maxBytes)\n )\n throw new Error('Feedback limit');\n const scope = this.scope(),\n now = (this.options.now?.() ?? new Date()).toISOString();\n const row = {\n id: randomUUID(),\n slug: randomUUID(),\n context: '',\n created_at: now,\n updated_at: now,\n tenant_id: scope.tenantId,\n confidential_scope_id: scope.confidentialScopeId,\n item_id: ctx.itemId,\n request_key: key,\n supersedes_id: supersedesId,\n kind,\n data: serialized,\n };\n return (\n await ctx.db.query(\n `INSERT INTO intake_feedback (${Object.keys(row).join(',')}) VALUES (${Object.keys(\n row,\n )\n .map(() => '?')\n .join(',')}) RETURNING *`,\n ...Object.values(row),\n )\n ).rows[0];\n }\n private receipt(row: Row): FeedbackReceipt {\n return {\n id: String(row.id),\n digest: String(object(row.data).digest),\n kind: row.kind as FeedbackReceipt['kind'],\n };\n }\n /** Source text, pin and (when a model suggestion exists) generation versions. */\n private async provenance(ctx: FeedbackActionContext) {\n const output = object(ctx.result.output);\n // A reviewer-selected action on an extraction-only item carries no generation.\n const generation = output.proposals ? object(output.proposals) : undefined;\n const pin = generation\n ? object(generation.source)\n : { attemptId: ctx.attemptId, outputDigest: digest(ctx.result) };\n const provenance = generation ? object(generation.provenance) : undefined;\n if (generation && provenance?.feedback) {\n const inherited = object(provenance.feedback);\n const key = ctx.attemptId;\n if (this.lineage.has(key) || this.lineage.size >= 8)\n throw new Error('Feedback lineage unavailable');\n this.lineage.add(key);\n try {\n // Stored lineage is re-verified, never re-selected (#4504).\n await this.checkSelection(\n {\n itemId: ctx.itemId,\n query: String(inherited.query),\n offered: generation.offered as GenerationOutput['offered'],\n promptVersion: String(provenance.promptVersion),\n configurationVersion: String(provenance.configurationVersion),\n model: provenance.generative as RetrieveFeedbackInput['model'],\n providers: [\n String(object(provenance.generative).provider),\n ...(object(provenance.decision).configured\n ? [String(object(provenance.decision).provider)]\n : []),\n ],\n },\n inherited.selection as unknown as FeedbackReferences,\n ctx.db,\n 'verify',\n );\n } finally {\n this.lineage.delete(key);\n }\n }\n const scope = this.scope();\n const [source] = (\n await ctx.db.query(\n 'SELECT data,output_digest FROM intake_analysis_attempts WHERE tenant_id=? AND confidential_scope_id=? AND item_id=? AND id=?',\n scope.tenantId,\n scope.confidentialScopeId,\n ctx.itemId,\n pin.attemptId,\n )\n ).rows;\n if (!source || source.output_digest !== pin.outputDigest)\n throw new Error('Feedback source unavailable');\n const sourceResult = resultData(object(source.data));\n if (digest(sourceResult) !== pin.outputDigest)\n throw new Error('Feedback source integrity');\n const results = object(sourceResult.output).results;\n if (!Array.isArray(results))\n throw new Error('Feedback extraction unavailable');\n const query = results\n .flatMap((entry) => {\n const segments = object(entry).segments;\n return Array.isArray(segments)\n ? segments.map((segment) => String(object(segment).text ?? ''))\n : [];\n })\n .join('\\n')\n .slice(0, 4096);\n if (!provenance)\n return {\n generation: false as const,\n query,\n attemptId: ctx.attemptId,\n evidence: object(ctx.analysis).inputs,\n source: pin,\n };\n const model = object(provenance.generative);\n for (const field of ['provider', 'model', 'version']) text(model[field]);\n text(provenance.promptVersion);\n text(provenance.configurationVersion);\n // A judgment made under reviewer guidance references that guidance by id\n // and digest only; retrieval joins the text from the source's own record,\n // so instruction text never counts against the write budget.\n const instruction = this.instructionFor(ctx);\n return {\n generation: true as const,\n query,\n ...(instruction\n ? { instruction: { id: instruction.id, digest: instruction.digest } }\n : {}),\n model: {\n provider: String(model.provider),\n model: String(model.model),\n version: String(model.version),\n },\n promptVersion: String(provenance.promptVersion),\n configurationVersion: String(provenance.configurationVersion),\n attemptId: ctx.attemptId,\n evidence: object(ctx.analysis).inputs,\n source: pin,\n };\n }\n /** The example exactly as retrieval returns it; shared by the write-time size check. */\n private exampleOf(\n id: string,\n stored: string,\n data: Row,\n ctx: FeedbackActionContext,\n guidance?: { id: string; digest: string; text: string },\n ): FeedbackExample {\n return {\n feedbackId: id,\n digest: stored,\n itemId: ctx.itemId,\n actionId: ctx.review.actionId,\n revision: ctx.review.revision,\n handlerId: ctx.handlerId,\n handlerVersion: ctx.handlerVersion,\n judgment: data.judgment as 'correct' | 'incorrect',\n query: String(data.query),\n args: object(data.args),\n model: data.model as FeedbackExample['model'],\n promptVersion: String(data.promptVersion),\n configurationVersion: String(data.configurationVersion),\n ...(guidance ? { instruction: guidance } : {}),\n };\n }\n /**\n * The verified reviewer instruction the action's generation ran under: the\n * authenticated extraction record must match the generation's provenance.\n */\n private instructionFor(\n ctx: FeedbackActionContext,\n ): { id: string; digest: string; text: string } | undefined {\n const provenance = object(\n object(object(ctx.result.output).proposals).provenance,\n );\n const instructionRecord = object(\n object(ctx.analysis).configuration,\n ).reviewerInstruction;\n const recorded = provenance.reviewerInstruction\n ? object(provenance.reviewerInstruction)\n : undefined;\n if (!instructionRecord && !recorded) return undefined;\n const view = reviewerInstructionView(instructionRecord);\n if (!recorded || recorded.id !== view.id || recorded.digest !== view.digest)\n throw new Error('Feedback instruction integrity');\n return { id: view.id, digest: view.digest, text: view.text };\n }\n /** Internal saved-action gate; the execution owner supplies its transaction. */\n /**\n * The caller's own current interpretation judgment per displayed action\n * (#4503): not superseded, recorded by this actor, bound to the action's\n * displayed revision and binding, integrity-checked. Presentation only;\n * the caller has already read these actions under review authority.\n */\n async ownJudgments(\n itemId: string,\n actions: ReadonlyArray<{\n actionId: string;\n revision: number;\n bindingHash: string;\n }>,\n ): Promise<Map<string, import('./review-dto.js').ReviewFeedback>> {\n const result = new Map<string, import('./review-dto.js').ReviewFeedback>();\n if (!actions.length) return result;\n const wanted = new Map(actions.map((action) => [action.actionId, action]));\n const rows = await this.rows(\n this.options.db,\n \"item_id=? AND kind='interpretation' AND NOT EXISTS (SELECT 1 FROM intake_feedback successor WHERE successor.tenant_id=intake_feedback.tenant_id AND successor.confidential_scope_id=intake_feedback.confidential_scope_id AND successor.supersedes_id=intake_feedback.id)\",\n [itemId],\n );\n const newest = new Map<string, Row>();\n for (const row of rows) {\n let data: Row;\n try {\n data = object(row.data);\n } catch {\n continue;\n }\n const { digest: stored, ...body } = data;\n const action =\n typeof data.actionId === 'string'\n ? wanted.get(data.actionId)\n : undefined;\n if (\n !action ||\n typeof stored !== 'string' ||\n digest(body) !== stored ||\n data.reviewer !== this.scope().actorId ||\n data.revision !== action.revision ||\n data.bindingHash !== action.bindingHash ||\n !['correct', 'incorrect'].includes(String(data.judgment))\n )\n continue;\n const previous = newest.get(action.actionId);\n const at = (value: Row) => new Date(value.created_at as string).getTime();\n if (\n !previous ||\n at(row) > at(previous) ||\n (at(row) === at(previous) && String(row.id) > String(previous.id))\n )\n newest.set(action.actionId, row);\n }\n for (const [actionId, row] of newest) {\n const data = object(row.data);\n result.set(actionId, {\n id: String(row.id),\n judgment: data.judgment as 'correct' | 'incorrect',\n ...(typeof data.comment === 'string' && data.comment\n ? { comment: data.comment }\n : {}),\n recordedAt: new Date(row.created_at as string).toISOString(),\n });\n }\n return result;\n }\n async assertActionLineage(\n actionId: string,\n db: DatabaseInterface,\n proposalId: string,\n ): Promise<void> {\n await this.execution[feedbackActionTransaction](\n actionId,\n false,\n async (ctx) => {\n await this.provenance(ctx);\n },\n db,\n undefined,\n proposalId,\n );\n }\n async record(input: RecordFeedbackInput): Promise<FeedbackReceipt> {\n digest(input);\n text(input.requestId);\n if (\n !['correct', 'incorrect'].includes(input.judgment) ||\n (input.comment !== undefined &&\n (typeof input.comment !== 'string' || input.comment.length > 4000))\n )\n throw new Error('Invalid feedback');\n const frozen = structuredClone(input);\n return this.execution[feedbackActionTransaction](\n input.actionId,\n true,\n async (ctx) => {\n await this.authorize(ctx, 'capture');\n this.checkBinding(frozen, ctx);\n const requestHash = digest(frozen),\n key = `judgment:${frozen.requestId}`;\n const [replay] = await this.rows(\n ctx.db,\n 'item_id=? AND request_key=?',\n [ctx.itemId, key],\n );\n if (replay) {\n const data = object(replay.data);\n if (\n data.requestHash !== requestHash ||\n data.reviewer !== this.scope().actorId\n )\n throw new Error('Feedback request conflict');\n return this.receipt(replay);\n }\n if (frozen.supersedesId) {\n const [old] = await this.rows(\n ctx.db,\n 'item_id=? AND id=? AND kind=?',\n [ctx.itemId, frozen.supersedesId, 'interpretation'],\n );\n if (\n !old ||\n object(old.data).actionId !== frozen.actionId ||\n (await this.rows(ctx.db, 'supersedes_id=?', [old.id])).length\n )\n throw new Error('Feedback supersession conflict');\n }\n const { generation, ...provenance } = await this.provenance(ctx),\n routing = this.routing(ctx);\n // Interpretation judgments label a model suggestion; reviewer-selected\n // actions are captured as routing choices by their owning operation,\n // even when the item also carries a (different) model generation.\n if (!generation || ctx.origin === 'reviewer-selected')\n throw new Error('Feedback requires a model suggestion');\n const body = {\n version: 1,\n requestHash,\n reviewer: this.scope().actorId,\n actionId: ctx.review.actionId,\n revision: ctx.review.revision,\n reviewVersion: ctx.review.reviewVersion,\n bindingHash: ctx.review.bindingHash,\n handlerId: ctx.handlerId,\n handlerVersion: ctx.handlerVersion,\n args: ctx.args,\n ...(routing.projection ? { routing } : {}),\n judgment: frozen.judgment,\n comment: frozen.comment ?? '',\n ...provenance,\n };\n const row = await this.insert(\n ctx,\n key,\n 'interpretation',\n { ...body, digest: digest(body) },\n frozen.supersedesId ?? null,\n );\n // The judgment stores only the instruction reference, but retrieval\n // joins its text. Refuse here, inside the transaction, if that single\n // joined example could never fit the handler's read budget; otherwise\n // every later retrieval ranking it would fail closed scope-wide.\n const guidance = this.instructionFor(ctx);\n if (guidance) {\n const data = object(row.data);\n const selection = {\n version: this.config.version,\n configurationDigest: this.configurationDigest(),\n examples: [\n this.exampleOf(\n String(row.id),\n String(data.digest),\n data,\n ctx,\n guidance,\n ),\n ],\n };\n if (\n Buffer.byteLength(JSON.stringify(selection)) >\n Math.min(this.config.maxBytes, ctx.context.policy.maxBytes)\n )\n throw new Error('Feedback instruction exceeds retrieval budget');\n }\n const receipt = this.receipt(row);\n // Same transaction and executor: the host's entry commits or rolls\n // back with the judgment (#4522).\n await this.config.onRecorded?.({\n db: ctx.db,\n scope: this.scope(),\n receipt: structuredClone(receipt),\n input: structuredClone(frozen),\n });\n await this.authorize(ctx, 'capture');\n if (digest(routing) !== digest(this.routing(ctx)))\n throw new Error('Routing projection changed');\n return receipt;\n },\n );\n }\n /** Consume a durable owner event idempotently. Never derive correctness from these signals. */\n async observe(input: ObserveFeedbackInput): Promise<FeedbackReceipt> {\n digest(input);\n text(input.eventId);\n if (!['action_decision', 'downstream_outcome'].includes(input.kind))\n throw new Error('Invalid feedback kind');\n return this.execution[feedbackActionTransaction](\n input.actionId,\n true,\n async (ctx) => {\n await this.authorize(ctx, 'capture');\n this.checkBinding(input, ctx);\n const scope = this.scope();\n const table =\n input.kind === 'action_decision'\n ? 'intake_review_decisions'\n : 'intake_executions';\n const [event] = (\n await ctx.db.query(\n `SELECT * FROM ${table} WHERE tenant_id=? AND confidential_scope_id=? AND item_id=? AND action_id=? AND id=?`,\n scope.tenantId,\n scope.confidentialScopeId,\n ctx.itemId,\n input.actionId,\n input.eventId,\n )\n ).rows;\n if (!event || event.binding_hash !== ctx.review.bindingHash)\n throw new Error('Feedback event unavailable');\n const state =\n input.kind === 'action_decision' ? event.decision : event.state;\n if (\n input.kind === 'downstream_outcome' &&\n !['succeeded', 'failed', 'outcome_unknown'].includes(String(state))\n )\n throw new Error('Outcome is not terminal');\n const body = {\n version: 1,\n eventId: input.eventId,\n actionId: input.actionId,\n revision: ctx.review.revision,\n reviewer:\n input.kind === 'action_decision'\n ? object(event.data).reviewer\n : null,\n decisionMode:\n input.kind === 'action_decision'\n ? (object(event.data).mode ?? 'review')\n : null,\n selfDecision:\n input.kind === 'action_decision' &&\n object(event.data).selfDecision === true,\n observedBy: this.scope().actorId,\n principalId: object(event.data).principalId ?? null,\n signal: state,\n provenance: await this.provenance(ctx),\n };\n const key = `event:${input.kind}:${input.eventId}:${String(state)}`;\n const [existing] = await this.rows(\n ctx.db,\n 'item_id=? AND request_key=?',\n [ctx.itemId, key],\n );\n if (existing) return this.receipt(existing);\n const row = await this.insert(ctx, key, input.kind, {\n ...body,\n digest: digest(body),\n });\n await this.authorize(ctx, 'capture');\n return this.receipt(row);\n },\n );\n }\n private async example(\n row: Row,\n input: RetrieveFeedbackInput,\n executor?: DatabaseInterface,\n operation: 'retrieve' | 'verify' = 'retrieve',\n ): Promise<FeedbackExample | undefined> {\n if (++this.exampleChecks > this.config.maxScan) return undefined;\n try {\n const candidate = object(row.data);\n // Retention deliberately redacts ledger payloads. Reject tombstones before\n // issuing a UUID query: catching a PostgreSQL cast error cannot repair its transaction.\n if (\n typeof candidate.actionId !== 'string' ||\n !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(\n candidate.actionId,\n )\n )\n return undefined;\n return await this.execution[feedbackActionTransaction](\n candidate.actionId,\n false,\n async (ctx) => {\n await this.authorize(ctx, operation);\n await this.provenance(ctx);\n const guidance = this.instructionFor(ctx);\n const [current] = await this.rows(\n ctx.db,\n 'id=? AND kind=? AND NOT EXISTS (SELECT 1 FROM intake_feedback successor WHERE successor.tenant_id=intake_feedback.tenant_id AND successor.confidential_scope_id=intake_feedback.confidential_scope_id AND successor.supersedes_id=intake_feedback.id)',\n [row.id, 'interpretation'],\n );\n if (!current) return undefined;\n const data = object(current.data);\n const { digest: stored, ...body } = data;\n if (digest(body) !== stored) throw new Error('Feedback integrity');\n if (\n // A reviewer-selected action never labels a model suggestion. A\n // disposition says nothing about whether the suggestion was right.\n ctx.origin === 'reviewer-selected' ||\n data.revision !== ctx.review.revision ||\n data.bindingHash !== ctx.review.bindingHash ||\n data.attemptId !== ctx.attemptId ||\n data.promptVersion !== input.promptVersion ||\n data.configurationVersion !== input.configurationVersion ||\n digest(data.model) !== digest(input.model)\n )\n return undefined;\n // The stored reference must still name the source's verified record.\n const reference = data.instruction\n ? object(data.instruction)\n : undefined;\n if (\n !!reference !== !!guidance ||\n (reference &&\n (reference.id !== guidance?.id ||\n reference.digest !== guidance?.digest))\n )\n return undefined;\n const offered = input.offered.find(\n (entry) =>\n entry.handler.id === data.handlerId &&\n entry.handler.version === data.handlerVersion,\n );\n if (!offered) return undefined;\n const args = object(data.args);\n for (const [field, reference] of Object.entries(\n offered.handler.references,\n )) {\n if (\n reference.kind === 'candidate' &&\n Object.hasOwn(args, field) &&\n !offered.candidates.some(\n (candidate) =>\n candidate.id === args[field] &&\n candidate.model === reference.model,\n )\n )\n return undefined;\n }\n return this.exampleOf(\n String(current.id),\n String(stored),\n data,\n ctx,\n guidance,\n );\n },\n executor,\n input.providers ?? [input.model.provider],\n );\n } catch {\n return undefined;\n }\n }\n /** Reviewer routing choice, reusable without a model suggestion; fails closed like `example`. */\n private async routingExample(\n row: Row,\n input: RetrieveFeedbackInput,\n executor?: DatabaseInterface,\n /** Re-checking an earlier selection: only integrity and revocation count. */\n lineage = false,\n operation: 'retrieve' | 'verify' = 'retrieve',\n ): Promise<FeedbackExample | undefined> {\n if (++this.exampleChecks > this.config.maxScan) return undefined;\n try {\n const data = object(row.data);\n const { digest: stored, ...body } = data;\n const itemId = String(row.item_id);\n const uuid =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n // Redacted tombstones carry no digest; reject before any UUID query.\n if (typeof stored !== 'string' || digest(body) !== stored)\n return undefined;\n const chosen = data.choice === 'handler';\n if (\n chosen &&\n (typeof data.actionId !== 'string' || !uuid.test(data.actionId))\n )\n return undefined;\n const offered = chosen\n ? input.offered.find(\n (entry) =>\n entry.handler.id === data.handlerId &&\n entry.handler.version === data.handlerVersion,\n )\n : undefined;\n if (chosen && !offered) return undefined;\n const args = chosen ? object(data.args) : {};\n if (offered)\n for (const [field, reference] of Object.entries(\n offered.handler.references,\n ))\n if (\n reference.kind === 'candidate' &&\n Object.hasOwn(args, field) &&\n !offered.candidates.some(\n (candidate) =>\n candidate.id === args[field] &&\n candidate.model === reference.model,\n )\n )\n return undefined;\n const providers = input.providers ?? [input.model.provider];\n const scope = this.scope();\n const current = async (db: DatabaseInterface) => {\n if (!(await this.permits(db, itemId, operation)))\n throw new Error('Feedback unavailable');\n const [attempt] = (\n await db.query(\n 'SELECT output_digest FROM intake_analysis_attempts WHERE tenant_id=? AND confidential_scope_id=? AND item_id=? AND id=?',\n scope.tenantId,\n scope.confidentialScopeId,\n itemId,\n data.attemptId,\n )\n ).rows;\n if (!attempt || attempt.output_digest !== data.attemptDigest)\n throw new Error('Feedback source unavailable');\n const evidence = data.evidence;\n if (!Array.isArray(evidence) || !evidence.length)\n throw new Error('Feedback source unavailable');\n for (const frozen of evidence) {\n const pinned = object(frozen);\n const [row] = (\n await db.query(\n \"SELECT content_hash FROM intake_evidence WHERE tenant_id=? AND confidential_scope_id=? AND item_id=? AND id=? AND state='durable'\",\n scope.tenantId,\n scope.confidentialScopeId,\n itemId,\n pinned.id,\n )\n ).rows;\n if (!row || row.content_hash !== pinned.hash)\n throw new Error('Feedback source unavailable');\n }\n if ((await this.rows(db, 'supersedes_id=?', [row.id])).length)\n throw new Error('Feedback superseded');\n };\n const example: FeedbackExample = {\n feedbackId: String(row.id),\n digest: stored,\n itemId,\n actionId: chosen ? String(data.actionId) : '',\n revision: chosen ? Number(data.revision) : 0,\n handlerId: chosen ? String(data.handlerId) : 'none',\n handlerVersion: chosen ? String(data.handlerVersion) : '',\n judgment: 'correct',\n query: String(data.query),\n args,\n kind: 'reviewer_routing',\n routing: {\n choice: chosen ? 'handler' : 'none',\n reason: typeof data.reason === 'string' ? data.reason : '',\n },\n };\n if (chosen)\n // The action binding, handler access, targets, providers and retention\n // are rechecked by the owning execution boundary.\n return await this.execution[feedbackActionTransaction](\n String(data.actionId),\n false,\n async (ctx) => {\n // Only an approved (or applied) reviewer choice is a routing example;\n // a later correction changes the revision and retires it until the\n // new revision is approved and captured again.\n if (\n ctx.itemId !== itemId ||\n ctx.origin !== 'reviewer-selected' ||\n // Settledness gates selection only; a later resolution, lapse or\n // outcome change must not revoke an example already used.\n (!lineage && !ctx.settled) ||\n data.revision !== ctx.review.revision ||\n data.bindingHash !== ctx.review.bindingHash ||\n data.attemptId !== ctx.attemptId ||\n data.handlerId !== ctx.handlerId ||\n data.handlerVersion !== ctx.handlerVersion ||\n digest(args) !== digest(ctx.args)\n )\n return undefined;\n await current(ctx.db);\n return example;\n },\n executor,\n providers,\n undefined,\n !lineage,\n );\n // No handler was chosen: the source item must still be readable under a\n // currently offered handler, with the generation recipients allowed.\n for (const entry of input.offered) {\n try {\n return await this.execution[feedbackDiscoveryContext](\n executor,\n itemId,\n entry.handler.id,\n entry.handler.version,\n async (context) => {\n if (\n providers.some(\n (provider) => !context.policy.providers.includes(provider),\n )\n )\n throw new Error('Feedback source provider unavailable');\n await current(context.db);\n return example;\n },\n async (context) => {\n if (\n providers.some(\n (provider) => !context.policy.providers.includes(provider),\n )\n )\n throw new Error('Feedback source provider unavailable');\n await current(context.db);\n },\n );\n } catch {\n /* try the next currently offered handler; none means excluded */\n }\n }\n return undefined;\n } catch {\n return undefined;\n }\n }\n private receivingContext(\n input: RetrieveFeedbackInput,\n executor: DatabaseInterface | undefined,\n work: (\n context: import('./execution-contracts.js').HandlerContext,\n ) => Promise<FeedbackSelection>,\n ): Promise<FeedbackSelection> {\n let limit = this.config.maxBytes;\n let bytes: number | undefined;\n const validate = async (\n context: import('./execution-contracts.js').HandlerContext,\n ) => {\n if (\n (input.providers ?? [input.model.provider]).some(\n (provider) => !context.policy.providers.includes(provider),\n )\n )\n throw new Error('Feedback recipient unavailable');\n limit = Math.min(limit, context.policy.maxBytes);\n if (bytes !== undefined && bytes > limit)\n throw new Error('Feedback limit');\n };\n const visit = (\n index: number,\n db: DatabaseInterface | undefined,\n ): Promise<FeedbackSelection> => {\n const entry = input.offered[index];\n return this.execution[feedbackDiscoveryContext](\n db,\n input.itemId,\n entry.handler.id,\n entry.handler.version,\n async (context) => {\n await validate(context);\n const selection =\n index + 1 < input.offered.length\n ? await visit(index + 1, context.db)\n : await work(context);\n bytes = Buffer.byteLength(JSON.stringify(selection));\n if (bytes > limit) throw new Error('Feedback limit');\n return selection;\n },\n validate,\n );\n };\n return visit(0, executor);\n }\n async retrieve(\n input: RetrieveFeedbackInput,\n executor?: DatabaseInterface,\n ): Promise<FeedbackSelection> {\n text(input.query, 4096);\n const offered = input.offered[0];\n if (!offered)\n return {\n version: this.config.version,\n configurationDigest: this.configurationDigest(),\n examples: [],\n };\n const work = async (\n context: import('./execution-contracts.js').HandlerContext,\n ) => {\n const authorize = async (phase: 'initial' | 'final') => {\n if (\n !(await this.config.authorize({\n db: context.db,\n scope: this.scope(),\n itemId: input.itemId,\n operation: 'retrieve',\n }))\n ) {\n if (phase === 'initial') throw new FeedbackRetrievalDeniedError();\n throw new Error('Feedback unavailable');\n }\n };\n await authorize('initial');\n const scope = this.scope();\n const rows = (\n await context.db.query(\n \"SELECT * FROM intake_feedback WHERE tenant_id=? AND confidential_scope_id=? AND kind IN ('interpretation','reviewer_routing') ORDER BY id LIMIT ?\",\n scope.tenantId,\n scope.confidentialScopeId,\n this.config.maxScan,\n )\n ).rows;\n const ranked: Array<{ example: FeedbackExample; score: number }> = [];\n for (const row of rows) {\n const example =\n row.kind === 'reviewer_routing'\n ? await this.routingExample(row, input, context.db)\n : await this.example(row, input, context.db);\n if (!example) continue;\n const score = feedbackSimilarity(input.query, example.query);\n if (score >= this.config.minimumSimilarity)\n ranked.push({ example, score });\n }\n ranked.sort(\n (a, b) =>\n b.score - a.score ||\n a.example.feedbackId.localeCompare(b.example.feedbackId),\n );\n const selection = {\n version: this.config.version,\n configurationDigest: this.configurationDigest(),\n examples: ranked\n .slice(0, this.config.maxExamples)\n .map((entry) => entry.example),\n };\n await authorize('final');\n return selection;\n };\n return this.receivingContext(input, executor, work);\n }\n async assertSelection(\n input: RetrieveFeedbackInput,\n selection: FeedbackReferences,\n executor?: DatabaseInterface,\n ): Promise<void> {\n await this.checkSelection(input, selection, executor, 'retrieve');\n }\n /**\n * Re-verify the stored selection an existing generation was produced with\n * (#4504): the same checks as `assertSelection`, asked as `verify` (which\n * falls back to `retrieve` for authorizers that predate it).\n */\n async verifySelection(\n input: RetrieveFeedbackInput,\n selection: FeedbackReferences,\n executor?: DatabaseInterface,\n ): Promise<void> {\n await this.checkSelection(input, selection, executor, 'verify');\n }\n /**\n * `retrieve` revalidates a selection before provider disclosure; `verify`\n * re-checks the stored lineage of an existing generation (#4504).\n */\n private async checkSelection(\n input: RetrieveFeedbackInput,\n selection: FeedbackReferences,\n executor: DatabaseInterface | undefined,\n operation: 'retrieve' | 'verify',\n ): Promise<void> {\n if (\n selection.version !== this.config.version ||\n selection.configurationDigest !== this.configurationDigest() ||\n !Array.isArray(selection.examples) ||\n selection.examples.length > this.config.maxExamples ||\n new Set(selection.examples.map((example) => example.feedbackId)).size !==\n selection.examples.length ||\n Buffer.byteLength(JSON.stringify(selection)) > this.config.maxBytes\n )\n throw new Error('Feedback eligibility changed');\n const offered = input.offered[0];\n if (!offered) {\n if (selection.examples.length)\n throw new Error('Feedback eligibility changed');\n return;\n }\n const work = async (\n context: import('./execution-contracts.js').HandlerContext,\n ) => {\n if (!(await this.permits(context.db, input.itemId, operation)))\n throw new Error('Feedback unavailable');\n const examples: FeedbackExample[] = [];\n for (const expected of selection.examples) {\n const [row] = await this.rows(\n context.db,\n \"id=? AND kind IN ('interpretation','reviewer_routing')\",\n [expected.feedbackId],\n );\n const current = !row\n ? undefined\n : row.kind === 'reviewer_routing'\n ? await this.routingExample(row, input, context.db, true, operation)\n : await this.example(row, input, context.db, operation);\n if (\n !current ||\n current.digest !== expected.digest ||\n feedbackSimilarity(input.query, current.query) <\n this.config.minimumSimilarity\n )\n throw new Error('Feedback eligibility changed');\n examples.push(current);\n }\n if (!(await this.permits(context.db, input.itemId, operation)))\n throw new Error('Feedback unavailable');\n return { ...selection, examples };\n };\n await this.receivingContext(input, executor, work);\n }\n private async support(\n ctx: FeedbackActionContext,\n ids: string[],\n /** Re-checking stored support (read/adopt): only integrity and revocation count. */\n lineage = false,\n ): Promise<Array<{ id: string; digest: string; query: string }>> {\n if (\n !Array.isArray(ids) ||\n ids.length < 2 ||\n ids.length > this.config.maxExamples ||\n new Set(ids).size !== ids.length\n )\n throw new Error('Insufficient rule evidence');\n const provenance = await this.provenance(ctx),\n origins = new Set<string>(),\n result: Array<{ id: string; digest: string; query: string }> = [];\n for (const id of [...ids].sort()) {\n text(id);\n const [row] = await this.rows(\n ctx.db,\n \"id=? AND kind IN ('interpretation','reviewer_routing')\",\n [id],\n );\n if (!row) throw new Error('Rule evidence unavailable');\n const data = object(row.data);\n // A reviewer routing choice supports a rule only when it chose this handler.\n const routing = row.kind === 'reviewer_routing';\n if (\n routing &&\n (data.choice !== 'handler' || typeof data.actionId !== 'string')\n )\n throw new Error('Rule evidence unavailable');\n await this.execution[feedbackActionTransaction](\n String(data.actionId),\n false,\n async (source) => {\n await this.authorize(source, 'retrieve');\n await this.provenance(source);\n if (origins.has(source.itemId))\n throw new Error('Independent rule evidence required');\n origins.add(source.itemId);\n const { digest: stored, ...body } = data;\n const generationMatch = routing\n ? source.origin === 'reviewer-selected' &&\n (lineage || source.settled)\n : source.origin !== 'reviewer-selected' &&\n provenance.generation &&\n data.judgment === 'correct' &&\n data.promptVersion === provenance.promptVersion &&\n data.configurationVersion === provenance.configurationVersion &&\n digest(data.model) === digest(provenance.model) &&\n digest(data.routing ?? { args: data.args }) ===\n digest(this.routing(source));\n if (\n digest(body) !== stored ||\n !generationMatch ||\n data.revision !== source.review.revision ||\n data.bindingHash !== source.review.bindingHash ||\n data.attemptId !== source.attemptId ||\n data.handlerId !== source.handlerId ||\n data.handlerVersion !== source.handlerVersion ||\n data.handlerId !== ctx.handlerId ||\n data.handlerVersion !== ctx.handlerVersion ||\n digest(data.args) !== digest(source.args) ||\n digest(this.routing(source)) !== digest(this.routing(ctx)) ||\n (await this.rows(ctx.db, 'supersedes_id=?', [id])).length\n )\n throw new Error('Rule evidence unavailable');\n result.push({\n id,\n digest: String(stored),\n query: String(data.query),\n });\n },\n ctx.db,\n undefined,\n undefined,\n !(lineage && routing),\n );\n }\n return result;\n }\n async suggest(input: SuggestRuleInput): Promise<RuleSuggestion> {\n digest(input);\n text(input.requestId);\n if (!this.config.policy) throw new Error('Rule policy owner unavailable');\n return this.execution[feedbackActionTransaction](\n input.actionId,\n true,\n async (ctx) => {\n this.checkBinding(input, ctx);\n await this.authorize(ctx, 'suggest');\n const key = `rule:${input.requestId}`;\n // A replay returns the stored suggestion; its support is re-checked\n // as lineage (integrity and revocation), never re-selected.\n const [stored] = await this.rows(\n ctx.db,\n 'item_id=? AND request_key=?',\n [ctx.itemId, key],\n );\n if (stored) {\n if (object(stored.data).requestHash !== digest(input))\n throw new Error('Rule request conflict');\n await this.rule(ctx, String(stored.id));\n return this.ruleDTO(stored);\n }\n const support = await this.support(ctx, input.supportingFeedbackIds);\n const terms = feedbackTerms(support[0].query).filter((term) =>\n support.every((example) =>\n feedbackTerms(example.query).includes(term),\n ),\n );\n if (!terms.length) throw new Error('No shared routing evidence');\n const rule: RoutingRule = {\n handlerId: ctx.handlerId,\n handlerVersion: ctx.handlerVersion,\n matchTerms: terms,\n ...this.routing(ctx),\n };\n const preview = await this.config.policy!.preview({\n db: ctx.db,\n scope: this.scope(),\n rule: structuredClone(rule),\n });\n text(preview.version);\n text(preview.preview, 4000);\n const body = {\n version: 1,\n actionId: input.actionId,\n revision: ctx.review.revision,\n bindingHash: ctx.review.bindingHash,\n rule,\n supportingFeedback: support.map(({ id, digest }) => ({ id, digest })),\n expectedPolicyVersion: preview.version,\n preview: preview.preview,\n reviewer: this.scope().actorId,\n requestHash: digest(input),\n };\n const row = await this.insert(ctx, key, 'rule_suggestion', {\n ...body,\n digest: digest(body),\n });\n await this.authorize(ctx, 'suggest');\n await this.rule(ctx, String(row.id));\n return this.ruleDTO(row);\n },\n );\n }\n private ruleDTO(row: Row): RuleSuggestion {\n const data = object(row.data);\n return {\n id: String(row.id),\n digest: String(data.digest),\n itemId: String(row.item_id),\n rule: data.rule as unknown as RoutingRule,\n supportingFeedback:\n data.supportingFeedback as RuleSuggestion['supportingFeedback'],\n expectedPolicyVersion: String(data.expectedPolicyVersion),\n preview: String(data.preview),\n automaticActionEligible: false,\n };\n }\n private async rule(ctx: FeedbackActionContext, id: string): Promise<Row> {\n const [row] = await this.rows(ctx.db, 'item_id=? AND id=? AND kind=?', [\n ctx.itemId,\n id,\n 'rule_suggestion',\n ]);\n if (!row) throw new Error('Rule unavailable');\n const data = object(row.data),\n { digest: stored, ...body } = data;\n if (\n digest(body) !== stored ||\n data.actionId !== ctx.review.actionId ||\n data.revision !== ctx.review.revision ||\n data.bindingHash !== ctx.review.bindingHash\n )\n throw new Error('Stale rule');\n const rule = object(data.rule);\n if (\n rule.handlerId !== ctx.handlerId ||\n rule.handlerVersion !== ctx.handlerVersion ||\n digest({\n args: rule.args,\n ...(rule.projection ? { projection: rule.projection } : {}),\n }) !== digest(this.routing(ctx))\n )\n throw new Error('Rule routing projection changed');\n const support = data.supportingFeedback as Array<{\n id: string;\n digest: string;\n }>;\n const current = await this.support(\n ctx,\n support.map((entry) => entry.id),\n true,\n );\n if (\n digest(current.map(({ id, digest }) => ({ id, digest }))) !==\n digest(support)\n )\n throw new Error('Rule evidence changed');\n return row;\n }\n async readRule(input: ReadRuleInput): Promise<RuleSuggestion> {\n return this.execution[feedbackActionTransaction](\n input.actionId,\n true,\n async (ctx) => {\n this.checkBinding(input, ctx);\n await this.authorize(ctx, 'suggest');\n const suggestion = this.ruleDTO(\n await this.rule(ctx, input.suggestionId),\n );\n if (!this.config.policy)\n throw new Error('Rule policy owner unavailable');\n const current = await this.config.policy.preview({\n db: ctx.db,\n scope: this.scope(),\n rule: structuredClone(suggestion.rule),\n });\n if (\n current.version !== suggestion.expectedPolicyVersion ||\n current.preview !== suggestion.preview\n )\n throw new Error('Rule policy changed');\n await this.authorize(ctx, 'suggest');\n await this.rule(ctx, input.suggestionId);\n return suggestion;\n },\n );\n }\n async adopt(input: AdoptRuleInput): Promise<RuleAdoption> {\n digest(input);\n text(input.requestId);\n if (!this.config.policy) throw new Error('Rule policy owner unavailable');\n return this.execution[feedbackActionTransaction](\n input.actionId,\n true,\n async (ctx) => {\n this.checkBinding(input, ctx);\n await this.authorize(ctx, 'adopt');\n const row = await this.rule(ctx, input.suggestionId),\n suggestion = this.ruleDTO(row);\n if (\n input.expectedDigest !== suggestion.digest ||\n input.expectedPolicyVersion !== suggestion.expectedPolicyVersion\n )\n throw new Error('Stale rule');\n const requestHash = digest(input),\n key = `adopt:${input.requestId}`;\n const [replay] = await this.rows(\n ctx.db,\n 'item_id=? AND request_key=?',\n [ctx.itemId, key],\n );\n if (replay) {\n const data = object(replay.data);\n if (\n data.requestHash !== requestHash ||\n data.reviewer !== this.scope().actorId\n )\n throw new Error('Rule request conflict');\n return {\n id: String(replay.id),\n policyVersion: String(data.policyVersion),\n auditId: String(data.auditId),\n automaticActionEligible: false,\n };\n }\n const current = await this.config.policy!.preview({\n db: ctx.db,\n scope: this.scope(),\n rule: structuredClone(suggestion.rule),\n });\n if (current.version !== input.expectedPolicyVersion)\n throw new Error('Policy version changed');\n const applied = await this.config.policy!.adopt({\n db: ctx.db,\n scope: this.scope(),\n rule: structuredClone(suggestion.rule),\n expectedVersion: input.expectedPolicyVersion,\n requestId: input.requestId,\n });\n text(applied.version);\n text(applied.auditId);\n if (applied.version === input.expectedPolicyVersion)\n throw new Error('Policy version did not advance');\n const verified = await this.config.policy!.preview({\n db: ctx.db,\n scope: this.scope(),\n rule: structuredClone(suggestion.rule),\n });\n if (verified.version !== applied.version)\n throw new Error('Policy adoption mismatch');\n const body = {\n version: 1,\n requestHash,\n suggestionId: suggestion.id,\n suggestionDigest: suggestion.digest,\n previousPolicyVersion: input.expectedPolicyVersion,\n policyVersion: applied.version,\n auditId: applied.auditId,\n reviewer: this.scope().actorId,\n automaticActionEligible: false,\n };\n const saved = await this.insert(ctx, key, 'rule_adoption', {\n ...body,\n digest: digest(body),\n });\n await this.authorize(ctx, 'adopt');\n await this.rule(ctx, input.suggestionId);\n return {\n id: String(saved.id),\n policyVersion: applied.version,\n auditId: applied.auditId,\n automaticActionEligible: false,\n };\n },\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -319,6 +319,79 @@ function proposeDocumentSplits(result, revision, groups) {
|
|
|
319
319
|
};
|
|
320
320
|
}
|
|
321
321
|
//#endregion
|
|
322
|
+
//#region src/generation-retry.ts
|
|
323
|
+
var MAX_ATTEMPTS = 10;
|
|
324
|
+
var MAX_BACKOFF_MS = 6e4;
|
|
325
|
+
var MAX_CONCURRENCY = 1e3;
|
|
326
|
+
function generationRetryPolicy(policy) {
|
|
327
|
+
if (policy === void 0) return { attempts: 1 };
|
|
328
|
+
if (!policy || typeof policy !== "object") throw new Error("Invalid generation retry policy");
|
|
329
|
+
const attempts = policy.attempts ?? 1;
|
|
330
|
+
if (!Number.isSafeInteger(attempts) || attempts < 1 || attempts > MAX_ATTEMPTS) throw new Error("Invalid generation retry attempts");
|
|
331
|
+
const { backoffMs, retryable } = policy;
|
|
332
|
+
if (backoffMs !== void 0 && typeof backoffMs !== "function" && !validDelay(backoffMs)) throw new Error("Invalid generation retry backoff");
|
|
333
|
+
if (retryable !== void 0 && typeof retryable !== "function") throw new Error("Invalid generation retry predicate");
|
|
334
|
+
return Object.freeze({
|
|
335
|
+
attempts,
|
|
336
|
+
...backoffMs === void 0 ? {} : { backoffMs },
|
|
337
|
+
...retryable ? { retryable } : {}
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
function validDelay(value) {
|
|
341
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= MAX_BACKOFF_MS;
|
|
342
|
+
}
|
|
343
|
+
function retryDelay(policy, attempt) {
|
|
344
|
+
const value = typeof policy.backoffMs === "function" ? policy.backoffMs(attempt) : policy.backoffMs ?? 0;
|
|
345
|
+
if (!validDelay(value)) throw new Error("Invalid generation retry backoff");
|
|
346
|
+
return value;
|
|
347
|
+
}
|
|
348
|
+
function shouldRetry(policy, error, attempt) {
|
|
349
|
+
if (attempt >= (policy.attempts ?? 1)) return false;
|
|
350
|
+
if (!policy.retryable) return true;
|
|
351
|
+
try {
|
|
352
|
+
return policy.retryable(error, attempt) === true;
|
|
353
|
+
} catch {
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
function assertGenerationBounds(config) {
|
|
358
|
+
generationRetryPolicy(config.retry);
|
|
359
|
+
if (config.concurrency !== void 0) new GenerationLimiter(config.concurrency);
|
|
360
|
+
}
|
|
361
|
+
var GenerationLimiter = class {
|
|
362
|
+
constructor(limit) {
|
|
363
|
+
this.limit = limit;
|
|
364
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_CONCURRENCY) throw new Error("Invalid generation concurrency");
|
|
365
|
+
}
|
|
366
|
+
limit;
|
|
367
|
+
active = 0;
|
|
368
|
+
waiting = [];
|
|
369
|
+
/** Tasks running now (for tests and diagnostics). */
|
|
370
|
+
get running() {
|
|
371
|
+
return this.active;
|
|
372
|
+
}
|
|
373
|
+
async run(work) {
|
|
374
|
+
if (this.active < this.limit) this.active++;
|
|
375
|
+
else await new Promise((resolve) => this.waiting.push(resolve));
|
|
376
|
+
try {
|
|
377
|
+
return await work();
|
|
378
|
+
} finally {
|
|
379
|
+
const next = this.waiting.shift();
|
|
380
|
+
if (next) next();
|
|
381
|
+
else this.active--;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
var limiters = /* @__PURE__ */ new WeakMap();
|
|
386
|
+
function generationLimiter(owner, concurrency) {
|
|
387
|
+
if (concurrency === void 0) return void 0;
|
|
388
|
+
const existing = limiters.get(owner);
|
|
389
|
+
if (existing?.limit === concurrency) return existing;
|
|
390
|
+
const limiter = new GenerationLimiter(concurrency);
|
|
391
|
+
limiters.set(owner, limiter);
|
|
392
|
+
return limiter;
|
|
393
|
+
}
|
|
394
|
+
//#endregion
|
|
322
395
|
//#region src/proposal-limits.ts
|
|
323
396
|
function assertProposalLimits(limits) {
|
|
324
397
|
if (!limits || [
|
|
@@ -356,6 +429,6 @@ function proposalReadConfiguration(config) {
|
|
|
356
429
|
};
|
|
357
430
|
}
|
|
358
431
|
//#endregion
|
|
359
|
-
export {
|
|
432
|
+
export { generationLimiter as a, shouldRetry as c, extractAnalysis as d, proposeDocumentSplits as f, assertGenerationBounds as i, SplitGroupError as l, assertProposalLimits as n, generationRetryPolicy as o, GenerationLimiter as r, retryDelay as s, proposalReadConfiguration as t, createSDKExtractionAdapter as u };
|
|
360
433
|
|
|
361
|
-
//# sourceMappingURL=proposal-contracts-
|
|
434
|
+
//# sourceMappingURL=proposal-contracts-DREPLG56.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposal-contracts-DREPLG56.js","names":[],"sources":["../../src/extraction.ts","../../src/generation-retry.ts","../../src/proposal-limits.ts","../../src/proposal-contracts.ts"],"sourcesContent":["import { fork } from 'node:child_process';\nimport { createHash } from 'node:crypto';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { GetAIOptions } from '@happyvertical/ai';\nimport type { PDFReaderOptions } from '@happyvertical/pdf';\nimport type { GetTranscriberOptions } from '@happyvertical/speech';\nimport type { AnalysisOutput } from './dto.js';\nimport {\n ExtractionFailure,\n emptyExtraction,\n validateExtractionRequest,\n visionImageLimits,\n} from './extraction-providers.js';\nimport type {\n ExtractionAdapter,\n ExtractionRequest,\n ExtractionResult,\n ProviderIdentity,\n VisionImageLimits,\n} from './extraction-types.js';\nimport { providerIdentity } from './extraction-types.js';\nimport { normalizeObservedImageRegions } from './observed-regions.js';\nimport type { AnalysisLease, IngestionService } from './server.js';\n\nexport type * from './extraction-types.js';\n\n/** Trusted server configuration. Credentials never enter analysis provenance. */\nexport interface ExtractionSDKConfiguration {\n pdf?: {\n provider: NonNullable<PDFReaderOptions['provider']>;\n identity: ProviderIdentity;\n };\n ocr?: { identity: ProviderIdentity; options?: Record<string, unknown> };\n speech?: { identity: ProviderIdentity; options: GetTranscriberOptions };\n vision?: { identity: ProviderIdentity; options: GetAIOptions };\n imageMode?: 'ocr' | 'vision';\n /** Vision derivatives only. Optional bounds may tighten the safe versioned defaults. */\n visionImageLimits?: VisionImageLimits;\n /** Trusted opt-in to advisory image answer-region observations. */\n observeAnswerRegions?: boolean;\n /** Maximum concurrent child processes for this adapter instance (default 1). */\n maxConcurrentProcesses?: number;\n /** The deployment enforces a native-memory ceiling outside Node (e.g. container).\n * Required for native decoders: Node's heap cap does not bound native allocation. */\n nativeMemoryIsolation: 'host-enforced';\n}\n\n/** Production adapter: bounded per-evidence child, terminated on deadline/abort. */\nexport function createSDKExtractionAdapter(\n configuration: ExtractionSDKConfiguration,\n): ExtractionAdapter {\n try {\n configuration = structuredClone(configuration);\n } catch {\n throw new Error('Serializable SDK configuration required');\n }\n const maximum = configuration.maxConcurrentProcesses ?? 1;\n if (!Number.isSafeInteger(maximum) || maximum < 1 || maximum > 32)\n throw new Error('Invalid extraction concurrency');\n visionImageLimits(configuration.visionImageLimits);\n if (\n configuration.observeAnswerRegions !== undefined &&\n typeof configuration.observeAnswerRegions !== 'boolean'\n )\n throw new Error('Invalid observed region configuration');\n let running = 0;\n if (configuration.nativeMemoryIsolation !== 'host-enforced')\n throw new Error('Native memory isolation is required');\n for (const provider of [\n configuration.pdf,\n configuration.ocr,\n configuration.speech,\n configuration.vision,\n ]) {\n if (provider) provider.identity = providerIdentity(provider.identity);\n }\n if (\n configuration.pdf?.provider === 'auto' ||\n configuration.ocr?.identity.provider === 'auto'\n )\n throw new Error('Pin extraction providers');\n return {\n async extract(request) {\n let latest = emptyExtraction(request);\n try {\n validateExtractionRequest(request);\n } catch (caught) {\n if (!(caught instanceof ExtractionFailure)) throw caught;\n latest.errors.push({\n category: caught.category,\n location: { kind: 'source' },\n });\n return latest;\n }\n if (request.evidence.mediaType.toLowerCase().startsWith('video/')) {\n latest.status = 'unsupported';\n latest.errors.push({\n category: 'unsupported_type',\n location: { kind: 'source' },\n });\n return latest;\n }\n if (request.signal?.aborted) {\n latest.errors.push({\n category: 'cancelled',\n location: { kind: 'source' },\n });\n return latest;\n }\n if (running >= maximum) {\n latest.errors.push({ category: 'limit', location: { kind: 'source' } });\n return latest;\n }\n running++;\n return new Promise<ExtractionResult>((resolve) => {\n // A public entry can move shared code into chunks; resolve without loading it.\n const child = fork(\n join(\n dirname(\n fileURLToPath(\n import.meta.resolve('@happyvertical/smrt-ingestion/server'),\n ),\n ),\n 'extraction-worker.js',\n ),\n [],\n {\n serialization: 'advanced',\n stdio: ['ignore', 'ignore', 'ignore', 'ipc'],\n execArgv: [`--max-old-space-size=${request.limits.workerHeapMb}`],\n detached: process.platform !== 'win32',\n },\n );\n let done = false;\n const stop = () => {\n try {\n if (process.platform !== 'win32' && child.pid)\n process.kill(-child.pid, 'SIGKILL');\n else child.kill('SIGKILL');\n } catch {\n child.kill('SIGKILL');\n }\n };\n const finish = (\n category?: 'timeout' | 'cancelled' | 'unavailable' | 'limit',\n ) => {\n if (done) return;\n done = true;\n running--;\n clearTimeout(timer);\n request.signal?.removeEventListener('abort', abort);\n stop();\n if (category) {\n latest.errors.push({ category, location: { kind: 'source' } });\n latest.status = latest.segments.length ? 'partial' : 'failed';\n latest.truncated = true;\n latest.omitted.push({ kind: 'source' });\n }\n resolve(latest);\n };\n const abort = () => finish('cancelled');\n const timer = setTimeout(\n () => finish('timeout'),\n request.limits.timeoutMs,\n );\n request.signal?.addEventListener('abort', abort, { once: true });\n child.on('error', () => finish('unavailable'));\n child.on('exit', () => {\n if (!done) finish('unavailable');\n });\n child.on(\n 'message',\n async (message: {\n kind: string;\n id?: number;\n result?: ExtractionResult;\n }) => {\n if (done) return;\n if (\n message.kind === 'authorize' &&\n Number.isSafeInteger(message.id)\n ) {\n try {\n await request.beforeProviderCall?.();\n if (!done) child.send({ kind: 'authorized', id: message.id });\n } catch {\n finish('cancelled');\n }\n return;\n }\n if (\n (message.kind === 'progress' || message.kind === 'result') &&\n message.result\n ) {\n // The child is our trusted normalizer; bound serialized IPC output as well.\n if (\n Buffer.byteLength(JSON.stringify(message.result)) >\n request.limits.maxOutputBytes + 65536\n )\n return finish('limit');\n latest = message.result;\n if (message.kind === 'result') finish();\n } else finish('unavailable');\n },\n );\n const {\n signal: _signal,\n beforeProviderCall: _authorize,\n ...wireRequest\n } = request;\n child.send({ request: wireRequest, configuration }, (error) => {\n if (error) finish('unavailable');\n });\n if (request.signal?.aborted) abort();\n });\n },\n };\n}\n\nfunction validateAndNormalizeExtractionOutput(\n result: ExtractionResult,\n request: ExtractionRequest,\n): void {\n const numeric = (value: number) => Number.isFinite(value) && value >= 0;\n const location = (\n value: ExtractionResult['segments'][number]['location'],\n ) => {\n if (!value || typeof value !== 'object') return false;\n if (value.kind === 'source') return true;\n if (value.kind === 'page')\n return Number.isSafeInteger(value.page) && value.page > 0;\n if (value.kind === 'pages')\n return (\n Number.isSafeInteger(value.startPage) &&\n value.startPage > 0 &&\n Number.isSafeInteger(value.endPage) &&\n value.endPage >= value.startPage\n );\n return (\n value.kind === 'time' &&\n numeric(value.startMs) &&\n numeric(value.endMs) &&\n value.endMs >= value.startMs\n );\n };\n if (\n !result ||\n !['complete', 'partial', 'failed', 'unsupported'].includes(result.status) ||\n result.automaticActionEligible !== false ||\n result.configurationRevision !== request.configurationRevision ||\n !result.evidence ||\n Object.entries(request.evidence).some(\n ([key, value]) =>\n result.evidence[key as keyof typeof result.evidence] !== value,\n ) ||\n typeof result.truncated !== 'boolean' ||\n !Array.isArray(result.capabilities) ||\n result.capabilities.some(\n (capability) =>\n !capability ||\n typeof capability.confidence !== 'boolean' ||\n typeof capability.boxes !== 'boolean' ||\n !['source', 'page', 'time'].includes(capability.location) ||\n !['unknown', 'reported'].includes(capability.truncation) ||\n !['unknown', 'reported'].includes(capability.usage),\n ) ||\n !result.limits ||\n Object.entries(request.limits).some(\n ([key, value]) =>\n result.limits[key as keyof typeof result.limits] !== value,\n ) ||\n (result.imagePreparations !== undefined &&\n (!Array.isArray(result.imagePreparations) ||\n result.imagePreparations.some(\n (image) =>\n image.policy !== 'vision-image-v1' ||\n !location(image.location) ||\n !['source', 'page'].includes(image.location.kind) ||\n !Number.isSafeInteger(image.sourceOrientation) ||\n image.sourceOrientation < 1 ||\n image.sourceOrientation > 8 ||\n !Number.isSafeInteger(image.maxEdge) ||\n image.maxEdge < 256 ||\n image.maxEdge > 2048 ||\n !Number.isSafeInteger(image.maxEncodedBytes) ||\n image.maxEncodedBytes < 1024 ||\n image.maxEncodedBytes > 512 * 1024 ||\n ![\n image.sourceWidth,\n image.sourceHeight,\n image.width,\n image.height,\n image.encodedBytes,\n ].every((value) => Number.isSafeInteger(value) && value > 0) ||\n image.sourceWidth * image.sourceHeight > request.limits.maxPixels ||\n image.width > image.maxEdge ||\n image.height > image.maxEdge ||\n image.encodedBytes > image.maxEncodedBytes ||\n !['jpeg', 'png'].includes(image.format) ||\n (image.format === 'png'\n ? image.quality !== null\n : ![80, 85].includes(image.quality ?? 0)),\n ))) ||\n !Array.isArray(result.segments) ||\n !Array.isArray(result.errors) ||\n !Array.isArray(result.omitted) ||\n (result.status === 'complete' &&\n (result.truncated ||\n result.errors.length > 0 ||\n result.omitted.length > 0)) ||\n result.omitted.some((value) => !location(value)) ||\n result.segments.some(\n (segment) =>\n typeof segment.text !== 'string' ||\n !location(segment.location) ||\n segment.location.kind === 'pages' ||\n (segment.provenance?.provider === 'unlimited-ocr' &&\n (segment.confidence !== null || segment.boxes !== null)) ||\n !segment.provenance ||\n [\n segment.provenance.provider,\n segment.provenance.model,\n segment.provenance.version,\n ].some((value) => typeof value !== 'string' || !value) ||\n (segment.confidence !== null &&\n (!segment.confidence ||\n !numeric(segment.confidence.value) ||\n segment.confidence.value > 1 ||\n segment.confidence.scale !== '0-1' ||\n segment.confidence.calibration !== 'unknown')) ||\n (segment.boxes !== null &&\n (!Array.isArray(segment.boxes) ||\n segment.boxes.some(\n (box) =>\n typeof box.text !== 'string' ||\n ![box.x, box.y, box.width, box.height].every(numeric),\n ))),\n ) ||\n result.errors.some(\n (error) =>\n ![\n 'unsupported_type',\n 'malformed_output',\n 'limit',\n 'timeout',\n 'unavailable',\n 'authentication',\n 'cancelled',\n 'integrity',\n ].includes(error.category) || !location(error.location),\n ) ||\n !result.usage ||\n Object.values(result.usage).some((value) => !numeric(value))\n )\n throw new Error('Invalid extraction output');\n // Structural typing permits extra host fields. Never persist them as identity.\n for (const segment of result.segments) {\n segment.provenance = providerIdentity(segment.provenance);\n const regions =\n request.evidence.mediaType.startsWith('image/') &&\n segment.kind === 'observation' &&\n segment.location.kind === 'source'\n ? normalizeObservedImageRegions(segment.observedRegions)\n : undefined;\n delete segment.observedRegions;\n if (regions) segment.observedRegions = regions;\n }\n if (result.imagePreparations)\n result.imagePreparations = result.imagePreparations.map((image) => ({\n policy: image.policy,\n maxEdge: image.maxEdge,\n maxEncodedBytes: image.maxEncodedBytes,\n sourceOrientation: image.sourceOrientation,\n sourceWidth: image.sourceWidth,\n sourceHeight: image.sourceHeight,\n width: image.width,\n height: image.height,\n format: image.format,\n quality: image.quality,\n encodedBytes: image.encodedBytes,\n location:\n image.location.kind === 'page'\n ? { kind: 'page', page: image.location.page }\n : { kind: 'source' },\n }));\n result.capabilities = result.capabilities.map((capability) => ({\n ...providerIdentity(capability),\n confidence: capability.confidence,\n boxes: capability.boxes,\n location: capability.location,\n truncation: capability.truncation,\n usage: capability.usage,\n }));\n}\n\n/** Current access is rechecked on read and fenced publication by the foundation.\n * The host already allocated the immutable input/config revision and lease. */\nexport async function extractAnalysis(\n service: IngestionService,\n lease: AnalysisLease,\n adapter: ExtractionAdapter,\n options: Pick<\n ExtractionRequest,\n 'limits' | 'configurationRevision' | 'signal'\n >,\n): Promise<boolean> {\n const snapshot = await service.getAnalysisInput(lease);\n const persisted = snapshot.configuration.extraction as\n | { configurationRevision?: unknown; limits?: Record<string, unknown> }\n | undefined;\n if (\n !persisted ||\n persisted.configurationRevision !== options.configurationRevision ||\n !persisted.limits ||\n Object.keys(options.limits).some(\n (key) =>\n persisted.limits?.[key] !==\n options.limits[key as keyof typeof options.limits],\n ) ||\n Object.keys(persisted.limits).length !== Object.keys(options.limits).length\n )\n throw new Error('Extraction configuration mismatch');\n const evidence = snapshot.evidence;\n const boundOptions = { ...options, limits: structuredClone(options.limits) };\n const results: ExtractionResult[] = [];\n let limited = false;\n const publication = (reserve = false): AnalysisOutput => {\n const allComplete =\n !limited &&\n results.length === evidence.length &&\n results.every((result) => result.status === 'complete');\n const firstError =\n limited || reserve\n ? 'limit'\n : results.flatMap((result) => result.errors)[0]?.category;\n return {\n status: reserve\n ? 'needs_attention'\n : allComplete\n ? 'completed'\n : results.some((result) => result.segments.length)\n ? 'partial'\n : 'needs_attention',\n provider: 'smrt-ingestion-extraction',\n model: 'none',\n version: '1',\n output: {\n configurationRevision: options.configurationRevision,\n results,\n ...(limited || reserve\n ? {\n truncated: true,\n omittedEvidenceCount: evidence.length - results.length,\n }\n : {}),\n },\n usage: {},\n ...(firstError ? { error: firstError } : {}),\n };\n };\n // Canonical persistence sorts keys but uses identical JSON value encoding/size.\n const fits = (output: AnalysisOutput) =>\n Buffer.byteLength(JSON.stringify(output)) <= snapshot.maxOutputBytes;\n const minimum: AnalysisOutput = {\n status: 'needs_attention',\n provider: 'smrt-ingestion-extraction',\n model: 'none',\n version: '1',\n output: {},\n usage: {},\n error: 'limit',\n };\n if (!fits(minimum)) return service.failAnalysis(lease, 'limit');\n if (!fits(publication(true))) return service.completeAnalysis(lease, minimum);\n for (const part of evidence) {\n await service.getAnalysisInput(lease);\n const bytes = await service.readEvidence(lease.itemId, part.id);\n await service.getAnalysisInput(lease);\n const request = { ...boundOptions, evidence: part, bytes };\n const result = await adapter.extract({\n ...request,\n evidence: { ...part },\n limits: { ...request.limits },\n bytes: bytes.slice(),\n beforeProviderCall: async () => {\n await service.getAnalysisInput(lease);\n },\n });\n validateAndNormalizeExtractionOutput(result, request);\n results.push(result);\n if (!fits(publication(true))) {\n limited = true;\n // Preserve earlier parts and the largest prefix of complete segments that fits.\n result.status = 'partial';\n result.truncated = true;\n result.errors.push({ category: 'limit', location: { kind: 'source' } });\n while (result.segments.length && !fits(publication(true))) {\n const removed = result.segments.pop();\n if (removed) result.omitted.push(removed.location);\n }\n // Diagnostics are indivisible: omit this result rather than erase known gaps.\n if (!fits(publication(true))) results.pop();\n }\n // Revalidation after an external call prevents returning/publishing revoked evidence.\n await service.getAnalysisInput(lease);\n if (limited || options.signal?.aborted) break;\n }\n return service.completeAnalysis(lease, publication());\n}\n\n/**\n * A split's page groups failed the group check (empty, unknown or repeated\n * page, unordered). Generated splits that fail it are dropped (#4288); the\n * message is a fixed phrase, never page numbers.\n */\nexport class SplitGroupError extends Error {}\n/** Side-effect-free, versioned split proposal. Original evidence is not replaced. */\nexport function proposeDocumentSplits(\n result: ExtractionResult,\n revision: number,\n groups: number[][],\n) {\n if (!Number.isSafeInteger(revision) || revision < 1 || !groups.length)\n throw new Error('Invalid split revision');\n const available = new Set(\n result.segments.flatMap((segment) =>\n segment.location.kind === 'page' ? [segment.location.page] : [],\n ),\n );\n const seen = new Set<number>();\n for (const group of groups) {\n if (!group.length) throw new SplitGroupError('Empty split');\n for (const page of group) {\n if (!Number.isSafeInteger(page) || !available.has(page) || seen.has(page))\n throw new SplitGroupError('Invalid split page');\n seen.add(page);\n }\n if (group.some((page, index) => index > 0 && page <= group[index - 1]))\n throw new SplitGroupError('Unordered split');\n }\n const proposal = {\n revision,\n evidenceId: result.evidence.id,\n inputHash: result.evidence.contentHash,\n configurationRevision: result.configurationRevision,\n groups: groups.map((pages) => ({ pages: [...pages] })),\n status: 'proposed' as const,\n };\n return {\n ...proposal,\n digest: createHash('sha256').update(JSON.stringify(proposal)).digest('hex'),\n };\n}\n","/**\n * Opt-in retry and concurrency bounds for `ProposalGenerator.generate`\n * (#4504). Server-only; never part of frozen configuration or digests.\n */\n\n/** How a failed `generator.generate` call is retried. Absent: one call, as before. */\nexport interface GenerationRetryPolicy {\n /** Total calls including the first, 1..10. Default 1 (no retry). */\n attempts?: number;\n /**\n * Delay before call `attempt` (2 is the first retry), in milliseconds,\n * 0..60000; a function is called per retry. Default 0.\n */\n backoffMs?: number | ((attempt: number) => number);\n /**\n * Whether the generator's rejection is worth another call (`attempt` is the\n * call that failed). Default: every rejection. A throw counts as `false`.\n * A stage timeout, a revoked lease and output validation are never retried.\n */\n retryable?: (error: unknown, attempt: number) => boolean;\n}\n\nconst MAX_ATTEMPTS = 10;\nconst MAX_BACKOFF_MS = 60_000;\nconst MAX_CONCURRENCY = 1_000;\n\n/** Validated, frozen copy of a host policy; throws on invalid settings. */\nexport function generationRetryPolicy(\n policy: GenerationRetryPolicy | undefined,\n): GenerationRetryPolicy & { attempts: number } {\n if (policy === undefined) return { attempts: 1 };\n if (!policy || typeof policy !== 'object')\n throw new Error('Invalid generation retry policy');\n const attempts = policy.attempts ?? 1;\n if (\n !Number.isSafeInteger(attempts) ||\n attempts < 1 ||\n attempts > MAX_ATTEMPTS\n )\n throw new Error('Invalid generation retry attempts');\n const { backoffMs, retryable } = policy;\n if (\n backoffMs !== undefined &&\n typeof backoffMs !== 'function' &&\n !validDelay(backoffMs)\n )\n throw new Error('Invalid generation retry backoff');\n if (retryable !== undefined && typeof retryable !== 'function')\n throw new Error('Invalid generation retry predicate');\n return Object.freeze({\n attempts,\n ...(backoffMs === undefined ? {} : { backoffMs }),\n ...(retryable ? { retryable } : {}),\n });\n}\nfunction validDelay(value: unknown): value is number {\n return (\n typeof value === 'number' &&\n Number.isFinite(value) &&\n value >= 0 &&\n value <= MAX_BACKOFF_MS\n );\n}\n/** The delay before call `attempt`; a malformed host answer is refused. */\nexport function retryDelay(\n policy: GenerationRetryPolicy,\n attempt: number,\n): number {\n const value =\n typeof policy.backoffMs === 'function'\n ? policy.backoffMs(attempt)\n : (policy.backoffMs ?? 0);\n if (!validDelay(value)) throw new Error('Invalid generation retry backoff');\n return value;\n}\n/** Whether to call again after `attempt` failed; a throwing predicate says no. */\nexport function shouldRetry(\n policy: GenerationRetryPolicy,\n error: unknown,\n attempt: number,\n): boolean {\n if (attempt >= (policy.attempts ?? 1)) return false;\n if (!policy.retryable) return true;\n try {\n return policy.retryable(error, attempt) === true;\n } catch {\n return false;\n }\n}\n\n/** Construction-time check of a host's `retry` and `concurrency` settings. */\nexport function assertGenerationBounds(config: {\n retry?: GenerationRetryPolicy;\n concurrency?: number;\n}): void {\n generationRetryPolicy(config.retry);\n if (config.concurrency !== undefined)\n new GenerationLimiter(config.concurrency);\n}\n/** A FIFO counting semaphore: at most `limit` tasks run at once. */\nexport class GenerationLimiter {\n private active = 0;\n private readonly waiting: Array<() => void> = [];\n constructor(readonly limit: number) {\n if (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_CONCURRENCY)\n throw new Error('Invalid generation concurrency');\n }\n /** Tasks running now (for tests and diagnostics). */\n get running(): number {\n return this.active;\n }\n async run<T>(work: () => Promise<T>): Promise<T> {\n if (this.active < this.limit) this.active++;\n // A released slot passes straight to the next waiter (active unchanged).\n else await new Promise<void>((resolve) => this.waiting.push(resolve));\n try {\n return await work();\n } finally {\n const next = this.waiting.shift();\n if (next) next();\n else this.active--;\n }\n }\n}\n// One limiter per host configuration object, so every service built from the\n// same configuration (one per request scope) shares the bound.\nconst limiters = new WeakMap<object, GenerationLimiter>();\nexport function generationLimiter(\n owner: object,\n concurrency: number | undefined,\n): GenerationLimiter | undefined {\n if (concurrency === undefined) return undefined;\n const existing = limiters.get(owner);\n if (existing?.limit === concurrency) return existing;\n const limiter = new GenerationLimiter(concurrency);\n limiters.set(owner, limiter);\n return limiter;\n}\n","import type { ProposalConfiguration } from './proposal-contracts.js';\n\n/** Validate deployment limits before any item is interpreted. */\nexport function assertProposalLimits(\n limits: ProposalConfiguration['limits'],\n): void {\n if (\n !limits ||\n [\n 'maxHandlers',\n 'maxCandidates',\n 'maxSuggestions',\n 'maxInputBytes',\n 'maxOutputBytes',\n 'maxQueryLength',\n 'timeoutMs',\n ].some(\n (key) =>\n !Number.isSafeInteger(limits[key as keyof typeof limits]) ||\n limits[key as keyof typeof limits] <= 0,\n ) ||\n limits.maxHandlers > 20 ||\n limits.maxCandidates > 20 ||\n limits.maxSuggestions > 20 ||\n limits.timeoutMs > 2_147_483_647\n )\n throw new Error('Invalid proposal limits');\n}\n","import type { DecisionClient } from '@happyvertical/smrt-core';\nimport type { HandlerContext } from './execution-contracts.js';\nimport type { IntakeValues } from './execution-dto.js';\nimport {\n type EvidenceLocation,\n type ProviderIdentity,\n providerIdentity,\n} from './extraction-types.js';\nimport type {\n ProposalCandidate,\n ProposalCatalogEntry,\n ProposalReferenceField,\n} from './proposal-dto.js';\n\n/** Optional discovery capability on the existing application execution handler. */\nexport interface HandlerDiscovery {\n mediaTypes: readonly string[];\n /** Every existing-record argument exposed to generation must be declared here. */\n references: Readonly<Record<string, ProposalReferenceField>>;\n /** Database reads only; filter in the query before ranking/summarizing. */\n candidates?(\n query: string,\n context: HandlerContext,\n page: { limit: number },\n ): Promise<{\n items: Array<Omit<ProposalCandidate, 'key'>>;\n hasMore: boolean;\n }>;\n}\nexport interface GenerationLimits {\n maxHandlers: number;\n maxCandidates: number;\n maxSuggestions: number;\n maxInputBytes: number;\n maxOutputBytes: number;\n maxQueryLength: number;\n timeoutMs: number;\n}\nexport interface GenerativeProposalInput {\n evidence: Array<{\n evidenceId: string;\n partId: string;\n parentEvidenceId: string | null;\n mediaType: string;\n contentHash: string;\n segments: Array<{\n text: string;\n location: EvidenceLocation;\n observedRegions?: import('./observed-regions.js').ObservedImageRegions;\n }>;\n }>;\n offered: Array<{\n handler: ProposalCatalogEntry;\n candidates: ProposalCandidate[];\n }>;\n instructions: string;\n /** Bounded, currently eligible examples; neither evidence nor authority. */\n examples?: import('./feedback-dto.js').FeedbackSelection;\n /** Authenticated human correction carried through fresh extraction; never model authority. */\n humanCorrection?: IntakeValues;\n /** Authenticated reviewer guidance; trusted steering only, never catalog or approval authority. */\n reviewerInstruction?: { id: string; text: string };\n}\n/** Inject only trusted SDK-bound adapters. Generative output is always untrusted. */\nexport interface ProposalGenerator {\n identity: ProviderIdentity;\n generate(\n input: GenerativeProposalInput,\n options: { signal: AbortSignal; maxOutputBytes: number },\n ): Promise<{\n output: unknown;\n completion: 'complete' | 'unknown';\n usage?: Record<string, number>;\n /** Provider-reported immutable model revision, when it safely resolves a configured alias. */\n responseModel?: string;\n }>;\n}\n/**\n * How validated decision answers affect readiness. `gate` (default) sends a\n * suggestion to `needs_review` when the thresholds are not met; `record` still\n * runs and persists the same answers but leaves outcome/disposition to the\n * validator. Neither mode makes any action automation-eligible.\n */\nexport type DecisionReadiness = 'gate' | 'record';\n/** Public decision settings shared by generation and read configuration. */\nexport interface DecisionSettings {\n minimumDecisionProbability?: number;\n tieMargin?: number;\n /**\n * Per-request token window forwarded to the decision client as `maxLen`\n * (the SDK Laya provider option). Absent keeps the client/checkpoint default.\n */\n decisionMaxLen?: number;\n decisionReadiness?: DecisionReadiness;\n}\nexport interface ProposalConfiguration extends DecisionSettings {\n version: string;\n promptVersion: string;\n generator: ProposalGenerator;\n /** Absent means the normal unconfigured decision path, never fake probability. */\n decision?: { client: DecisionClient; identity: ProviderIdentity };\n limits: GenerationLimits;\n /**\n * Opt-in, bounded, redacted capture of the model output on a failed\n * interpretation attempt (#4285). Text requires a host redactor; absent or\n * failed redaction retains no text. Off when absent. Not public read\n * configuration: it never enters frozen configuration, digests or\n * `proposalReadConfiguration`. See PROPOSALS.md.\n */\n failureCapture?: import('./failure-capture.js').FailureCaptureConfiguration;\n /**\n * Optional host checks on each validated suggestion (trusted, server-only).\n * Runs after validation and before the decision gate, with a copy of the\n * suggestion, its handler and the retained evidence text. The result can\n * only hold the suggestion at `needs_review` and record bounded, value-free\n * annotations; it can never upgrade a disposition or change args. A throw,\n * timeout or malformed result holds the suggestion with a fixed reason code.\n * Not public read configuration: it never enters frozen configuration or\n * digests. See PROPOSALS.md.\n */\n reviewSuggestion?: (\n input: SuggestionReviewInput,\n ) =>\n | HostSuggestionReviewResult\n | undefined\n | Promise<HostSuggestionReviewResult | undefined>;\n /**\n * Opt-in retry of a rejected `generator.generate` call (#4504). Absent (or\n * `attempts: 1`) keeps one call. Each call gets its own `limits.timeoutMs`\n * deadline; a timeout is final, and a retry is skipped when the analysis\n * lease could not cover the backoff plus another full deadline. Only the\n * final rejection becomes `provider_error`. Not public read configuration.\n */\n retry?: import('./generation-retry.js').GenerationRetryPolicy;\n /**\n * Most `generator.generate` calls in flight at once, shared by every\n * service built from this configuration object (1..1000). Absent:\n * unlimited, as before. A queued call waits before its deadline starts.\n * Not public read configuration.\n */\n concurrency?: number;\n}\n/** A copy of what the host may inspect; mutating it changes nothing. */\nexport interface SuggestionReviewInput {\n suggestion: import('./proposal-dto.js').GeneratedSuggestion;\n handler: ProposalCatalogEntry;\n evidence: GenerativeProposalInput['evidence'];\n}\n/** Host result: bounded codes and argument field names only. */\nexport interface HostSuggestionReviewResult {\n /** Hold the suggestion at `needs_review`. */\n hold?: boolean;\n /** Up to 8 codes matching `^[a-z][a-z0-9_.-]{0,47}$`; never document values. */\n reasons?: string[];\n /** Argument names declared in the handler's `argsSchema` that the host filled itself. */\n prefilled?: string[];\n}\n/** Credential-free configuration for validating persisted proposal snapshots. */\nexport interface ProposalReadConfiguration extends DecisionSettings {\n version: string;\n promptVersion: string;\n generator: ProviderIdentity;\n decision?: ProviderIdentity;\n limits: GenerationLimits;\n}\n/** Remove generation capability while preserving the public persisted configuration. */\nexport function proposalReadConfiguration(\n config: ProposalConfiguration | ProposalReadConfiguration,\n): ProposalReadConfiguration {\n const generator = providerIdentity(\n 'identity' in config.generator\n ? config.generator.identity\n : config.generator,\n );\n return {\n version: config.version,\n promptVersion: config.promptVersion,\n generator,\n ...(config.decision\n ? {\n decision: providerIdentity(\n 'identity' in config.decision\n ? config.decision.identity\n : config.decision,\n ),\n }\n : {}),\n ...(config.minimumDecisionProbability === undefined\n ? {}\n : { minimumDecisionProbability: config.minimumDecisionProbability }),\n ...(config.tieMargin === undefined ? {} : { tieMargin: config.tieMargin }),\n ...(config.decisionMaxLen === undefined\n ? {}\n : { decisionMaxLen: config.decisionMaxLen }),\n ...(config.decisionReadiness === undefined\n ? {}\n : { decisionReadiness: config.decisionReadiness }),\n limits: {\n maxHandlers: config.limits.maxHandlers,\n maxCandidates: config.limits.maxCandidates,\n maxSuggestions: config.limits.maxSuggestions,\n maxInputBytes: config.limits.maxInputBytes,\n maxOutputBytes: config.limits.maxOutputBytes,\n maxQueryLength: config.limits.maxQueryLength,\n timeoutMs: config.limits.timeoutMs,\n },\n };\n}\nexport interface GenerationStageConfiguration extends IntakeValues {\n stage: 'interpret';\n /** Copied from the pinned extraction source; verified against it before provider disclosure. */\n reviewerInstruction?: IntakeValues;\n proposals: {\n source: import('./proposal-dto.js').GenerationSourcePin;\n configurationVersion: string;\n promptVersion: string;\n catalogDigest: string;\n generator: ProviderIdentity;\n decision: ProviderIdentity | null;\n limits: GenerationLimits;\n minimumDecisionProbability: number;\n tieMargin: number;\n /** Present only when configured, so default digests stay stable. */\n decisionMaxLen?: number;\n /** Present only for `record`; `gate` is the default. */\n decisionReadiness?: 'record';\n };\n}\n"],"mappings":";;;;;;AAiDO,SAAS,2BACd,eACmB;CACnB,IAAI;EACF,gBAAgB,gBAAgB,aAAa;CAC/C,QAAQ;EACN,MAAM,IAAI,MAAM,yCAAyC;CAC3D;CACA,MAAM,UAAU,cAAc,0BAA0B;CACxD,IAAI,CAAC,OAAO,cAAc,OAAO,KAAK,UAAU,KAAK,UAAU,IAC7D,MAAM,IAAI,MAAM,gCAAgC;CAClD,kBAAkB,cAAc,iBAAiB;CACjD,IACE,cAAc,yBAAyB,KAAA,KACvC,OAAO,cAAc,yBAAyB,WAE9C,MAAM,IAAI,MAAM,uCAAuC;CACzD,IAAI,UAAU;CACd,IAAI,cAAc,0BAA0B,iBAC1C,MAAM,IAAI,MAAM,qCAAqC;CACvD,KAAA,MAAW,YAAY;EACrB,cAAc;EACd,cAAc;EACd,cAAc;EACd,cAAc;CAChB,GACE,IAAI,UAAU,SAAS,WAAW,iBAAiB,SAAS,QAAQ;CAEtE,IACE,cAAc,KAAK,aAAa,UAChC,cAAc,KAAK,SAAS,aAAa,QAEzC,MAAM,IAAI,MAAM,0BAA0B;CAC5C,OAAO,EACL,MAAM,QAAQ,SAAS;EACrB,IAAI,SAAS,gBAAgB,OAAO;EACpC,IAAI;GACF,0BAA0B,OAAO;EACnC,SAAS,QAAQ;GACf,IAAI,EAAE,kBAAkB,oBAAoB,MAAM;GAClD,OAAO,OAAO,KAAK;IACjB,UAAU,OAAO;IACjB,UAAU,EAAE,MAAM,SAAS;GAC7B,CAAC;GACD,OAAO;EACT;EACA,IAAI,QAAQ,SAAS,UAAU,YAAY,CAAA,CAAE,WAAW,QAAQ,GAAG;GACjE,OAAO,SAAS;GAChB,OAAO,OAAO,KAAK;IACjB,UAAU;IACV,UAAU,EAAE,MAAM,SAAS;GAC7B,CAAC;GACD,OAAO;EACT;EACA,IAAI,QAAQ,QAAQ,SAAS;GAC3B,OAAO,OAAO,KAAK;IACjB,UAAU;IACV,UAAU,EAAE,MAAM,SAAS;GAC7B,CAAC;GACD,OAAO;EACT;EACA,IAAI,WAAW,SAAS;GACtB,OAAO,OAAO,KAAK;IAAE,UAAU;IAAS,UAAU,EAAE,MAAM,SAAS;GAAE,CAAC;GACtE,OAAO;EACT;EACA;EACA,OAAO,IAAI,SAA2B,YAAY;GAEhD,MAAM,QAAQ,KACZ,KACE,QACE,cACE,OAAA,KAAY,QAAQ,sCAAsC,CAC5D,CACF,GACA,sBACF,GACA,CAAC,GACD;IACE,eAAe;IACf,OAAO;KAAC;KAAU;KAAU;KAAU;IAAK;IAC3C,UAAU,CAAC,wBAAwB,QAAQ,OAAO,cAAc;IAChE,UAAU,QAAQ,aAAa;GACjC,CACF;GACA,IAAI,OAAO;GACX,MAAM,aAAa;IACjB,IAAI;KACF,IAAI,QAAQ,aAAa,WAAW,MAAM,KACxC,QAAQ,KAAK,CAAC,MAAM,KAAK,SAAS;UAC/B,MAAM,KAAK,SAAS;IAC3B,QAAQ;KACN,MAAM,KAAK,SAAS;IACtB;GACF;GACA,MAAM,UACJ,aACG;IACH,IAAI,MAAM;IACV,OAAO;IACP;IACA,aAAa,KAAK;IAClB,QAAQ,QAAQ,oBAAoB,SAAS,KAAK;IAClD,KAAK;IACL,IAAI,UAAU;KACZ,OAAO,OAAO,KAAK;MAAE;MAAU,UAAU,EAAE,MAAM,SAAS;KAAE,CAAC;KAC7D,OAAO,SAAS,OAAO,SAAS,SAAS,YAAY;KACrD,OAAO,YAAY;KACnB,OAAO,QAAQ,KAAK,EAAE,MAAM,SAAS,CAAC;IACxC;IACA,QAAQ,MAAM;GAChB;GACA,MAAM,cAAc,OAAO,WAAW;GACtC,MAAM,QAAQ,iBACN,OAAO,SAAS,GACtB,QAAQ,OAAO,SACjB;GACA,QAAQ,QAAQ,iBAAiB,SAAS,OAAO,EAAE,MAAM,KAAK,CAAC;GAC/D,MAAM,GAAG,eAAe,OAAO,aAAa,CAAC;GAC7C,MAAM,GAAG,cAAc;IACrB,IAAI,CAAC,MAAM,OAAO,aAAa;GACjC,CAAC;GACD,MAAM,GACJ,WACA,OAAO,YAID;IACJ,IAAI,MAAM;IACV,IACE,QAAQ,SAAS,eACjB,OAAO,cAAc,QAAQ,EAAE,GAC/B;KACA,IAAI;MACF,MAAM,QAAQ,qBAAqB;MACnC,IAAI,CAAC,MAAM,MAAM,KAAK;OAAE,MAAM;OAAc,IAAI,QAAQ;MAAG,CAAC;KAC9D,QAAQ;MACN,OAAO,WAAW;KACpB;KACA;IACF;IACA,KACG,QAAQ,SAAS,cAAc,QAAQ,SAAS,aACjD,QAAQ,QACR;KAEA,IACE,OAAO,WAAW,KAAK,UAAU,QAAQ,MAAM,CAAC,IAChD,QAAQ,OAAO,iBAAiB,OAEhC,OAAO,OAAO,OAAO;KACvB,SAAS,QAAQ;KACjB,IAAI,QAAQ,SAAS,UAAU,OAAO;IACxC,OAAO,OAAO,aAAa;GAC7B,CACF;GACA,MAAM,EACJ,QAAQ,SACR,oBAAoB,YACpB,GAAG,gBACD;GACJ,MAAM,KAAK;IAAE,SAAS;IAAa;GAAc,IAAI,UAAU;IAC7D,IAAI,OAAO,OAAO,aAAa;GACjC,CAAC;GACD,IAAI,QAAQ,QAAQ,SAAS,MAAM;EACrC,CAAC;CACH,EACF;AACF;AAEA,SAAS,qCACP,QACA,SACM;CACN,MAAM,WAAW,UAAkB,OAAO,SAAS,KAAK,KAAK,SAAS;CACtE,MAAM,YACJ,UACG;EACH,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO;EAChD,IAAI,MAAM,SAAS,UAAU,OAAO;EACpC,IAAI,MAAM,SAAS,QACjB,OAAO,OAAO,cAAc,MAAM,IAAI,KAAK,MAAM,OAAO;EAC1D,IAAI,MAAM,SAAS,SACjB,OACE,OAAO,cAAc,MAAM,SAAS,KACpC,MAAM,YAAY,KAClB,OAAO,cAAc,MAAM,OAAO,KAClC,MAAM,WAAW,MAAM;EAE3B,OACE,MAAM,SAAS,UACf,QAAQ,MAAM,OAAO,KACrB,QAAQ,MAAM,KAAK,KACnB,MAAM,SAAS,MAAM;CAEzB;CACA,IACE,CAAC,UACD,CAAC;EAAC;EAAY;EAAW;EAAU;CAAa,CAAA,CAAE,SAAS,OAAO,MAAM,KACxE,OAAO,4BAA4B,SACnC,OAAO,0BAA0B,QAAQ,yBACzC,CAAC,OAAO,YACR,OAAO,QAAQ,QAAQ,QAAQ,CAAA,CAAE,MAC9B,CAAC,KAAK,WACL,OAAO,SAAS,SAAyC,KAC7D,KACA,OAAO,OAAO,cAAc,aAC5B,CAAC,MAAM,QAAQ,OAAO,YAAY,KAClC,OAAO,aAAa,MACjB,eACC,CAAC,cACD,OAAO,WAAW,eAAe,aACjC,OAAO,WAAW,UAAU,aAC5B,CAAC;EAAC;EAAU;EAAQ;CAAM,CAAA,CAAE,SAAS,WAAW,QAAQ,KACxD,CAAC,CAAC,WAAW,UAAU,CAAA,CAAE,SAAS,WAAW,UAAU,KACvD,CAAC,CAAC,WAAW,UAAU,CAAA,CAAE,SAAS,WAAW,KAAK,CACtD,KACA,CAAC,OAAO,UACR,OAAO,QAAQ,QAAQ,MAAM,CAAA,CAAE,MAC5B,CAAC,KAAK,WACL,OAAO,OAAO,SAAuC,KACzD,KACC,OAAO,sBAAsB,KAAA,MAC3B,CAAC,MAAM,QAAQ,OAAO,iBAAiB,KACtC,OAAO,kBAAkB,MACtB,UACC,MAAM,WAAW,qBACjB,CAAC,SAAS,MAAM,QAAQ,KACxB,CAAC,CAAC,UAAU,MAAM,CAAA,CAAE,SAAS,MAAM,SAAS,IAAI,KAChD,CAAC,OAAO,cAAc,MAAM,iBAAiB,KAC7C,MAAM,oBAAoB,KAC1B,MAAM,oBAAoB,KAC1B,CAAC,OAAO,cAAc,MAAM,OAAO,KACnC,MAAM,UAAU,OAChB,MAAM,UAAU,QAChB,CAAC,OAAO,cAAc,MAAM,eAAe,KAC3C,MAAM,kBAAkB,QACxB,MAAM,kBAAkB,MAAM,QAC9B,CAAC;EACC,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;CACR,CAAA,CAAE,OAAO,UAAU,OAAO,cAAc,KAAK,KAAK,QAAQ,CAAC,KAC3D,MAAM,cAAc,MAAM,eAAe,QAAQ,OAAO,aACxD,MAAM,QAAQ,MAAM,WACpB,MAAM,SAAS,MAAM,WACrB,MAAM,eAAe,MAAM,mBAC3B,CAAC,CAAC,QAAQ,KAAK,CAAA,CAAE,SAAS,MAAM,MAAM,MACrC,MAAM,WAAW,QACd,MAAM,YAAY,OAClB,CAAC,CAAC,IAAI,EAAE,CAAA,CAAE,SAAS,MAAM,WAAW,CAAC,EAC7C,MACJ,CAAC,MAAM,QAAQ,OAAO,QAAQ,KAC9B,CAAC,MAAM,QAAQ,OAAO,MAAM,KAC5B,CAAC,MAAM,QAAQ,OAAO,OAAO,KAC5B,OAAO,WAAW,eAChB,OAAO,aACN,OAAO,OAAO,SAAS,KACvB,OAAO,QAAQ,SAAS,MAC5B,OAAO,QAAQ,MAAM,UAAU,CAAC,SAAS,KAAK,CAAC,KAC/C,OAAO,SAAS,MACb,YACC,OAAO,QAAQ,SAAS,YACxB,CAAC,SAAS,QAAQ,QAAQ,KAC1B,QAAQ,SAAS,SAAS,WACzB,QAAQ,YAAY,aAAa,oBAC/B,QAAQ,eAAe,QAAQ,QAAQ,UAAU,SACpD,CAAC,QAAQ,cACT;EACE,QAAQ,WAAW;EACnB,QAAQ,WAAW;EACnB,QAAQ,WAAW;CACrB,CAAA,CAAE,MAAM,UAAU,OAAO,UAAU,YAAY,CAAC,KAAK,KACpD,QAAQ,eAAe,SACrB,CAAC,QAAQ,cACR,CAAC,QAAQ,QAAQ,WAAW,KAAK,KACjC,QAAQ,WAAW,QAAQ,KAC3B,QAAQ,WAAW,UAAU,SAC7B,QAAQ,WAAW,gBAAgB,cACtC,QAAQ,UAAU,SAChB,CAAC,MAAM,QAAQ,QAAQ,KAAK,KAC3B,QAAQ,MAAM,MACX,QACC,OAAO,IAAI,SAAS,YACpB,CAAC;EAAC,IAAI;EAAG,IAAI;EAAG,IAAI;EAAO,IAAI;CAAM,CAAA,CAAE,MAAM,OAAO,CACxD,EACR,KACA,OAAO,OAAO,MACX,UACC,CAAC;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAA,CAAE,SAAS,MAAM,QAAQ,KAAK,CAAC,SAAS,MAAM,QAAQ,CAC1D,KACA,CAAC,OAAO,SACR,OAAO,OAAO,OAAO,KAAK,CAAA,CAAE,MAAM,UAAU,CAAC,QAAQ,KAAK,CAAC,GAE3D,MAAM,IAAI,MAAM,2BAA2B;CAE7C,KAAA,MAAW,WAAW,OAAO,UAAU;EACrC,QAAQ,aAAa,iBAAiB,QAAQ,UAAU;EACxD,MAAM,UACJ,QAAQ,SAAS,UAAU,WAAW,QAAQ,KAC9C,QAAQ,SAAS,iBACjB,QAAQ,SAAS,SAAS,WACtB,8BAA8B,QAAQ,eAAe,IACrD,KAAA;EACN,OAAO,QAAQ;EACf,IAAI,SAAS,QAAQ,kBAAkB;CACzC;CACA,IAAI,OAAO,mBACT,OAAO,oBAAoB,OAAO,kBAAkB,KAAK,WAAW;EAClE,QAAQ,MAAM;EACd,SAAS,MAAM;EACf,iBAAiB,MAAM;EACvB,mBAAmB,MAAM;EACzB,aAAa,MAAM;EACnB,cAAc,MAAM;EACpB,OAAO,MAAM;EACb,QAAQ,MAAM;EACd,QAAQ,MAAM;EACd,SAAS,MAAM;EACf,cAAc,MAAM;EACpB,UACE,MAAM,SAAS,SAAS,SACpB;GAAE,MAAM;GAAQ,MAAM,MAAM,SAAS;EAAK,IAC1C,EAAE,MAAM,SAAS;CACzB,EAAE;CACJ,OAAO,eAAe,OAAO,aAAa,KAAK,gBAAgB;EAC7D,GAAG,iBAAiB,UAAU;EAC9B,YAAY,WAAW;EACvB,OAAO,WAAW;EAClB,UAAU,WAAW;EACrB,YAAY,WAAW;EACvB,OAAO,WAAW;CACpB,EAAE;AACJ;AAIA,eAAsB,gBACpB,SACA,OACA,SACA,SAIkB;CAClB,MAAM,WAAW,MAAM,QAAQ,iBAAiB,KAAK;CACrD,MAAM,YAAY,SAAS,cAAc;CAGzC,IACE,CAAC,aACD,UAAU,0BAA0B,QAAQ,yBAC5C,CAAC,UAAU,UACX,OAAO,KAAK,QAAQ,MAAM,CAAA,CAAE,MACzB,QACC,UAAU,SAAS,SACnB,QAAQ,OAAO,IACnB,KACA,OAAO,KAAK,UAAU,MAAM,CAAA,CAAE,WAAW,OAAO,KAAK,QAAQ,MAAM,CAAA,CAAE,QAErE,MAAM,IAAI,MAAM,mCAAmC;CACrD,MAAM,WAAW,SAAS;CAC1B,MAAM,eAAe;EAAE,GAAG;EAAS,QAAQ,gBAAgB,QAAQ,MAAM;CAAE;CAC3E,MAAM,UAA8B,CAAC;CACrC,IAAI,UAAU;CACd,MAAM,eAAe,UAAU,UAA0B;EACvD,MAAM,cACJ,CAAC,WACD,QAAQ,WAAW,SAAS,UAC5B,QAAQ,OAAO,WAAW,OAAO,WAAW,UAAU;EACxD,MAAM,aACJ,WAAW,UACP,UACA,QAAQ,SAAS,WAAW,OAAO,MAAM,CAAA,CAAE,EAAC,EAAG;EACrD,OAAO;GACL,QAAQ,UACJ,oBACA,cACE,cACA,QAAQ,MAAM,WAAW,OAAO,SAAS,MAAM,IAC7C,YACA;GACR,UAAU;GACV,OAAO;GACP,SAAS;GACT,QAAQ;IACN,uBAAuB,QAAQ;IAC/B;IACA,GAAI,WAAW,UACX;KACE,WAAW;KACX,sBAAsB,SAAS,SAAS,QAAQ;IAClD,IACA,CAAC;GACP;GACA,OAAO,CAAC;GACR,GAAI,aAAa,EAAE,OAAO,WAAW,IAAI,CAAC;EAC5C;CACF;CAEA,MAAM,QAAQ,WACZ,OAAO,WAAW,KAAK,UAAU,MAAM,CAAC,KAAK,SAAS;CACxD,MAAM,UAA0B;EAC9B,QAAQ;EACR,UAAU;EACV,OAAO;EACP,SAAS;EACT,QAAQ,CAAC;EACT,OAAO,CAAC;EACR,OAAO;CACT;CACA,IAAI,CAAC,KAAK,OAAO,GAAG,OAAO,QAAQ,aAAa,OAAO,OAAO;CAC9D,IAAI,CAAC,KAAK,YAAY,IAAI,CAAC,GAAG,OAAO,QAAQ,iBAAiB,OAAO,OAAO;CAC5E,KAAA,MAAW,QAAQ,UAAU;EAC3B,MAAM,QAAQ,iBAAiB,KAAK;EACpC,MAAM,QAAQ,MAAM,QAAQ,aAAa,MAAM,QAAQ,KAAK,EAAE;EAC9D,MAAM,QAAQ,iBAAiB,KAAK;EACpC,MAAM,UAAU;GAAE,GAAG;GAAc,UAAU;GAAM;EAAM;EACzD,MAAM,SAAS,MAAM,QAAQ,QAAQ;GACnC,GAAG;GACH,UAAU,EAAE,GAAG,KAAK;GACpB,QAAQ,EAAE,GAAG,QAAQ,OAAO;GAC5B,OAAO,MAAM,MAAM;GACnB,oBAAoB,YAAY;IAC9B,MAAM,QAAQ,iBAAiB,KAAK;GACtC;EACF,CAAC;EACD,qCAAqC,QAAQ,OAAO;EACpD,QAAQ,KAAK,MAAM;EACnB,IAAI,CAAC,KAAK,YAAY,IAAI,CAAC,GAAG;GAC5B,UAAU;GAEV,OAAO,SAAS;GAChB,OAAO,YAAY;GACnB,OAAO,OAAO,KAAK;IAAE,UAAU;IAAS,UAAU,EAAE,MAAM,SAAS;GAAE,CAAC;GACtE,OAAO,OAAO,SAAS,UAAU,CAAC,KAAK,YAAY,IAAI,CAAC,GAAG;IACzD,MAAM,UAAU,OAAO,SAAS,IAAI;IACpC,IAAI,SAAS,OAAO,QAAQ,KAAK,QAAQ,QAAQ;GACnD;GAEA,IAAI,CAAC,KAAK,YAAY,IAAI,CAAC,GAAG,QAAQ,IAAI;EAC5C;EAEA,MAAM,QAAQ,iBAAiB,KAAK;EACpC,IAAI,WAAW,QAAQ,QAAQ,SAAS;CAC1C;CACA,OAAO,QAAQ,iBAAiB,OAAO,YAAY,CAAC;AACtD;AAOO,IAAM,kBAAN,cAA8B,MAAM,CAAC;AAErC,SAAS,sBACd,QACA,UACA,QACA;CACA,IAAI,CAAC,OAAO,cAAc,QAAQ,KAAK,WAAW,KAAK,CAAC,OAAO,QAC7D,MAAM,IAAI,MAAM,wBAAwB;CAC1C,MAAM,YAAY,IAAI,IACpB,OAAO,SAAS,SAAS,YACvB,QAAQ,SAAS,SAAS,SAAS,CAAC,QAAQ,SAAS,IAAI,IAAI,CAAC,CAChE,CACF;CACA,MAAM,uBAAO,IAAI,IAAY;CAC7B,KAAA,MAAW,SAAS,QAAQ;EAC1B,IAAI,CAAC,MAAM,QAAQ,MAAM,IAAI,gBAAgB,aAAa;EAC1D,KAAA,MAAW,QAAQ,OAAO;GACxB,IAAI,CAAC,OAAO,cAAc,IAAI,KAAK,CAAC,UAAU,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,GACtE,MAAM,IAAI,gBAAgB,oBAAoB;GAChD,KAAK,IAAI,IAAI;EACf;EACA,IAAI,MAAM,MAAM,MAAM,UAAU,QAAQ,KAAK,QAAQ,MAAM,QAAQ,EAAE,GACnE,MAAM,IAAI,gBAAgB,iBAAiB;CAC/C;CACA,MAAM,WAAW;EACf;EACA,YAAY,OAAO,SAAS;EAC5B,WAAW,OAAO,SAAS;EAC3B,uBAAuB,OAAO;EAC9B,QAAQ,OAAO,KAAK,WAAW,EAAE,OAAO,CAAC,GAAG,KAAK,EAAE,EAAE;EACrD,QAAQ;CACV;CACA,OAAO;EACL,GAAG;EACH,QAAQ,WAAW,QAAQ,CAAA,CAAE,OAAO,KAAK,UAAU,QAAQ,CAAC,CAAA,CAAE,OAAO,KAAK;CAC5E;AACF;;;ACnhBA,IAAM,eAAe;AACrB,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AAGjB,SAAS,sBACd,QAC8C;CAC9C,IAAI,WAAW,KAAA,GAAW,OAAO,EAAE,UAAU,EAAE;CAC/C,IAAI,CAAC,UAAU,OAAO,WAAW,UAC/B,MAAM,IAAI,MAAM,iCAAiC;CACnD,MAAM,WAAW,OAAO,YAAY;CACpC,IACE,CAAC,OAAO,cAAc,QAAQ,KAC9B,WAAW,KACX,WAAW,cAEX,MAAM,IAAI,MAAM,mCAAmC;CACrD,MAAM,EAAE,WAAW,cAAc;CACjC,IACE,cAAc,KAAA,KACd,OAAO,cAAc,cACrB,CAAC,WAAW,SAAS,GAErB,MAAM,IAAI,MAAM,kCAAkC;CACpD,IAAI,cAAc,KAAA,KAAa,OAAO,cAAc,YAClD,MAAM,IAAI,MAAM,oCAAoC;CACtD,OAAO,OAAO,OAAO;EACnB;EACA,GAAI,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU;EAC/C,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;CACnC,CAAC;AACH;AACA,SAAS,WAAW,OAAiC;CACnD,OACE,OAAO,UAAU,YACjB,OAAO,SAAS,KAAK,KACrB,SAAS,KACT,SAAS;AAEb;AAEO,SAAS,WACd,QACA,SACQ;CACR,MAAM,QACJ,OAAO,OAAO,cAAc,aACxB,OAAO,UAAU,OAAO,IACvB,OAAO,aAAa;CAC3B,IAAI,CAAC,WAAW,KAAK,GAAG,MAAM,IAAI,MAAM,kCAAkC;CAC1E,OAAO;AACT;AAEO,SAAS,YACd,QACA,OACA,SACS;CACT,IAAI,YAAY,OAAO,YAAY,IAAI,OAAO;CAC9C,IAAI,CAAC,OAAO,WAAW,OAAO;CAC9B,IAAI;EACF,OAAO,OAAO,UAAU,OAAO,OAAO,MAAM;CAC9C,QAAQ;EACN,OAAO;CACT;AACF;AAGO,SAAS,uBAAuB,QAG9B;CACP,sBAAsB,OAAO,KAAK;CAClC,IAAI,OAAO,gBAAgB,KAAA,GACzB,IAAI,kBAAkB,OAAO,WAAW;AAC5C;AAEO,IAAM,oBAAN,MAAwB;CAG7B,YAAqB,OAAe;EAAf,KAAA,QAAA;EACnB,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,KAAK,QAAQ,iBACvD,MAAM,IAAI,MAAM,gCAAgC;CACpD;CAHqB;CAFb,SAAS;CACA,UAA6B,CAAC;;CAM/C,IAAI,UAAkB;EACpB,OAAO,KAAK;CACd;CACA,MAAM,IAAO,MAAoC;EAC/C,IAAI,KAAK,SAAS,KAAK,OAAO,KAAK;OAE9B,MAAM,IAAI,SAAe,YAAY,KAAK,QAAQ,KAAK,OAAO,CAAC;EACpE,IAAI;GACF,OAAO,MAAM,KAAK;EACpB,UAAE;GACA,MAAM,OAAO,KAAK,QAAQ,MAAM;GAChC,IAAI,MAAM,KAAK;QACV,KAAK;EACZ;CACF;AACF;AAGA,IAAM,2BAAW,IAAI,QAAmC;AACjD,SAAS,kBACd,OACA,aAC+B;CAC/B,IAAI,gBAAgB,KAAA,GAAW,OAAO,KAAA;CACtC,MAAM,WAAW,SAAS,IAAI,KAAK;CACnC,IAAI,UAAU,UAAU,aAAa,OAAO;CAC5C,MAAM,UAAU,IAAI,kBAAkB,WAAW;CACjD,SAAS,IAAI,OAAO,OAAO;CAC3B,OAAO;AACT;;;ACtIO,SAAS,qBACd,QACM;CACN,IACE,CAAC,UACD;EACE;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAA,CAAE,MACC,QACC,CAAC,OAAO,cAAc,OAAO,IAA2B,KACxD,OAAO,QAA+B,CAC1C,KACA,OAAO,cAAc,MACrB,OAAO,gBAAgB,MACvB,OAAO,iBAAiB,MACxB,OAAO,YAAY,YAEnB,MAAM,IAAI,MAAM,yBAAyB;AAC7C;;;AC2IO,SAAS,0BACd,QAC2B;CAC3B,MAAM,YAAY,iBAChB,cAAc,OAAO,YACjB,OAAO,UAAU,WACjB,OAAO,SACb;CACA,OAAO;EACL,SAAS,OAAO;EAChB,eAAe,OAAO;EACtB;EACA,GAAI,OAAO,WACP,EACE,UAAU,iBACR,cAAc,OAAO,WACjB,OAAO,SAAS,WAChB,OAAO,QACb,EACF,IACA,CAAC;EACL,GAAI,OAAO,+BAA+B,KAAA,IACtC,CAAC,IACD,EAAE,4BAA4B,OAAO,2BAA2B;EACpE,GAAI,OAAO,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,OAAO,UAAU;EACxE,GAAI,OAAO,mBAAmB,KAAA,IAC1B,CAAC,IACD,EAAE,gBAAgB,OAAO,eAAe;EAC5C,GAAI,OAAO,sBAAsB,KAAA,IAC7B,CAAC,IACD,EAAE,mBAAmB,OAAO,kBAAkB;EAClD,QAAQ;GACN,aAAa,OAAO,OAAO;GAC3B,eAAe,OAAO,OAAO;GAC7B,gBAAgB,OAAO,OAAO;GAC9B,eAAe,OAAO,OAAO;GAC7B,gBAAgB,OAAO,OAAO;GAC9B,gBAAgB,OAAO,OAAO;GAC9B,WAAW,OAAO,OAAO;EAC3B;CACF;AACF"}
|