@toolproof-core/lib 1.0.28 → 1.0.30
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 +1 -1
- package/dist/integrations/firebase/firebaseAdminHelpers.d.ts.map +1 -1
- package/dist/integrations/firebase/firebaseAdminHelpers.js +14 -14
- package/dist/integrations/firebase/firebaseAdminHelpers.js.map +1 -1
- package/dist/utils/bindInputRoleToResource.js +20 -20
- package/dist/utils/bindInputRoleToResource.js.map +1 -1
- package/dist/utils/creation/resourceCreation.d.ts +4 -4
- package/dist/utils/creation/resourceCreation.d.ts.map +1 -1
- package/dist/utils/creation/resourceCreation.js +14 -14
- package/dist/utils/creation/resourceCreation.js.map +1 -1
- package/dist/utils/creation/stepCreation.js +1 -1
- package/dist/utils/creation/stepCreation.js.map +1 -1
- package/dist/utils/extractData.d.ts +4 -4
- package/dist/utils/extractData.d.ts.map +1 -1
- package/dist/utils/extractData.js +15 -15
- package/dist/utils/extractData.js.map +1 -1
- package/dist/utils/parallelizeSteps.js +5 -5
- package/dist/utils/parallelizeSteps.js.map +1 -1
- package/dist/utils/resolveResourceChain.js +3 -3
- package/dist/utils/resolveResourceChain.js.map +1 -1
- package/package.json +2 -2
- package/src/integrations/firebase/firebaseAdminHelpers.ts +14 -14
- package/src/utils/bindInputRoleToResource.ts +20 -20
- package/src/utils/creation/resourceCreation.ts +14 -14
- package/src/utils/creation/stepCreation.ts +1 -1
- package/src/utils/extractData.ts +15 -15
- package/src/utils/parallelizeSteps.ts +5 -5
- package/src/utils/resolveResourceChain.ts +3 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/toolproof-core-lib-1.0.27.tgz +0 -0
|
@@ -42,18 +42,18 @@ export function getNewStepId<K extends StepKindJson>(stepKind: K): StepIdStringB
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
export async function listResources(
|
|
45
|
-
|
|
45
|
+
resourceTypeIds: ResourceTypeIdJson[],
|
|
46
46
|
): Promise<ResourcesByType> {
|
|
47
47
|
const bucketResources = storageAdmin.bucket(CONSTANTS.Persistence.Buckets.tp_resources);
|
|
48
48
|
const bucketStrategies = storageAdmin.bucket(CONSTANTS.Persistence.Buckets.tp_strategies);
|
|
49
49
|
|
|
50
50
|
async function fetchFilesUnder(
|
|
51
|
-
|
|
51
|
+
resourceTypeId: ResourceTypeIdJson,
|
|
52
52
|
): Promise<Array<{ data: unknown; meta: any; name: string }>> {
|
|
53
|
-
const bucket =
|
|
53
|
+
const bucket = resourceTypeId === CONSTANTS.Cosmos.TYPE_RunnableStrategy
|
|
54
54
|
? bucketStrategies
|
|
55
55
|
: bucketResources;
|
|
56
|
-
const prefix = `${
|
|
56
|
+
const prefix = `${resourceTypeId}/`;
|
|
57
57
|
const [found] = await bucket.getFiles({ prefix });
|
|
58
58
|
const files = found.filter((file) => {
|
|
59
59
|
const name = file.name || '';
|
|
@@ -79,8 +79,8 @@ export async function listResources(
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
const entries = await Promise.all(
|
|
82
|
-
|
|
83
|
-
const rows = await fetchFilesUnder(
|
|
82
|
+
resourceTypeIds.map(async (resourceTypeId) => {
|
|
83
|
+
const rows = await fetchFilesUnder(resourceTypeId);
|
|
84
84
|
const items: ResourceJson[] = rows.map(({ data, meta, name }) => {
|
|
85
85
|
const flat = meta?.metadata ?? {};
|
|
86
86
|
const root: any = {};
|
|
@@ -147,8 +147,8 @@ export async function listResources(
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
const id = root.id;
|
|
150
|
-
const
|
|
151
|
-
const
|
|
150
|
+
const resourceRoleId = root.creationContext.resourceRoleId;
|
|
151
|
+
const toolStepId = root.creationContext.toolStepId;
|
|
152
152
|
const resourceShellKind = root.resourceShellKind;
|
|
153
153
|
const versionRaw = root.version;
|
|
154
154
|
const version = typeof versionRaw === 'number'
|
|
@@ -159,8 +159,8 @@ export async function listResources(
|
|
|
159
159
|
|
|
160
160
|
const missing = [
|
|
161
161
|
['id', id],
|
|
162
|
-
['
|
|
163
|
-
['
|
|
162
|
+
['resourceRoleId', resourceRoleId],
|
|
163
|
+
['toolStepId', toolStepId],
|
|
164
164
|
['resourceShellKind', resourceShellKind],
|
|
165
165
|
['version', Number.isFinite(version) ? String(version) : ''],
|
|
166
166
|
['timestamp', timestamp],
|
|
@@ -174,10 +174,10 @@ export async function listResources(
|
|
|
174
174
|
|
|
175
175
|
return {
|
|
176
176
|
id,
|
|
177
|
-
|
|
177
|
+
resourceTypeId,
|
|
178
178
|
creationContext: {
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
resourceRoleId,
|
|
180
|
+
toolStepId,
|
|
181
181
|
},
|
|
182
182
|
resourceShellKind,
|
|
183
183
|
version,
|
|
@@ -187,7 +187,7 @@ export async function listResources(
|
|
|
187
187
|
} as unknown as ResourceJson;
|
|
188
188
|
});
|
|
189
189
|
|
|
190
|
-
return [
|
|
190
|
+
return [resourceTypeId, items] as const;
|
|
191
191
|
}),
|
|
192
192
|
);
|
|
193
193
|
|
|
@@ -16,12 +16,12 @@ export function bindInputResInStrategyState(
|
|
|
16
16
|
target: CreationContextJson,
|
|
17
17
|
resource: ResourceJson
|
|
18
18
|
): StrategyStateJson {
|
|
19
|
-
const bucket = strategyState[target.
|
|
19
|
+
const bucket = strategyState[target.toolStepId] ?? {};
|
|
20
20
|
return {
|
|
21
21
|
...strategyState,
|
|
22
|
-
[target.
|
|
22
|
+
[target.toolStepId]: {
|
|
23
23
|
...bucket,
|
|
24
|
-
[target.
|
|
24
|
+
[target.resourceRoleId]: resource,
|
|
25
25
|
},
|
|
26
26
|
};
|
|
27
27
|
}
|
|
@@ -31,24 +31,24 @@ export function bindInputRefInStrategyState(
|
|
|
31
31
|
target: CreationContextJson,
|
|
32
32
|
source: CreationContextJson
|
|
33
33
|
): StrategyStateJson {
|
|
34
|
-
const sourceEntry = strategyState?.[source.
|
|
34
|
+
const sourceEntry = strategyState?.[source.toolStepId]?.[source.resourceRoleId] as (
|
|
35
35
|
| ResourceJson
|
|
36
36
|
| ResourcePotentialJson
|
|
37
37
|
| undefined
|
|
38
38
|
);
|
|
39
39
|
if (!sourceEntry) {
|
|
40
|
-
throw new Error(`resourceEntry not found for source (${source.
|
|
40
|
+
throw new Error(`resourceEntry not found for source (${source.toolStepId}, ${source.resourceRoleId})`);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
const result = resolveResourceChain(strategyState, source);
|
|
44
|
-
const bucket = strategyState[target.
|
|
44
|
+
const bucket = strategyState[target.toolStepId] ?? {};
|
|
45
45
|
|
|
46
46
|
if (result.status === CONSTANTS.Enums.ResourceShellKind.materialized) {
|
|
47
47
|
return {
|
|
48
48
|
...strategyState,
|
|
49
|
-
[target.
|
|
49
|
+
[target.toolStepId]: {
|
|
50
50
|
...bucket,
|
|
51
|
-
[target.
|
|
51
|
+
[target.resourceRoleId]: result.entry,
|
|
52
52
|
},
|
|
53
53
|
};
|
|
54
54
|
}
|
|
@@ -57,15 +57,15 @@ export function bindInputRefInStrategyState(
|
|
|
57
57
|
const externalInput = result.entry;
|
|
58
58
|
const reusedExternalInput: ExternalInputPotentialShellJson = {
|
|
59
59
|
id: externalInput.id,
|
|
60
|
-
|
|
60
|
+
resourceTypeId: externalInput.resourceTypeId,
|
|
61
61
|
resourceShellKind: CONSTANTS.Enums.ResourceShellKind.externalInputPotential,
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
return {
|
|
65
65
|
...strategyState,
|
|
66
|
-
[target.
|
|
66
|
+
[target.toolStepId]: {
|
|
67
67
|
...bucket,
|
|
68
|
-
[target.
|
|
68
|
+
[target.resourceRoleId]: reusedExternalInput,
|
|
69
69
|
},
|
|
70
70
|
};
|
|
71
71
|
}
|
|
@@ -73,19 +73,19 @@ export function bindInputRefInStrategyState(
|
|
|
73
73
|
if (result.status === CONSTANTS.Enums.ResourceShellKind.outputPotential) {
|
|
74
74
|
const potentialInput: InternalInputPotentialShellJson = {
|
|
75
75
|
id: sourceEntry.id,
|
|
76
|
-
|
|
76
|
+
resourceTypeId: sourceEntry.resourceTypeId,
|
|
77
77
|
creationContext: {
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
toolStepId: source.toolStepId,
|
|
79
|
+
resourceRoleId: source.resourceRoleId,
|
|
80
80
|
},
|
|
81
81
|
resourceShellKind: CONSTANTS.Enums.ResourceShellKind.internalInputPotential,
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
return {
|
|
85
85
|
...strategyState,
|
|
86
|
-
[target.
|
|
86
|
+
[target.toolStepId]: {
|
|
87
87
|
...bucket,
|
|
88
|
-
[target.
|
|
88
|
+
[target.resourceRoleId]: potentialInput,
|
|
89
89
|
},
|
|
90
90
|
};
|
|
91
91
|
}
|
|
@@ -97,14 +97,14 @@ export function clearInputBindingInStrategyState(
|
|
|
97
97
|
strategyState: StrategyStateJson,
|
|
98
98
|
target: CreationContextJson
|
|
99
99
|
): StrategyStateJson {
|
|
100
|
-
const bucket = strategyState?.[target.
|
|
101
|
-
if (!bucket?.[target.
|
|
100
|
+
const bucket = strategyState?.[target.toolStepId];
|
|
101
|
+
if (!bucket?.[target.resourceRoleId]) return strategyState;
|
|
102
102
|
|
|
103
103
|
const nextBucket = { ...bucket } as Record<string, unknown>;
|
|
104
|
-
delete nextBucket[target.
|
|
104
|
+
delete nextBucket[target.resourceRoleId];
|
|
105
105
|
|
|
106
106
|
return {
|
|
107
107
|
...strategyState,
|
|
108
|
-
[target.
|
|
108
|
+
[target.toolStepId]: nextBucket as any,
|
|
109
109
|
};
|
|
110
110
|
}
|
|
@@ -9,8 +9,8 @@ import type {
|
|
|
9
9
|
} from '@toolproof-core/schema';
|
|
10
10
|
import { CONSTANTS } from '../../artifacts/artifacts.js';
|
|
11
11
|
|
|
12
|
-
export function generatePath(
|
|
13
|
-
return `${
|
|
12
|
+
export function generatePath(resourceTypeId: ResourceTypeIdJson, id: ResourceIdJson): string {
|
|
13
|
+
return `${resourceTypeId}/${id}.json`;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export function createMaterializedFromOutputPotential(
|
|
@@ -18,12 +18,12 @@ export function createMaterializedFromOutputPotential(
|
|
|
18
18
|
nucleus: unknown,
|
|
19
19
|
timestamp?: string,
|
|
20
20
|
): ResourceJson {
|
|
21
|
-
const { id,
|
|
22
|
-
const path = generatePath(
|
|
21
|
+
const { id, resourceTypeId, creationContext } = outputPotential;
|
|
22
|
+
const path = generatePath(resourceTypeId, id);
|
|
23
23
|
|
|
24
24
|
return {
|
|
25
25
|
id,
|
|
26
|
-
|
|
26
|
+
resourceTypeId,
|
|
27
27
|
creationContext,
|
|
28
28
|
resourceShellKind: CONSTANTS.Enums.ResourceShellKind.materialized,
|
|
29
29
|
version: 1,
|
|
@@ -38,12 +38,12 @@ export function createMaterializedFromInputPotential(
|
|
|
38
38
|
nucleus: unknown,
|
|
39
39
|
timestamp?: string,
|
|
40
40
|
): ResourceJson {
|
|
41
|
-
const { id,
|
|
42
|
-
const path = generatePath(
|
|
41
|
+
const { id, resourceTypeId, creationContext } = inputPotential;
|
|
42
|
+
const path = generatePath(resourceTypeId, id);
|
|
43
43
|
|
|
44
44
|
return {
|
|
45
45
|
id,
|
|
46
|
-
|
|
46
|
+
resourceTypeId,
|
|
47
47
|
creationContext,
|
|
48
48
|
resourceShellKind: CONSTANTS.Enums.ResourceShellKind.materialized,
|
|
49
49
|
version: 1,
|
|
@@ -67,23 +67,23 @@ export function createMaterializedFromPotential(
|
|
|
67
67
|
|
|
68
68
|
export function createExternalInputPotential(
|
|
69
69
|
id: ResourceIdJson,
|
|
70
|
-
|
|
70
|
+
resourceTypeId: ResourceTypeIdJson,
|
|
71
71
|
): ExternalInputPotentialShellJson {
|
|
72
72
|
return {
|
|
73
73
|
id,
|
|
74
|
-
|
|
74
|
+
resourceTypeId,
|
|
75
75
|
resourceShellKind: CONSTANTS.Enums.ResourceShellKind.externalInputPotential,
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export function createInputPotential(
|
|
80
80
|
id: ResourceIdJson,
|
|
81
|
-
|
|
81
|
+
resourceTypeId: ResourceTypeIdJson,
|
|
82
82
|
creationContext: CreationContextJson,
|
|
83
83
|
): InternalInputPotentialShellJson {
|
|
84
84
|
return {
|
|
85
85
|
id,
|
|
86
|
-
|
|
86
|
+
resourceTypeId,
|
|
87
87
|
creationContext,
|
|
88
88
|
resourceShellKind: CONSTANTS.Enums.ResourceShellKind.internalInputPotential,
|
|
89
89
|
};
|
|
@@ -91,12 +91,12 @@ export function createInputPotential(
|
|
|
91
91
|
|
|
92
92
|
export function createOutputPotential(
|
|
93
93
|
id: ResourceIdJson,
|
|
94
|
-
|
|
94
|
+
resourceTypeId: ResourceTypeIdJson,
|
|
95
95
|
creationContext: CreationContextJson,
|
|
96
96
|
): OutputPotentialShellJson {
|
|
97
97
|
return {
|
|
98
98
|
id,
|
|
99
|
-
|
|
99
|
+
resourceTypeId,
|
|
100
100
|
creationContext,
|
|
101
101
|
resourceShellKind: CONSTANTS.Enums.ResourceShellKind.outputPotential,
|
|
102
102
|
};
|
package/src/utils/extractData.ts
CHANGED
|
@@ -14,11 +14,11 @@ import type {
|
|
|
14
14
|
import { CONSTANTS } from '../artifacts/artifacts.js';
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
export function
|
|
17
|
+
export function extractToolIdsFromRawStrategy(rawStrategy: RawStrategyJson): ToolIdJson[] {
|
|
18
18
|
const toolSteps = extractToolStepsFromRawStrategy(rawStrategy);
|
|
19
19
|
const ids = new Set<ToolIdJson>();
|
|
20
20
|
for (const jStep of toolSteps) {
|
|
21
|
-
ids.add(jStep.
|
|
21
|
+
ids.add(jStep.toolId);
|
|
22
22
|
}
|
|
23
23
|
return Array.from(ids);
|
|
24
24
|
}
|
|
@@ -71,10 +71,10 @@ export function extractToolStepsFromRawStrategy(rawStrategy: RawStrategyJson): T
|
|
|
71
71
|
|
|
72
72
|
export function extractRoleMapFromRawStrategy(rawStrategy: RawStrategyJson, toolMap: Map<ToolIdJson, ToolJson>): Map<ResourceRoleIdJson, ResourceRoleJson> {
|
|
73
73
|
const roleMap = new Map<ResourceRoleIdJson, ResourceRoleJson>();
|
|
74
|
-
const
|
|
74
|
+
const toolIds = extractToolIdsFromRawStrategy(rawStrategy);
|
|
75
75
|
|
|
76
|
-
for (const
|
|
77
|
-
const tool = toolMap.get(
|
|
76
|
+
for (const toolId of toolIds) {
|
|
77
|
+
const tool = toolMap.get(toolId);
|
|
78
78
|
if (!tool) continue;
|
|
79
79
|
|
|
80
80
|
for (const [rid, role] of Object.entries(tool.roleSpec.inputRoleValueById)) {
|
|
@@ -94,23 +94,23 @@ export function extractRoleMapFromRawStrategy(rawStrategy: RawStrategyJson, tool
|
|
|
94
94
|
return roleMap;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
export function
|
|
97
|
+
export function extractSingleNonErrorOutputTypeId(tool: ToolJson): ResourceTypeIdJson | null {
|
|
98
98
|
const errorRoleId = CONSTANTS.Cosmos.ROLE_ErrorOutput;
|
|
99
99
|
const outputEntries = Object.entries(tool.roleSpec.outputRoleValueById).filter(([roleId]) => roleId !== errorRoleId);
|
|
100
100
|
if (!outputEntries || !outputEntries[0] || outputEntries.length !== 1) {
|
|
101
101
|
throw new Error(`Tool ${tool.id} must have exactly one non-error output role to be branchable/loopable`);
|
|
102
102
|
} // ATTENTION_PUREIFY
|
|
103
103
|
const outputRole = outputEntries[0][1];
|
|
104
|
-
return outputRole.
|
|
104
|
+
return outputRole.resourceTypeId;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
|
|
108
108
|
|
|
109
109
|
export function extractResourceMapForType<TResource extends ResourceJson = ResourceJson>(
|
|
110
110
|
resourcesByType: Partial<Record<ResourceTypeIdJson, TResource[]>>,
|
|
111
|
-
|
|
111
|
+
resourceTypeId: ResourceTypeIdJson
|
|
112
112
|
): Map<ResourceIdJson, TResource> {
|
|
113
|
-
const resources = resourcesByType[
|
|
113
|
+
const resources = resourcesByType[resourceTypeId] ?? [];
|
|
114
114
|
const map = new Map<ResourceIdJson, TResource>();
|
|
115
115
|
|
|
116
116
|
for (const resource of resources) {
|
|
@@ -127,28 +127,28 @@ export function extractIdKeyedNucleusMapForType<
|
|
|
127
127
|
TResource extends ResourceJson = ResourceJson
|
|
128
128
|
>(
|
|
129
129
|
resourcesByType: Partial<Record<ResourceTypeIdJson, TResource[]>>,
|
|
130
|
-
|
|
130
|
+
resourceTypeId: ResourceTypeIdJson,
|
|
131
131
|
): Map<TKey, TNucleus> {
|
|
132
|
-
const resourceMap = extractResourceMapForType<TResource>(resourcesByType,
|
|
132
|
+
const resourceMap = extractResourceMapForType<TResource>(resourcesByType, resourceTypeId);
|
|
133
133
|
const out = new Map<TKey, TNucleus>();
|
|
134
134
|
|
|
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.id}' of type '${
|
|
139
|
+
`Expected resource '${resource.id}' of type '${resourceTypeId}' to have a nucleus`
|
|
140
140
|
);
|
|
141
141
|
}
|
|
142
142
|
if (typeof data !== 'object') {
|
|
143
143
|
throw new Error(
|
|
144
|
-
`Expected resource '${resource.id}' of type '${
|
|
144
|
+
`Expected resource '${resource.id}' of type '${resourceTypeId}' to have an object nucleus with id`
|
|
145
145
|
);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
const maybeId = (data as any).id as unknown;
|
|
149
149
|
if (maybeId === null || maybeId === undefined) {
|
|
150
150
|
throw new Error(
|
|
151
|
-
`Expected resource '${resource.id}' of type '${
|
|
151
|
+
`Expected resource '${resource.id}' of type '${resourceTypeId}' to have nucleus.id`
|
|
152
152
|
);
|
|
153
153
|
}
|
|
154
154
|
if (
|
|
@@ -157,7 +157,7 @@ export function extractIdKeyedNucleusMapForType<
|
|
|
157
157
|
typeof maybeId !== 'boolean'
|
|
158
158
|
) {
|
|
159
159
|
throw new Error(
|
|
160
|
-
`Expected resource '${resource.id}' of type '${
|
|
160
|
+
`Expected resource '${resource.id}' of type '${resourceTypeId}' to have nucleus.id as string, number, or boolean`
|
|
161
161
|
);
|
|
162
162
|
}
|
|
163
163
|
|
|
@@ -97,17 +97,17 @@ export function getIndependentThreads(steps: StepJson[], strategyState: Strategy
|
|
|
97
97
|
const entry = bucket?.[inputRoleHandle as ResourceRoleIdJson] as any;
|
|
98
98
|
if (!entry || entry.resourceShellKind !== 'internalInputPotential') continue;
|
|
99
99
|
|
|
100
|
-
const
|
|
101
|
-
if (!
|
|
100
|
+
const creatorToolStepId = entry?.creationContext?.toolStepId as ToolStepIdJson | undefined;
|
|
101
|
+
if (!creatorToolStepId) {
|
|
102
102
|
throw new Error(
|
|
103
|
-
`Unresolvable internalInputPotential in toolStep '${toolStepId}' (${getOwnerLabel(ownerIndex)}): missing creationContext.
|
|
103
|
+
`Unresolvable internalInputPotential in toolStep '${toolStepId}' (${getOwnerLabel(ownerIndex)}): missing creationContext.toolStepId for role '${inputRoleHandle}'`
|
|
104
104
|
);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
const producerOwner = toolStepIdToOwner.get(
|
|
107
|
+
const producerOwner = toolStepIdToOwner.get(creatorToolStepId);
|
|
108
108
|
if (producerOwner === undefined) {
|
|
109
109
|
throw new Error(
|
|
110
|
-
`Unresolvable internalInputPotential in toolStep '${toolStepId}' (${getOwnerLabel(ownerIndex)}): creator
|
|
110
|
+
`Unresolvable internalInputPotential in toolStep '${toolStepId}' (${getOwnerLabel(ownerIndex)}): creator toolStepId '${creatorToolStepId}' not found in strategy steps`
|
|
111
111
|
);
|
|
112
112
|
}
|
|
113
113
|
|
|
@@ -27,15 +27,15 @@ 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.toolStepId}::${current.resourceRoleId}`;
|
|
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.toolStepId];
|
|
37
37
|
if (!bucket) return { status: 'unresolved', reason: 'not-found', path };
|
|
38
|
-
const entry = bucket[current.
|
|
38
|
+
const entry = bucket[current.resourceRoleId] as (
|
|
39
39
|
| ResourceJson
|
|
40
40
|
| ResourcePotentialJson
|
|
41
41
|
| undefined
|