mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-31 20:55:34 +01:00
fix: remove duplicate SubagentStart hook execution in run() (#3747)
runStartHooks() and run() both called executeSubagentStartHook() for subagent requests, causing SubagentStart hooks to fire twice per subagent invocation. The caller (defaultIntentRequestHandler) always calls runStartHooks() before run(), so the call in run() was redundant. Remove the duplicate call from run() since runStartHooks() is the correct place for start hook execution.
This commit is contained in:
@@ -558,18 +558,6 @@ export abstract class ToolCallingLoop<TOptions extends IToolCallingLoopOptions =
|
||||
let stopHookActive = false;
|
||||
const sessionId = this.options.conversation.sessionId;
|
||||
|
||||
// Execute SubagentStart hook for subagent requests to get additional context
|
||||
if (this.options.request.subAgentInvocationId) {
|
||||
const startHookResult = await this.executeSubagentStartHook({
|
||||
agent_id: this.options.request.subAgentInvocationId,
|
||||
agent_type: this.options.request.subAgentName ?? 'default',
|
||||
}, sessionId, outputStream, token);
|
||||
if (startHookResult.additionalContext) {
|
||||
this.additionalHookContext = startHookResult.additionalContext;
|
||||
this._logService.info(`[ToolCallingLoop] SubagentStart hook provided context for subagent ${this.options.request.subAgentInvocationId}`);
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (lastResult && i++ >= this.options.toolCallLimit) {
|
||||
lastResult = this.hitToolCallLimit(outputStream, lastResult);
|
||||
|
||||
@@ -614,6 +614,36 @@ describe('ToolCallingLoop SubagentStart hook', () => {
|
||||
const input = subagentStartCalls[0].input as SubagentStartHookInput;
|
||||
expect(input.agent_type).toBe('default');
|
||||
});
|
||||
|
||||
it('should execute SubagentStart hook only once when runStartHooks and run are both called', async () => {
|
||||
const conversation = createTestConversation(1);
|
||||
const request = createMockChatRequest({
|
||||
subAgentInvocationId: 'subagent-dedup',
|
||||
subAgentName: 'DedupAgent',
|
||||
} as Partial<ChatRequest>);
|
||||
|
||||
const loop = instantiationService.createInstance(
|
||||
TestToolCallingLoop,
|
||||
{
|
||||
conversation,
|
||||
toolCallLimit: 10,
|
||||
request,
|
||||
}
|
||||
);
|
||||
disposables.add(loop);
|
||||
|
||||
// First call: runStartHooks should execute SubagentStart once
|
||||
await loop.testRunStartHooks(tokenSource.token);
|
||||
|
||||
// Second call: run() should NOT execute SubagentStart again
|
||||
// run() will throw because fetch() is not implemented, but SubagentStart
|
||||
// happens before fetch, so we need to verify it wasn't called again
|
||||
await expect(loop.run(undefined, tokenSource.token)).rejects.toThrow();
|
||||
|
||||
// SubagentStart should have been called exactly once (from runStartHooks only)
|
||||
const subagentStartCalls = mockChatHookService.getCallsForHook('SubagentStart');
|
||||
expect(subagentStartCalls).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SubagentStart hook result collection', () => {
|
||||
|
||||
Reference in New Issue
Block a user