@toolproof-core/lib 1.0.48 → 1.0.49
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/utils/mutableStrategyOverlay.d.ts +1 -3
- package/dist/utils/mutableStrategyOverlay.js +17 -18
- package/dist/utils/stepCreation.js +4 -5
- package/dist/utils/stepParallelization.js +13 -13
- package/dist/utils/strategyCanonicalization.d.ts +2 -2
- package/dist/utils/strategyCanonicalization.js +23 -25
- package/dist/utils/strategyStateResolution.js +1 -1
- package/package.json +1 -1
- package/src/utils/mutableStrategyOverlay.ts +17 -20
- package/src/utils/stepCreation.ts +4 -5
- package/src/utils/stepParallelization.ts +13 -13
- package/src/utils/strategyCanonicalization.ts +25 -27
- package/src/utils/strategyStateResolution.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -9,7 +9,6 @@ export type MutableStepKey = MutableToolStepKey | MutableMacroStepKey;
|
|
|
9
9
|
export type MutableMaterializedResource = MaterializedResource;
|
|
10
10
|
export type MutableToolStepRoleAddress = Omit<ToolStepRoleAddress, 'toolStepPath'> & {
|
|
11
11
|
stepKey: MutableToolStepKey;
|
|
12
|
-
toolStepKey: MutableToolStepKey;
|
|
13
12
|
};
|
|
14
13
|
export type MutableInternalInputPotential = Omit<InternalInputPotential, 'toolStepRoleAddress'> & {
|
|
15
14
|
toolStepRoleAddress: MutableToolStepRoleAddress;
|
|
@@ -20,7 +19,6 @@ export type MutableStrategyStateEntryByRoleName = Partial<Record<RoleName, Mutab
|
|
|
20
19
|
export type MutableStrategyState = Partial<Record<MutableToolStepKey, MutableStrategyStateEntryByRoleName>>;
|
|
21
20
|
export type MutableToolStep = ToolStep & {
|
|
22
21
|
stepKey: MutableToolStepKey;
|
|
23
|
-
toolStepKey: MutableToolStepKey;
|
|
24
22
|
};
|
|
25
23
|
export type MutableCase = Omit<Case, 'when' | 'what'> & {
|
|
26
24
|
when: MutableToolStep;
|
|
@@ -48,7 +46,7 @@ export type MutableStrategy = Omit<Strategy, 'stepsByThreadIndex' | 'strategySta
|
|
|
48
46
|
};
|
|
49
47
|
export declare function getAuthoringSteps(strategy: MutableStrategy): MutableStep[];
|
|
50
48
|
export declare function setAuthoringSteps(strategy: MutableStrategy, steps: MutableStep[]): MutableStrategy;
|
|
51
|
-
export declare function getStrategyStateEntryByRoleName(strategyState: MutableStrategyState,
|
|
49
|
+
export declare function getStrategyStateEntryByRoleName(strategyState: MutableStrategyState, stepKey: MutableToolStepKey): MutableStrategyStateEntryByRoleName | undefined;
|
|
52
50
|
export declare function getStrategyStateEntry(strategyState: MutableStrategyState, toolStepRoleAddress: MutableToolStepRoleAddress): MutableStrategyStateEntry | undefined;
|
|
53
51
|
export declare function setStrategyStateEntry(strategyState: MutableStrategyState, toolStepRoleAddress: MutableToolStepRoleAddress, entry: MutableStrategyStateEntry): MutableStrategyState;
|
|
54
52
|
export declare function clearInputBinding(strategyState: MutableStrategyState, toolStepRoleAddress: MutableToolStepRoleAddress): MutableStrategyState;
|
|
@@ -10,25 +10,25 @@ export function setAuthoringSteps(strategy, steps) {
|
|
|
10
10
|
stepsByThreadIndex: nextStepsByThreadIndex,
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
export function getStrategyStateEntryByRoleName(strategyState,
|
|
14
|
-
return strategyState[
|
|
13
|
+
export function getStrategyStateEntryByRoleName(strategyState, stepKey) {
|
|
14
|
+
return strategyState[stepKey];
|
|
15
15
|
}
|
|
16
16
|
export function getStrategyStateEntry(strategyState, toolStepRoleAddress) {
|
|
17
|
-
const inputEntryByRoleName = getStrategyStateEntryByRoleName(strategyState, toolStepRoleAddress.
|
|
17
|
+
const inputEntryByRoleName = getStrategyStateEntryByRoleName(strategyState, toolStepRoleAddress.stepKey);
|
|
18
18
|
return inputEntryByRoleName?.[toolStepRoleAddress.roleName];
|
|
19
19
|
}
|
|
20
20
|
export function setStrategyStateEntry(strategyState, toolStepRoleAddress, entry) {
|
|
21
|
-
const inputEntryByRoleName = getStrategyStateEntryByRoleName(strategyState, toolStepRoleAddress.
|
|
21
|
+
const inputEntryByRoleName = getStrategyStateEntryByRoleName(strategyState, toolStepRoleAddress.stepKey) ?? {};
|
|
22
22
|
return {
|
|
23
23
|
...strategyState,
|
|
24
|
-
[toolStepRoleAddress.
|
|
24
|
+
[toolStepRoleAddress.stepKey]: {
|
|
25
25
|
...inputEntryByRoleName,
|
|
26
26
|
[toolStepRoleAddress.roleName]: entry,
|
|
27
27
|
},
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
export function clearInputBinding(strategyState, toolStepRoleAddress) {
|
|
31
|
-
const inputEntryByRoleName = getStrategyStateEntryByRoleName(strategyState, toolStepRoleAddress.
|
|
31
|
+
const inputEntryByRoleName = getStrategyStateEntryByRoleName(strategyState, toolStepRoleAddress.stepKey);
|
|
32
32
|
if (!inputEntryByRoleName || !(toolStepRoleAddress.roleName in inputEntryByRoleName)) {
|
|
33
33
|
return strategyState;
|
|
34
34
|
}
|
|
@@ -36,12 +36,12 @@ export function clearInputBinding(strategyState, toolStepRoleAddress) {
|
|
|
36
36
|
delete nextInputEntryByRoleName[toolStepRoleAddress.roleName];
|
|
37
37
|
if (Object.keys(nextInputEntryByRoleName).length === 0) {
|
|
38
38
|
const nextStrategyState = { ...strategyState };
|
|
39
|
-
delete nextStrategyState[toolStepRoleAddress.
|
|
39
|
+
delete nextStrategyState[toolStepRoleAddress.stepKey];
|
|
40
40
|
return nextStrategyState;
|
|
41
41
|
}
|
|
42
42
|
return {
|
|
43
43
|
...strategyState,
|
|
44
|
-
[toolStepRoleAddress.
|
|
44
|
+
[toolStepRoleAddress.stepKey]: nextInputEntryByRoleName,
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
export function bindMaterializedResource(strategyState, target, resource) {
|
|
@@ -58,13 +58,13 @@ function getOutputRoleValue(tool, roleName) {
|
|
|
58
58
|
return tool.roleSpec.outputRoleValueByName[roleName];
|
|
59
59
|
}
|
|
60
60
|
export function bindInternalInputPotential(strategyState, targetAddress, sourceAddress, context) {
|
|
61
|
-
const sourceToolStep = context.toolStepByKey.get(sourceAddress.
|
|
61
|
+
const sourceToolStep = context.toolStepByKey.get(sourceAddress.stepKey);
|
|
62
62
|
if (!sourceToolStep) {
|
|
63
|
-
throw new Error(`Source tool step not found for '${sourceAddress.
|
|
63
|
+
throw new Error(`Source tool step not found for '${sourceAddress.stepKey}'.`);
|
|
64
64
|
}
|
|
65
|
-
const targetToolStep = context.toolStepByKey.get(targetAddress.
|
|
65
|
+
const targetToolStep = context.toolStepByKey.get(targetAddress.stepKey);
|
|
66
66
|
if (!targetToolStep) {
|
|
67
|
-
throw new Error(`Target tool step not found for '${targetAddress.
|
|
67
|
+
throw new Error(`Target tool step not found for '${targetAddress.stepKey}'.`);
|
|
68
68
|
}
|
|
69
69
|
const sourceTool = context.toolMap.get(sourceToolStep.toolHandle);
|
|
70
70
|
if (!sourceTool) {
|
|
@@ -76,11 +76,11 @@ export function bindInternalInputPotential(strategyState, targetAddress, sourceA
|
|
|
76
76
|
}
|
|
77
77
|
const targetInputRoleValue = getInputRoleValue(targetTool, targetAddress.roleName);
|
|
78
78
|
if (!targetInputRoleValue) {
|
|
79
|
-
throw new Error(`Target input role not found for (${targetAddress.
|
|
79
|
+
throw new Error(`Target input role not found for (${targetAddress.stepKey}, ${targetAddress.roleName}).`);
|
|
80
80
|
}
|
|
81
81
|
const sourceOutputRoleValue = getOutputRoleValue(sourceTool, sourceAddress.roleName);
|
|
82
82
|
const sourceInputRoleValue = getInputRoleValue(sourceTool, sourceAddress.roleName);
|
|
83
|
-
const sourceInputEntryByRoleName = strategyState[sourceAddress.
|
|
83
|
+
const sourceInputEntryByRoleName = strategyState[sourceAddress.stepKey];
|
|
84
84
|
const sourceInputEntry = sourceInputEntryByRoleName?.[sourceAddress.roleName];
|
|
85
85
|
const sourceRoleType = sourceOutputRoleValue
|
|
86
86
|
? extractResourceTypeHandleFromRoleValue(sourceOutputRoleValue)
|
|
@@ -90,20 +90,19 @@ export function bindInternalInputPotential(strategyState, targetAddress, sourceA
|
|
|
90
90
|
const targetRoleType = extractResourceTypeHandleFromRoleValue(targetInputRoleValue);
|
|
91
91
|
if (!sourceOutputRoleValue && sourceInputRoleValue) {
|
|
92
92
|
if (!sourceInputEntry) {
|
|
93
|
-
throw new Error(`Source input role is not bound for (${sourceAddress.
|
|
93
|
+
throw new Error(`Source input role is not bound for (${sourceAddress.stepKey}, ${sourceAddress.roleName}).`); // ATTENTION: not an ontological invariant, but it might help catch some mistakes early on.
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
if (!sourceOutputRoleValue && !sourceInputRoleValue) {
|
|
97
|
-
throw new Error(`Source role not found for (${sourceAddress.
|
|
97
|
+
throw new Error(`Source role not found for (${sourceAddress.stepKey}, ${sourceAddress.roleName}).`);
|
|
98
98
|
}
|
|
99
99
|
if (!sourceRoleType || !targetRoleType || sourceRoleType !== targetRoleType) {
|
|
100
|
-
throw new Error(`Reference type mismatch between source (${sourceAddress.
|
|
100
|
+
throw new Error(`Reference type mismatch between source (${sourceAddress.stepKey}, ${sourceAddress.roleName}) and target (${targetAddress.stepKey}, ${targetAddress.roleName}).`);
|
|
101
101
|
}
|
|
102
102
|
return setStrategyStateEntry(strategyState, targetAddress, {
|
|
103
103
|
strategyStateEntryKind: 'internalInputPotential',
|
|
104
104
|
toolStepRoleAddress: {
|
|
105
105
|
stepKey: sourceAddress.stepKey,
|
|
106
|
-
toolStepKey: sourceAddress.toolStepKey,
|
|
107
106
|
roleName: sourceAddress.roleName,
|
|
108
107
|
},
|
|
109
108
|
});
|
|
@@ -15,7 +15,6 @@ function getRoleBindingSpec(tool) {
|
|
|
15
15
|
export function createToolStepFromTool(tool) {
|
|
16
16
|
return {
|
|
17
17
|
stepKey: generateIdentifier('ToolStepKey'),
|
|
18
|
-
toolStepKey: generateIdentifier('ToolStepKey'),
|
|
19
18
|
stepKind: CONSTANTS.Enums.StepKind.tool,
|
|
20
19
|
toolHandle: tool.handle,
|
|
21
20
|
roleBindingSpec: getRoleBindingSpec(tool),
|
|
@@ -63,11 +62,11 @@ export function cloneForStep(forStep) {
|
|
|
63
62
|
case: {
|
|
64
63
|
what: {
|
|
65
64
|
...forStep.case.what,
|
|
66
|
-
|
|
65
|
+
stepKey: generateIdentifier('ToolStepKey'),
|
|
67
66
|
},
|
|
68
67
|
when: {
|
|
69
68
|
...forStep.case.when,
|
|
70
|
-
|
|
69
|
+
stepKey: generateIdentifier('ToolStepKey'),
|
|
71
70
|
},
|
|
72
71
|
},
|
|
73
72
|
};
|
|
@@ -80,11 +79,11 @@ export function cloneWhileStep(whileStep) {
|
|
|
80
79
|
case: {
|
|
81
80
|
what: {
|
|
82
81
|
...whileStep.case.what,
|
|
83
|
-
|
|
82
|
+
stepKey: generateIdentifier('ToolStepKey'),
|
|
84
83
|
},
|
|
85
84
|
when: {
|
|
86
85
|
...whileStep.case.when,
|
|
87
|
-
|
|
86
|
+
stepKey: generateIdentifier('ToolStepKey'),
|
|
88
87
|
},
|
|
89
88
|
},
|
|
90
89
|
};
|
|
@@ -4,17 +4,17 @@ export function getIndependentThreads(steps, strategyState) {
|
|
|
4
4
|
const step = steps[ownerIndex];
|
|
5
5
|
return `steps[${ownerIndex}] stepKind=${step?.stepKind ?? 'unknown'}`;
|
|
6
6
|
};
|
|
7
|
-
const
|
|
7
|
+
const stepKeyToOwner = new Map();
|
|
8
8
|
const toolStepByKey = new Map();
|
|
9
9
|
const addToolStep = (toolStep, ownerIndex) => {
|
|
10
10
|
if (!toolStep)
|
|
11
11
|
return;
|
|
12
|
-
const existingOwner =
|
|
12
|
+
const existingOwner = stepKeyToOwner.get(toolStep.stepKey);
|
|
13
13
|
if (existingOwner !== undefined) {
|
|
14
|
-
throw new Error(`Duplicate
|
|
14
|
+
throw new Error(`Duplicate stepKey '${toolStep.stepKey}' found in ${getOwnerLabel(ownerIndex)} and ${getOwnerLabel(existingOwner)}`);
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
toolStepByKey.set(toolStep.
|
|
16
|
+
stepKeyToOwner.set(toolStep.stepKey, ownerIndex);
|
|
17
|
+
toolStepByKey.set(toolStep.stepKey, toolStep);
|
|
18
18
|
};
|
|
19
19
|
steps.forEach((step, ownerIndex) => {
|
|
20
20
|
for (const toolStep of extractToolStepsFromStep(step, { branchCaseOrder: 'what-when' })) {
|
|
@@ -32,22 +32,22 @@ export function getIndependentThreads(steps, strategyState) {
|
|
|
32
32
|
for (let index = 0; index < steps.length; index++) {
|
|
33
33
|
ensureOwner(index);
|
|
34
34
|
}
|
|
35
|
-
for (const [
|
|
35
|
+
for (const [stepKey, ownerIndex] of stepKeyToOwner) {
|
|
36
36
|
ensureOwner(ownerIndex);
|
|
37
|
-
const toolStep = toolStepByKey.get(
|
|
37
|
+
const toolStep = toolStepByKey.get(stepKey);
|
|
38
38
|
const inputBindings = toolStep?.roleBindingSpec?.inputBindings ?? [];
|
|
39
|
-
const bucket = strategyState[
|
|
39
|
+
const bucket = strategyState[stepKey];
|
|
40
40
|
for (const inputRoleId of inputBindings) {
|
|
41
41
|
const entry = bucket?.[inputRoleId];
|
|
42
42
|
if (!entry || entry.strategyStateEntryKind !== 'internalInputPotential')
|
|
43
43
|
continue;
|
|
44
|
-
const
|
|
45
|
-
if (typeof
|
|
46
|
-
throw new Error(`Unresolvable internalInputPotential in toolStep '${
|
|
44
|
+
const producerStepKey = entry.toolStepRoleAddress?.stepKey;
|
|
45
|
+
if (typeof producerStepKey !== 'string') {
|
|
46
|
+
throw new Error(`Unresolvable internalInputPotential in toolStep '${stepKey}' (${getOwnerLabel(ownerIndex)}): missing toolStepRoleAddress.stepKey for role '${inputRoleId}'`);
|
|
47
47
|
}
|
|
48
|
-
const producerOwner =
|
|
48
|
+
const producerOwner = stepKeyToOwner.get(producerStepKey);
|
|
49
49
|
if (producerOwner === undefined) {
|
|
50
|
-
throw new Error(`Unresolvable internalInputPotential in toolStep '${
|
|
50
|
+
throw new Error(`Unresolvable internalInputPotential in toolStep '${stepKey}' (${getOwnerLabel(ownerIndex)}): source stepKey '${producerStepKey}' not found in strategy steps`);
|
|
51
51
|
}
|
|
52
52
|
ensureOwner(producerOwner);
|
|
53
53
|
ownerAdj.get(ownerIndex)?.add(producerOwner);
|
|
@@ -2,5 +2,5 @@ import type { Strategy, ToolStepPath } from '@toolproof-core/genesis';
|
|
|
2
2
|
import type { MutableStrategy, MutableStrategyStateEntryByRoleName, MutableToolStepKey } from './mutableStrategyOverlay.js';
|
|
3
3
|
export declare function strategyToMutableStrategy(strategy: Strategy): MutableStrategy;
|
|
4
4
|
export declare function mutableStrategyToStrategy(mutableStrategy: MutableStrategy): Strategy;
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function
|
|
5
|
+
export declare function mutableStepKeyToToolStepPath(mutableStrategy: MutableStrategy, stepKey: MutableToolStepKey): ToolStepPath;
|
|
6
|
+
export declare function projectMutableStrategyStateEntriesByStepKeyToCanonicalDelta(mutableStrategy: MutableStrategy, stepKey: MutableToolStepKey, entries: MutableStrategyStateEntryByRoleName): Strategy['strategyState'];
|
|
@@ -2,8 +2,8 @@ import { CONSTANTS } from '../lookups/lookups.js';
|
|
|
2
2
|
import { generateIdentifier } from './identifierGeneration.js';
|
|
3
3
|
function stripMutableCase(stepCase) {
|
|
4
4
|
const { when, what, ...rest } = stepCase;
|
|
5
|
-
const { stepKey: _whenStepKey,
|
|
6
|
-
const { stepKey: _whatStepKey,
|
|
5
|
+
const { stepKey: _whenStepKey, ...canonicalWhen } = when;
|
|
6
|
+
const { stepKey: _whatStepKey, ...canonicalWhat } = what;
|
|
7
7
|
return {
|
|
8
8
|
...rest,
|
|
9
9
|
when: canonicalWhen,
|
|
@@ -15,18 +15,18 @@ function buildExecutionPathMap(strategy) {
|
|
|
15
15
|
const registerStep = (step, pathPrefix) => {
|
|
16
16
|
switch (step.stepKind) {
|
|
17
17
|
case CONSTANTS.Enums.StepKind.tool:
|
|
18
|
-
executionPathByKey.set(step.
|
|
18
|
+
executionPathByKey.set(step.stepKey, `${pathPrefix}/self`);
|
|
19
19
|
return;
|
|
20
20
|
case CONSTANTS.Enums.StepKind.branch:
|
|
21
21
|
step.cases.forEach((stepCase, caseIndex) => {
|
|
22
|
-
executionPathByKey.set(stepCase.when.
|
|
23
|
-
executionPathByKey.set(stepCase.what.
|
|
22
|
+
executionPathByKey.set(stepCase.when.stepKey, `${pathPrefix}/cases/${caseIndex}/when`);
|
|
23
|
+
executionPathByKey.set(stepCase.what.stepKey, `${pathPrefix}/cases/${caseIndex}/what`);
|
|
24
24
|
});
|
|
25
25
|
return;
|
|
26
26
|
case CONSTANTS.Enums.StepKind.while:
|
|
27
27
|
case CONSTANTS.Enums.StepKind.for:
|
|
28
|
-
executionPathByKey.set(step.case.when.
|
|
29
|
-
executionPathByKey.set(step.case.what.
|
|
28
|
+
executionPathByKey.set(step.case.when.stepKey, `${pathPrefix}/case/when`);
|
|
29
|
+
executionPathByKey.set(step.case.what.stepKey, `${pathPrefix}/case/what`);
|
|
30
30
|
return;
|
|
31
31
|
default:
|
|
32
32
|
throw new Error('Unsupported step kind while projecting strategy.');
|
|
@@ -43,9 +43,9 @@ function toCanonicalStrategyStateEntry(entry, executionPathByKey) {
|
|
|
43
43
|
if (entry.strategyStateEntryKind !== 'internalInputPotential') {
|
|
44
44
|
return entry;
|
|
45
45
|
}
|
|
46
|
-
const sourceToolStepPath = executionPathByKey.get(entry.toolStepRoleAddress.
|
|
46
|
+
const sourceToolStepPath = executionPathByKey.get(entry.toolStepRoleAddress.stepKey);
|
|
47
47
|
if (!sourceToolStepPath) {
|
|
48
|
-
throw new Error(`Cannot project strategy state: no execution path found for
|
|
48
|
+
throw new Error(`Cannot project strategy state: no execution path found for stepKey '${entry.toolStepRoleAddress.stepKey}'.`);
|
|
49
49
|
}
|
|
50
50
|
return {
|
|
51
51
|
strategyStateEntryKind: 'internalInputPotential',
|
|
@@ -58,7 +58,7 @@ function toCanonicalStrategyStateEntry(entry, executionPathByKey) {
|
|
|
58
58
|
function toCanonicalStep(step) {
|
|
59
59
|
switch (step.stepKind) {
|
|
60
60
|
case CONSTANTS.Enums.StepKind.tool: {
|
|
61
|
-
const { stepKey: _stepKey,
|
|
61
|
+
const { stepKey: _stepKey, ...canonicalToolStep } = step;
|
|
62
62
|
return canonicalToolStep;
|
|
63
63
|
}
|
|
64
64
|
case CONSTANTS.Enums.StepKind.branch: {
|
|
@@ -92,7 +92,6 @@ function toMutableStrategyStateEntry(entry, executionKeyByPath) {
|
|
|
92
92
|
strategyStateEntryKind: 'internalInputPotential',
|
|
93
93
|
toolStepRoleAddress: {
|
|
94
94
|
stepKey: sourceToolStepKey,
|
|
95
|
-
toolStepKey: sourceToolStepKey,
|
|
96
95
|
roleName: entry.toolStepRoleAddress.roleName,
|
|
97
96
|
},
|
|
98
97
|
};
|
|
@@ -102,7 +101,6 @@ function toMutableToolStep(step) {
|
|
|
102
101
|
return {
|
|
103
102
|
...step,
|
|
104
103
|
stepKey: key,
|
|
105
|
-
toolStepKey: key,
|
|
106
104
|
};
|
|
107
105
|
}
|
|
108
106
|
function toMutableCase(stepCase) {
|
|
@@ -160,8 +158,8 @@ function toMutableStep(step) {
|
|
|
160
158
|
function buildExecutionKeyMap(strategy) {
|
|
161
159
|
const executionPathByKey = buildExecutionPathMap(strategy);
|
|
162
160
|
const executionKeyByPath = new Map();
|
|
163
|
-
for (const [
|
|
164
|
-
executionKeyByPath.set(toolStepPath,
|
|
161
|
+
for (const [stepKey, toolStepPath] of executionPathByKey.entries()) {
|
|
162
|
+
executionKeyByPath.set(toolStepPath, stepKey);
|
|
165
163
|
}
|
|
166
164
|
return executionKeyByPath;
|
|
167
165
|
}
|
|
@@ -198,17 +196,17 @@ export function strategyToMutableStrategy(strategy) {
|
|
|
198
196
|
export function mutableStrategyToStrategy(mutableStrategy) {
|
|
199
197
|
const executionPathByKey = buildExecutionPathMap(mutableStrategy);
|
|
200
198
|
const strategyState = {};
|
|
201
|
-
for (const [
|
|
199
|
+
for (const [stepKey, inputEntryByRoleName] of Object.entries(mutableStrategy.strategyState)) {
|
|
202
200
|
if (!inputEntryByRoleName) {
|
|
203
201
|
continue;
|
|
204
202
|
}
|
|
205
|
-
const toolStepPath = executionPathByKey.get(
|
|
203
|
+
const toolStepPath = executionPathByKey.get(stepKey);
|
|
206
204
|
if (!toolStepPath) {
|
|
207
|
-
throw new Error(`Cannot project strategy state: no execution path found for
|
|
205
|
+
throw new Error(`Cannot project strategy state: no execution path found for stepKey '${stepKey}'.`);
|
|
208
206
|
}
|
|
209
207
|
strategyState[toolStepPath] = Object.fromEntries(Object.entries(inputEntryByRoleName).map(([roleName, entry]) => {
|
|
210
208
|
if (entry === undefined) {
|
|
211
|
-
throw new Error(`Cannot project strategy state: role '${roleName}' on
|
|
209
|
+
throw new Error(`Cannot project strategy state: role '${roleName}' on stepKey '${stepKey}' is explicitly undefined.`);
|
|
212
210
|
}
|
|
213
211
|
return [
|
|
214
212
|
roleName,
|
|
@@ -222,25 +220,25 @@ export function mutableStrategyToStrategy(mutableStrategy) {
|
|
|
222
220
|
strategyState,
|
|
223
221
|
};
|
|
224
222
|
}
|
|
225
|
-
export function
|
|
223
|
+
export function mutableStepKeyToToolStepPath(mutableStrategy, stepKey) {
|
|
226
224
|
const executionPathByKey = buildExecutionPathMap(mutableStrategy);
|
|
227
|
-
const toolStepPath = executionPathByKey.get(
|
|
225
|
+
const toolStepPath = executionPathByKey.get(stepKey);
|
|
228
226
|
if (!toolStepPath) {
|
|
229
|
-
throw new Error(`Cannot project toolStepPath: no execution path found for
|
|
227
|
+
throw new Error(`Cannot project toolStepPath: no execution path found for stepKey '${stepKey}'.`);
|
|
230
228
|
}
|
|
231
229
|
return toolStepPath;
|
|
232
230
|
}
|
|
233
|
-
export function
|
|
231
|
+
export function projectMutableStrategyStateEntriesByStepKeyToCanonicalDelta(mutableStrategy, stepKey, entries) {
|
|
234
232
|
const executionPathByKey = buildExecutionPathMap(mutableStrategy);
|
|
235
|
-
const toolStepPath = executionPathByKey.get(
|
|
233
|
+
const toolStepPath = executionPathByKey.get(stepKey);
|
|
236
234
|
if (!toolStepPath) {
|
|
237
|
-
throw new Error(`Cannot project strategy state delta: no execution path found for
|
|
235
|
+
throw new Error(`Cannot project strategy state delta: no execution path found for stepKey '${stepKey}'.`);
|
|
238
236
|
}
|
|
239
237
|
const canonicalEntries = Object.fromEntries(Object.entries(entries)
|
|
240
238
|
.filter(([, entry]) => entry !== undefined)
|
|
241
239
|
.map(([roleName, entry]) => {
|
|
242
240
|
if (entry === undefined) {
|
|
243
|
-
throw new Error(`Cannot project strategy state delta: role '${roleName}' on
|
|
241
|
+
throw new Error(`Cannot project strategy state delta: role '${roleName}' on stepKey '${stepKey}' is explicitly undefined.`);
|
|
244
242
|
}
|
|
245
243
|
return [
|
|
246
244
|
roleName,
|
|
@@ -6,7 +6,7 @@ export function resolveStrategyStateChain(strategyState, start, opts) {
|
|
|
6
6
|
let current = start;
|
|
7
7
|
for (let depth = 0; depth <= maxDepth; depth++) {
|
|
8
8
|
path.push(current);
|
|
9
|
-
const visitKey = `${current.
|
|
9
|
+
const visitKey = `${current.stepKey}::${current.roleName}`;
|
|
10
10
|
if (visited.has(visitKey)) {
|
|
11
11
|
return { status: 'unresolved', reason: 'cycle', path };
|
|
12
12
|
}
|
package/package.json
CHANGED
|
@@ -29,7 +29,6 @@ export type MutableMaterializedResource = MaterializedResource;
|
|
|
29
29
|
export type MutableToolStepRoleAddress =
|
|
30
30
|
Omit<ToolStepRoleAddress, 'toolStepPath'> & {
|
|
31
31
|
stepKey: MutableToolStepKey;
|
|
32
|
-
toolStepKey: MutableToolStepKey;
|
|
33
32
|
};
|
|
34
33
|
|
|
35
34
|
export type MutableInternalInputPotential =
|
|
@@ -50,7 +49,6 @@ export type MutableStrategyState = Partial<Record<MutableToolStepKey, MutableStr
|
|
|
50
49
|
|
|
51
50
|
export type MutableToolStep = ToolStep & {
|
|
52
51
|
stepKey: MutableToolStepKey;
|
|
53
|
-
toolStepKey: MutableToolStepKey;
|
|
54
52
|
};
|
|
55
53
|
|
|
56
54
|
export type MutableCase = Omit<Case, 'when' | 'what'> & {
|
|
@@ -108,16 +106,16 @@ export function setAuthoringSteps(
|
|
|
108
106
|
|
|
109
107
|
export function getStrategyStateEntryByRoleName(
|
|
110
108
|
strategyState: MutableStrategyState,
|
|
111
|
-
|
|
109
|
+
stepKey: MutableToolStepKey,
|
|
112
110
|
): MutableStrategyStateEntryByRoleName | undefined {
|
|
113
|
-
return strategyState[
|
|
111
|
+
return strategyState[stepKey];
|
|
114
112
|
}
|
|
115
113
|
|
|
116
114
|
export function getStrategyStateEntry(
|
|
117
115
|
strategyState: MutableStrategyState,
|
|
118
116
|
toolStepRoleAddress: MutableToolStepRoleAddress,
|
|
119
117
|
): MutableStrategyStateEntry | undefined {
|
|
120
|
-
const inputEntryByRoleName = getStrategyStateEntryByRoleName(strategyState, toolStepRoleAddress.
|
|
118
|
+
const inputEntryByRoleName = getStrategyStateEntryByRoleName(strategyState, toolStepRoleAddress.stepKey);
|
|
121
119
|
return inputEntryByRoleName?.[toolStepRoleAddress.roleName];
|
|
122
120
|
}
|
|
123
121
|
|
|
@@ -126,11 +124,11 @@ export function setStrategyStateEntry(
|
|
|
126
124
|
toolStepRoleAddress: MutableToolStepRoleAddress,
|
|
127
125
|
entry: MutableStrategyStateEntry,
|
|
128
126
|
): MutableStrategyState {
|
|
129
|
-
const inputEntryByRoleName = getStrategyStateEntryByRoleName(strategyState, toolStepRoleAddress.
|
|
127
|
+
const inputEntryByRoleName = getStrategyStateEntryByRoleName(strategyState, toolStepRoleAddress.stepKey) ?? {};
|
|
130
128
|
|
|
131
129
|
return {
|
|
132
130
|
...strategyState,
|
|
133
|
-
[toolStepRoleAddress.
|
|
131
|
+
[toolStepRoleAddress.stepKey]: {
|
|
134
132
|
...inputEntryByRoleName,
|
|
135
133
|
[toolStepRoleAddress.roleName]: entry,
|
|
136
134
|
},
|
|
@@ -144,7 +142,7 @@ export function clearInputBinding(
|
|
|
144
142
|
const inputEntryByRoleName =
|
|
145
143
|
getStrategyStateEntryByRoleName(
|
|
146
144
|
strategyState,
|
|
147
|
-
toolStepRoleAddress.
|
|
145
|
+
toolStepRoleAddress.stepKey,
|
|
148
146
|
);
|
|
149
147
|
|
|
150
148
|
if (!inputEntryByRoleName || !(toolStepRoleAddress.roleName in inputEntryByRoleName)) {
|
|
@@ -156,13 +154,13 @@ export function clearInputBinding(
|
|
|
156
154
|
|
|
157
155
|
if (Object.keys(nextInputEntryByRoleName).length === 0) {
|
|
158
156
|
const nextStrategyState = { ...strategyState };
|
|
159
|
-
delete nextStrategyState[toolStepRoleAddress.
|
|
157
|
+
delete nextStrategyState[toolStepRoleAddress.stepKey];
|
|
160
158
|
return nextStrategyState;
|
|
161
159
|
}
|
|
162
160
|
|
|
163
161
|
return {
|
|
164
162
|
...strategyState,
|
|
165
|
-
[toolStepRoleAddress.
|
|
163
|
+
[toolStepRoleAddress.stepKey]: nextInputEntryByRoleName,
|
|
166
164
|
};
|
|
167
165
|
}
|
|
168
166
|
|
|
@@ -197,14 +195,14 @@ export function bindInternalInputPotential(
|
|
|
197
195
|
}
|
|
198
196
|
): MutableStrategyState {
|
|
199
197
|
|
|
200
|
-
const sourceToolStep = context.toolStepByKey.get(sourceAddress.
|
|
198
|
+
const sourceToolStep = context.toolStepByKey.get(sourceAddress.stepKey);
|
|
201
199
|
if (!sourceToolStep) {
|
|
202
|
-
throw new Error(`Source tool step not found for '${sourceAddress.
|
|
200
|
+
throw new Error(`Source tool step not found for '${sourceAddress.stepKey}'.`);
|
|
203
201
|
}
|
|
204
202
|
|
|
205
|
-
const targetToolStep = context.toolStepByKey.get(targetAddress.
|
|
203
|
+
const targetToolStep = context.toolStepByKey.get(targetAddress.stepKey);
|
|
206
204
|
if (!targetToolStep) {
|
|
207
|
-
throw new Error(`Target tool step not found for '${targetAddress.
|
|
205
|
+
throw new Error(`Target tool step not found for '${targetAddress.stepKey}'.`);
|
|
208
206
|
}
|
|
209
207
|
|
|
210
208
|
const sourceTool = context.toolMap.get(sourceToolStep.toolHandle);
|
|
@@ -219,13 +217,13 @@ export function bindInternalInputPotential(
|
|
|
219
217
|
|
|
220
218
|
const targetInputRoleValue = getInputRoleValue(targetTool, targetAddress.roleName);
|
|
221
219
|
if (!targetInputRoleValue) {
|
|
222
|
-
throw new Error(`Target input role not found for (${targetAddress.
|
|
220
|
+
throw new Error(`Target input role not found for (${targetAddress.stepKey}, ${targetAddress.roleName}).`);
|
|
223
221
|
}
|
|
224
222
|
|
|
225
223
|
const sourceOutputRoleValue = getOutputRoleValue(sourceTool, sourceAddress.roleName);
|
|
226
224
|
const sourceInputRoleValue = getInputRoleValue(sourceTool, sourceAddress.roleName);
|
|
227
225
|
|
|
228
|
-
const sourceInputEntryByRoleName = strategyState[sourceAddress.
|
|
226
|
+
const sourceInputEntryByRoleName = strategyState[sourceAddress.stepKey];
|
|
229
227
|
const sourceInputEntry = sourceInputEntryByRoleName?.[sourceAddress.roleName];
|
|
230
228
|
|
|
231
229
|
const sourceRoleType = sourceOutputRoleValue
|
|
@@ -238,17 +236,17 @@ export function bindInternalInputPotential(
|
|
|
238
236
|
|
|
239
237
|
if (!sourceOutputRoleValue && sourceInputRoleValue) {
|
|
240
238
|
if (!sourceInputEntry) {
|
|
241
|
-
throw new Error(`Source input role is not bound for (${sourceAddress.
|
|
239
|
+
throw new Error(`Source input role is not bound for (${sourceAddress.stepKey}, ${sourceAddress.roleName}).`); // ATTENTION: not an ontological invariant, but it might help catch some mistakes early on.
|
|
242
240
|
}
|
|
243
241
|
}
|
|
244
242
|
|
|
245
243
|
if (!sourceOutputRoleValue && !sourceInputRoleValue) {
|
|
246
|
-
throw new Error(`Source role not found for (${sourceAddress.
|
|
244
|
+
throw new Error(`Source role not found for (${sourceAddress.stepKey}, ${sourceAddress.roleName}).`);
|
|
247
245
|
}
|
|
248
246
|
|
|
249
247
|
if (!sourceRoleType || !targetRoleType || sourceRoleType !== targetRoleType) {
|
|
250
248
|
throw new Error(
|
|
251
|
-
`Reference type mismatch between source (${sourceAddress.
|
|
249
|
+
`Reference type mismatch between source (${sourceAddress.stepKey}, ${sourceAddress.roleName}) and target (${targetAddress.stepKey}, ${targetAddress.roleName}).`
|
|
252
250
|
);
|
|
253
251
|
}
|
|
254
252
|
|
|
@@ -256,7 +254,6 @@ export function bindInternalInputPotential(
|
|
|
256
254
|
strategyStateEntryKind: 'internalInputPotential',
|
|
257
255
|
toolStepRoleAddress: {
|
|
258
256
|
stepKey: sourceAddress.stepKey,
|
|
259
|
-
toolStepKey: sourceAddress.toolStepKey,
|
|
260
257
|
roleName: sourceAddress.roleName,
|
|
261
258
|
},
|
|
262
259
|
});
|
|
@@ -32,7 +32,6 @@ export function createToolStepFromTool(
|
|
|
32
32
|
): MutableToolStep {
|
|
33
33
|
return {
|
|
34
34
|
stepKey: generateIdentifier('ToolStepKey'),
|
|
35
|
-
toolStepKey: generateIdentifier('ToolStepKey'),
|
|
36
35
|
stepKind: CONSTANTS.Enums.StepKind.tool,
|
|
37
36
|
toolHandle: tool.handle,
|
|
38
37
|
roleBindingSpec: getRoleBindingSpec(tool),
|
|
@@ -100,11 +99,11 @@ export function cloneForStep(
|
|
|
100
99
|
case: {
|
|
101
100
|
what: {
|
|
102
101
|
...forStep.case.what,
|
|
103
|
-
|
|
102
|
+
stepKey: generateIdentifier('ToolStepKey'),
|
|
104
103
|
},
|
|
105
104
|
when: {
|
|
106
105
|
...forStep.case.when,
|
|
107
|
-
|
|
106
|
+
stepKey: generateIdentifier('ToolStepKey'),
|
|
108
107
|
},
|
|
109
108
|
},
|
|
110
109
|
};
|
|
@@ -120,11 +119,11 @@ export function cloneWhileStep(
|
|
|
120
119
|
case: {
|
|
121
120
|
what: {
|
|
122
121
|
...whileStep.case.what,
|
|
123
|
-
|
|
122
|
+
stepKey: generateIdentifier('ToolStepKey'),
|
|
124
123
|
},
|
|
125
124
|
when: {
|
|
126
125
|
...whileStep.case.when,
|
|
127
|
-
|
|
126
|
+
stepKey: generateIdentifier('ToolStepKey'),
|
|
128
127
|
},
|
|
129
128
|
},
|
|
130
129
|
};
|
|
@@ -17,7 +17,7 @@ export function getIndependentThreads(
|
|
|
17
17
|
return `steps[${ownerIndex}] stepKind=${step?.stepKind ?? 'unknown'}`;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
const
|
|
20
|
+
const stepKeyToOwner = new Map<MutableToolStepKey, OwnerIndex>();
|
|
21
21
|
const toolStepByKey = new Map<MutableToolStepKey, MutableToolStep>();
|
|
22
22
|
|
|
23
23
|
const addToolStep = (
|
|
@@ -26,15 +26,15 @@ export function getIndependentThreads(
|
|
|
26
26
|
) => {
|
|
27
27
|
if (!toolStep) return;
|
|
28
28
|
|
|
29
|
-
const existingOwner =
|
|
29
|
+
const existingOwner = stepKeyToOwner.get(toolStep.stepKey);
|
|
30
30
|
if (existingOwner !== undefined) {
|
|
31
31
|
throw new Error(
|
|
32
|
-
`Duplicate
|
|
32
|
+
`Duplicate stepKey '${toolStep.stepKey}' found in ${getOwnerLabel(ownerIndex)} and ${getOwnerLabel(existingOwner)}`
|
|
33
33
|
);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
toolStepByKey.set(toolStep.
|
|
36
|
+
stepKeyToOwner.set(toolStep.stepKey, ownerIndex);
|
|
37
|
+
toolStepByKey.set(toolStep.stepKey, toolStep);
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
steps.forEach((step, ownerIndex) => {
|
|
@@ -55,28 +55,28 @@ export function getIndependentThreads(
|
|
|
55
55
|
ensureOwner(index);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
for (const [
|
|
58
|
+
for (const [stepKey, ownerIndex] of stepKeyToOwner) {
|
|
59
59
|
ensureOwner(ownerIndex);
|
|
60
60
|
|
|
61
|
-
const toolStep = toolStepByKey.get(
|
|
61
|
+
const toolStep = toolStepByKey.get(stepKey);
|
|
62
62
|
const inputBindings = toolStep?.roleBindingSpec?.inputBindings ?? [];
|
|
63
|
-
const bucket = strategyState[
|
|
63
|
+
const bucket = strategyState[stepKey];
|
|
64
64
|
|
|
65
65
|
for (const inputRoleId of inputBindings) {
|
|
66
66
|
const entry = bucket?.[inputRoleId];
|
|
67
67
|
if (!entry || entry.strategyStateEntryKind !== 'internalInputPotential') continue;
|
|
68
68
|
|
|
69
|
-
const
|
|
70
|
-
if (typeof
|
|
69
|
+
const producerStepKey = entry.toolStepRoleAddress?.stepKey;
|
|
70
|
+
if (typeof producerStepKey !== 'string') {
|
|
71
71
|
throw new Error(
|
|
72
|
-
`Unresolvable internalInputPotential in toolStep '${
|
|
72
|
+
`Unresolvable internalInputPotential in toolStep '${stepKey}' (${getOwnerLabel(ownerIndex)}): missing toolStepRoleAddress.stepKey for role '${inputRoleId}'`
|
|
73
73
|
);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
const producerOwner =
|
|
76
|
+
const producerOwner = stepKeyToOwner.get(producerStepKey);
|
|
77
77
|
if (producerOwner === undefined) {
|
|
78
78
|
throw new Error(
|
|
79
|
-
`Unresolvable internalInputPotential in toolStep '${
|
|
79
|
+
`Unresolvable internalInputPotential in toolStep '${stepKey}' (${getOwnerLabel(ownerIndex)}): source stepKey '${producerStepKey}' not found in strategy steps`
|
|
80
80
|
);
|
|
81
81
|
}
|
|
82
82
|
|