@toolproof-core/lib 1.0.24 → 1.0.26
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/artifacts/artifacts.d.ts +21 -23
- package/dist/artifacts/artifacts.d.ts.map +1 -1
- package/dist/artifacts/artifacts.js +8 -8
- package/dist/artifacts/artifacts.js.map +1 -1
- package/dist/integrations/firebase/createStep.d.ts +6 -6
- package/dist/integrations/firebase/createStep.d.ts.map +1 -1
- package/dist/integrations/firebase/createStep.js +18 -18
- package/dist/integrations/firebase/createStep.js.map +1 -1
- package/dist/integrations/firebase/firebaseAdminHelpers.js +3 -3
- package/dist/integrations/firebase/firebaseAdminHelpers.js.map +1 -1
- package/dist/utils/bindInputRoleToResource.js +11 -11
- package/dist/utils/bindInputRoleToResource.js.map +1 -1
- package/dist/utils/creation/stepCreation.d.ts +16 -16
- package/dist/utils/creation/stepCreation.d.ts.map +1 -1
- package/dist/utils/creation/stepCreation.js +16 -16
- package/dist/utils/creation/stepCreation.js.map +1 -1
- package/dist/utils/extractData.d.ts +6 -6
- package/dist/utils/extractData.d.ts.map +1 -1
- package/dist/utils/extractData.js +38 -33
- package/dist/utils/extractData.js.map +1 -1
- package/dist/utils/parallelizeSteps.js +30 -30
- package/dist/utils/parallelizeSteps.js.map +1 -1
- package/dist/utils/resolveResourceChain.js +2 -2
- package/dist/utils/resolveResourceChain.js.map +1 -1
- package/package.json +2 -2
- package/src/artifacts/artifacts.ts +8 -8
- package/src/integrations/firebase/createStep.ts +25 -25
- package/src/integrations/firebase/firebaseAdminHelpers.ts +3 -3
- package/src/utils/bindInputRoleToResource.ts +11 -11
- package/src/utils/creation/stepCreation.ts +35 -35
- package/src/utils/extractData.ts +54 -39
- package/src/utils/parallelizeSteps.ts +32 -32
- package/src/utils/resolveResourceChain.ts +2 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -4,9 +4,9 @@ import type {
|
|
|
4
4
|
CaseJson,
|
|
5
5
|
ForStepIdentityJson,
|
|
6
6
|
ForStepJson,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
ToolJson,
|
|
8
|
+
ToolStepIdentityJson,
|
|
9
|
+
ToolStepJson,
|
|
10
10
|
ResourceRoleIdentityJson,
|
|
11
11
|
WhileStepIdentityJson,
|
|
12
12
|
WhileStepJson,
|
|
@@ -17,19 +17,19 @@ export type LoopStepBuildIdentities =
|
|
|
17
17
|
| {
|
|
18
18
|
stepKind: typeof CONSTANTS.Enums.StepKind.for;
|
|
19
19
|
stepIdentity: ForStepIdentityJson;
|
|
20
|
-
whatIdentity:
|
|
21
|
-
whenIdentity:
|
|
20
|
+
whatIdentity: ToolStepIdentityJson;
|
|
21
|
+
whenIdentity: ToolStepIdentityJson;
|
|
22
22
|
}
|
|
23
23
|
| {
|
|
24
24
|
stepKind: typeof CONSTANTS.Enums.StepKind.while;
|
|
25
25
|
stepIdentity: WhileStepIdentityJson;
|
|
26
|
-
whatIdentity:
|
|
27
|
-
whenIdentity:
|
|
26
|
+
whatIdentity: ToolStepIdentityJson;
|
|
27
|
+
whenIdentity: ToolStepIdentityJson;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
export type BranchCaseBuildIdentities = {
|
|
31
|
-
whatIdentity:
|
|
32
|
-
whenIdentity:
|
|
31
|
+
whatIdentity: ToolStepIdentityJson;
|
|
32
|
+
whenIdentity: ToolStepIdentityJson;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
function assertNonEmpty<T>(arr: T[], msg: string): asserts arr is [T, ...T[]] {
|
|
@@ -38,32 +38,32 @@ function assertNonEmpty<T>(arr: T[], msg: string): asserts arr is [T, ...T[]] {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
function getRoleBindingSpec(
|
|
41
|
+
function getRoleBindingSpec(tool: ToolJson): ToolStepJson['roleBindingSpec'] {
|
|
42
42
|
return {
|
|
43
|
-
inputBindings: Object.keys(
|
|
44
|
-
outputBindings: Object.keys(
|
|
43
|
+
inputBindings: Object.keys(tool.roleSpec.inputRoleValueByIdentity) as ResourceRoleIdentityJson[],
|
|
44
|
+
outputBindings: Object.keys(tool.roleSpec.outputRoleValueByIdentity) as ResourceRoleIdentityJson[],
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
export function
|
|
49
|
-
|
|
50
|
-
identity:
|
|
51
|
-
):
|
|
48
|
+
export function buildToolStepFromTool(
|
|
49
|
+
tool: ToolJson,
|
|
50
|
+
identity: ToolStepIdentityJson,
|
|
51
|
+
): ToolStepJson {
|
|
52
52
|
return {
|
|
53
53
|
identity,
|
|
54
|
-
stepKind: CONSTANTS.Enums.StepKind.
|
|
55
|
-
|
|
56
|
-
roleBindingSpec: getRoleBindingSpec(
|
|
54
|
+
stepKind: CONSTANTS.Enums.StepKind.tool,
|
|
55
|
+
toolHandle: tool.identity,
|
|
56
|
+
roleBindingSpec: getRoleBindingSpec(tool),
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
export function
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
export function buildLoopStepFromToolPair(
|
|
61
|
+
whatTool: ToolJson,
|
|
62
|
+
whenTool: ToolJson,
|
|
63
63
|
identities: LoopStepBuildIdentities,
|
|
64
64
|
): ForStepJson | WhileStepJson {
|
|
65
|
-
const what =
|
|
66
|
-
const when =
|
|
65
|
+
const what = buildToolStepFromTool(whatTool, identities.whatIdentity);
|
|
66
|
+
const when = buildToolStepFromTool(whenTool, identities.whenIdentity);
|
|
67
67
|
|
|
68
68
|
if (identities.stepKind === CONSTANTS.Enums.StepKind.for) {
|
|
69
69
|
return {
|
|
@@ -80,28 +80,28 @@ export function buildLoopStepFromJobPair(
|
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
export function
|
|
84
|
-
cases: Array<{
|
|
83
|
+
export function buildBranchStepFromToolPairs(
|
|
84
|
+
cases: Array<{ whatTool: ToolJson; whenTool: ToolJson }>,
|
|
85
85
|
branchIdentity: BranchStepIdentityJson,
|
|
86
86
|
caseIdentities: BranchCaseBuildIdentities[],
|
|
87
87
|
): BranchStepJson {
|
|
88
88
|
if (cases.length !== caseIdentities.length) {
|
|
89
|
-
throw new Error('
|
|
89
|
+
throw new Error('buildBranchStepFromToolPairs requires one identity pair per case');
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
const resolved = cases.map(({
|
|
92
|
+
const resolved = cases.map(({ whatTool, whenTool }, index) => {
|
|
93
93
|
const identities = caseIdentities[index];
|
|
94
94
|
|
|
95
95
|
if (!identities) {
|
|
96
96
|
throw new Error(`Missing case identities for case index ${index}`);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
const what =
|
|
100
|
-
const when =
|
|
99
|
+
const what = buildToolStepFromTool(whatTool, identities.whatIdentity);
|
|
100
|
+
const when = buildToolStepFromTool(whenTool, identities.whenIdentity);
|
|
101
101
|
return { what, when } satisfies CaseJson;
|
|
102
102
|
});
|
|
103
103
|
|
|
104
|
-
assertNonEmpty(resolved, '
|
|
104
|
+
assertNonEmpty(resolved, 'buildBranchStepFromToolPairs requires at least one case');
|
|
105
105
|
|
|
106
106
|
return {
|
|
107
107
|
identity: branchIdentity,
|
|
@@ -114,8 +114,8 @@ export function cloneForStepWithIdentities(
|
|
|
114
114
|
forStep: ForStepJson,
|
|
115
115
|
identities: {
|
|
116
116
|
stepIdentity: ForStepIdentityJson;
|
|
117
|
-
whatIdentity:
|
|
118
|
-
whenIdentity:
|
|
117
|
+
whatIdentity: ToolStepIdentityJson;
|
|
118
|
+
whenIdentity: ToolStepIdentityJson;
|
|
119
119
|
},
|
|
120
120
|
): ForStepJson {
|
|
121
121
|
return {
|
|
@@ -138,8 +138,8 @@ export function cloneWhileStepWithIdentities(
|
|
|
138
138
|
whileStep: WhileStepJson,
|
|
139
139
|
identities: {
|
|
140
140
|
stepIdentity: WhileStepIdentityJson;
|
|
141
|
-
whatIdentity:
|
|
142
|
-
whenIdentity:
|
|
141
|
+
whatIdentity: ToolStepIdentityJson;
|
|
142
|
+
whenIdentity: ToolStepIdentityJson;
|
|
143
143
|
},
|
|
144
144
|
): WhileStepJson {
|
|
145
145
|
return {
|
package/src/utils/extractData.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
RawStrategyJson,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
ToolIdentityJson,
|
|
4
|
+
ToolJson,
|
|
5
|
+
ToolStepIdentityJson,
|
|
6
|
+
ToolStepJson,
|
|
7
7
|
StepJson,
|
|
8
8
|
ResourceRoleIdentityJson,
|
|
9
9
|
ResourceRoleJson,
|
|
@@ -14,44 +14,44 @@ import type {
|
|
|
14
14
|
import { CONSTANTS } from '../artifacts/artifacts.js';
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
export function
|
|
18
|
-
const
|
|
19
|
-
const ids = new Set<
|
|
20
|
-
for (const jStep of
|
|
21
|
-
ids.add(jStep.
|
|
17
|
+
export function extractToolHandlesFromRawStrategy(rawStrategy: RawStrategyJson): ToolIdentityJson[] {
|
|
18
|
+
const toolSteps = extractToolStepsFromRawStrategy(rawStrategy);
|
|
19
|
+
const ids = new Set<ToolIdentityJson>();
|
|
20
|
+
for (const jStep of toolSteps) {
|
|
21
|
+
ids.add(jStep.toolHandle);
|
|
22
22
|
}
|
|
23
23
|
return Array.from(ids);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
export function
|
|
27
|
-
const
|
|
28
|
-
const seen = new Set<
|
|
26
|
+
export function extractToolStepsFromRawStrategy(rawStrategy: RawStrategyJson): ToolStepJson[] {
|
|
27
|
+
const toolSteps: ToolStepJson[] = [];
|
|
28
|
+
const seen = new Set<ToolStepIdentityJson>();
|
|
29
29
|
|
|
30
|
-
const
|
|
31
|
-
if (seen.has(
|
|
32
|
-
throw new Error(`Duplicate
|
|
30
|
+
const addToolStep = (toolStep: ToolStepJson) => {
|
|
31
|
+
if (seen.has(toolStep.identity)) {
|
|
32
|
+
throw new Error(`Duplicate tool step identity encountered: ${toolStep.identity}`);
|
|
33
33
|
}
|
|
34
|
-
seen.add(
|
|
35
|
-
|
|
34
|
+
seen.add(toolStep.identity);
|
|
35
|
+
toolSteps.push(toolStep);
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
const visitStep = (step: StepJson) => {
|
|
39
39
|
switch (step.stepKind) {
|
|
40
|
-
case CONSTANTS.Enums.StepKind.
|
|
41
|
-
|
|
40
|
+
case CONSTANTS.Enums.StepKind.tool: {
|
|
41
|
+
addToolStep(step);
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
case CONSTANTS.Enums.StepKind.branch: {
|
|
45
45
|
for (const conditional of step.cases) {
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
addToolStep(conditional.when);
|
|
47
|
+
addToolStep(conditional.what);
|
|
48
48
|
}
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
case CONSTANTS.Enums.StepKind.while:
|
|
52
52
|
case CONSTANTS.Enums.StepKind.for: {
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
addToolStep(step.case.when);
|
|
54
|
+
addToolStep(step.case.what);
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
default: {
|
|
@@ -65,25 +65,25 @@ export function extractJobStepsFromRawStrategy(rawStrategy: RawStrategyJson): Jo
|
|
|
65
65
|
visitStep(step);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
return
|
|
68
|
+
return toolSteps;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
|
|
72
|
-
export function extractRoleMapFromRawStrategy(rawStrategy: RawStrategyJson,
|
|
72
|
+
export function extractRoleMapFromRawStrategy(rawStrategy: RawStrategyJson, toolMap: Map<ToolIdentityJson, ToolJson>): Map<ResourceRoleIdentityJson, ResourceRoleJson> {
|
|
73
73
|
const roleMap = new Map<ResourceRoleIdentityJson, ResourceRoleJson>();
|
|
74
|
-
const
|
|
74
|
+
const toolHandles = extractToolHandlesFromRawStrategy(rawStrategy);
|
|
75
75
|
|
|
76
|
-
for (const
|
|
77
|
-
const
|
|
78
|
-
if (!
|
|
76
|
+
for (const toolHandle of toolHandles) {
|
|
77
|
+
const tool = toolMap.get(toolHandle);
|
|
78
|
+
if (!tool) continue;
|
|
79
79
|
|
|
80
|
-
for (const [rid, role] of Object.entries(
|
|
80
|
+
for (const [rid, role] of Object.entries(tool.roleSpec.inputRoleValueByIdentity)) {
|
|
81
81
|
roleMap.set(rid as ResourceRoleIdentityJson, {
|
|
82
82
|
identity: rid as ResourceRoleIdentityJson,
|
|
83
83
|
...role,
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
-
for (const [rid, role] of Object.entries(
|
|
86
|
+
for (const [rid, role] of Object.entries(tool.roleSpec.outputRoleValueByIdentity)) {
|
|
87
87
|
roleMap.set(rid as ResourceRoleIdentityJson, {
|
|
88
88
|
identity: rid as ResourceRoleIdentityJson,
|
|
89
89
|
...role,
|
|
@@ -94,11 +94,11 @@ export function extractRoleMapFromRawStrategy(rawStrategy: RawStrategyJson, jobM
|
|
|
94
94
|
return roleMap;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
export function extractSingleNonErrorOutputTypeHandle(
|
|
97
|
+
export function extractSingleNonErrorOutputTypeHandle(tool: ToolJson): ResourceTypeIdentityJson | null {
|
|
98
98
|
const errorRoleId = CONSTANTS.Cosmos.ROLE_ErrorOutput;
|
|
99
|
-
const outputEntries = Object.entries(
|
|
99
|
+
const outputEntries = Object.entries(tool.roleSpec.outputRoleValueByIdentity).filter(([roleId]) => roleId !== errorRoleId);
|
|
100
100
|
if (!outputEntries || !outputEntries[0] || outputEntries.length !== 1) {
|
|
101
|
-
throw new Error(`
|
|
101
|
+
throw new Error(`Tool ${tool.identity} must have exactly one non-error output role to be branchable/loopable`);
|
|
102
102
|
} // ATTENTION_PUREIFY
|
|
103
103
|
const outputRole = outputEntries[0][1];
|
|
104
104
|
return outputRole.resourceTypeHandle;
|
|
@@ -120,8 +120,8 @@ export function extractResourceMapForType<TResource extends ResourceJson = Resou
|
|
|
120
120
|
return map;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
//
|
|
124
|
-
export function
|
|
123
|
+
// Only use this for resource types whose nuclei are entity-like objects with their own intrinsic identity.
|
|
124
|
+
export function extractIdentityKeyedNucleusMapForType<
|
|
125
125
|
TKey extends string = string,
|
|
126
126
|
TNucleus extends { identity: string | number | boolean } = { identity: string | number | boolean },
|
|
127
127
|
TResource extends ResourceJson = ResourceJson
|
|
@@ -135,15 +135,30 @@ export function extractNucleusMapForType<
|
|
|
135
135
|
for (const resource of resourceMap.values()) {
|
|
136
136
|
const data = (resource as any).nucleus as unknown;
|
|
137
137
|
if (data === null || data === undefined) {
|
|
138
|
-
|
|
138
|
+
throw new Error(
|
|
139
|
+
`Expected resource '${resource.identity}' of type '${resourceTypeHandle}' to have a nucleus`
|
|
140
|
+
);
|
|
139
141
|
}
|
|
140
142
|
if (typeof data !== 'object') {
|
|
141
|
-
|
|
143
|
+
throw new Error(
|
|
144
|
+
`Expected resource '${resource.identity}' of type '${resourceTypeHandle}' to have an object nucleus with identity`
|
|
145
|
+
);
|
|
142
146
|
}
|
|
143
147
|
|
|
144
148
|
const maybeIdentity = (data as any).identity as unknown;
|
|
145
149
|
if (maybeIdentity === null || maybeIdentity === undefined) {
|
|
146
|
-
|
|
150
|
+
throw new Error(
|
|
151
|
+
`Expected resource '${resource.identity}' of type '${resourceTypeHandle}' to have nucleus.identity`
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
if (
|
|
155
|
+
typeof maybeIdentity !== 'string' &&
|
|
156
|
+
typeof maybeIdentity !== 'number' &&
|
|
157
|
+
typeof maybeIdentity !== 'boolean'
|
|
158
|
+
) {
|
|
159
|
+
throw new Error(
|
|
160
|
+
`Expected resource '${resource.identity}' of type '${resourceTypeHandle}' to have nucleus.identity as string, number, or boolean`
|
|
161
|
+
);
|
|
147
162
|
}
|
|
148
163
|
|
|
149
164
|
const value = data as TNucleus;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
BranchStepJson,
|
|
3
3
|
ForStepJson,
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
ToolStepIdentityJson,
|
|
5
|
+
ToolStepJson,
|
|
6
6
|
ResourceRoleIdentityJson,
|
|
7
7
|
StepJson,
|
|
8
8
|
StrategyStateJson,
|
|
@@ -19,53 +19,53 @@ export function getIndependentThreads(steps: StepJson[], strategyState: Strategy
|
|
|
19
19
|
return `steps[${ownerIndex}] stepKind=${(step as any)?.stepKind ?? 'unknown'}`;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
// Map each
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
22
|
+
// Map each toolStep.identity (including macro-nested tool steps) to owning top-level step index.
|
|
23
|
+
const toolStepIdToOwner = new Map<ToolStepIdentityJson, OwnerIndex>();
|
|
24
|
+
const ownerToToolStepIds = new Map<OwnerIndex, ToolStepIdentityJson[]>();
|
|
25
|
+
const toolStepById = new Map<ToolStepIdentityJson, ToolStepJson>();
|
|
26
26
|
|
|
27
|
-
const
|
|
28
|
-
if (!
|
|
27
|
+
const addToolStep = (toolStep: ToolStepJson | undefined, ownerIndex: OwnerIndex) => {
|
|
28
|
+
if (!toolStep?.identity) return;
|
|
29
29
|
|
|
30
|
-
const existingOwner =
|
|
30
|
+
const existingOwner = toolStepIdToOwner.get(toolStep.identity);
|
|
31
31
|
if (existingOwner !== undefined) {
|
|
32
32
|
throw new Error(
|
|
33
|
-
`Duplicate
|
|
33
|
+
`Duplicate toolStep.identity '${toolStep.identity}' found in ${getOwnerLabel(ownerIndex)} and ${getOwnerLabel(existingOwner)}`
|
|
34
34
|
);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const bucket =
|
|
40
|
-
bucket.push(
|
|
41
|
-
|
|
37
|
+
toolStepIdToOwner.set(toolStep.identity, ownerIndex);
|
|
38
|
+
toolStepById.set(toolStep.identity, toolStep);
|
|
39
|
+
const bucket = ownerToToolStepIds.get(ownerIndex) ?? [];
|
|
40
|
+
bucket.push(toolStep.identity);
|
|
41
|
+
ownerToToolStepIds.set(ownerIndex, bucket);
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
steps.forEach((step, ownerIndex) => {
|
|
45
|
-
if (step.stepKind === CONSTANTS.Enums.StepKind.
|
|
46
|
-
|
|
45
|
+
if (step.stepKind === CONSTANTS.Enums.StepKind.tool) {
|
|
46
|
+
addToolStep(step as ToolStepJson, ownerIndex);
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
if (step.stepKind === CONSTANTS.Enums.StepKind.for) {
|
|
51
51
|
const loop = step as ForStepJson;
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
addToolStep(loop.case?.what, ownerIndex);
|
|
53
|
+
addToolStep(loop.case?.when, ownerIndex);
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
if (step.stepKind === CONSTANTS.Enums.StepKind.while) {
|
|
58
58
|
const loop = step as WhileStepJson;
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
addToolStep(loop.case?.what, ownerIndex);
|
|
60
|
+
addToolStep(loop.case?.when, ownerIndex);
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
if (step.stepKind === CONSTANTS.Enums.StepKind.branch) {
|
|
65
65
|
const branch = step as BranchStepJson;
|
|
66
66
|
for (const caseItem of branch.cases ?? []) {
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
addToolStep(caseItem?.what, ownerIndex);
|
|
68
|
+
addToolStep(caseItem?.when, ownerIndex);
|
|
69
69
|
}
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
@@ -86,28 +86,28 @@ export function getIndependentThreads(steps: StepJson[], strategyState: Strategy
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
// Discover dependencies from strategyState.
|
|
89
|
-
for (const [
|
|
89
|
+
for (const [toolStepId, ownerIndex] of toolStepIdToOwner) {
|
|
90
90
|
ensureOwner(ownerIndex);
|
|
91
91
|
|
|
92
|
-
const
|
|
93
|
-
const inputBindings =
|
|
94
|
-
const bucket = strategyState?.[
|
|
92
|
+
const toolStep = toolStepById.get(toolStepId);
|
|
93
|
+
const inputBindings = toolStep?.roleBindingSpec?.inputBindings ?? [];
|
|
94
|
+
const bucket = strategyState?.[toolStepId] ?? ({} as any);
|
|
95
95
|
|
|
96
96
|
for (const inputRoleHandle of inputBindings) {
|
|
97
97
|
const entry = bucket?.[inputRoleHandle as ResourceRoleIdentityJson] as any;
|
|
98
98
|
if (!entry || entry.resourceShellKind !== 'internalInputPotential') continue;
|
|
99
99
|
|
|
100
|
-
const
|
|
101
|
-
if (!
|
|
100
|
+
const creatorToolStepHandle = entry?.creationContext?.toolStepHandle as ToolStepIdentityJson | undefined;
|
|
101
|
+
if (!creatorToolStepHandle) {
|
|
102
102
|
throw new Error(
|
|
103
|
-
`Unresolvable internalInputPotential in
|
|
103
|
+
`Unresolvable internalInputPotential in toolStep '${toolStepId}' (${getOwnerLabel(ownerIndex)}): missing creationContext.toolStepHandle for role '${inputRoleHandle}'`
|
|
104
104
|
);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
const producerOwner =
|
|
107
|
+
const producerOwner = toolStepIdToOwner.get(creatorToolStepHandle);
|
|
108
108
|
if (producerOwner === undefined) {
|
|
109
109
|
throw new Error(
|
|
110
|
-
`Unresolvable internalInputPotential in
|
|
110
|
+
`Unresolvable internalInputPotential in toolStep '${toolStepId}' (${getOwnerLabel(ownerIndex)}): creator toolStepHandle '${creatorToolStepHandle}' not found in strategy steps`
|
|
111
111
|
);
|
|
112
112
|
}
|
|
113
113
|
|
|
@@ -27,13 +27,13 @@ export function resolveResourceChain(
|
|
|
27
27
|
|
|
28
28
|
for (let depth = 0; depth <= maxDepth; depth++) {
|
|
29
29
|
path.push(current);
|
|
30
|
-
const visitKey = `${current.
|
|
30
|
+
const visitKey = `${current.toolStepHandle}::${current.resourceRoleHandle}`;
|
|
31
31
|
if (visited.has(visitKey)) {
|
|
32
32
|
return { status: 'unresolved', reason: 'cycle', path };
|
|
33
33
|
}
|
|
34
34
|
visited.add(visitKey);
|
|
35
35
|
|
|
36
|
-
const bucket = strategyState[current.
|
|
36
|
+
const bucket = strategyState[current.toolStepHandle];
|
|
37
37
|
if (!bucket) return { status: 'unresolved', reason: 'not-found', path };
|
|
38
38
|
const entry = bucket[current.resourceRoleHandle] as (
|
|
39
39
|
| ResourceJson
|