feat: implement AfterTool tail tool calls (#18486)

This commit is contained in:
Steven Robertson
2026-02-23 19:57:00 -08:00
committed by GitHub
parent ee5eb70070
commit b0ceb74462
23 changed files with 567 additions and 26 deletions
@@ -13,6 +13,7 @@ import {
Scheduler,
type Config,
type MessageBus,
type ExecutingToolCall,
type CompletedToolCall,
type ToolCallsUpdateMessage,
type AnyDeclarativeTool,
@@ -110,7 +111,7 @@ describe('useToolScheduler', () => {
tool: createMockTool(),
invocation: createMockInvocation(),
liveOutput: 'Loading...',
};
} as ExecutingToolCall;
act(() => {
void mockMessageBus.publish({
@@ -405,4 +406,62 @@ describe('useToolScheduler', () => {
toolCalls.find((t) => t.request.callId === 'call-sub')?.schedulerId,
).toBe('subagent-1');
});
it('adapts success/error status to executing when a tail call is present', () => {
vi.useFakeTimers();
const { result } = renderHook(() =>
useToolScheduler(
vi.fn().mockResolvedValue(undefined),
mockConfig,
() => undefined,
),
);
const startTime = Date.now();
vi.advanceTimersByTime(1000);
const mockToolCall = {
status: CoreToolCallStatus.Success as const,
request: {
callId: 'call-1',
name: 'test_tool',
args: {},
isClientInitiated: false,
prompt_id: 'p1',
},
tool: createMockTool(),
invocation: createMockInvocation(),
response: {
callId: 'call-1',
resultDisplay: 'OK',
responseParts: [],
error: undefined,
errorType: undefined,
},
tailToolCallRequest: {
name: 'tail_tool',
args: {},
isClientInitiated: false,
prompt_id: '123',
},
};
act(() => {
void mockMessageBus.publish({
type: MessageBusType.TOOL_CALLS_UPDATE,
toolCalls: [mockToolCall],
schedulerId: ROOT_SCHEDULER_ID,
} as ToolCallsUpdateMessage);
});
const [toolCalls, , , , , lastOutputTime] = result.current;
// Check if status has been adapted to 'executing'
expect(toolCalls[0].status).toBe(CoreToolCallStatus.Executing);
// Check if lastOutputTime was updated due to the transitional state
expect(lastOutputTime).toBeGreaterThan(startTime);
vi.useRealTimers();
});
});