@toolproof-core/lib 1.0.34 → 1.0.37
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/integrations/firebase/firebaseAdminHelpers.d.ts +3 -10
- package/dist/integrations/firebase/firebaseAdminHelpers.js +43 -148
- package/dist/integrations/firebase/firebaseAdminInit.d.ts +0 -1
- package/dist/integrations/firebase/firebaseAdminInit.js +0 -1
- package/dist/lookups/lookups.d.ts +214 -0
- package/dist/lookups/lookups.js +33 -0
- package/dist/types/types.d.ts +15 -15
- package/dist/types/types.js +2 -3
- package/dist/utils/cosmosDataExtraction.d.ts +5 -0
- package/dist/utils/cosmosDataExtraction.js +15 -0
- package/dist/utils/identifierGeneration.d.ts +2 -0
- package/dist/utils/identifierGeneration.js +5 -0
- package/dist/utils/mutableStrategyOverlay.d.ts +55 -0
- package/dist/utils/mutableStrategyOverlay.js +115 -0
- package/dist/utils/resourceCreation.d.ts +11 -0
- package/dist/utils/resourceCreation.js +32 -0
- package/dist/utils/stepCreation.d.ts +9 -0
- package/dist/utils/stepCreation.js +79 -0
- package/dist/utils/stepParallelization.d.ts +2 -0
- package/dist/utils/{parallelizeSteps.js → stepParallelization.js} +40 -55
- package/dist/utils/strategyAssembly.d.ts +3 -0
- package/dist/utils/strategyAssembly.js +6 -0
- package/dist/utils/strategyCanonicalization.d.ts +4 -0
- package/dist/utils/strategyCanonicalization.js +215 -0
- package/dist/utils/strategyExtraction.d.ts +17 -0
- package/dist/utils/strategyExtraction.js +88 -0
- package/dist/utils/strategyStateResolution.d.ts +17 -0
- package/dist/utils/strategyStateResolution.js +27 -0
- package/dist/utils/strategyThreading.d.ts +2 -0
- package/dist/utils/strategyThreading.js +10 -0
- package/dist/utils/toolStepPaths.d.ts +2 -0
- package/dist/utils/toolStepPaths.js +21 -0
- package/package.json +43 -23
- package/src/integrations/firebase/firebaseAdminHelpers.ts +57 -180
- package/src/lookups/lookups.ts +35 -0
- package/src/types/types.ts +16 -13
- package/src/utils/cosmosDataExtraction.ts +25 -0
- package/src/utils/identifierGeneration.ts +12 -0
- package/src/utils/mutableStrategyOverlay.ts +286 -0
- package/src/utils/resourceCreation.ts +87 -0
- package/src/utils/stepCreation.ts +114 -0
- package/src/utils/stepParallelization.ts +181 -0
- package/src/utils/strategyAssembly.ts +14 -0
- package/src/utils/strategyCanonicalization.ts +294 -0
- package/src/utils/strategyExtraction.ts +150 -0
- package/src/utils/strategyStateResolution.ts +57 -0
- package/src/utils/strategyThreading.ts +27 -0
- package/src/utils/toolStepPaths.ts +34 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/artifacts/artifacts.d.ts +0 -175
- package/dist/artifacts/artifacts.d.ts.map +0 -1
- package/dist/artifacts/artifacts.js +0 -48
- package/dist/artifacts/artifacts.js.map +0 -1
- package/dist/integrations/firebase/createStep.d.ts +0 -11
- package/dist/integrations/firebase/createStep.d.ts.map +0 -1
- package/dist/integrations/firebase/createStep.js +0 -43
- package/dist/integrations/firebase/createStep.js.map +0 -1
- package/dist/integrations/firebase/createThreadedStrategy.d.ts +0 -3
- package/dist/integrations/firebase/createThreadedStrategy.d.ts.map +0 -1
- package/dist/integrations/firebase/createThreadedStrategy.js +0 -9
- package/dist/integrations/firebase/createThreadedStrategy.js.map +0 -1
- package/dist/integrations/firebase/firebaseAdminHelpers.d.ts.map +0 -1
- package/dist/integrations/firebase/firebaseAdminHelpers.js.map +0 -1
- package/dist/integrations/firebase/firebaseAdminInit.d.ts.map +0 -1
- package/dist/integrations/firebase/firebaseAdminInit.js.map +0 -1
- package/dist/types/types.d.ts.map +0 -1
- package/dist/types/types.js.map +0 -1
- package/dist/utils/bindInputRoleToResource.d.ts +0 -6
- package/dist/utils/bindInputRoleToResource.d.ts.map +0 -1
- package/dist/utils/bindInputRoleToResource.js +0 -25
- package/dist/utils/bindInputRoleToResource.js.map +0 -1
- package/dist/utils/creation/resourceCreation.d.ts +0 -21
- package/dist/utils/creation/resourceCreation.d.ts.map +0 -1
- package/dist/utils/creation/resourceCreation.js +0 -66
- package/dist/utils/creation/resourceCreation.js.map +0 -1
- package/dist/utils/creation/stepCreation.d.ts +0 -51
- package/dist/utils/creation/stepCreation.d.ts.map +0 -1
- package/dist/utils/creation/stepCreation.js +0 -90
- package/dist/utils/creation/stepCreation.js.map +0 -1
- package/dist/utils/creation/threadedStrategyCreation.d.ts +0 -19
- package/dist/utils/creation/threadedStrategyCreation.d.ts.map +0 -1
- package/dist/utils/creation/threadedStrategyCreation.js +0 -17
- package/dist/utils/creation/threadedStrategyCreation.js.map +0 -1
- package/dist/utils/extractData.d.ts +0 -13
- package/dist/utils/extractData.d.ts.map +0 -1
- package/dist/utils/extractData.js +0 -74
- package/dist/utils/extractData.js.map +0 -1
- package/dist/utils/parallelizeSteps.d.ts +0 -4
- package/dist/utils/parallelizeSteps.d.ts.map +0 -1
- package/dist/utils/parallelizeSteps.js.map +0 -1
- package/dist/utils/resolveResourceChain.d.ts +0 -19
- package/dist/utils/resolveResourceChain.d.ts.map +0 -1
- package/dist/utils/resolveResourceChain.js +0 -31
- package/dist/utils/resolveResourceChain.js.map +0 -1
- package/dist/utils/roleSpec.d.ts +0 -17
- package/dist/utils/roleSpec.d.ts.map +0 -1
- package/dist/utils/roleSpec.js +0 -58
- package/dist/utils/roleSpec.js.map +0 -1
- package/dist/utils/strategyState.d.ts +0 -8
- package/dist/utils/strategyState.d.ts.map +0 -1
- package/dist/utils/strategyState.js +0 -29
- package/dist/utils/strategyState.js.map +0 -1
- package/src/artifacts/artifacts.ts +0 -49
- package/src/integrations/firebase/createStep.ts +0 -71
- package/src/integrations/firebase/createThreadedStrategy.ts +0 -19
- package/src/utils/bindInputRoleToResource.ts +0 -54
- package/src/utils/creation/resourceCreation.ts +0 -121
- package/src/utils/creation/stepCreation.ts +0 -165
- package/src/utils/creation/threadedStrategyCreation.ts +0 -42
- package/src/utils/extractData.ts +0 -129
- package/src/utils/parallelizeSteps.ts +0 -187
- package/src/utils/resolveResourceChain.ts +0 -52
- package/src/utils/roleSpec.ts +0 -84
- package/src/utils/strategyState.ts +0 -57
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
BranchStep,
|
|
3
|
+
Case,
|
|
4
|
+
ExternalInputPotential,
|
|
5
|
+
ForStep,
|
|
6
|
+
InputResource,
|
|
7
|
+
InternalInputPotential,
|
|
8
|
+
Resource,
|
|
9
|
+
RoleName,
|
|
10
|
+
Strategy,
|
|
11
|
+
Tool,
|
|
12
|
+
ToolHandle,
|
|
13
|
+
ToolStep,
|
|
14
|
+
ToolStepRoleAddress,
|
|
15
|
+
WhileStep,
|
|
16
|
+
} from '@toolproof-core/genesis';
|
|
17
|
+
import { extractResourceTypeHandleFromRoleValue } from './strategyExtraction.js';
|
|
18
|
+
|
|
19
|
+
export type MutableToolStepKey = string;
|
|
20
|
+
export type MutableBranchStepKey = string;
|
|
21
|
+
export type MutableWhileStepKey = string;
|
|
22
|
+
export type MutableForStepKey = string;
|
|
23
|
+
export type MutableLoopStepKey = MutableWhileStepKey | MutableForStepKey;
|
|
24
|
+
export type MutableMacroStepKey = MutableBranchStepKey | MutableLoopStepKey;
|
|
25
|
+
|
|
26
|
+
export type MutableInputResource = InputResource;
|
|
27
|
+
|
|
28
|
+
export type MutableToolStepRoleAddress<TKey extends string = MutableToolStepKey> =
|
|
29
|
+
Omit<ToolStepRoleAddress, 'toolStepPath'> & {
|
|
30
|
+
toolStepKey: TKey;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type MutableInternalInputPotential<TKey extends string = MutableToolStepKey> =
|
|
34
|
+
Omit<InternalInputPotential, 'toolStepRoleAddress'> & {
|
|
35
|
+
toolStepRoleAddress: MutableToolStepRoleAddress<TKey>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type MutableExternalInputPotential = ExternalInputPotential;
|
|
39
|
+
|
|
40
|
+
export type MutableStrategyStateInputEntry<TKey extends string = MutableToolStepKey> =
|
|
41
|
+
| MutableInputResource
|
|
42
|
+
| MutableInternalInputPotential<TKey>
|
|
43
|
+
| MutableExternalInputPotential;
|
|
44
|
+
|
|
45
|
+
export type MutableStrategyStateInputEntryByRoleName<
|
|
46
|
+
TKey extends string = MutableToolStepKey,
|
|
47
|
+
> = Partial<Record<RoleName, MutableStrategyStateInputEntry<TKey>>>;
|
|
48
|
+
|
|
49
|
+
export type MutableStrategyState<
|
|
50
|
+
TKey extends string = MutableToolStepKey,
|
|
51
|
+
> = Partial<Record<TKey, MutableStrategyStateInputEntryByRoleName<TKey>>>;
|
|
52
|
+
|
|
53
|
+
export type MutableToolStep<TKey extends string = MutableToolStepKey> = ToolStep & {
|
|
54
|
+
toolStepKey: TKey;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export type MutableCase<TKey extends string = MutableToolStepKey> = Omit<Case, 'when' | 'what'> & {
|
|
58
|
+
when: MutableToolStep<TKey>;
|
|
59
|
+
what: MutableToolStep<TKey>;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export type MutableBranchStep<TKey extends string = MutableToolStepKey> = Omit<BranchStep, 'cases'> & {
|
|
63
|
+
macroStepKey: MutableBranchStepKey;
|
|
64
|
+
cases: [MutableCase<TKey>, ...MutableCase<TKey>[]];
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export type MutableWhileStep<TKey extends string = MutableToolStepKey> = Omit<WhileStep, 'case'> & {
|
|
68
|
+
macroStepKey: MutableWhileStepKey;
|
|
69
|
+
case: MutableCase<TKey>;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export type MutableForStep<TKey extends string = MutableToolStepKey> = Omit<ForStep, 'case'> & {
|
|
73
|
+
macroStepKey: MutableForStepKey;
|
|
74
|
+
case: MutableCase<TKey>;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export type MutableStep<TKey extends string = MutableToolStepKey> =
|
|
78
|
+
| MutableToolStep<TKey>
|
|
79
|
+
| MutableBranchStep<TKey>
|
|
80
|
+
| MutableWhileStep<TKey>
|
|
81
|
+
| MutableForStep<TKey>;
|
|
82
|
+
|
|
83
|
+
export type MutableStrategy<
|
|
84
|
+
TKey extends string = MutableToolStepKey,
|
|
85
|
+
TStep extends MutableStep<TKey> = MutableStep<TKey>,
|
|
86
|
+
TState extends MutableStrategyState<TKey> = MutableStrategyState<TKey>,
|
|
87
|
+
> = Omit<Strategy, 'stepsByThreadIndex' | 'strategyState'> & {
|
|
88
|
+
stepsByThreadIndex: TStep[][];
|
|
89
|
+
strategyState: TState;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export function getAuthoringSteps<
|
|
93
|
+
TKey extends string = MutableToolStepKey,
|
|
94
|
+
TStep extends MutableStep<TKey> = MutableStep<TKey>,
|
|
95
|
+
TState extends MutableStrategyState<TKey> = MutableStrategyState<TKey>,
|
|
96
|
+
>(
|
|
97
|
+
strategy: MutableStrategy<TKey, TStep, TState>,
|
|
98
|
+
): TStep[] {
|
|
99
|
+
return strategy.stepsByThreadIndex[0] ?? [];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function setAuthoringSteps< // ATTENTION
|
|
103
|
+
TKey extends string = MutableToolStepKey,
|
|
104
|
+
TStep extends MutableStep<TKey> = MutableStep<TKey>,
|
|
105
|
+
TState extends MutableStrategyState<TKey> = MutableStrategyState<TKey>,
|
|
106
|
+
>(
|
|
107
|
+
strategy: MutableStrategy<TKey, TStep, TState>,
|
|
108
|
+
steps: TStep[],
|
|
109
|
+
): MutableStrategy<TKey, TStep, TState> {
|
|
110
|
+
const nextStepsByThreadIndex = [...strategy.stepsByThreadIndex];
|
|
111
|
+
nextStepsByThreadIndex[0] = steps;
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
...strategy,
|
|
115
|
+
stepsByThreadIndex: nextStepsByThreadIndex,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function getStrategyStateInputEntryByRoleName<TKey extends string, TStrategyState extends MutableStrategyState<TKey>>(
|
|
120
|
+
strategyState: TStrategyState,
|
|
121
|
+
toolStepKey: TKey,
|
|
122
|
+
): MutableStrategyStateInputEntryByRoleName<TKey> | undefined {
|
|
123
|
+
return strategyState[toolStepKey];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function getStrategyStateInputEntry<TKey extends string, TStrategyState extends MutableStrategyState<TKey>>(
|
|
127
|
+
strategyState: TStrategyState,
|
|
128
|
+
toolStepRoleAddress: MutableToolStepRoleAddress<TKey>,
|
|
129
|
+
): MutableStrategyStateInputEntry<TKey> | undefined {
|
|
130
|
+
const inputEntryByRoleName = getStrategyStateInputEntryByRoleName(strategyState, toolStepRoleAddress.toolStepKey);
|
|
131
|
+
return inputEntryByRoleName?.[toolStepRoleAddress.roleName];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function setStrategyStateInputEntry<TKey extends string, TStrategyState extends MutableStrategyState<TKey>>(
|
|
135
|
+
strategyState: TStrategyState,
|
|
136
|
+
toolStepRoleAddress: MutableToolStepRoleAddress<TKey>,
|
|
137
|
+
entry: MutableStrategyStateInputEntry<TKey>,
|
|
138
|
+
): TStrategyState {
|
|
139
|
+
const inputEntryByRoleName = getStrategyStateInputEntryByRoleName(strategyState, toolStepRoleAddress.toolStepKey) ?? {};
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
...strategyState,
|
|
143
|
+
[toolStepRoleAddress.toolStepKey]: {
|
|
144
|
+
...inputEntryByRoleName,
|
|
145
|
+
[toolStepRoleAddress.roleName]: entry,
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function clearInputBinding<
|
|
151
|
+
TKey extends string,
|
|
152
|
+
TStrategyState extends MutableStrategyState<TKey>
|
|
153
|
+
>(
|
|
154
|
+
strategyState: TStrategyState,
|
|
155
|
+
toolStepRoleAddress: MutableToolStepRoleAddress<TKey>,
|
|
156
|
+
): TStrategyState {
|
|
157
|
+
const inputEntryByRoleName =
|
|
158
|
+
getStrategyStateInputEntryByRoleName(
|
|
159
|
+
strategyState,
|
|
160
|
+
toolStepRoleAddress.toolStepKey,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
if (!inputEntryByRoleName || !(toolStepRoleAddress.roleName in inputEntryByRoleName)) {
|
|
164
|
+
return strategyState;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const nextInputEntryByRoleName = { ...inputEntryByRoleName };
|
|
168
|
+
delete nextInputEntryByRoleName[toolStepRoleAddress.roleName];
|
|
169
|
+
|
|
170
|
+
if (Object.keys(nextInputEntryByRoleName).length === 0) {
|
|
171
|
+
const nextStrategyState = { ...strategyState };
|
|
172
|
+
delete nextStrategyState[toolStepRoleAddress.toolStepKey];
|
|
173
|
+
return nextStrategyState as TStrategyState;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
...strategyState,
|
|
178
|
+
[toolStepRoleAddress.toolStepKey]: nextInputEntryByRoleName,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function bindInputResource<TKey extends string, TStrategyState extends MutableStrategyState<TKey>>(
|
|
183
|
+
strategyState: TStrategyState,
|
|
184
|
+
target: MutableToolStepRoleAddress<TKey>,
|
|
185
|
+
resource: Resource,
|
|
186
|
+
): TStrategyState {
|
|
187
|
+
const mutableInputResource: MutableInputResource = {
|
|
188
|
+
...resource,
|
|
189
|
+
strategyStateInputKind: 'inputResource',
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
return setStrategyStateInputEntry(strategyState, target, mutableInputResource);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function getInputRoleValue(tool: Tool, roleName: RoleName) {
|
|
196
|
+
return tool.roleSpec.inputRoleValueByName[roleName];
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function getOutputRoleValue(tool: Tool, roleName: RoleName) {
|
|
200
|
+
return tool.roleSpec.outputRoleValueByName[roleName];
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function bindInternalInputPotential<TKey extends string, TStrategyState extends MutableStrategyState<TKey>>(
|
|
204
|
+
strategyState: TStrategyState,
|
|
205
|
+
targetAddress: MutableToolStepRoleAddress<TKey>,
|
|
206
|
+
sourceAddress: MutableToolStepRoleAddress<TKey>,
|
|
207
|
+
context: {
|
|
208
|
+
toolStepByKey: ReadonlyMap<TKey, MutableToolStep<TKey>>;
|
|
209
|
+
toolMap: ReadonlyMap<ToolHandle, Tool>;
|
|
210
|
+
}
|
|
211
|
+
): TStrategyState {
|
|
212
|
+
|
|
213
|
+
const sourceToolStep = context.toolStepByKey.get(sourceAddress.toolStepKey) ?? null;
|
|
214
|
+
if (!sourceToolStep) {
|
|
215
|
+
throw new Error(`Source tool step not found for '${sourceAddress.toolStepKey}'.`);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const targetToolStep = context.toolStepByKey.get(targetAddress.toolStepKey) ?? null;
|
|
219
|
+
if (!targetToolStep) {
|
|
220
|
+
throw new Error(`Target tool step not found for '${targetAddress.toolStepKey}'.`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const sourceTool = context.toolMap.get(sourceToolStep.toolHandle) ?? null;
|
|
224
|
+
if (!sourceTool) {
|
|
225
|
+
throw new Error(`Source tool not found for '${sourceToolStep.toolHandle}'.`);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const targetTool = context.toolMap.get(targetToolStep.toolHandle) ?? null;
|
|
229
|
+
if (!targetTool) {
|
|
230
|
+
throw new Error(`Target tool not found for '${targetToolStep.toolHandle}'.`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const targetInputRole = getInputRoleValue(targetTool, targetAddress.roleName);
|
|
234
|
+
if (!targetInputRole) {
|
|
235
|
+
throw new Error(`Target input role not found for (${targetAddress.toolStepKey}, ${targetAddress.roleName}).`);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const sourceOutputRole = getOutputRoleValue(sourceTool, sourceAddress.roleName);
|
|
239
|
+
const sourceInputRole = getInputRoleValue(sourceTool, sourceAddress.roleName);
|
|
240
|
+
|
|
241
|
+
const sourceInputEntryByRoleName = strategyState[sourceAddress.toolStepKey];
|
|
242
|
+
const sourceInputEntry = sourceInputEntryByRoleName?.[sourceAddress.roleName];
|
|
243
|
+
|
|
244
|
+
const sourceRoleType = sourceOutputRole
|
|
245
|
+
? extractResourceTypeHandleFromRoleValue(sourceOutputRole)
|
|
246
|
+
: sourceInputRole
|
|
247
|
+
? extractResourceTypeHandleFromRoleValue(sourceInputRole)
|
|
248
|
+
: null;
|
|
249
|
+
|
|
250
|
+
const targetRoleType = extractResourceTypeHandleFromRoleValue(targetInputRole);
|
|
251
|
+
|
|
252
|
+
if (!sourceOutputRole && sourceInputRole) {
|
|
253
|
+
if (!sourceInputEntry) {
|
|
254
|
+
throw new Error(`Source input role is not bound for (${sourceAddress.toolStepKey}, ${sourceAddress.roleName}).`); // ATTENTION: not an ontological invariant, but it might help catch some mistakes early on.
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (!sourceOutputRole && !sourceInputRole) {
|
|
259
|
+
throw new Error(`Source role not found for (${sourceAddress.toolStepKey}, ${sourceAddress.roleName}).`);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (!sourceRoleType || !targetRoleType || sourceRoleType !== targetRoleType) {
|
|
263
|
+
throw new Error(
|
|
264
|
+
`Reference type mismatch between source (${sourceAddress.toolStepKey}, ${sourceAddress.roleName}) and target (${targetAddress.toolStepKey}, ${targetAddress.roleName}).`
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return setStrategyStateInputEntry(strategyState, targetAddress, {
|
|
269
|
+
strategyStateInputKind: 'internalInputPotential',
|
|
270
|
+
toolStepRoleAddress: {
|
|
271
|
+
toolStepKey: sourceAddress.toolStepKey,
|
|
272
|
+
roleName: sourceAddress.roleName,
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export function bindExternalInputPotential<TKey extends string, TStrategyState extends MutableStrategyState<TKey>>(
|
|
278
|
+
strategyState: TStrategyState,
|
|
279
|
+
target: MutableToolStepRoleAddress<TKey>,
|
|
280
|
+
): TStrategyState {
|
|
281
|
+
const mutableExternalInputPotential: MutableExternalInputPotential = {
|
|
282
|
+
strategyStateInputKind: 'externalInputPotential',
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
return setStrategyStateInputEntry(strategyState, target, mutableExternalInputPotential);
|
|
286
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ToolStepRoleAddress,
|
|
3
|
+
ResourceId,
|
|
4
|
+
Resource,
|
|
5
|
+
ResourcePointer,
|
|
6
|
+
ResourceTypeHandle,
|
|
7
|
+
RuntimeProvenance,
|
|
8
|
+
StrategyProvenance,
|
|
9
|
+
Provenance,
|
|
10
|
+
StrategyTraceHandle,
|
|
11
|
+
} from '@toolproof-core/genesis';
|
|
12
|
+
import { CONSTANTS } from '../lookups/lookups.js';
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
export type ResourceCreationDescriptor =
|
|
16
|
+
| {
|
|
17
|
+
id: ResourceId;
|
|
18
|
+
resourceTypeHandle: ResourceTypeHandle;
|
|
19
|
+
}
|
|
20
|
+
| {
|
|
21
|
+
id: ResourceId;
|
|
22
|
+
resourceTypeHandle: ResourceTypeHandle;
|
|
23
|
+
toolStepRoleAddress: ToolStepRoleAddress;
|
|
24
|
+
strategyTraceHandle: StrategyTraceHandle;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function createStrategyProvenance(
|
|
28
|
+
strategyTraceHandle: StrategyTraceHandle,
|
|
29
|
+
toolStepRoleAddress: ToolStepRoleAddress,
|
|
30
|
+
): StrategyProvenance {
|
|
31
|
+
return {
|
|
32
|
+
provenanceKind: CONSTANTS.Enums.ProvenanceKind.strategy,
|
|
33
|
+
strategyTraceHandle,
|
|
34
|
+
toolStepRoleAddress,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function createRuntimeProvenance(): RuntimeProvenance {
|
|
39
|
+
return {
|
|
40
|
+
provenanceKind: CONSTANTS.Enums.ProvenanceKind.runtime,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function createResourcePointer(
|
|
45
|
+
id: ResourceId,
|
|
46
|
+
resourceTypeHandle: ResourceTypeHandle,
|
|
47
|
+
provenance: Provenance,
|
|
48
|
+
): ResourcePointer {
|
|
49
|
+
return {
|
|
50
|
+
id,
|
|
51
|
+
resourceTypeHandle,
|
|
52
|
+
provenance,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function createResource(
|
|
57
|
+
resourcePointer: ResourcePointer,
|
|
58
|
+
projection: unknown,
|
|
59
|
+
): Resource {
|
|
60
|
+
return {
|
|
61
|
+
...resourcePointer,
|
|
62
|
+
projection,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function createResourceFromDescriptor(
|
|
67
|
+
descriptor: ResourceCreationDescriptor,
|
|
68
|
+
projection: unknown,
|
|
69
|
+
): Resource {
|
|
70
|
+
const provenance =
|
|
71
|
+
'toolStepRoleAddress' in descriptor
|
|
72
|
+
? createStrategyProvenance(
|
|
73
|
+
descriptor.strategyTraceHandle,
|
|
74
|
+
descriptor.toolStepRoleAddress,
|
|
75
|
+
)
|
|
76
|
+
: createRuntimeProvenance();
|
|
77
|
+
|
|
78
|
+
return createResource(
|
|
79
|
+
createResourcePointer(
|
|
80
|
+
descriptor.id,
|
|
81
|
+
descriptor.resourceTypeHandle,
|
|
82
|
+
provenance,
|
|
83
|
+
),
|
|
84
|
+
projection,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Tool,
|
|
3
|
+
} from '@toolproof-core/genesis';
|
|
4
|
+
import type {
|
|
5
|
+
MutableToolStep,
|
|
6
|
+
MutableCase,
|
|
7
|
+
MutableWhileStep,
|
|
8
|
+
MutableForStep,
|
|
9
|
+
MutableBranchStep,
|
|
10
|
+
} from './mutableStrategyOverlay.js';
|
|
11
|
+
import { CONSTANTS } from '../lookups/lookups.js';
|
|
12
|
+
import { getInputRoleNamesFromTool, getOutputRoleNamesFromTool } from './strategyExtraction.js';
|
|
13
|
+
import { generateIdentifier } from './identifierGeneration.js';
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
function assertNonEmpty<T>(arr: T[], msg: string): asserts arr is [T, ...T[]] {
|
|
17
|
+
if (arr.length === 0) {
|
|
18
|
+
throw new Error(msg);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getRoleBindingSpec(tool: Tool): MutableToolStep['roleBindingSpec'] {
|
|
23
|
+
return {
|
|
24
|
+
inputBindings: getInputRoleNamesFromTool(tool),
|
|
25
|
+
outputBindings: getOutputRoleNamesFromTool(tool),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function createToolStepFromTool(
|
|
30
|
+
tool: Tool,
|
|
31
|
+
): MutableToolStep {
|
|
32
|
+
return {
|
|
33
|
+
toolStepKey: generateIdentifier('ToolStepKey'),
|
|
34
|
+
stepKind: CONSTANTS.Enums.StepKind.tool,
|
|
35
|
+
toolHandle: tool.handle,
|
|
36
|
+
roleBindingSpec: getRoleBindingSpec(tool),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function createCaseFromToolStepPair(
|
|
41
|
+
what: MutableToolStep,
|
|
42
|
+
when: MutableToolStep,
|
|
43
|
+
): MutableCase {
|
|
44
|
+
return { what, when };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function createLoopStepFromCase(
|
|
48
|
+
stepCase: MutableCase,
|
|
49
|
+
stepKind: typeof CONSTANTS.Enums.StepKind.for | typeof CONSTANTS.Enums.StepKind.while,
|
|
50
|
+
): MutableForStep | MutableWhileStep {
|
|
51
|
+
if (stepKind === CONSTANTS.Enums.StepKind.for) {
|
|
52
|
+
return {
|
|
53
|
+
macroStepKey: generateIdentifier('ForStepKey'),
|
|
54
|
+
stepKind: CONSTANTS.Enums.StepKind.for,
|
|
55
|
+
case: stepCase,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
macroStepKey: generateIdentifier('WhileStepKey'),
|
|
61
|
+
stepKind: CONSTANTS.Enums.StepKind.while,
|
|
62
|
+
case: stepCase,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function createBranchStepFromCases(
|
|
67
|
+
cases: MutableCase[],
|
|
68
|
+
): MutableBranchStep {
|
|
69
|
+
assertNonEmpty(cases, 'createBranchStepFromCases requires at least one case');
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
macroStepKey: generateIdentifier('BranchStepKey'),
|
|
73
|
+
stepKind: CONSTANTS.Enums.StepKind.branch,
|
|
74
|
+
cases,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function cloneForStep(
|
|
79
|
+
forStep: MutableForStep,
|
|
80
|
+
): MutableForStep {
|
|
81
|
+
return {
|
|
82
|
+
macroStepKey: generateIdentifier('ForStepKey'),
|
|
83
|
+
stepKind: CONSTANTS.Enums.StepKind.for,
|
|
84
|
+
case: {
|
|
85
|
+
what: {
|
|
86
|
+
...forStep.case.what,
|
|
87
|
+
toolStepKey: generateIdentifier('ToolStepKey'),
|
|
88
|
+
},
|
|
89
|
+
when: {
|
|
90
|
+
...forStep.case.when,
|
|
91
|
+
toolStepKey: generateIdentifier('ToolStepKey'),
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function cloneWhileStep(
|
|
98
|
+
whileStep: MutableWhileStep,
|
|
99
|
+
): MutableWhileStep {
|
|
100
|
+
return {
|
|
101
|
+
macroStepKey: generateIdentifier('WhileStepKey'),
|
|
102
|
+
stepKind: CONSTANTS.Enums.StepKind.while,
|
|
103
|
+
case: {
|
|
104
|
+
what: {
|
|
105
|
+
...whileStep.case.what,
|
|
106
|
+
toolStepKey: generateIdentifier('ToolStepKey'),
|
|
107
|
+
},
|
|
108
|
+
when: {
|
|
109
|
+
...whileStep.case.when,
|
|
110
|
+
toolStepKey: generateIdentifier('ToolStepKey'),
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
MutableBranchStep,
|
|
3
|
+
MutableForStep,
|
|
4
|
+
MutableStep,
|
|
5
|
+
MutableStrategyState,
|
|
6
|
+
MutableToolStep,
|
|
7
|
+
MutableToolStepKey,
|
|
8
|
+
MutableWhileStep,
|
|
9
|
+
} from './mutableStrategyOverlay.js';
|
|
10
|
+
import { CONSTANTS } from '../lookups/lookups.js';
|
|
11
|
+
|
|
12
|
+
export function getIndependentThreads<
|
|
13
|
+
TKey extends string = MutableToolStepKey,
|
|
14
|
+
TStep extends MutableStep<TKey> = MutableStep<TKey>,
|
|
15
|
+
>(
|
|
16
|
+
steps: TStep[],
|
|
17
|
+
strategyState: MutableStrategyState<TKey>,
|
|
18
|
+
): TStep[][] {
|
|
19
|
+
type OwnerIndex = number;
|
|
20
|
+
|
|
21
|
+
const getOwnerLabel = (ownerIndex: OwnerIndex) => {
|
|
22
|
+
const step = steps[ownerIndex];
|
|
23
|
+
return `steps[${ownerIndex}] stepKind=${step?.stepKind ?? 'unknown'}`;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const toolStepKeyToOwner = new Map<TKey, OwnerIndex>();
|
|
27
|
+
const toolStepByKey = new Map<TKey, MutableToolStep<TKey>>();
|
|
28
|
+
|
|
29
|
+
const addToolStep = (
|
|
30
|
+
toolStep: MutableToolStep<TKey> | undefined,
|
|
31
|
+
ownerIndex: OwnerIndex,
|
|
32
|
+
) => {
|
|
33
|
+
if (!toolStep) return;
|
|
34
|
+
|
|
35
|
+
const existingOwner = toolStepKeyToOwner.get(toolStep.toolStepKey);
|
|
36
|
+
if (existingOwner !== undefined) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`Duplicate toolStepKey '${toolStep.toolStepKey}' found in ${getOwnerLabel(ownerIndex)} and ${getOwnerLabel(existingOwner)}`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
toolStepKeyToOwner.set(toolStep.toolStepKey, ownerIndex);
|
|
43
|
+
toolStepByKey.set(toolStep.toolStepKey, toolStep);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
steps.forEach((step, ownerIndex) => {
|
|
47
|
+
if (step.stepKind === CONSTANTS.Enums.StepKind.tool) {
|
|
48
|
+
addToolStep(step as MutableToolStep<TKey>, ownerIndex);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (step.stepKind === CONSTANTS.Enums.StepKind.for) {
|
|
53
|
+
const loop = step as MutableForStep<TKey>;
|
|
54
|
+
addToolStep(loop.case?.what, ownerIndex);
|
|
55
|
+
addToolStep(loop.case?.when, ownerIndex);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (step.stepKind === CONSTANTS.Enums.StepKind.while) {
|
|
60
|
+
const loop = step as MutableWhileStep<TKey>;
|
|
61
|
+
addToolStep(loop.case?.what, ownerIndex);
|
|
62
|
+
addToolStep(loop.case?.when, ownerIndex);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (step.stepKind === CONSTANTS.Enums.StepKind.branch) {
|
|
67
|
+
const branch = step as MutableBranchStep<TKey>;
|
|
68
|
+
for (const stepCase of branch.cases) {
|
|
69
|
+
addToolStep(stepCase?.what, ownerIndex);
|
|
70
|
+
addToolStep(stepCase?.when, ownerIndex);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const ownerAdj = new Map<OwnerIndex, Set<OwnerIndex>>();
|
|
76
|
+
const ownerDeps = new Map<OwnerIndex, Set<OwnerIndex>>();
|
|
77
|
+
|
|
78
|
+
const ensureOwner = (ownerIndex: OwnerIndex) => {
|
|
79
|
+
if (!ownerAdj.has(ownerIndex)) ownerAdj.set(ownerIndex, new Set());
|
|
80
|
+
if (!ownerDeps.has(ownerIndex)) ownerDeps.set(ownerIndex, new Set());
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
for (let index = 0; index < steps.length; index++) {
|
|
84
|
+
ensureOwner(index);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
for (const [toolStepKey, ownerIndex] of toolStepKeyToOwner) {
|
|
88
|
+
ensureOwner(ownerIndex);
|
|
89
|
+
|
|
90
|
+
const toolStep = toolStepByKey.get(toolStepKey);
|
|
91
|
+
const inputBindings = toolStep?.roleBindingSpec?.inputBindings ?? [];
|
|
92
|
+
const bucket = strategyState[toolStepKey];
|
|
93
|
+
|
|
94
|
+
for (const inputRoleId of inputBindings) {
|
|
95
|
+
const entry = bucket?.[inputRoleId];
|
|
96
|
+
if (!entry || entry.strategyStateInputKind !== 'internalInputPotential') continue;
|
|
97
|
+
|
|
98
|
+
const producerToolStepKey = entry.toolStepRoleAddress?.toolStepKey;
|
|
99
|
+
if (typeof producerToolStepKey !== 'string') {
|
|
100
|
+
throw new Error(
|
|
101
|
+
`Unresolvable internalInputPotential in toolStep '${toolStepKey}' (${getOwnerLabel(ownerIndex)}): missing toolStepRoleAddress.toolStepKey for role '${inputRoleId}'`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const producerOwner = toolStepKeyToOwner.get(producerToolStepKey as TKey);
|
|
106
|
+
if (producerOwner === undefined) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`Unresolvable internalInputPotential in toolStep '${toolStepKey}' (${getOwnerLabel(ownerIndex)}): source toolStepKey '${producerToolStepKey}' not found in strategy steps`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
ensureOwner(producerOwner);
|
|
113
|
+
ownerAdj.get(ownerIndex)?.add(producerOwner);
|
|
114
|
+
ownerAdj.get(producerOwner)?.add(ownerIndex);
|
|
115
|
+
ownerDeps.get(ownerIndex)?.add(producerOwner);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const visited = new Set<OwnerIndex>();
|
|
120
|
+
const components: OwnerIndex[][] = [];
|
|
121
|
+
|
|
122
|
+
for (let ownerIndex = 0; ownerIndex < steps.length; ownerIndex++) {
|
|
123
|
+
if (visited.has(ownerIndex)) continue;
|
|
124
|
+
|
|
125
|
+
const component: OwnerIndex[] = [];
|
|
126
|
+
const queue: OwnerIndex[] = [ownerIndex];
|
|
127
|
+
visited.add(ownerIndex);
|
|
128
|
+
|
|
129
|
+
while (queue.length > 0) {
|
|
130
|
+
const node = queue.shift();
|
|
131
|
+
if (node === undefined) break;
|
|
132
|
+
component.push(node);
|
|
133
|
+
|
|
134
|
+
for (const neighbor of ownerAdj.get(node) ?? []) {
|
|
135
|
+
if (visited.has(neighbor)) continue;
|
|
136
|
+
visited.add(neighbor);
|
|
137
|
+
queue.push(neighbor);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
components.push(component);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for (const component of components) {
|
|
145
|
+
const componentOwners = new Set(component);
|
|
146
|
+
const ownersInOrder = steps.map((_, index) => index).filter((index) => componentOwners.has(index));
|
|
147
|
+
const position = new Map<OwnerIndex, number>();
|
|
148
|
+
|
|
149
|
+
ownersInOrder.forEach((owner, index) => position.set(owner, index));
|
|
150
|
+
|
|
151
|
+
for (const consumerOwner of ownersInOrder) {
|
|
152
|
+
const deps = ownerDeps.get(consumerOwner);
|
|
153
|
+
if (!deps || deps.size === 0) continue;
|
|
154
|
+
|
|
155
|
+
const consumerPos = position.get(consumerOwner);
|
|
156
|
+
if (consumerPos === undefined) continue;
|
|
157
|
+
|
|
158
|
+
for (const producerOwner of deps) {
|
|
159
|
+
const producerPos = position.get(producerOwner);
|
|
160
|
+
if (producerPos === undefined) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`Internal error: dependency producer ${getOwnerLabel(producerOwner)} missing from computed thread for ${getOwnerLabel(consumerOwner)}`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (producerPos >= consumerPos) {
|
|
167
|
+
throw new Error(
|
|
168
|
+
`Invalid step order in thread: ${getOwnerLabel(consumerOwner)} depends on ${getOwnerLabel(producerOwner)}, but producer is not scheduled before consumer`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return components
|
|
176
|
+
.map((component) => {
|
|
177
|
+
const ownerSet = new Set(component);
|
|
178
|
+
return steps.filter((_step, index) => ownerSet.has(index));
|
|
179
|
+
})
|
|
180
|
+
.filter((group) => group.length > 0);
|
|
181
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Strategy } from '@toolproof-core/genesis';
|
|
2
|
+
import type { MutableStrategy } from './mutableStrategyOverlay.js';
|
|
3
|
+
import { toExecutionMutableStrategy } from './strategyThreading.js';
|
|
4
|
+
import { mutableStrategyToStrategy } from './strategyCanonicalization.js';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export function composeStrategyForExecution<TKey extends string>(
|
|
8
|
+
mutableStrategy: MutableStrategy<TKey>,
|
|
9
|
+
): Strategy {
|
|
10
|
+
const executionStrategy =
|
|
11
|
+
toExecutionMutableStrategy(mutableStrategy);
|
|
12
|
+
|
|
13
|
+
return mutableStrategyToStrategy(executionStrategy);
|
|
14
|
+
}
|