@exaudeus/workrail 3.9.2 → 3.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/application/services/validation-engine.js +134 -0
- package/dist/application/services/workflow-compiler.js +54 -0
- package/dist/manifest.json +150 -78
- package/dist/mcp/handlers/v2-advance-core/assessment-consequences.d.ts +14 -0
- package/dist/mcp/handlers/v2-advance-core/assessment-consequences.js +27 -0
- package/dist/mcp/handlers/v2-advance-core/assessment-validation.d.ts +16 -0
- package/dist/mcp/handlers/v2-advance-core/assessment-validation.js +213 -0
- package/dist/mcp/handlers/v2-advance-core/event-builders.d.ts +1 -0
- package/dist/mcp/handlers/v2-advance-core/event-builders.js +3 -2
- package/dist/mcp/handlers/v2-advance-core/index.js +23 -8
- package/dist/mcp/handlers/v2-advance-core/input-validation.d.ts +9 -1
- package/dist/mcp/handlers/v2-advance-core/input-validation.js +22 -2
- package/dist/mcp/handlers/v2-advance-core/outcome-blocked.d.ts +2 -0
- package/dist/mcp/handlers/v2-advance-core/outcome-blocked.js +69 -19
- package/dist/mcp/handlers/v2-advance-core/outcome-success.js +22 -0
- package/dist/mcp/handlers/v2-execution/replay.js +7 -0
- package/dist/mcp/output-schemas.d.ts +156 -42
- package/dist/mcp/output-schemas.js +17 -1
- package/dist/mcp/v2-response-formatter.js +7 -1
- package/dist/types/workflow-definition.d.ts +26 -0
- package/dist/types/workflow-definition.js +16 -1
- package/dist/v2/durable-core/constants.d.ts +4 -1
- package/dist/v2/durable-core/constants.js +5 -2
- package/dist/v2/durable-core/domain/assessment-consequence-event-builder.d.ts +23 -0
- package/dist/v2/durable-core/domain/assessment-consequence-event-builder.js +36 -0
- package/dist/v2/durable-core/domain/assessment-record.d.ts +12 -0
- package/dist/v2/durable-core/domain/assessment-record.js +2 -0
- package/dist/v2/durable-core/domain/assessment-recorded-event-builder.d.ts +22 -0
- package/dist/v2/durable-core/domain/assessment-recorded-event-builder.js +38 -0
- package/dist/v2/durable-core/domain/blocked-node-builder.d.ts +1 -1
- package/dist/v2/durable-core/domain/blocked-node-builder.js +8 -0
- package/dist/v2/durable-core/domain/blocking-decision.d.ts +6 -0
- package/dist/v2/durable-core/domain/blocking-decision.js +15 -0
- package/dist/v2/durable-core/domain/prompt-renderer.js +53 -67
- package/dist/v2/durable-core/domain/reason-model.d.ts +12 -2
- package/dist/v2/durable-core/domain/reason-model.js +27 -2
- package/dist/v2/durable-core/domain/retrieval-contract.d.ts +105 -0
- package/dist/v2/durable-core/domain/retrieval-contract.js +310 -0
- package/dist/v2/durable-core/domain/risk-policy-guardrails.js +1 -0
- package/dist/v2/durable-core/domain/validation-criteria-validator.d.ts +1 -0
- package/dist/v2/durable-core/domain/validation-criteria-validator.js +11 -0
- package/dist/v2/durable-core/schemas/artifacts/assessment.d.ts +55 -0
- package/dist/v2/durable-core/schemas/artifacts/assessment.js +29 -0
- package/dist/v2/durable-core/schemas/artifacts/index.d.ts +2 -1
- package/dist/v2/durable-core/schemas/artifacts/index.js +8 -1
- package/dist/v2/durable-core/schemas/compiled-workflow/index.d.ts +24 -24
- package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.d.ts +141 -21
- package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.js +10 -1
- package/dist/v2/durable-core/schemas/execution-snapshot/execution-snapshot.v1.d.ts +729 -171
- package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +1442 -202
- package/dist/v2/durable-core/schemas/session/events.d.ts +231 -8
- package/dist/v2/durable-core/schemas/session/events.js +36 -0
- package/dist/v2/durable-core/schemas/session/gaps.d.ts +2 -2
- package/dist/v2/projections/assessment-consequences.d.ts +19 -0
- package/dist/v2/projections/assessment-consequences.js +33 -0
- package/dist/v2/projections/assessments.d.ts +21 -0
- package/dist/v2/projections/assessments.js +35 -0
- package/dist/v2/projections/resume-ranking.d.ts +1 -0
- package/dist/v2/projections/resume-ranking.js +12 -24
- package/package.json +1 -1
- package/spec/workflow.schema.json +110 -0
- package/workflows/bug-investigation.agentic.v2.json +28 -2
- package/workflows/mr-review-workflow.agentic.v2.json +10 -5
- package/workflows/test-artifact-loop-control.json +28 -2
|
@@ -8,7 +8,7 @@ export type GapReasonV1 = {
|
|
|
8
8
|
readonly detail: UserOnlyDependencyReasonV1;
|
|
9
9
|
} | {
|
|
10
10
|
readonly category: 'contract_violation';
|
|
11
|
-
readonly detail: 'missing_required_output' | 'invalid_required_output' | 'missing_required_notes';
|
|
11
|
+
readonly detail: 'missing_required_output' | 'invalid_required_output' | 'missing_required_notes' | 'assessment_followup_required';
|
|
12
12
|
} | {
|
|
13
13
|
readonly category: 'capability_missing';
|
|
14
14
|
readonly detail: 'required_capability_unavailable' | 'required_capability_unknown';
|
|
@@ -16,7 +16,7 @@ export type GapReasonV1 = {
|
|
|
16
16
|
readonly category: 'unexpected';
|
|
17
17
|
readonly detail: 'invariant_violation' | 'storage_corruption_detected' | 'evaluation_error';
|
|
18
18
|
};
|
|
19
|
-
export type BlockerCodeV1 = 'USER_ONLY_DEPENDENCY' | 'MISSING_REQUIRED_OUTPUT' | 'INVALID_REQUIRED_OUTPUT' | 'MISSING_REQUIRED_NOTES' | 'MISSING_CONTEXT_KEY' | 'CONTEXT_BUDGET_EXCEEDED' | 'REQUIRED_CAPABILITY_UNKNOWN' | 'REQUIRED_CAPABILITY_UNAVAILABLE' | 'INVARIANT_VIOLATION' | 'STORAGE_CORRUPTION_DETECTED';
|
|
19
|
+
export type BlockerCodeV1 = 'USER_ONLY_DEPENDENCY' | 'MISSING_REQUIRED_OUTPUT' | 'INVALID_REQUIRED_OUTPUT' | 'ASSESSMENT_FOLLOWUP_REQUIRED' | 'MISSING_REQUIRED_NOTES' | 'MISSING_CONTEXT_KEY' | 'CONTEXT_BUDGET_EXCEEDED' | 'REQUIRED_CAPABILITY_UNKNOWN' | 'REQUIRED_CAPABILITY_UNAVAILABLE' | 'INVARIANT_VIOLATION' | 'STORAGE_CORRUPTION_DETECTED';
|
|
20
20
|
export type BlockerPointerV1 = {
|
|
21
21
|
readonly kind: 'context_key';
|
|
22
22
|
readonly key: string;
|
|
@@ -28,6 +28,10 @@ export type BlockerPointerV1 = {
|
|
|
28
28
|
} | {
|
|
29
29
|
readonly kind: 'capability';
|
|
30
30
|
readonly capability: CapabilityV2;
|
|
31
|
+
} | {
|
|
32
|
+
readonly kind: 'assessment_dimension';
|
|
33
|
+
readonly assessmentId: string;
|
|
34
|
+
readonly dimensionId: string;
|
|
31
35
|
} | {
|
|
32
36
|
readonly kind: 'workflow_step';
|
|
33
37
|
readonly stepId: string;
|
|
@@ -52,6 +56,12 @@ export type ReasonV1 = {
|
|
|
52
56
|
} | {
|
|
53
57
|
readonly kind: 'invalid_required_output';
|
|
54
58
|
readonly contractRef: string;
|
|
59
|
+
} | {
|
|
60
|
+
readonly kind: 'assessment_followup_required';
|
|
61
|
+
readonly assessmentId: string;
|
|
62
|
+
readonly dimensionId: string;
|
|
63
|
+
readonly level: string;
|
|
64
|
+
readonly guidance: string;
|
|
55
65
|
} | {
|
|
56
66
|
readonly kind: 'missing_notes';
|
|
57
67
|
readonly stepId: string;
|
|
@@ -8,6 +8,7 @@ exports.shouldBlock = shouldBlock;
|
|
|
8
8
|
const constants_js_1 = require("../constants.js");
|
|
9
9
|
const neverthrow_1 = require("neverthrow");
|
|
10
10
|
const utf8_byte_length_js_1 = require("../schemas/lib/utf8-byte-length.js");
|
|
11
|
+
const index_js_1 = require("../schemas/artifacts/index.js");
|
|
11
12
|
function ensureDelimiterSafeId(label, value) {
|
|
12
13
|
if (!constants_js_1.DELIMITER_SAFE_ID_PATTERN.test(value)) {
|
|
13
14
|
return (0, neverthrow_1.err)({
|
|
@@ -58,6 +59,12 @@ function reasonToGap(reason) {
|
|
|
58
59
|
reason: { category: 'contract_violation', detail: 'invalid_required_output' },
|
|
59
60
|
summary: `Invalid required output for contractRef=${reason.contractRef}`,
|
|
60
61
|
};
|
|
62
|
+
case 'assessment_followup_required':
|
|
63
|
+
return {
|
|
64
|
+
severity: 'critical',
|
|
65
|
+
reason: { category: 'contract_violation', detail: 'assessment_followup_required' },
|
|
66
|
+
summary: `Assessment follow-up required: ${reason.assessmentId}.${reason.dimensionId} == ${reason.level}`,
|
|
67
|
+
};
|
|
61
68
|
case 'missing_notes':
|
|
62
69
|
return {
|
|
63
70
|
severity: 'critical',
|
|
@@ -125,6 +132,9 @@ function blockerSortKey(b) {
|
|
|
125
132
|
case 'capability':
|
|
126
133
|
ptrStable = p.capability;
|
|
127
134
|
break;
|
|
135
|
+
case 'assessment_dimension':
|
|
136
|
+
ptrStable = `${p.assessmentId}|${p.dimensionId}`;
|
|
137
|
+
break;
|
|
128
138
|
case 'workflow_step':
|
|
129
139
|
ptrStable = p.stepId;
|
|
130
140
|
break;
|
|
@@ -162,7 +172,9 @@ function reasonToBlocker(reason) {
|
|
|
162
172
|
code: 'MISSING_REQUIRED_OUTPUT',
|
|
163
173
|
pointer: { kind: 'output_contract', contractRef },
|
|
164
174
|
message: `Missing required output (contractRef=${contractRef}).`,
|
|
165
|
-
suggestedFix:
|
|
175
|
+
suggestedFix: contractRef === index_js_1.ASSESSMENT_CONTRACT_REF
|
|
176
|
+
? 'Call continue_workflow without output to rehydrate the current step, then retry with an assessment artifact under output.artifacts using kind "wr.assessment" and the required canonical dimension levels.'
|
|
177
|
+
: 'Call continue_workflow without output to rehydrate the current step, then retry with output.notesMarkdown that satisfies the step output requirements.',
|
|
166
178
|
}))
|
|
167
179
|
.andThen(ensureBlockerTextBudgets);
|
|
168
180
|
case 'invalid_required_output':
|
|
@@ -171,9 +183,22 @@ function reasonToBlocker(reason) {
|
|
|
171
183
|
code: 'INVALID_REQUIRED_OUTPUT',
|
|
172
184
|
pointer: { kind: 'output_contract', contractRef },
|
|
173
185
|
message: `Invalid output for contractRef=${contractRef}.`,
|
|
174
|
-
suggestedFix:
|
|
186
|
+
suggestedFix: contractRef === index_js_1.ASSESSMENT_CONTRACT_REF
|
|
187
|
+
? 'Update the assessment artifact in output.artifacts so it uses the expected assessment ID and canonical dimension levels. Then call continue_workflow without output to rehydrate the current step and retry with the corrected artifact.'
|
|
188
|
+
: 'Update output.notesMarkdown to satisfy validation. Then call continue_workflow without output to rehydrate the current step and retry advance with the corrected output. Replaying the same invalid advance will keep returning this blocked result.',
|
|
175
189
|
}))
|
|
176
190
|
.andThen(ensureBlockerTextBudgets);
|
|
191
|
+
case 'assessment_followup_required':
|
|
192
|
+
return ensureBlockerTextBudgets({
|
|
193
|
+
code: 'ASSESSMENT_FOLLOWUP_REQUIRED',
|
|
194
|
+
pointer: {
|
|
195
|
+
kind: 'assessment_dimension',
|
|
196
|
+
assessmentId: reason.assessmentId,
|
|
197
|
+
dimensionId: reason.dimensionId,
|
|
198
|
+
},
|
|
199
|
+
message: `Follow-up required before this step can proceed: ${reason.assessmentId}.${reason.dimensionId} matched "${reason.level}".`,
|
|
200
|
+
suggestedFix: `Stay on this step, address this follow-up, and retry with updated output: ${reason.guidance}`,
|
|
201
|
+
});
|
|
177
202
|
case 'missing_notes':
|
|
178
203
|
return ensureDelimiterSafeId('workflow_step.stepId', reason.stepId)
|
|
179
204
|
.map((stepId) => ({
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export type RetrievalPackSurface = 'rehydrate';
|
|
2
|
+
export type ResumePreviewSurface = 'resume_preview';
|
|
3
|
+
export type RetrievalPackTier = 'structural_context' | 'durable_recap' | 'reference_material';
|
|
4
|
+
export type ResumePreviewTier = 'identity_context' | 'durable_recap';
|
|
5
|
+
export interface RetrievalPackTierDefinition {
|
|
6
|
+
readonly tier: RetrievalPackTier;
|
|
7
|
+
readonly purpose: string;
|
|
8
|
+
readonly priority: number;
|
|
9
|
+
readonly retention: 'core' | 'tail';
|
|
10
|
+
}
|
|
11
|
+
export interface ResumePreviewTierDefinition {
|
|
12
|
+
readonly tier: ResumePreviewTier;
|
|
13
|
+
readonly purpose: string;
|
|
14
|
+
readonly priority: number;
|
|
15
|
+
readonly maxBytes: number;
|
|
16
|
+
}
|
|
17
|
+
export interface RetrievalPackTruncationPolicy {
|
|
18
|
+
readonly mode: 'drop_lower_tiers_then_global_utf8_trim';
|
|
19
|
+
readonly budgetScope: 'shared_recovery_prompt';
|
|
20
|
+
readonly antiReconstructionRule: 'select_order_and_compress_explicit_facts_only';
|
|
21
|
+
}
|
|
22
|
+
export interface RetrievalPackContract {
|
|
23
|
+
readonly surface: RetrievalPackSurface;
|
|
24
|
+
readonly tiers: readonly RetrievalPackTierDefinition[];
|
|
25
|
+
readonly truncation: RetrievalPackTruncationPolicy;
|
|
26
|
+
}
|
|
27
|
+
export interface ResumePreviewContract {
|
|
28
|
+
readonly surface: ResumePreviewSurface;
|
|
29
|
+
readonly tiers: readonly ResumePreviewTierDefinition[];
|
|
30
|
+
readonly budgetBytes: number;
|
|
31
|
+
}
|
|
32
|
+
export interface BranchSummarySegment {
|
|
33
|
+
readonly kind: 'branch_summary';
|
|
34
|
+
readonly tier: 'structural_context';
|
|
35
|
+
readonly source: 'deterministic_structure';
|
|
36
|
+
readonly title: 'Branch Summary';
|
|
37
|
+
readonly body: string;
|
|
38
|
+
}
|
|
39
|
+
export interface DownstreamRecapSegment {
|
|
40
|
+
readonly kind: 'downstream_recap';
|
|
41
|
+
readonly tier: 'structural_context';
|
|
42
|
+
readonly source: 'explicit_durable_fact';
|
|
43
|
+
readonly title: 'Downstream Recap (Preferred Branch)';
|
|
44
|
+
readonly body: string;
|
|
45
|
+
}
|
|
46
|
+
export interface AncestryRecapSegment {
|
|
47
|
+
readonly kind: 'ancestry_recap';
|
|
48
|
+
readonly tier: 'durable_recap';
|
|
49
|
+
readonly source: 'explicit_durable_fact';
|
|
50
|
+
readonly title: 'Ancestry Recap';
|
|
51
|
+
readonly body: string;
|
|
52
|
+
}
|
|
53
|
+
export interface FunctionDefinitionsSegment {
|
|
54
|
+
readonly kind: 'function_definitions';
|
|
55
|
+
readonly tier: 'reference_material';
|
|
56
|
+
readonly source: 'workflow_definition';
|
|
57
|
+
readonly title: 'Function Definitions';
|
|
58
|
+
readonly body: string;
|
|
59
|
+
}
|
|
60
|
+
export type RetrievalPackSegment = BranchSummarySegment | DownstreamRecapSegment | AncestryRecapSegment | FunctionDefinitionsSegment;
|
|
61
|
+
export interface RetrievalPackRenderResult {
|
|
62
|
+
readonly text: string;
|
|
63
|
+
readonly includedTiers: readonly RetrievalPackTier[];
|
|
64
|
+
readonly omittedTierCount: number;
|
|
65
|
+
readonly truncatedWithinTier: boolean;
|
|
66
|
+
}
|
|
67
|
+
export interface SessionTitlePreviewSegment {
|
|
68
|
+
readonly kind: 'session_title_preview';
|
|
69
|
+
readonly tier: 'identity_context';
|
|
70
|
+
readonly source: 'persisted_context';
|
|
71
|
+
readonly body: string;
|
|
72
|
+
}
|
|
73
|
+
export interface RecapPreviewSegment {
|
|
74
|
+
readonly kind: 'recap_preview';
|
|
75
|
+
readonly tier: 'durable_recap';
|
|
76
|
+
readonly source: 'explicit_durable_fact';
|
|
77
|
+
readonly body: string;
|
|
78
|
+
}
|
|
79
|
+
export type ResumePreviewSegment = SessionTitlePreviewSegment | RecapPreviewSegment;
|
|
80
|
+
export type ResumePreviewText = string & {
|
|
81
|
+
readonly __brand: 'ResumePreviewText';
|
|
82
|
+
};
|
|
83
|
+
export interface ResumePreviewRenderResult {
|
|
84
|
+
readonly text: ResumePreviewText;
|
|
85
|
+
readonly includedTiers: readonly ResumePreviewTier[];
|
|
86
|
+
}
|
|
87
|
+
export declare const REHYDRATE_RETRIEVAL_CONTRACT: RetrievalPackContract;
|
|
88
|
+
export declare const RESUME_PREVIEW_CONTRACT: ResumePreviewContract;
|
|
89
|
+
export declare function createBranchSummarySegment(body: string): BranchSummarySegment | null;
|
|
90
|
+
export declare function createDownstreamRecapSegment(body: string): DownstreamRecapSegment | null;
|
|
91
|
+
export declare function createAncestryRecapSegment(body: string): AncestryRecapSegment | null;
|
|
92
|
+
export declare function createFunctionDefinitionsSegment(body: string): FunctionDefinitionsSegment | null;
|
|
93
|
+
export declare function createSessionTitlePreviewSegment(body: string): SessionTitlePreviewSegment | null;
|
|
94
|
+
export declare function createRecapPreviewSegment(body: string): RecapPreviewSegment | null;
|
|
95
|
+
export declare function compareRetrievalPackSegments(a: RetrievalPackSegment, b: RetrievalPackSegment): number;
|
|
96
|
+
export declare function orderRetrievalPackSegments(segments: readonly RetrievalPackSegment[]): readonly RetrievalPackSegment[];
|
|
97
|
+
export declare function renderRetrievalPackSections(segments: readonly RetrievalPackSegment[]): readonly string[];
|
|
98
|
+
export declare function renderBudgetedResumePreview(args: {
|
|
99
|
+
readonly segments: readonly ResumePreviewSegment[];
|
|
100
|
+
readonly focusTerms?: readonly string[];
|
|
101
|
+
}): ResumePreviewRenderResult;
|
|
102
|
+
export declare function renderBudgetedRehydrateRecovery(args: {
|
|
103
|
+
readonly header: string;
|
|
104
|
+
readonly segments: readonly RetrievalPackSegment[];
|
|
105
|
+
}): RetrievalPackRenderResult;
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RESUME_PREVIEW_CONTRACT = exports.REHYDRATE_RETRIEVAL_CONTRACT = void 0;
|
|
4
|
+
exports.createBranchSummarySegment = createBranchSummarySegment;
|
|
5
|
+
exports.createDownstreamRecapSegment = createDownstreamRecapSegment;
|
|
6
|
+
exports.createAncestryRecapSegment = createAncestryRecapSegment;
|
|
7
|
+
exports.createFunctionDefinitionsSegment = createFunctionDefinitionsSegment;
|
|
8
|
+
exports.createSessionTitlePreviewSegment = createSessionTitlePreviewSegment;
|
|
9
|
+
exports.createRecapPreviewSegment = createRecapPreviewSegment;
|
|
10
|
+
exports.compareRetrievalPackSegments = compareRetrievalPackSegments;
|
|
11
|
+
exports.orderRetrievalPackSegments = orderRetrievalPackSegments;
|
|
12
|
+
exports.renderRetrievalPackSections = renderRetrievalPackSections;
|
|
13
|
+
exports.renderBudgetedResumePreview = renderBudgetedResumePreview;
|
|
14
|
+
exports.renderBudgetedRehydrateRecovery = renderBudgetedRehydrateRecovery;
|
|
15
|
+
const constants_js_1 = require("../constants.js");
|
|
16
|
+
const REHYDRATE_TIER_DEFINITIONS = [
|
|
17
|
+
{
|
|
18
|
+
tier: 'structural_context',
|
|
19
|
+
purpose: 'Orient the agent to branch shape and preferred continuation path.',
|
|
20
|
+
priority: 0,
|
|
21
|
+
retention: 'core',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
tier: 'durable_recap',
|
|
25
|
+
purpose: 'Surface durable notes captured from explicit recap outputs.',
|
|
26
|
+
priority: 1,
|
|
27
|
+
retention: 'core',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
tier: 'reference_material',
|
|
31
|
+
purpose: 'Surface authored workflow definitions referenced by the current step.',
|
|
32
|
+
priority: 2,
|
|
33
|
+
retention: 'tail',
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
exports.REHYDRATE_RETRIEVAL_CONTRACT = {
|
|
37
|
+
surface: 'rehydrate',
|
|
38
|
+
tiers: REHYDRATE_TIER_DEFINITIONS,
|
|
39
|
+
truncation: {
|
|
40
|
+
mode: 'drop_lower_tiers_then_global_utf8_trim',
|
|
41
|
+
budgetScope: 'shared_recovery_prompt',
|
|
42
|
+
antiReconstructionRule: 'select_order_and_compress_explicit_facts_only',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
const RESUME_PREVIEW_TIER_DEFINITIONS = [
|
|
46
|
+
{
|
|
47
|
+
tier: 'identity_context',
|
|
48
|
+
purpose: 'Surface the best concise identity hint for the session.',
|
|
49
|
+
priority: 0,
|
|
50
|
+
maxBytes: 320,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
tier: 'durable_recap',
|
|
54
|
+
purpose: 'Surface durable recap text, focused around the user query when possible.',
|
|
55
|
+
priority: 1,
|
|
56
|
+
maxBytes: 1600,
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
exports.RESUME_PREVIEW_CONTRACT = {
|
|
60
|
+
surface: 'resume_preview',
|
|
61
|
+
tiers: RESUME_PREVIEW_TIER_DEFINITIONS,
|
|
62
|
+
budgetBytes: constants_js_1.MAX_RESUME_PREVIEW_BYTES,
|
|
63
|
+
};
|
|
64
|
+
const encoder = new TextEncoder();
|
|
65
|
+
const decoder = new TextDecoder('utf-8');
|
|
66
|
+
function getTierPriority(tier) {
|
|
67
|
+
return exports.REHYDRATE_RETRIEVAL_CONTRACT.tiers.find((candidate) => candidate.tier === tier)?.priority ?? Number.MAX_SAFE_INTEGER;
|
|
68
|
+
}
|
|
69
|
+
function getTierRetention(tier) {
|
|
70
|
+
return exports.REHYDRATE_RETRIEVAL_CONTRACT.tiers.find((candidate) => candidate.tier === tier)?.retention ?? 'tail';
|
|
71
|
+
}
|
|
72
|
+
function getResumePreviewTierPriority(tier) {
|
|
73
|
+
return exports.RESUME_PREVIEW_CONTRACT.tiers.find((candidate) => candidate.tier === tier)?.priority ?? Number.MAX_SAFE_INTEGER;
|
|
74
|
+
}
|
|
75
|
+
function getResumePreviewTierMaxBytes(tier) {
|
|
76
|
+
return exports.RESUME_PREVIEW_CONTRACT.tiers.find((candidate) => candidate.tier === tier)?.maxBytes ?? exports.RESUME_PREVIEW_CONTRACT.budgetBytes;
|
|
77
|
+
}
|
|
78
|
+
function compareAscii(a, b) {
|
|
79
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
80
|
+
}
|
|
81
|
+
function trimToUtf8Boundary(bytes) {
|
|
82
|
+
const n = bytes.length;
|
|
83
|
+
if (n === 0)
|
|
84
|
+
return bytes;
|
|
85
|
+
let cont = 0;
|
|
86
|
+
for (let i = n - 1; i >= 0 && i >= n - 4; i--) {
|
|
87
|
+
const b = bytes[i];
|
|
88
|
+
if ((b & 192) === 128) {
|
|
89
|
+
cont++;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (cont === 0)
|
|
96
|
+
return bytes;
|
|
97
|
+
const leadByteIndex = n - cont - 1;
|
|
98
|
+
if (leadByteIndex < 0) {
|
|
99
|
+
return new Uint8Array(0);
|
|
100
|
+
}
|
|
101
|
+
const leadByte = bytes[leadByteIndex];
|
|
102
|
+
const expectedLen = (leadByte & 128) === 0 ? 1 :
|
|
103
|
+
(leadByte & 224) === 192 ? 2 :
|
|
104
|
+
(leadByte & 240) === 224 ? 3 :
|
|
105
|
+
(leadByte & 248) === 240 ? 4 :
|
|
106
|
+
0;
|
|
107
|
+
const actualLen = cont + 1;
|
|
108
|
+
if (expectedLen === 0 || expectedLen !== actualLen) {
|
|
109
|
+
return bytes.subarray(0, leadByteIndex);
|
|
110
|
+
}
|
|
111
|
+
return bytes;
|
|
112
|
+
}
|
|
113
|
+
function truncateUtf8(text, maxBytes) {
|
|
114
|
+
const bytes = encoder.encode(text);
|
|
115
|
+
if (bytes.length <= maxBytes) {
|
|
116
|
+
return text;
|
|
117
|
+
}
|
|
118
|
+
return decoder.decode(trimToUtf8Boundary(bytes.subarray(0, Math.max(0, maxBytes))));
|
|
119
|
+
}
|
|
120
|
+
function buildOmissionSuffix(omittedTierCount) {
|
|
121
|
+
const omissionLine = omittedTierCount > 0
|
|
122
|
+
? `\nOmitted ${omittedTierCount} lower-priority tier${omittedTierCount === 1 ? '' : 's'} due to budget constraints.`
|
|
123
|
+
: '\nOmitted recovery content due to budget constraints.';
|
|
124
|
+
return `${constants_js_1.TRUNCATION_MARKER}${omissionLine}`;
|
|
125
|
+
}
|
|
126
|
+
function trimFinalRecoveryText(text, omittedTierCount) {
|
|
127
|
+
const suffix = buildOmissionSuffix(omittedTierCount);
|
|
128
|
+
const maxContentBytes = constants_js_1.RECOVERY_BUDGET_BYTES - encoder.encode(suffix).length;
|
|
129
|
+
const truncated = truncateUtf8(text, maxContentBytes);
|
|
130
|
+
return truncated + suffix;
|
|
131
|
+
}
|
|
132
|
+
function normalizePreviewFocusTerms(focusTerms) {
|
|
133
|
+
return [...new Set(focusTerms.map((term) => term.trim().toLowerCase()).filter((term) => term.length >= 3))];
|
|
134
|
+
}
|
|
135
|
+
function findFocusIndex(text, focusTerms) {
|
|
136
|
+
if (focusTerms.length === 0)
|
|
137
|
+
return -1;
|
|
138
|
+
const lower = text.toLowerCase();
|
|
139
|
+
return focusTerms.reduce((bestIndex, term) => {
|
|
140
|
+
const idx = lower.indexOf(term);
|
|
141
|
+
if (idx === -1)
|
|
142
|
+
return bestIndex;
|
|
143
|
+
if (bestIndex === -1)
|
|
144
|
+
return idx;
|
|
145
|
+
return Math.min(bestIndex, idx);
|
|
146
|
+
}, -1);
|
|
147
|
+
}
|
|
148
|
+
function excerptAroundFocus(text, maxBytes, focusTerms) {
|
|
149
|
+
const focusIndex = findFocusIndex(text, focusTerms);
|
|
150
|
+
if (focusIndex === -1) {
|
|
151
|
+
const truncated = truncateUtf8(text, maxBytes);
|
|
152
|
+
return truncated.length < text.length ? `${truncated}...` : truncated;
|
|
153
|
+
}
|
|
154
|
+
const contextChars = Math.max(80, Math.floor(maxBytes / 4));
|
|
155
|
+
const start = Math.max(0, focusIndex - contextChars);
|
|
156
|
+
const end = Math.min(text.length, focusIndex + contextChars * 2);
|
|
157
|
+
const slice = text.slice(start, end).trim();
|
|
158
|
+
const prefix = start > 0 ? '...' : '';
|
|
159
|
+
const suffix = end < text.length ? '...' : '';
|
|
160
|
+
const excerpt = `${prefix}${slice}${suffix}`;
|
|
161
|
+
return truncateUtf8(excerpt, maxBytes);
|
|
162
|
+
}
|
|
163
|
+
function createBranchSummarySegment(body) {
|
|
164
|
+
const trimmed = body.trim();
|
|
165
|
+
return trimmed.length === 0
|
|
166
|
+
? null
|
|
167
|
+
: {
|
|
168
|
+
kind: 'branch_summary',
|
|
169
|
+
tier: 'structural_context',
|
|
170
|
+
source: 'deterministic_structure',
|
|
171
|
+
title: 'Branch Summary',
|
|
172
|
+
body: trimmed,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function createDownstreamRecapSegment(body) {
|
|
176
|
+
const trimmed = body.trim();
|
|
177
|
+
return trimmed.length === 0
|
|
178
|
+
? null
|
|
179
|
+
: {
|
|
180
|
+
kind: 'downstream_recap',
|
|
181
|
+
tier: 'structural_context',
|
|
182
|
+
source: 'explicit_durable_fact',
|
|
183
|
+
title: 'Downstream Recap (Preferred Branch)',
|
|
184
|
+
body: trimmed,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function createAncestryRecapSegment(body) {
|
|
188
|
+
const trimmed = body.trim();
|
|
189
|
+
return trimmed.length === 0
|
|
190
|
+
? null
|
|
191
|
+
: {
|
|
192
|
+
kind: 'ancestry_recap',
|
|
193
|
+
tier: 'durable_recap',
|
|
194
|
+
source: 'explicit_durable_fact',
|
|
195
|
+
title: 'Ancestry Recap',
|
|
196
|
+
body: trimmed,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function createFunctionDefinitionsSegment(body) {
|
|
200
|
+
const trimmed = body.trim();
|
|
201
|
+
return trimmed.length === 0
|
|
202
|
+
? null
|
|
203
|
+
: {
|
|
204
|
+
kind: 'function_definitions',
|
|
205
|
+
tier: 'reference_material',
|
|
206
|
+
source: 'workflow_definition',
|
|
207
|
+
title: 'Function Definitions',
|
|
208
|
+
body: trimmed,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function createSessionTitlePreviewSegment(body) {
|
|
212
|
+
const trimmed = body.trim();
|
|
213
|
+
return trimmed.length === 0
|
|
214
|
+
? null
|
|
215
|
+
: {
|
|
216
|
+
kind: 'session_title_preview',
|
|
217
|
+
tier: 'identity_context',
|
|
218
|
+
source: 'persisted_context',
|
|
219
|
+
body: trimmed,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function createRecapPreviewSegment(body) {
|
|
223
|
+
const trimmed = body.trim();
|
|
224
|
+
return trimmed.length === 0
|
|
225
|
+
? null
|
|
226
|
+
: {
|
|
227
|
+
kind: 'recap_preview',
|
|
228
|
+
tier: 'durable_recap',
|
|
229
|
+
source: 'explicit_durable_fact',
|
|
230
|
+
body: trimmed,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function compareRetrievalPackSegments(a, b) {
|
|
234
|
+
const tierDiff = getTierPriority(a.tier) - getTierPriority(b.tier);
|
|
235
|
+
if (tierDiff !== 0)
|
|
236
|
+
return tierDiff;
|
|
237
|
+
const titleDiff = compareAscii(a.title, b.title);
|
|
238
|
+
if (titleDiff !== 0)
|
|
239
|
+
return titleDiff;
|
|
240
|
+
return compareAscii(a.body, b.body);
|
|
241
|
+
}
|
|
242
|
+
function orderRetrievalPackSegments(segments) {
|
|
243
|
+
return [...segments].sort(compareRetrievalPackSegments);
|
|
244
|
+
}
|
|
245
|
+
function renderRetrievalPackSections(segments) {
|
|
246
|
+
return orderRetrievalPackSegments(segments).map((segment) => `### ${segment.title}\n${segment.body}`);
|
|
247
|
+
}
|
|
248
|
+
function compareResumePreviewSegments(a, b) {
|
|
249
|
+
const tierDiff = getResumePreviewTierPriority(a.tier) - getResumePreviewTierPriority(b.tier);
|
|
250
|
+
if (tierDiff !== 0)
|
|
251
|
+
return tierDiff;
|
|
252
|
+
return compareAscii(a.body, b.body);
|
|
253
|
+
}
|
|
254
|
+
function renderBudgetedResumePreview(args) {
|
|
255
|
+
const ordered = [...args.segments].sort(compareResumePreviewSegments);
|
|
256
|
+
if (ordered.length === 0) {
|
|
257
|
+
return { text: '', includedTiers: [] };
|
|
258
|
+
}
|
|
259
|
+
const focusTerms = normalizePreviewFocusTerms(args.focusTerms ?? []);
|
|
260
|
+
const tierTexts = ordered.map((segment) => {
|
|
261
|
+
const maxBytes = getResumePreviewTierMaxBytes(segment.tier);
|
|
262
|
+
return {
|
|
263
|
+
tier: segment.tier,
|
|
264
|
+
text: excerptAroundFocus(segment.body, maxBytes, focusTerms),
|
|
265
|
+
};
|
|
266
|
+
});
|
|
267
|
+
const joined = tierTexts.map((entry) => entry.text).filter((text) => text.length > 0).join('\n\n');
|
|
268
|
+
const finalText = truncateUtf8(joined, exports.RESUME_PREVIEW_CONTRACT.budgetBytes);
|
|
269
|
+
const includedTiers = [...new Set(tierTexts.filter((entry) => entry.text.length > 0).map((entry) => entry.tier))];
|
|
270
|
+
return { text: finalText, includedTiers };
|
|
271
|
+
}
|
|
272
|
+
function renderBudgetedRehydrateRecovery(args) {
|
|
273
|
+
const ordered = orderRetrievalPackSegments(args.segments);
|
|
274
|
+
if (ordered.length === 0) {
|
|
275
|
+
return { text: '', includedTiers: [], omittedTierCount: 0, truncatedWithinTier: false };
|
|
276
|
+
}
|
|
277
|
+
const tiersInOrder = exports.REHYDRATE_RETRIEVAL_CONTRACT.tiers.map((tier) => tier.tier);
|
|
278
|
+
const sectionsByTier = new Map(tiersInOrder.map((tier) => [tier, ordered.filter((segment) => segment.tier === tier).map((segment) => `### ${segment.title}\n${segment.body}`)]));
|
|
279
|
+
const renderFromTiers = (tiers) => {
|
|
280
|
+
const sections = tiers.flatMap((tier) => sectionsByTier.get(tier) ?? []);
|
|
281
|
+
return sections.length === 0 ? '' : `${args.header}\n\n${sections.join('\n\n')}`;
|
|
282
|
+
};
|
|
283
|
+
const initiallyIncludedTiers = tiersInOrder.filter((tier) => (sectionsByTier.get(tier) ?? []).length > 0);
|
|
284
|
+
let includedTiers = initiallyIncludedTiers;
|
|
285
|
+
let recoveryText = renderFromTiers(includedTiers);
|
|
286
|
+
while (encoder.encode(recoveryText).length > constants_js_1.RECOVERY_BUDGET_BYTES) {
|
|
287
|
+
const droppableTierIndex = [...includedTiers]
|
|
288
|
+
.reverse()
|
|
289
|
+
.findIndex((tier) => getTierRetention(tier) === 'tail');
|
|
290
|
+
if (droppableTierIndex === -1) {
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
const actualIndex = includedTiers.length - 1 - droppableTierIndex;
|
|
294
|
+
includedTiers = includedTiers.filter((_, index) => index !== actualIndex);
|
|
295
|
+
recoveryText = renderFromTiers(includedTiers);
|
|
296
|
+
}
|
|
297
|
+
const omittedTierCount = initiallyIncludedTiers.length - includedTiers.length;
|
|
298
|
+
const needsSuffix = omittedTierCount > 0 || encoder.encode(recoveryText).length > constants_js_1.RECOVERY_BUDGET_BYTES || includedTiers.length === 0;
|
|
299
|
+
const finalText = recoveryText.length === 0
|
|
300
|
+
? trimFinalRecoveryText(args.header, initiallyIncludedTiers.length)
|
|
301
|
+
: !needsSuffix
|
|
302
|
+
? recoveryText
|
|
303
|
+
: trimFinalRecoveryText(recoveryText, omittedTierCount);
|
|
304
|
+
return {
|
|
305
|
+
text: finalText,
|
|
306
|
+
includedTiers,
|
|
307
|
+
omittedTierCount,
|
|
308
|
+
truncatedWithinTier: encoder.encode(recoveryText).length > constants_js_1.RECOVERY_BUDGET_BYTES || includedTiers.length === 0,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
@@ -11,6 +11,7 @@ export declare function getOutputRequirementStatusWithArtifactsV1(args: {
|
|
|
11
11
|
readonly outputContract: OutputContract | undefined;
|
|
12
12
|
readonly artifacts: readonly unknown[];
|
|
13
13
|
readonly validationCriteria: ValidationCriteria | undefined;
|
|
14
|
+
readonly assessmentValidation?: ValidationResult;
|
|
14
15
|
readonly notesMarkdown: string | undefined;
|
|
15
16
|
readonly validation: ValidationResult | undefined;
|
|
16
17
|
}): OutputRequirementStatus;
|
|
@@ -4,6 +4,7 @@ exports.VALIDATION_CRITERIA_CONTRACT_REF = void 0;
|
|
|
4
4
|
exports.getOutputRequirementStatusV1 = getOutputRequirementStatusV1;
|
|
5
5
|
exports.getOutputRequirementStatusWithArtifactsV1 = getOutputRequirementStatusWithArtifactsV1;
|
|
6
6
|
const artifact_contract_validator_js_1 = require("./artifact-contract-validator.js");
|
|
7
|
+
const index_js_1 = require("../schemas/artifacts/index.js");
|
|
7
8
|
exports.VALIDATION_CRITERIA_CONTRACT_REF = 'wr.validationCriteria';
|
|
8
9
|
function getOutputRequirementStatusV1(args) {
|
|
9
10
|
if (!args.validationCriteria)
|
|
@@ -38,6 +39,16 @@ function getOutputRequirementStatusWithArtifactsV1(args) {
|
|
|
38
39
|
}
|
|
39
40
|
return { kind: 'satisfied' };
|
|
40
41
|
}
|
|
42
|
+
if (args.assessmentValidation) {
|
|
43
|
+
if (!args.assessmentValidation.valid) {
|
|
44
|
+
return {
|
|
45
|
+
kind: 'invalid',
|
|
46
|
+
contractRef: index_js_1.ASSESSMENT_CONTRACT_REF,
|
|
47
|
+
validation: args.assessmentValidation,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return { kind: 'satisfied' };
|
|
51
|
+
}
|
|
41
52
|
return getOutputRequirementStatusV1({
|
|
42
53
|
validationCriteria: args.validationCriteria,
|
|
43
54
|
notesMarkdown: args.notesMarkdown,
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const ASSESSMENT_CONTRACT_REF: "wr.contracts.assessment";
|
|
3
|
+
export declare const AssessmentDimensionSubmissionSchema: z.ZodUnion<[z.ZodString, z.ZodObject<{
|
|
4
|
+
level: z.ZodString;
|
|
5
|
+
rationale: z.ZodOptional<z.ZodString>;
|
|
6
|
+
}, "strict", z.ZodTypeAny, {
|
|
7
|
+
level: string;
|
|
8
|
+
rationale?: string | undefined;
|
|
9
|
+
}, {
|
|
10
|
+
level: string;
|
|
11
|
+
rationale?: string | undefined;
|
|
12
|
+
}>]>;
|
|
13
|
+
export type AssessmentDimensionSubmission = z.infer<typeof AssessmentDimensionSubmissionSchema>;
|
|
14
|
+
export declare const AssessmentArtifactV1Schema: z.ZodObject<{
|
|
15
|
+
kind: z.ZodLiteral<"wr.assessment">;
|
|
16
|
+
assessmentId: z.ZodOptional<z.ZodString>;
|
|
17
|
+
dimensions: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodObject<{
|
|
18
|
+
level: z.ZodString;
|
|
19
|
+
rationale: z.ZodOptional<z.ZodString>;
|
|
20
|
+
}, "strict", z.ZodTypeAny, {
|
|
21
|
+
level: string;
|
|
22
|
+
rationale?: string | undefined;
|
|
23
|
+
}, {
|
|
24
|
+
level: string;
|
|
25
|
+
rationale?: string | undefined;
|
|
26
|
+
}>]>>, Record<string, string | {
|
|
27
|
+
level: string;
|
|
28
|
+
rationale?: string | undefined;
|
|
29
|
+
}>, Record<string, string | {
|
|
30
|
+
level: string;
|
|
31
|
+
rationale?: string | undefined;
|
|
32
|
+
}>>;
|
|
33
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
34
|
+
}, "strict", z.ZodTypeAny, {
|
|
35
|
+
kind: "wr.assessment";
|
|
36
|
+
dimensions: Record<string, string | {
|
|
37
|
+
level: string;
|
|
38
|
+
rationale?: string | undefined;
|
|
39
|
+
}>;
|
|
40
|
+
assessmentId?: string | undefined;
|
|
41
|
+
summary?: string | undefined;
|
|
42
|
+
}, {
|
|
43
|
+
kind: "wr.assessment";
|
|
44
|
+
dimensions: Record<string, string | {
|
|
45
|
+
level: string;
|
|
46
|
+
rationale?: string | undefined;
|
|
47
|
+
}>;
|
|
48
|
+
assessmentId?: string | undefined;
|
|
49
|
+
summary?: string | undefined;
|
|
50
|
+
}>;
|
|
51
|
+
export type AssessmentArtifactV1 = z.infer<typeof AssessmentArtifactV1Schema>;
|
|
52
|
+
export declare function isAssessmentArtifact(artifact: unknown): artifact is {
|
|
53
|
+
readonly kind: 'wr.assessment';
|
|
54
|
+
};
|
|
55
|
+
export declare function parseAssessmentArtifact(artifact: unknown): AssessmentArtifactV1 | null;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AssessmentArtifactV1Schema = exports.AssessmentDimensionSubmissionSchema = exports.ASSESSMENT_CONTRACT_REF = void 0;
|
|
4
|
+
exports.isAssessmentArtifact = isAssessmentArtifact;
|
|
5
|
+
exports.parseAssessmentArtifact = parseAssessmentArtifact;
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
const MAX_ASSESSMENT_SUMMARY_LENGTH = 1024;
|
|
8
|
+
const MAX_DIMENSION_RATIONALE_LENGTH = 512;
|
|
9
|
+
exports.ASSESSMENT_CONTRACT_REF = 'wr.contracts.assessment';
|
|
10
|
+
exports.AssessmentDimensionSubmissionSchema = zod_1.z.union([
|
|
11
|
+
zod_1.z.string().min(1),
|
|
12
|
+
zod_1.z.object({
|
|
13
|
+
level: zod_1.z.string().min(1),
|
|
14
|
+
rationale: zod_1.z.string().min(1).max(MAX_DIMENSION_RATIONALE_LENGTH).optional(),
|
|
15
|
+
}).strict(),
|
|
16
|
+
]);
|
|
17
|
+
exports.AssessmentArtifactV1Schema = zod_1.z.object({
|
|
18
|
+
kind: zod_1.z.literal('wr.assessment'),
|
|
19
|
+
assessmentId: zod_1.z.string().min(1).max(64).optional(),
|
|
20
|
+
dimensions: zod_1.z.record(exports.AssessmentDimensionSubmissionSchema).refine((value) => Object.keys(value).length > 0, 'dimensions must contain at least one entry'),
|
|
21
|
+
summary: zod_1.z.string().max(MAX_ASSESSMENT_SUMMARY_LENGTH).optional(),
|
|
22
|
+
}).strict();
|
|
23
|
+
function isAssessmentArtifact(artifact) {
|
|
24
|
+
return typeof artifact === 'object' && artifact !== null && artifact.kind === 'wr.assessment';
|
|
25
|
+
}
|
|
26
|
+
function parseAssessmentArtifact(artifact) {
|
|
27
|
+
const result = exports.AssessmentArtifactV1Schema.safeParse(artifact);
|
|
28
|
+
return result.success ? result.data : null;
|
|
29
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
export { ASSESSMENT_CONTRACT_REF, AssessmentArtifactV1Schema, AssessmentDimensionSubmissionSchema, isAssessmentArtifact, parseAssessmentArtifact, type AssessmentArtifactV1, type AssessmentDimensionSubmission, } from './assessment.js';
|
|
1
2
|
export { LOOP_CONTROL_CONTRACT_REF, LoopControlDecisionSchema, LoopControlMetadataV1Schema, LoopControlArtifactV1Schema, isLoopControlArtifact, parseLoopControlArtifact, findLoopControlArtifact, type LoopControlDecision, type LoopControlMetadataV1, type LoopControlArtifactV1, } from './loop-control.js';
|
|
2
|
-
export declare const ARTIFACT_CONTRACT_REFS: readonly ["wr.contracts.loop_control"];
|
|
3
|
+
export declare const ARTIFACT_CONTRACT_REFS: readonly ["wr.contracts.assessment", "wr.contracts.loop_control"];
|
|
3
4
|
export type ArtifactContractRef = (typeof ARTIFACT_CONTRACT_REFS)[number];
|
|
4
5
|
export declare function isValidContractRef(ref: string): ref is ArtifactContractRef;
|