Skip to content

Commit a01a1f1

Browse files
cameroncookeclaude
andcommitted
fix(runtime): Make manifest templates canonical for next steps
Always render manifest-defined next steps when templates exist. Remove\ntool-level nextSteps fallback behavior and keep dynamic injection\nlimited to nextStepParams overlays on manifest params. Refs #216 Co-Authored-By: Claude <noreply@anthropic.com>
1 parent f0ebe65 commit a01a1f1

2 files changed

Lines changed: 30 additions & 44 deletions

File tree

src/runtime/__tests__/tool-invoker.test.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,9 @@ describe('DefaultToolInvoker next steps post-processing', () => {
329329
priority: 99,
330330
},
331331
],
332+
nextStepParams: {
333+
stop_sim_log_cap: { logSessionId: 'session-123' },
334+
},
332335
} satisfies ToolResponse);
333336

334337
const catalog = createToolCatalog([
@@ -473,7 +476,7 @@ describe('DefaultToolInvoker next steps post-processing', () => {
473476
]);
474477
});
475478

476-
it('keeps tool-provided next steps when template count does not match', async () => {
479+
it('always uses manifest templates when they exist', async () => {
477480
const directHandler = vi.fn().mockResolvedValue({
478481
content: [{ type: 'text', text: 'ok' }],
479482
nextSteps: [
@@ -530,12 +533,20 @@ describe('DefaultToolInvoker next steps post-processing', () => {
530533

531534
expect(response.nextSteps).toEqual([
532535
{
533-
tool: 'launch_app_sim',
534-
label: 'Launch app (platform-specific)',
535-
params: { simulatorId: '123', bundleId: 'com.example.app' },
536+
tool: 'get_app_bundle_id',
537+
label: 'Get bundle ID',
538+
params: {},
536539
priority: 1,
540+
workflow: 'project-discovery',
541+
cliTool: 'get-app-bundle-id',
542+
},
543+
{
544+
tool: 'boot_sim',
545+
label: 'Boot simulator',
546+
params: {},
547+
priority: 2,
537548
workflow: 'simulator',
538-
cliTool: 'launch-app',
549+
cliTool: 'boot',
539550
},
540551
]);
541552
});

src/runtime/tool-invoker.ts

Lines changed: 14 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ function buildTemplateNextSteps(
5656
return built;
5757
}
5858

59-
function hasTemplateParams(step: NextStep): boolean {
60-
return !!step.params && Object.keys(step.params).length > 0;
61-
}
62-
6359
function consumeDynamicParams(
6460
nextStepParams: NextStepParamsMap | undefined,
6561
toolId: string,
@@ -82,11 +78,10 @@ function consumeDynamicParams(
8278
function mergeTemplateAndResponseNextSteps(
8379
templateSteps: BuiltTemplateNextStep[],
8480
responseParamsMap: NextStepParamsMap | undefined,
85-
responseSteps: NextStep[] | undefined,
8681
): NextStep[] {
8782
const consumedCounts = new Map<string, number>();
8883

89-
return templateSteps.map((builtTemplateStep, index) => {
84+
return templateSteps.map((builtTemplateStep) => {
9085
const templateStep = builtTemplateStep.step;
9186
if (!builtTemplateStep.templateToolId || !templateStep.tool) {
9287
return templateStep;
@@ -97,28 +92,16 @@ function mergeTemplateAndResponseNextSteps(
9792
builtTemplateStep.templateToolId,
9893
consumedCounts,
9994
);
100-
if (paramsFromMap) {
101-
return {
102-
...templateStep,
103-
params: {
104-
...(templateStep.params ?? {}),
105-
...paramsFromMap,
106-
},
107-
};
108-
}
109-
110-
if (hasTemplateParams(templateStep)) {
111-
return templateStep;
112-
}
113-
114-
const fallbackStep = responseSteps?.[index];
115-
if (!fallbackStep?.params) {
95+
if (!paramsFromMap) {
11696
return templateStep;
11797
}
11898

11999
return {
120100
...templateStep,
121-
params: fallbackStep.params,
101+
params: {
102+
...(templateStep.params ?? {}),
103+
...paramsFromMap,
104+
},
122105
};
123106
});
124107
}
@@ -168,22 +151,14 @@ export function postProcessToolResponse(params: {
168151
const { tool, response, catalog, runtime } = params;
169152

170153
const templateSteps = buildTemplateNextSteps(tool, catalog);
171-
const canApplyTemplates =
172-
templateSteps.length > 0 &&
173-
(!response.nextSteps ||
174-
response.nextSteps.length === 0 ||
175-
response.nextSteps.length === templateSteps.length);
176-
177-
const withTemplates = canApplyTemplates
178-
? {
179-
...response,
180-
nextSteps: mergeTemplateAndResponseNextSteps(
181-
templateSteps,
182-
response.nextStepParams,
183-
response.nextSteps,
184-
),
185-
}
186-
: response;
154+
155+
const withTemplates =
156+
templateSteps.length > 0
157+
? {
158+
...response,
159+
nextSteps: mergeTemplateAndResponseNextSteps(templateSteps, response.nextStepParams),
160+
}
161+
: response;
187162

188163
const result = normalizeNextSteps(withTemplates, catalog, runtime);
189164
delete result.nextStepParams;

0 commit comments

Comments
 (0)