@superdoc-dev/sdk 1.19.2 → 1.20.1
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/action-primitives/doc-index.cjs +215 -0
- package/dist/action-primitives/doc-index.d.ts +83 -0
- package/dist/action-primitives/doc-index.d.ts.map +1 -0
- package/dist/action-primitives/doc-index.js +211 -0
- package/dist/action-primitives/engine.cjs +204 -0
- package/dist/action-primitives/engine.d.ts +71 -0
- package/dist/action-primitives/engine.d.ts.map +1 -0
- package/dist/action-primitives/engine.js +196 -0
- package/dist/action-primitives/receipt.cjs +39 -0
- package/dist/action-primitives/receipt.d.ts +49 -0
- package/dist/action-primitives/receipt.d.ts.map +1 -0
- package/dist/action-primitives/receipt.js +32 -0
- package/dist/action-primitives/resolve.cjs +252 -0
- package/dist/action-primitives/resolve.d.ts +56 -0
- package/dist/action-primitives/resolve.d.ts.map +1 -0
- package/dist/action-primitives/resolve.js +246 -0
- package/dist/action-primitives/session-cache.cjs +43 -0
- package/dist/action-primitives/session-cache.d.ts +19 -0
- package/dist/action-primitives/session-cache.d.ts.map +1 -0
- package/dist/action-primitives/session-cache.js +37 -0
- package/dist/action-primitives/tools/list-transform.cjs +661 -0
- package/dist/action-primitives/tools/list-transform.d.ts +98 -0
- package/dist/action-primitives/tools/list-transform.d.ts.map +1 -0
- package/dist/action-primitives/tools/list-transform.js +656 -0
- package/dist/action-primitives/tools/structure-insert.cjs +1343 -0
- package/dist/action-primitives/tools/structure-insert.d.ts +183 -0
- package/dist/action-primitives/tools/structure-insert.d.ts.map +1 -0
- package/dist/action-primitives/tools/structure-insert.js +1338 -0
- package/dist/action-primitives/tools/text-transform.cjs +669 -0
- package/dist/action-primitives/tools/text-transform.d.ts +64 -0
- package/dist/action-primitives/tools/text-transform.d.ts.map +1 -0
- package/dist/action-primitives/tools/text-transform.js +664 -0
- package/dist/action-primitives/types.d.ts +36 -0
- package/dist/action-primitives/types.d.ts.map +1 -0
- package/dist/action-primitives/types.js +15 -0
- package/dist/agent/actions.cjs +5381 -0
- package/dist/agent/actions.d.ts +404 -0
- package/dist/agent/actions.d.ts.map +1 -0
- package/dist/agent/actions.js +5373 -0
- package/dist/agent/catalog.cjs +483 -0
- package/dist/agent/catalog.d.ts +103 -0
- package/dist/agent/catalog.d.ts.map +1 -0
- package/dist/agent/catalog.js +471 -0
- package/dist/agent/doc-snapshot.cjs +663 -0
- package/dist/agent/doc-snapshot.d.ts +247 -0
- package/dist/agent/doc-snapshot.d.ts.map +1 -0
- package/dist/agent/doc-snapshot.js +657 -0
- package/dist/agent/index.d.ts +16 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +15 -0
- package/dist/agent/ir.cjs +170 -0
- package/dist/agent/ir.d.ts +216 -0
- package/dist/agent/ir.d.ts.map +1 -0
- package/dist/agent/ir.js +181 -0
- package/dist/agent/operation-catalog.cjs +418 -0
- package/dist/agent/operation-catalog.d.ts +36 -0
- package/dist/agent/operation-catalog.d.ts.map +1 -0
- package/dist/agent/operation-catalog.js +446 -0
- package/dist/agent/runtime.cjs +501 -0
- package/dist/agent/runtime.d.ts +120 -0
- package/dist/agent/runtime.d.ts.map +1 -0
- package/dist/agent/runtime.js +493 -0
- package/dist/embedded-prompts.generated.cjs +13 -0
- package/dist/embedded-prompts.generated.d.ts +4 -0
- package/dist/embedded-prompts.generated.d.ts.map +1 -0
- package/dist/embedded-prompts.generated.js +9 -0
- package/dist/generated/client.cjs +18 -0
- package/dist/generated/client.d.ts +134 -0
- package/dist/generated/client.d.ts.map +1 -1
- package/dist/generated/client.js +18 -0
- package/dist/generated/contract.cjs +622 -3
- package/dist/generated/contract.d.ts.map +1 -1
- package/dist/generated/contract.js +622 -3
- package/dist/index.cjs +3 -7
- package/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -8
- package/dist/presets/core.cjs +454 -0
- package/dist/presets/core.d.ts +20 -0
- package/dist/presets/core.d.ts.map +1 -0
- package/dist/presets/core.js +447 -0
- package/dist/presets.cjs +55 -8
- package/dist/presets.d.ts +39 -8
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +53 -8
- package/dist/prompts/mcp-prompt.md +23 -0
- package/dist/prompts/system-prompt.md +108 -0
- package/dist/runtime/transport-common.cjs +8 -0
- package/dist/runtime/transport-common.d.ts.map +1 -1
- package/dist/runtime/transport-common.js +8 -0
- package/dist/tools.cjs +46 -11
- package/dist/tools.d.ts +55 -8
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +45 -13
- package/package.json +9 -8
- package/tools/__pycache__/__init__.cpython-312.pyc +0 -0
- package/tools/__pycache__/intent_dispatch_generated.cpython-312.pyc +0 -0
- package/tools/catalog.json +14 -0
- package/tools/tools-policy.json +1 -1
- package/tools/tools.anthropic.json +14 -0
- package/tools/tools.generic.json +14 -0
- package/tools/tools.openai.json +14 -0
- package/tools/tools.vercel.json +14 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clean DOCX agent runtime.
|
|
3
|
+
*
|
|
4
|
+
* This barrel exposes the four product-stable agent tool entry points
|
|
5
|
+
* (inspect, apply, verify, operation) plus the IR types and the
|
|
6
|
+
* contract-derived operation catalog. Consumers should depend on this
|
|
7
|
+
* barrel — never reach into the benchmark `workflow-poc` profile from
|
|
8
|
+
* product code.
|
|
9
|
+
*/
|
|
10
|
+
export { AGENT_TOOL_DEFINITIONS, AGENT_TOOL_NAMES, isAgentToolName, listAgentTools, } from './catalog.js';
|
|
11
|
+
export { agentInspect, agentApply, agentVerify, agentOperation, } from './runtime.js';
|
|
12
|
+
export { validatePlan, isApplyStep, isInspectStep, isSelectStep, isVerifyStep, } from './ir.js';
|
|
13
|
+
export { OPERATION_CATALOG, getOperationCatalogEntry, getOperationCatalogSummary, listMutatingOperations, listOperationsByDomain, listOperationsMissingStructuralVerification, } from './operation-catalog.js';
|
|
14
|
+
export { AmbiguousSelectorError, buildDocumentSnapshot, resolveSnapshotSelector, } from './doc-snapshot.js';
|
|
15
|
+
export { superdocPerformAction, isActionName, ACTION_NAMES_LIST, } from './actions.js';
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var operationCatalog = require('./operation-catalog.cjs');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Clean agent IR.
|
|
7
|
+
*
|
|
8
|
+
* The IR makes the four phases of an agent edit explicit:
|
|
9
|
+
*
|
|
10
|
+
* inspect -> select -> apply -> verify
|
|
11
|
+
*
|
|
12
|
+
* Every mutation a stable agent runtime path produces must be expressible as
|
|
13
|
+
* an `AgentPlan` whose steps reference real entries in the generated
|
|
14
|
+
* operation catalog. There is no prompt-derived execution contract: the IR is
|
|
15
|
+
* the only contract.
|
|
16
|
+
*
|
|
17
|
+
* Selectors are deterministic — they resolve to concrete blocks/ranges by
|
|
18
|
+
* ordinal, ref, nodeId, or named entity. Ambiguity is returned as a
|
|
19
|
+
* structured error so the agent must clarify rather than silently picking.
|
|
20
|
+
*
|
|
21
|
+
* Apply steps reference a generated `doc.*` operation id and carry the
|
|
22
|
+
* arguments the operation expects. The validator enforces that the operation
|
|
23
|
+
* id exists in the catalog, that it is the right mode for the requested
|
|
24
|
+
* intent (read vs write), and that arguments do not include reserved
|
|
25
|
+
* runtime keys.
|
|
26
|
+
*
|
|
27
|
+
* Verify steps describe the post-conditions the runtime must prove before
|
|
28
|
+
* declaring success. For risky domains (sections, protection,
|
|
29
|
+
* permission-ranges) the runtime additionally captures save/reopen evidence.
|
|
30
|
+
*/
|
|
31
|
+
const RESERVED_ARG_KEYS = new Set(['sessionId', 'doc']);
|
|
32
|
+
function isSelectorValid(selector) {
|
|
33
|
+
switch (selector.kind) {
|
|
34
|
+
case 'ref':
|
|
35
|
+
return typeof selector.ref === 'string' && selector.ref.length > 0;
|
|
36
|
+
case 'nodeId':
|
|
37
|
+
return typeof selector.nodeId === 'string' && selector.nodeId.length > 0;
|
|
38
|
+
case 'ordinal':
|
|
39
|
+
return Number.isInteger(selector.value) && selector.value >= 1;
|
|
40
|
+
case 'tableCell':
|
|
41
|
+
return (Number.isInteger(selector.tableOrdinal) &&
|
|
42
|
+
selector.tableOrdinal >= 1 &&
|
|
43
|
+
Number.isInteger(selector.rowIndex) &&
|
|
44
|
+
selector.rowIndex >= 0 &&
|
|
45
|
+
Number.isInteger(selector.columnIndex) &&
|
|
46
|
+
selector.columnIndex >= 0);
|
|
47
|
+
case 'textSearch':
|
|
48
|
+
return (Array.isArray(selector.terms) &&
|
|
49
|
+
selector.terms.length > 0 &&
|
|
50
|
+
selector.terms.every((term) => typeof term === 'string' && term.length > 0) &&
|
|
51
|
+
(selector.match == null || selector.match === 'all' || selector.match === 'any') &&
|
|
52
|
+
(selector.occurrence == null || (Number.isInteger(selector.occurrence) && selector.occurrence >= 1)));
|
|
53
|
+
case 'entity':
|
|
54
|
+
return typeof selector.entityId === 'string' && selector.entityId.length > 0;
|
|
55
|
+
case 'placement':
|
|
56
|
+
return selector.at === 'document_start' || selector.at === 'document_end';
|
|
57
|
+
case 'relative':
|
|
58
|
+
return (selector.position === 'before' || selector.position === 'after') && isSelectorValid(selector.target);
|
|
59
|
+
case 'document':
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function validatePlan(plan) {
|
|
64
|
+
const errors = [];
|
|
65
|
+
const references = [];
|
|
66
|
+
if (!plan.steps || plan.steps.length === 0) {
|
|
67
|
+
errors.push({ code: 'EMPTY_PLAN', message: 'Plan must contain at least one step.' });
|
|
68
|
+
return { ok: false, errors, references };
|
|
69
|
+
}
|
|
70
|
+
let hasApply = false;
|
|
71
|
+
let hasVerify = false;
|
|
72
|
+
let hasMutatingApply = false;
|
|
73
|
+
plan.steps.forEach((step, index) => {
|
|
74
|
+
switch (step.kind) {
|
|
75
|
+
case 'inspect': {
|
|
76
|
+
const entry = operationCatalog.getOperationCatalogEntry(step.operationId);
|
|
77
|
+
if (!entry) {
|
|
78
|
+
errors.push({
|
|
79
|
+
code: 'UNKNOWN_OPERATION',
|
|
80
|
+
message: `Inspect step references unknown operation: ${step.operationId}.`,
|
|
81
|
+
stepIndex: index,
|
|
82
|
+
operationId: step.operationId,
|
|
83
|
+
});
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
if (entry.mode === 'write') {
|
|
87
|
+
errors.push({
|
|
88
|
+
code: 'WRONG_OPERATION_MODE',
|
|
89
|
+
message: `Inspect step ${step.operationId} must use a read-mode operation.`,
|
|
90
|
+
stepIndex: index,
|
|
91
|
+
operationId: step.operationId,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
for (const key of Object.keys(step.args)) {
|
|
95
|
+
if (RESERVED_ARG_KEYS.has(key)) {
|
|
96
|
+
errors.push({
|
|
97
|
+
code: 'RESERVED_ARG_KEY',
|
|
98
|
+
message: `Reserved key "${key}" must not appear in IR args.`,
|
|
99
|
+
stepIndex: index,
|
|
100
|
+
operationId: step.operationId,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
references.push(entry);
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
case 'select': {
|
|
108
|
+
if (!isSelectorValid(step.selector)) {
|
|
109
|
+
errors.push({
|
|
110
|
+
code: 'INVALID_SELECTOR',
|
|
111
|
+
message: `Select step has invalid selector at index ${index}.`,
|
|
112
|
+
stepIndex: index,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case 'apply': {
|
|
118
|
+
hasApply = true;
|
|
119
|
+
const entry = operationCatalog.getOperationCatalogEntry(step.operationId);
|
|
120
|
+
if (!entry) {
|
|
121
|
+
errors.push({
|
|
122
|
+
code: 'UNKNOWN_OPERATION',
|
|
123
|
+
message: `Apply step references unknown operation: ${step.operationId}.`,
|
|
124
|
+
stepIndex: index,
|
|
125
|
+
operationId: step.operationId,
|
|
126
|
+
});
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
if (entry.mode === 'read') {
|
|
130
|
+
errors.push({
|
|
131
|
+
code: 'WRONG_OPERATION_MODE',
|
|
132
|
+
message: `Apply step ${step.operationId} must use a write-mode operation.`,
|
|
133
|
+
stepIndex: index,
|
|
134
|
+
operationId: step.operationId,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
if (entry.isMutating)
|
|
138
|
+
hasMutatingApply = true;
|
|
139
|
+
for (const key of Object.keys(step.args)) {
|
|
140
|
+
if (RESERVED_ARG_KEYS.has(key)) {
|
|
141
|
+
errors.push({
|
|
142
|
+
code: 'RESERVED_ARG_KEY',
|
|
143
|
+
message: `Reserved key "${key}" must not appear in IR args.`,
|
|
144
|
+
stepIndex: index,
|
|
145
|
+
operationId: step.operationId,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
references.push(entry);
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case 'verify': {
|
|
153
|
+
hasVerify = true;
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
if (!hasApply) {
|
|
159
|
+
errors.push({ code: 'MISSING_APPLY_STEP', message: 'Plan must contain at least one apply step.' });
|
|
160
|
+
}
|
|
161
|
+
if (hasMutatingApply && !hasVerify) {
|
|
162
|
+
errors.push({
|
|
163
|
+
code: 'MISSING_VERIFY_STEP',
|
|
164
|
+
message: 'Mutating plans must include a verify step with explicit checks.',
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return { ok: errors.length === 0, errors, references };
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
exports.validatePlan = validatePlan;
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clean agent IR.
|
|
3
|
+
*
|
|
4
|
+
* The IR makes the four phases of an agent edit explicit:
|
|
5
|
+
*
|
|
6
|
+
* inspect -> select -> apply -> verify
|
|
7
|
+
*
|
|
8
|
+
* Every mutation a stable agent runtime path produces must be expressible as
|
|
9
|
+
* an `AgentPlan` whose steps reference real entries in the generated
|
|
10
|
+
* operation catalog. There is no prompt-derived execution contract: the IR is
|
|
11
|
+
* the only contract.
|
|
12
|
+
*
|
|
13
|
+
* Selectors are deterministic — they resolve to concrete blocks/ranges by
|
|
14
|
+
* ordinal, ref, nodeId, or named entity. Ambiguity is returned as a
|
|
15
|
+
* structured error so the agent must clarify rather than silently picking.
|
|
16
|
+
*
|
|
17
|
+
* Apply steps reference a generated `doc.*` operation id and carry the
|
|
18
|
+
* arguments the operation expects. The validator enforces that the operation
|
|
19
|
+
* id exists in the catalog, that it is the right mode for the requested
|
|
20
|
+
* intent (read vs write), and that arguments do not include reserved
|
|
21
|
+
* runtime keys.
|
|
22
|
+
*
|
|
23
|
+
* Verify steps describe the post-conditions the runtime must prove before
|
|
24
|
+
* declaring success. For risky domains (sections, protection,
|
|
25
|
+
* permission-ranges) the runtime additionally captures save/reopen evidence.
|
|
26
|
+
*/
|
|
27
|
+
import { type OperationCatalogEntry } from './operation-catalog.js';
|
|
28
|
+
export type AgentSelector = {
|
|
29
|
+
kind: 'ref';
|
|
30
|
+
ref: string;
|
|
31
|
+
} | {
|
|
32
|
+
kind: 'nodeId';
|
|
33
|
+
nodeId: string;
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'ordinal';
|
|
36
|
+
ordinalKind: AgentOrdinalKind;
|
|
37
|
+
value: number;
|
|
38
|
+
} | {
|
|
39
|
+
kind: 'tableCell';
|
|
40
|
+
tableOrdinal: number;
|
|
41
|
+
rowIndex: number;
|
|
42
|
+
columnIndex: number;
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'textSearch';
|
|
45
|
+
terms: readonly string[];
|
|
46
|
+
match?: 'all' | 'any';
|
|
47
|
+
occurrence?: number;
|
|
48
|
+
caseSensitive?: boolean;
|
|
49
|
+
nodeTypes?: readonly ('paragraph' | 'heading' | 'listItem')[];
|
|
50
|
+
} | {
|
|
51
|
+
kind: 'entity';
|
|
52
|
+
entityType: AgentEntityKind;
|
|
53
|
+
entityId: string;
|
|
54
|
+
} | {
|
|
55
|
+
kind: 'document';
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'placement';
|
|
58
|
+
at: 'document_start' | 'document_end';
|
|
59
|
+
} | {
|
|
60
|
+
kind: 'relative';
|
|
61
|
+
position: 'before' | 'after';
|
|
62
|
+
target: AgentSelector;
|
|
63
|
+
};
|
|
64
|
+
export type AgentOrdinalKind = 'blockOrdinal' | 'paragraphOrdinal' | 'bodyParagraphOrdinal' | 'headingOrdinal' | 'listOrdinal' | 'tableOrdinal' | 'sectionOrdinal';
|
|
65
|
+
export type AgentEntityKind = 'comment' | 'trackedChange' | 'bookmark' | 'image' | 'hyperlink' | 'field';
|
|
66
|
+
export type AgentChangeMode = 'direct' | 'tracked';
|
|
67
|
+
export type AgentVerificationCheck = {
|
|
68
|
+
kind: 'block-text-contains';
|
|
69
|
+
nodeId: string;
|
|
70
|
+
text: string;
|
|
71
|
+
} | {
|
|
72
|
+
kind: 'block-text-equals';
|
|
73
|
+
nodeId: string;
|
|
74
|
+
text: string;
|
|
75
|
+
} | {
|
|
76
|
+
kind: 'block-count-delta';
|
|
77
|
+
nodeType: string;
|
|
78
|
+
delta: number;
|
|
79
|
+
} | {
|
|
80
|
+
kind: 'list-item-count';
|
|
81
|
+
listId?: string;
|
|
82
|
+
expected: number;
|
|
83
|
+
} | {
|
|
84
|
+
kind: 'table-shape';
|
|
85
|
+
nodeId: string;
|
|
86
|
+
rows: number;
|
|
87
|
+
columns: number;
|
|
88
|
+
} | {
|
|
89
|
+
kind: 'comment-count-delta';
|
|
90
|
+
delta: number;
|
|
91
|
+
} | {
|
|
92
|
+
kind: 'tracked-change-count-delta';
|
|
93
|
+
delta: number;
|
|
94
|
+
} | {
|
|
95
|
+
kind: 'image-anchor-present';
|
|
96
|
+
imageId?: string;
|
|
97
|
+
} | {
|
|
98
|
+
kind: 'revision-changed';
|
|
99
|
+
} | {
|
|
100
|
+
kind: 'revision-unchanged';
|
|
101
|
+
} | {
|
|
102
|
+
kind: 'document-saves-cleanly';
|
|
103
|
+
} | {
|
|
104
|
+
kind: 'save-reopen-text-contains';
|
|
105
|
+
text: string;
|
|
106
|
+
} | {
|
|
107
|
+
kind: 'block-text-matches-expectation';
|
|
108
|
+
} | {
|
|
109
|
+
kind: 'list-kind-equals';
|
|
110
|
+
expected: string;
|
|
111
|
+
} | {
|
|
112
|
+
kind: 'range-converted';
|
|
113
|
+
expected: number;
|
|
114
|
+
} | {
|
|
115
|
+
kind: 'paragraphs-form-one-list';
|
|
116
|
+
expected: number;
|
|
117
|
+
} | {
|
|
118
|
+
kind: 'single-list-with-expected-items';
|
|
119
|
+
expected: number;
|
|
120
|
+
} | {
|
|
121
|
+
kind: 'items-form-one-list';
|
|
122
|
+
expected: number;
|
|
123
|
+
} | {
|
|
124
|
+
kind: 'placement-honored';
|
|
125
|
+
at: string;
|
|
126
|
+
anchorNodeId: string;
|
|
127
|
+
} | {
|
|
128
|
+
kind: 'marker-restored';
|
|
129
|
+
marker: string;
|
|
130
|
+
} | {
|
|
131
|
+
kind: 'steps-undone';
|
|
132
|
+
} | {
|
|
133
|
+
kind: 'marker-rendered';
|
|
134
|
+
} | {
|
|
135
|
+
kind: 'block-style-equals';
|
|
136
|
+
styleId: string;
|
|
137
|
+
};
|
|
138
|
+
export type AgentInspectStep = {
|
|
139
|
+
kind: 'inspect';
|
|
140
|
+
/**
|
|
141
|
+
* `read`-mode catalog operation used to gather inspection data. e.g.
|
|
142
|
+
* `doc.info`, `doc.blocks.list`, `doc.tables.get`.
|
|
143
|
+
*/
|
|
144
|
+
operationId: string;
|
|
145
|
+
args: Record<string, unknown>;
|
|
146
|
+
/** Optional alias used by later steps to reference the inspection result. */
|
|
147
|
+
bind?: string;
|
|
148
|
+
};
|
|
149
|
+
export type AgentSelectStep = {
|
|
150
|
+
kind: 'select';
|
|
151
|
+
selector: AgentSelector;
|
|
152
|
+
/** Optional alias used by later steps to reference the resolved selector. */
|
|
153
|
+
bind?: string;
|
|
154
|
+
/**
|
|
155
|
+
* When true, the selector must resolve uniquely. Multiple matches are
|
|
156
|
+
* reported as a structured AMBIGUOUS_SELECTOR error and the plan halts.
|
|
157
|
+
*/
|
|
158
|
+
requireUnique?: boolean;
|
|
159
|
+
};
|
|
160
|
+
export type AgentApplyStep = {
|
|
161
|
+
kind: 'apply';
|
|
162
|
+
operationId: string;
|
|
163
|
+
args: Record<string, unknown>;
|
|
164
|
+
/** Optional human-readable rationale included in receipts for auditability. */
|
|
165
|
+
rationale?: string;
|
|
166
|
+
changeMode?: AgentChangeMode;
|
|
167
|
+
/** True for plans that must run as a single atomic batch. */
|
|
168
|
+
atomic?: boolean;
|
|
169
|
+
};
|
|
170
|
+
export type AgentVerifyStep = {
|
|
171
|
+
kind: 'verify';
|
|
172
|
+
checks: readonly AgentVerificationCheck[];
|
|
173
|
+
/** When true, the runtime must save and re-open the document and re-run the checks. */
|
|
174
|
+
saveReopen?: boolean;
|
|
175
|
+
};
|
|
176
|
+
export type AgentPlanStep = AgentInspectStep | AgentSelectStep | AgentApplyStep | AgentVerifyStep;
|
|
177
|
+
export type AgentPlan = {
|
|
178
|
+
intent: string;
|
|
179
|
+
steps: readonly AgentPlanStep[];
|
|
180
|
+
/** Optional plain-language preconditions evaluated before execution. */
|
|
181
|
+
preconditions?: readonly string[];
|
|
182
|
+
/** Optional plain-language postconditions used for evidence reporting. */
|
|
183
|
+
postconditions?: readonly string[];
|
|
184
|
+
/** When true, the entire plan must be applied atomically. */
|
|
185
|
+
atomic?: boolean;
|
|
186
|
+
/** Expected diff summary (informational; used in receipts). */
|
|
187
|
+
expectedDiff?: {
|
|
188
|
+
blocksAdded?: number;
|
|
189
|
+
blocksRemoved?: number;
|
|
190
|
+
textReplacements?: number;
|
|
191
|
+
commentsAdded?: number;
|
|
192
|
+
trackedChangesAdded?: number;
|
|
193
|
+
};
|
|
194
|
+
};
|
|
195
|
+
export type IrValidationError = {
|
|
196
|
+
code: 'UNKNOWN_OPERATION' | 'WRONG_OPERATION_MODE' | 'MISSING_VERIFY_STEP' | 'MISSING_APPLY_STEP' | 'RESERVED_ARG_KEY' | 'INVALID_SELECTOR' | 'EMPTY_PLAN';
|
|
197
|
+
message: string;
|
|
198
|
+
stepIndex?: number;
|
|
199
|
+
operationId?: string;
|
|
200
|
+
};
|
|
201
|
+
export type IrValidationResult = {
|
|
202
|
+
ok: boolean;
|
|
203
|
+
errors: readonly IrValidationError[];
|
|
204
|
+
/** Catalog entries referenced by the plan, in order. */
|
|
205
|
+
references: readonly OperationCatalogEntry[];
|
|
206
|
+
};
|
|
207
|
+
export declare function validatePlan(plan: AgentPlan): IrValidationResult;
|
|
208
|
+
/**
|
|
209
|
+
* Tagged-union narrowing helper used by runtimes and tests. Keeps the IR types
|
|
210
|
+
* the single source of truth for step discrimination.
|
|
211
|
+
*/
|
|
212
|
+
export declare function isApplyStep(step: AgentPlanStep): step is AgentApplyStep;
|
|
213
|
+
export declare function isVerifyStep(step: AgentPlanStep): step is AgentVerifyStep;
|
|
214
|
+
export declare function isInspectStep(step: AgentPlanStep): step is AgentInspectStep;
|
|
215
|
+
export declare function isSelectStep(step: AgentPlanStep): step is AgentSelectStep;
|
|
216
|
+
//# sourceMappingURL=ir.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ir.d.ts","sourceRoot":"","sources":["../../src/agent/ir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAA4B,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE9F,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,WAAW,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAClF;IACE,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC,EAAE,CAAC;CAC/D,GACD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,eAAe,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,gBAAgB,GAAG,cAAc,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC;AAE9E,MAAM,MAAM,gBAAgB,GACxB,cAAc,GACd,kBAAkB,GAClB,sBAAsB,GACtB,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,gBAAgB,CAAC;AAErB,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,eAAe,GAAG,UAAU,GAAG,OAAO,GAAG,WAAW,GAAG,OAAO,CAAC;AAEzG,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEnD,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,4BAA4B,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,oBAAoB,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,wBAAwB,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,2BAA2B,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAEnD;IAAE,IAAI,EAAE,gCAAgC,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,0BAA0B,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,iCAAiC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,aAAa,CAAC;IACxB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,6DAA6D;IAC7D,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAC1C,uFAAuF;IACvF,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG,eAAe,GAAG,cAAc,GAAG,eAAe,CAAC;AAElG,MAAM,MAAM,SAAS,GAAG;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC,wEAAwE;IACxE,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,0EAA0E;IAC1E,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,+DAA+D;IAC/D,YAAY,CAAC,EAAE;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EACA,mBAAmB,GACnB,sBAAsB,GACtB,qBAAqB,GACrB,oBAAoB,GACpB,kBAAkB,GAClB,kBAAkB,GAClB,YAAY,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACrC,wDAAwD;IACxD,UAAU,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC9C,CAAC;AAwCF,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,kBAAkB,CA6GhE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,IAAI,cAAc,CAEvE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,IAAI,eAAe,CAEzE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,IAAI,gBAAgB,CAE3E;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,IAAI,eAAe,CAEzE"}
|
package/dist/agent/ir.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clean agent IR.
|
|
3
|
+
*
|
|
4
|
+
* The IR makes the four phases of an agent edit explicit:
|
|
5
|
+
*
|
|
6
|
+
* inspect -> select -> apply -> verify
|
|
7
|
+
*
|
|
8
|
+
* Every mutation a stable agent runtime path produces must be expressible as
|
|
9
|
+
* an `AgentPlan` whose steps reference real entries in the generated
|
|
10
|
+
* operation catalog. There is no prompt-derived execution contract: the IR is
|
|
11
|
+
* the only contract.
|
|
12
|
+
*
|
|
13
|
+
* Selectors are deterministic — they resolve to concrete blocks/ranges by
|
|
14
|
+
* ordinal, ref, nodeId, or named entity. Ambiguity is returned as a
|
|
15
|
+
* structured error so the agent must clarify rather than silently picking.
|
|
16
|
+
*
|
|
17
|
+
* Apply steps reference a generated `doc.*` operation id and carry the
|
|
18
|
+
* arguments the operation expects. The validator enforces that the operation
|
|
19
|
+
* id exists in the catalog, that it is the right mode for the requested
|
|
20
|
+
* intent (read vs write), and that arguments do not include reserved
|
|
21
|
+
* runtime keys.
|
|
22
|
+
*
|
|
23
|
+
* Verify steps describe the post-conditions the runtime must prove before
|
|
24
|
+
* declaring success. For risky domains (sections, protection,
|
|
25
|
+
* permission-ranges) the runtime additionally captures save/reopen evidence.
|
|
26
|
+
*/
|
|
27
|
+
import { getOperationCatalogEntry } from './operation-catalog.js';
|
|
28
|
+
const RESERVED_ARG_KEYS = new Set(['sessionId', 'doc']);
|
|
29
|
+
function isSelectorValid(selector) {
|
|
30
|
+
switch (selector.kind) {
|
|
31
|
+
case 'ref':
|
|
32
|
+
return typeof selector.ref === 'string' && selector.ref.length > 0;
|
|
33
|
+
case 'nodeId':
|
|
34
|
+
return typeof selector.nodeId === 'string' && selector.nodeId.length > 0;
|
|
35
|
+
case 'ordinal':
|
|
36
|
+
return Number.isInteger(selector.value) && selector.value >= 1;
|
|
37
|
+
case 'tableCell':
|
|
38
|
+
return (Number.isInteger(selector.tableOrdinal) &&
|
|
39
|
+
selector.tableOrdinal >= 1 &&
|
|
40
|
+
Number.isInteger(selector.rowIndex) &&
|
|
41
|
+
selector.rowIndex >= 0 &&
|
|
42
|
+
Number.isInteger(selector.columnIndex) &&
|
|
43
|
+
selector.columnIndex >= 0);
|
|
44
|
+
case 'textSearch':
|
|
45
|
+
return (Array.isArray(selector.terms) &&
|
|
46
|
+
selector.terms.length > 0 &&
|
|
47
|
+
selector.terms.every((term) => typeof term === 'string' && term.length > 0) &&
|
|
48
|
+
(selector.match == null || selector.match === 'all' || selector.match === 'any') &&
|
|
49
|
+
(selector.occurrence == null || (Number.isInteger(selector.occurrence) && selector.occurrence >= 1)));
|
|
50
|
+
case 'entity':
|
|
51
|
+
return typeof selector.entityId === 'string' && selector.entityId.length > 0;
|
|
52
|
+
case 'placement':
|
|
53
|
+
return selector.at === 'document_start' || selector.at === 'document_end';
|
|
54
|
+
case 'relative':
|
|
55
|
+
return (selector.position === 'before' || selector.position === 'after') && isSelectorValid(selector.target);
|
|
56
|
+
case 'document':
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export function validatePlan(plan) {
|
|
61
|
+
const errors = [];
|
|
62
|
+
const references = [];
|
|
63
|
+
if (!plan.steps || plan.steps.length === 0) {
|
|
64
|
+
errors.push({ code: 'EMPTY_PLAN', message: 'Plan must contain at least one step.' });
|
|
65
|
+
return { ok: false, errors, references };
|
|
66
|
+
}
|
|
67
|
+
let hasApply = false;
|
|
68
|
+
let hasVerify = false;
|
|
69
|
+
let hasMutatingApply = false;
|
|
70
|
+
plan.steps.forEach((step, index) => {
|
|
71
|
+
switch (step.kind) {
|
|
72
|
+
case 'inspect': {
|
|
73
|
+
const entry = getOperationCatalogEntry(step.operationId);
|
|
74
|
+
if (!entry) {
|
|
75
|
+
errors.push({
|
|
76
|
+
code: 'UNKNOWN_OPERATION',
|
|
77
|
+
message: `Inspect step references unknown operation: ${step.operationId}.`,
|
|
78
|
+
stepIndex: index,
|
|
79
|
+
operationId: step.operationId,
|
|
80
|
+
});
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
if (entry.mode === 'write') {
|
|
84
|
+
errors.push({
|
|
85
|
+
code: 'WRONG_OPERATION_MODE',
|
|
86
|
+
message: `Inspect step ${step.operationId} must use a read-mode operation.`,
|
|
87
|
+
stepIndex: index,
|
|
88
|
+
operationId: step.operationId,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
for (const key of Object.keys(step.args)) {
|
|
92
|
+
if (RESERVED_ARG_KEYS.has(key)) {
|
|
93
|
+
errors.push({
|
|
94
|
+
code: 'RESERVED_ARG_KEY',
|
|
95
|
+
message: `Reserved key "${key}" must not appear in IR args.`,
|
|
96
|
+
stepIndex: index,
|
|
97
|
+
operationId: step.operationId,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
references.push(entry);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case 'select': {
|
|
105
|
+
if (!isSelectorValid(step.selector)) {
|
|
106
|
+
errors.push({
|
|
107
|
+
code: 'INVALID_SELECTOR',
|
|
108
|
+
message: `Select step has invalid selector at index ${index}.`,
|
|
109
|
+
stepIndex: index,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
case 'apply': {
|
|
115
|
+
hasApply = true;
|
|
116
|
+
const entry = getOperationCatalogEntry(step.operationId);
|
|
117
|
+
if (!entry) {
|
|
118
|
+
errors.push({
|
|
119
|
+
code: 'UNKNOWN_OPERATION',
|
|
120
|
+
message: `Apply step references unknown operation: ${step.operationId}.`,
|
|
121
|
+
stepIndex: index,
|
|
122
|
+
operationId: step.operationId,
|
|
123
|
+
});
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
if (entry.mode === 'read') {
|
|
127
|
+
errors.push({
|
|
128
|
+
code: 'WRONG_OPERATION_MODE',
|
|
129
|
+
message: `Apply step ${step.operationId} must use a write-mode operation.`,
|
|
130
|
+
stepIndex: index,
|
|
131
|
+
operationId: step.operationId,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
if (entry.isMutating)
|
|
135
|
+
hasMutatingApply = true;
|
|
136
|
+
for (const key of Object.keys(step.args)) {
|
|
137
|
+
if (RESERVED_ARG_KEYS.has(key)) {
|
|
138
|
+
errors.push({
|
|
139
|
+
code: 'RESERVED_ARG_KEY',
|
|
140
|
+
message: `Reserved key "${key}" must not appear in IR args.`,
|
|
141
|
+
stepIndex: index,
|
|
142
|
+
operationId: step.operationId,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
references.push(entry);
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
case 'verify': {
|
|
150
|
+
hasVerify = true;
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
if (!hasApply) {
|
|
156
|
+
errors.push({ code: 'MISSING_APPLY_STEP', message: 'Plan must contain at least one apply step.' });
|
|
157
|
+
}
|
|
158
|
+
if (hasMutatingApply && !hasVerify) {
|
|
159
|
+
errors.push({
|
|
160
|
+
code: 'MISSING_VERIFY_STEP',
|
|
161
|
+
message: 'Mutating plans must include a verify step with explicit checks.',
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return { ok: errors.length === 0, errors, references };
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Tagged-union narrowing helper used by runtimes and tests. Keeps the IR types
|
|
168
|
+
* the single source of truth for step discrimination.
|
|
169
|
+
*/
|
|
170
|
+
export function isApplyStep(step) {
|
|
171
|
+
return step.kind === 'apply';
|
|
172
|
+
}
|
|
173
|
+
export function isVerifyStep(step) {
|
|
174
|
+
return step.kind === 'verify';
|
|
175
|
+
}
|
|
176
|
+
export function isInspectStep(step) {
|
|
177
|
+
return step.kind === 'inspect';
|
|
178
|
+
}
|
|
179
|
+
export function isSelectStep(step) {
|
|
180
|
+
return step.kind === 'select';
|
|
181
|
+
}
|