@toolproof-core/lib 1.0.41 → 1.0.43

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.
@@ -16,7 +16,11 @@ export declare const CONSTANTS: {
16
16
  };
17
17
  };
18
18
  readonly Cosmos: {
19
- readonly ErrorOutputRoleName: "ErrorOutput";
19
+ readonly RoleNames: {
20
+ readonly ErrorOutput: "ErrorOutput";
21
+ readonly LessThanSource: "LessThanSource";
22
+ readonly LessThanTarget: "LessThanTarget";
23
+ };
20
24
  };
21
25
  readonly Names: {
22
26
  readonly AtomicTypeRef: "AtomicTypeRef";
@@ -18,7 +18,11 @@ export const CONSTANTS = {
18
18
  },
19
19
  },
20
20
  Cosmos: {
21
- ErrorOutputRoleName: 'ErrorOutput',
21
+ RoleNames: {
22
+ ErrorOutput: 'ErrorOutput',
23
+ LessThanSource: 'LessThanSource',
24
+ LessThanTarget: 'LessThanTarget',
25
+ }
22
26
  }
23
27
  };
24
28
  export const MAPPINGS = {
@@ -58,42 +58,42 @@ 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.toolStepKey) ?? null;
61
+ const sourceToolStep = context.toolStepByKey.get(sourceAddress.toolStepKey);
62
62
  if (!sourceToolStep) {
63
63
  throw new Error(`Source tool step not found for '${sourceAddress.toolStepKey}'.`);
64
64
  }
65
- const targetToolStep = context.toolStepByKey.get(targetAddress.toolStepKey) ?? null;
65
+ const targetToolStep = context.toolStepByKey.get(targetAddress.toolStepKey);
66
66
  if (!targetToolStep) {
67
67
  throw new Error(`Target tool step not found for '${targetAddress.toolStepKey}'.`);
68
68
  }
69
- const sourceTool = context.toolMap.get(sourceToolStep.toolHandle) ?? null;
69
+ const sourceTool = context.toolMap.get(sourceToolStep.toolHandle);
70
70
  if (!sourceTool) {
71
71
  throw new Error(`Source tool not found for '${sourceToolStep.toolHandle}'.`);
72
72
  }
73
- const targetTool = context.toolMap.get(targetToolStep.toolHandle) ?? null;
73
+ const targetTool = context.toolMap.get(targetToolStep.toolHandle);
74
74
  if (!targetTool) {
75
75
  throw new Error(`Target tool not found for '${targetToolStep.toolHandle}'.`);
76
76
  }
77
- const targetInputRole = getInputRoleValue(targetTool, targetAddress.roleName);
78
- if (!targetInputRole) {
77
+ const targetInputRoleValue = getInputRoleValue(targetTool, targetAddress.roleName);
78
+ if (!targetInputRoleValue) {
79
79
  throw new Error(`Target input role not found for (${targetAddress.toolStepKey}, ${targetAddress.roleName}).`);
80
80
  }
81
- const sourceOutputRole = getOutputRoleValue(sourceTool, sourceAddress.roleName);
82
- const sourceInputRole = getInputRoleValue(sourceTool, sourceAddress.roleName);
81
+ const sourceOutputRoleValue = getOutputRoleValue(sourceTool, sourceAddress.roleName);
82
+ const sourceInputRoleValue = getInputRoleValue(sourceTool, sourceAddress.roleName);
83
83
  const sourceInputEntryByRoleName = strategyState[sourceAddress.toolStepKey];
84
84
  const sourceInputEntry = sourceInputEntryByRoleName?.[sourceAddress.roleName];
85
- const sourceRoleType = sourceOutputRole
86
- ? extractResourceTypeHandleFromRoleValue(sourceOutputRole)
87
- : sourceInputRole
88
- ? extractResourceTypeHandleFromRoleValue(sourceInputRole)
85
+ const sourceRoleType = sourceOutputRoleValue
86
+ ? extractResourceTypeHandleFromRoleValue(sourceOutputRoleValue)
87
+ : sourceInputRoleValue
88
+ ? extractResourceTypeHandleFromRoleValue(sourceInputRoleValue)
89
89
  : null;
90
- const targetRoleType = extractResourceTypeHandleFromRoleValue(targetInputRole);
91
- if (!sourceOutputRole && sourceInputRole) {
90
+ const targetRoleType = extractResourceTypeHandleFromRoleValue(targetInputRoleValue);
91
+ if (!sourceOutputRoleValue && sourceInputRoleValue) {
92
92
  if (!sourceInputEntry) {
93
93
  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.
94
94
  }
95
95
  }
96
- if (!sourceOutputRole && !sourceInputRole) {
96
+ if (!sourceOutputRoleValue && !sourceInputRoleValue) {
97
97
  throw new Error(`Source role not found for (${sourceAddress.toolStepKey}, ${sourceAddress.roleName}).`);
98
98
  }
99
99
  if (!sourceRoleType || !targetRoleType || sourceRoleType !== targetRoleType) {
@@ -0,0 +1,6 @@
1
+ import type { MutableStep, MutableToolStep, MutableToolStepKey } from './mutableStrategyOverlay.js';
2
+ export type StepExpansionOrder = {
3
+ branchCaseOrder?: 'when-what' | 'what-when';
4
+ loopCaseOrder?: 'what-when' | 'when-what';
5
+ };
6
+ export declare function extractToolStepsFromStep<TKey extends string = MutableToolStepKey, TStep extends MutableStep<TKey> = MutableStep<TKey>>(step: TStep, order?: StepExpansionOrder): MutableToolStep<TKey>[];
@@ -0,0 +1,32 @@
1
+ import { CONSTANTS } from '../lookups/lookups.js';
2
+ export function extractToolStepsFromStep(step, order = {}) {
3
+ const { branchCaseOrder = 'when-what', loopCaseOrder = 'what-when', } = order;
4
+ if (step.stepKind === CONSTANTS.Enums.StepKind.tool) {
5
+ return [step];
6
+ }
7
+ if (step.stepKind === CONSTANTS.Enums.StepKind.branch) {
8
+ const branch = step;
9
+ const cases = branch.cases ?? [];
10
+ return cases.flatMap((stepCase) => {
11
+ if (branchCaseOrder === 'what-when') {
12
+ return [stepCase.what, stepCase.when];
13
+ }
14
+ return [stepCase.when, stepCase.what];
15
+ }).filter(Boolean);
16
+ }
17
+ if (step.stepKind === CONSTANTS.Enums.StepKind.while) {
18
+ const loop = step;
19
+ if (loopCaseOrder === 'when-what') {
20
+ return [loop.case.when, loop.case.what].filter(Boolean);
21
+ }
22
+ return [loop.case.what, loop.case.when].filter(Boolean);
23
+ }
24
+ if (step.stepKind === CONSTANTS.Enums.StepKind.for) {
25
+ const loop = step;
26
+ if (loopCaseOrder === 'when-what') {
27
+ return [loop.case.when, loop.case.what].filter(Boolean);
28
+ }
29
+ return [loop.case.what, loop.case.when].filter(Boolean);
30
+ }
31
+ return [];
32
+ }
@@ -1,4 +1,4 @@
1
- import { CONSTANTS } from '../lookups/lookups.js';
1
+ import { extractToolStepsFromStep } from './stepExpansion.js';
2
2
  export function getIndependentThreads(steps, strategyState) {
3
3
  const getOwnerLabel = (ownerIndex) => {
4
4
  const step = steps[ownerIndex];
@@ -17,28 +17,8 @@ export function getIndependentThreads(steps, strategyState) {
17
17
  toolStepByKey.set(toolStep.toolStepKey, toolStep);
18
18
  };
19
19
  steps.forEach((step, ownerIndex) => {
20
- if (step.stepKind === CONSTANTS.Enums.StepKind.tool) {
21
- addToolStep(step, ownerIndex);
22
- return;
23
- }
24
- if (step.stepKind === CONSTANTS.Enums.StepKind.for) {
25
- const loop = step;
26
- addToolStep(loop.case?.what, ownerIndex);
27
- addToolStep(loop.case?.when, ownerIndex);
28
- return;
29
- }
30
- if (step.stepKind === CONSTANTS.Enums.StepKind.while) {
31
- const loop = step;
32
- addToolStep(loop.case?.what, ownerIndex);
33
- addToolStep(loop.case?.when, ownerIndex);
34
- return;
35
- }
36
- if (step.stepKind === CONSTANTS.Enums.StepKind.branch) {
37
- const branch = step;
38
- for (const stepCase of branch.cases) {
39
- addToolStep(stepCase?.what, ownerIndex);
40
- addToolStep(stepCase?.when, ownerIndex);
41
- }
20
+ for (const toolStep of extractToolStepsFromStep(step, { branchCaseOrder: 'what-when' })) {
21
+ addToolStep(toolStep, ownerIndex);
42
22
  }
43
23
  });
44
24
  const ownerAdj = new Map();
@@ -1,4 +1,5 @@
1
1
  import { CONSTANTS } from '../lookups/lookups.js';
2
+ import { extractToolStepsFromStep } from './stepExpansion.js';
2
3
  export function getInputRoleSpecEntriesFromTool(tool) {
3
4
  return Object.entries(tool.roleSpec.inputRoleValueByName);
4
5
  }
@@ -20,32 +21,9 @@ export function extractResourceTypeHandleFromRoleValue(roleValue) {
20
21
  }
21
22
  export function extractToolStepsFromStrategy(strategy) {
22
23
  const toolSteps = [];
23
- const visitStep = (step) => {
24
- switch (step.stepKind) {
25
- case 'tool': {
26
- toolSteps.push(step);
27
- return;
28
- }
29
- case 'branch': {
30
- for (const conditional of step.cases) {
31
- toolSteps.push(conditional.when, conditional.what);
32
- }
33
- return;
34
- }
35
- case 'while':
36
- case 'for': {
37
- toolSteps.push(step.case.when, step.case.what);
38
- return;
39
- }
40
- default: {
41
- const _exhaustive = step;
42
- return _exhaustive;
43
- }
44
- }
45
- };
46
24
  for (const threadSteps of strategy.stepsByThreadIndex) {
47
25
  for (const step of threadSteps) {
48
- visitStep(step);
26
+ toolSteps.push(...extractToolStepsFromStep(step, { loopCaseOrder: 'when-what' }));
49
27
  }
50
28
  }
51
29
  return toolSteps;
@@ -80,7 +58,7 @@ export function extractRoleSpecByDirectionByToolHandleFromStrategy(strategy, too
80
58
  return roleSpecByDirectionByToolHandle;
81
59
  }
82
60
  export function extractSingleBranchableOutputResourceTypeHandle(tool) {
83
- const outputRoleSpecEntries = getOutputRoleSpecEntriesFromTool(tool).filter(([roleName]) => roleName !== CONSTANTS.Cosmos.ErrorOutputRoleName);
61
+ const outputRoleSpecEntries = getOutputRoleSpecEntriesFromTool(tool).filter(([roleName]) => roleName !== CONSTANTS.Cosmos.RoleNames.ErrorOutput);
84
62
  if (!outputRoleSpecEntries[0] || outputRoleSpecEntries.length !== 1) {
85
63
  throw new Error(`Tool ${tool.handle} must have exactly one branchable output resource type to be branchable/loopable`);
86
64
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolproof-core/lib",
3
- "version": "1.0.41",
3
+ "version": "1.0.43",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "keywords": [],
@@ -39,6 +39,10 @@
39
39
  "types": "./dist/utils/stepCreation.d.ts",
40
40
  "import": "./dist/utils/stepCreation.js"
41
41
  },
42
+ "./step-expansion": {
43
+ "types": "./dist/utils/stepExpansion.d.ts",
44
+ "import": "./dist/utils/stepExpansion.js"
45
+ },
42
46
  "./tool-step-paths": {
43
47
  "types": "./dist/utils/toolStepPaths.d.ts",
44
48
  "import": "./dist/utils/toolStepPaths.js"
@@ -19,7 +19,11 @@ export const CONSTANTS = {
19
19
  },
20
20
  },
21
21
  Cosmos: {
22
- ErrorOutputRoleName: 'ErrorOutput' as const,
22
+ RoleNames: {
23
+ ErrorOutput: 'ErrorOutput' as const,
24
+ LessThanSource: 'LessThanSource' as const,
25
+ LessThanTarget: 'LessThanTarget' as const,
26
+ }
23
27
  }
24
28
  } as const;
25
29
 
@@ -210,52 +210,52 @@ export function bindInternalInputPotential<TKey extends string, TStrategyState e
210
210
  }
211
211
  ): TStrategyState {
212
212
 
213
- const sourceToolStep = context.toolStepByKey.get(sourceAddress.toolStepKey) ?? null;
213
+ const sourceToolStep = context.toolStepByKey.get(sourceAddress.toolStepKey);
214
214
  if (!sourceToolStep) {
215
215
  throw new Error(`Source tool step not found for '${sourceAddress.toolStepKey}'.`);
216
216
  }
217
217
 
218
- const targetToolStep = context.toolStepByKey.get(targetAddress.toolStepKey) ?? null;
218
+ const targetToolStep = context.toolStepByKey.get(targetAddress.toolStepKey);
219
219
  if (!targetToolStep) {
220
220
  throw new Error(`Target tool step not found for '${targetAddress.toolStepKey}'.`);
221
221
  }
222
222
 
223
- const sourceTool = context.toolMap.get(sourceToolStep.toolHandle) ?? null;
223
+ const sourceTool = context.toolMap.get(sourceToolStep.toolHandle);
224
224
  if (!sourceTool) {
225
225
  throw new Error(`Source tool not found for '${sourceToolStep.toolHandle}'.`);
226
226
  }
227
227
 
228
- const targetTool = context.toolMap.get(targetToolStep.toolHandle) ?? null;
228
+ const targetTool = context.toolMap.get(targetToolStep.toolHandle);
229
229
  if (!targetTool) {
230
230
  throw new Error(`Target tool not found for '${targetToolStep.toolHandle}'.`);
231
231
  }
232
232
 
233
- const targetInputRole = getInputRoleValue(targetTool, targetAddress.roleName);
234
- if (!targetInputRole) {
233
+ const targetInputRoleValue = getInputRoleValue(targetTool, targetAddress.roleName);
234
+ if (!targetInputRoleValue) {
235
235
  throw new Error(`Target input role not found for (${targetAddress.toolStepKey}, ${targetAddress.roleName}).`);
236
236
  }
237
237
 
238
- const sourceOutputRole = getOutputRoleValue(sourceTool, sourceAddress.roleName);
239
- const sourceInputRole = getInputRoleValue(sourceTool, sourceAddress.roleName);
238
+ const sourceOutputRoleValue = getOutputRoleValue(sourceTool, sourceAddress.roleName);
239
+ const sourceInputRoleValue = getInputRoleValue(sourceTool, sourceAddress.roleName);
240
240
 
241
241
  const sourceInputEntryByRoleName = strategyState[sourceAddress.toolStepKey];
242
242
  const sourceInputEntry = sourceInputEntryByRoleName?.[sourceAddress.roleName];
243
243
 
244
- const sourceRoleType = sourceOutputRole
245
- ? extractResourceTypeHandleFromRoleValue(sourceOutputRole)
246
- : sourceInputRole
247
- ? extractResourceTypeHandleFromRoleValue(sourceInputRole)
244
+ const sourceRoleType = sourceOutputRoleValue
245
+ ? extractResourceTypeHandleFromRoleValue(sourceOutputRoleValue)
246
+ : sourceInputRoleValue
247
+ ? extractResourceTypeHandleFromRoleValue(sourceInputRoleValue)
248
248
  : null;
249
249
 
250
- const targetRoleType = extractResourceTypeHandleFromRoleValue(targetInputRole);
250
+ const targetRoleType = extractResourceTypeHandleFromRoleValue(targetInputRoleValue);
251
251
 
252
- if (!sourceOutputRole && sourceInputRole) {
252
+ if (!sourceOutputRoleValue && sourceInputRoleValue) {
253
253
  if (!sourceInputEntry) {
254
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
255
  }
256
256
  }
257
257
 
258
- if (!sourceOutputRole && !sourceInputRole) {
258
+ if (!sourceOutputRoleValue && !sourceInputRoleValue) {
259
259
  throw new Error(`Source role not found for (${sourceAddress.toolStepKey}, ${sourceAddress.roleName}).`);
260
260
  }
261
261
 
@@ -0,0 +1,63 @@
1
+ import { CONSTANTS } from '../lookups/lookups.js';
2
+ import type {
3
+ MutableBranchStep,
4
+ MutableForStep,
5
+ MutableStep,
6
+ MutableToolStep,
7
+ MutableToolStepKey,
8
+ MutableWhileStep,
9
+ } from './mutableStrategyOverlay.js';
10
+
11
+ export type StepExpansionOrder = {
12
+ branchCaseOrder?: 'when-what' | 'what-when';
13
+ loopCaseOrder?: 'what-when' | 'when-what';
14
+ };
15
+
16
+ export function extractToolStepsFromStep<
17
+ TKey extends string = MutableToolStepKey,
18
+ TStep extends MutableStep<TKey> = MutableStep<TKey>,
19
+ >(
20
+ step: TStep,
21
+ order: StepExpansionOrder = {},
22
+ ): MutableToolStep<TKey>[] {
23
+ const {
24
+ branchCaseOrder = 'when-what',
25
+ loopCaseOrder = 'what-when',
26
+ } = order;
27
+
28
+ if (step.stepKind === CONSTANTS.Enums.StepKind.tool) {
29
+ return [step as MutableToolStep<TKey>];
30
+ }
31
+
32
+ if (step.stepKind === CONSTANTS.Enums.StepKind.branch) {
33
+ const branch = step as MutableBranchStep<TKey>;
34
+ const cases = branch.cases ?? [];
35
+ return cases.flatMap((stepCase) => {
36
+ if (branchCaseOrder === 'what-when') {
37
+ return [stepCase.what, stepCase.when];
38
+ }
39
+
40
+ return [stepCase.when, stepCase.what];
41
+ }).filter(Boolean) as MutableToolStep<TKey>[];
42
+ }
43
+
44
+ if (step.stepKind === CONSTANTS.Enums.StepKind.while) {
45
+ const loop = step as MutableWhileStep<TKey>;
46
+ if (loopCaseOrder === 'when-what') {
47
+ return [loop.case.when, loop.case.what].filter(Boolean) as MutableToolStep<TKey>[];
48
+ }
49
+
50
+ return [loop.case.what, loop.case.when].filter(Boolean) as MutableToolStep<TKey>[];
51
+ }
52
+
53
+ if (step.stepKind === CONSTANTS.Enums.StepKind.for) {
54
+ const loop = step as MutableForStep<TKey>;
55
+ if (loopCaseOrder === 'when-what') {
56
+ return [loop.case.when, loop.case.what].filter(Boolean) as MutableToolStep<TKey>[];
57
+ }
58
+
59
+ return [loop.case.what, loop.case.when].filter(Boolean) as MutableToolStep<TKey>[];
60
+ }
61
+
62
+ return [] as MutableToolStep<TKey>[];
63
+ }
@@ -1,13 +1,10 @@
1
1
  import type {
2
- MutableBranchStep,
3
- MutableForStep,
4
2
  MutableStep,
5
3
  MutableStrategyState,
6
4
  MutableToolStep,
7
5
  MutableToolStepKey,
8
- MutableWhileStep,
9
6
  } from './mutableStrategyOverlay.js';
10
- import { CONSTANTS } from '../lookups/lookups.js';
7
+ import { extractToolStepsFromStep } from './stepExpansion.js';
11
8
 
12
9
  export function getIndependentThreads<
13
10
  TKey extends string = MutableToolStepKey,
@@ -44,31 +41,8 @@ export function getIndependentThreads<
44
41
  };
45
42
 
46
43
  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
- }
44
+ for (const toolStep of extractToolStepsFromStep<TKey, TStep>(step, { branchCaseOrder: 'what-when' })) {
45
+ addToolStep(toolStep, ownerIndex);
72
46
  }
73
47
  });
74
48
 
@@ -8,10 +8,10 @@ import type {
8
8
  } from '@toolproof-core/genesis';
9
9
  import type {
10
10
  MutableStrategy,
11
- MutableStep,
12
11
  MutableToolStep
13
12
  } from './mutableStrategyOverlay.js';
14
13
  import { CONSTANTS } from '../lookups/lookups.js';
14
+ import { extractToolStepsFromStep } from './stepExpansion.js';
15
15
 
16
16
  export type RoleSpecEntry = [RoleName, RoleValue];
17
17
 
@@ -55,33 +55,9 @@ export function extractResourceTypeHandleFromRoleValue(
55
55
  export function extractToolStepsFromStrategy(strategy: MutableStrategy): MutableToolStep[] {
56
56
  const toolSteps: MutableToolStep[] = [];
57
57
 
58
- const visitStep = (step: MutableStep) => {
59
- switch (step.stepKind) {
60
- case 'tool': {
61
- toolSteps.push(step);
62
- return;
63
- }
64
- case 'branch': {
65
- for (const conditional of step.cases) {
66
- toolSteps.push(conditional.when, conditional.what);
67
- }
68
- return;
69
- }
70
- case 'while':
71
- case 'for': {
72
- toolSteps.push(step.case.when, step.case.what);
73
- return;
74
- }
75
- default: {
76
- const _exhaustive: never = step;
77
- return _exhaustive;
78
- }
79
- }
80
- };
81
-
82
58
  for (const threadSteps of strategy.stepsByThreadIndex) {
83
59
  for (const step of threadSteps) {
84
- visitStep(step);
60
+ toolSteps.push(...extractToolStepsFromStep(step, { loopCaseOrder: 'when-what' }));
85
61
  }
86
62
  }
87
63
 
@@ -137,7 +113,7 @@ export function extractSingleBranchableOutputResourceTypeHandle(
137
113
  tool: Tool,
138
114
  ): ResourceTypeHandle | null {
139
115
  const outputRoleSpecEntries = getOutputRoleSpecEntriesFromTool(tool).filter(
140
- ([roleName]) => roleName !== CONSTANTS.Cosmos.ErrorOutputRoleName,
116
+ ([roleName]) => roleName !== CONSTANTS.Cosmos.RoleNames.ErrorOutput,
141
117
  );
142
118
 
143
119
  if (!outputRoleSpecEntries[0] || outputRoleSpecEntries.length !== 1) {