mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-20 08:47:44 +00:00
Fix: TaskTool Dynamic Updates (#697)
This commit is contained in:
@@ -43,6 +43,7 @@ describe('TaskTool', () => {
|
||||
let config: Config;
|
||||
let taskTool: TaskTool;
|
||||
let mockSubagentManager: SubagentManager;
|
||||
let changeListeners: Array<() => void>;
|
||||
|
||||
const mockSubagents: SubagentConfig[] = [
|
||||
{
|
||||
@@ -70,13 +71,25 @@ describe('TaskTool', () => {
|
||||
getProjectRoot: vi.fn().mockReturnValue('/test/project'),
|
||||
getSessionId: vi.fn().mockReturnValue('test-session-id'),
|
||||
getSubagentManager: vi.fn(),
|
||||
getGeminiClient: vi.fn().mockReturnValue(undefined),
|
||||
} as unknown as Config;
|
||||
|
||||
changeListeners = [];
|
||||
|
||||
// Setup SubagentManager mock
|
||||
mockSubagentManager = {
|
||||
listSubagents: vi.fn().mockResolvedValue(mockSubagents),
|
||||
loadSubagent: vi.fn(),
|
||||
createSubagentScope: vi.fn(),
|
||||
addChangeListener: vi.fn((listener: () => void) => {
|
||||
changeListeners.push(listener);
|
||||
return () => {
|
||||
const index = changeListeners.indexOf(listener);
|
||||
if (index >= 0) {
|
||||
changeListeners.splice(index, 1);
|
||||
}
|
||||
};
|
||||
}),
|
||||
} as unknown as SubagentManager;
|
||||
|
||||
MockedSubagentManager.mockImplementation(() => mockSubagentManager);
|
||||
@@ -106,6 +119,10 @@ describe('TaskTool', () => {
|
||||
expect(mockSubagentManager.listSubagents).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should subscribe to subagent manager changes', () => {
|
||||
expect(mockSubagentManager.addChangeListener).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should update description with available subagents', () => {
|
||||
expect(taskTool.description).toContain('file-search');
|
||||
expect(taskTool.description).toContain(
|
||||
@@ -232,6 +249,31 @@ describe('TaskTool', () => {
|
||||
});
|
||||
|
||||
describe('refreshSubagents', () => {
|
||||
it('should refresh when change listener fires', async () => {
|
||||
const newSubagents: SubagentConfig[] = [
|
||||
{
|
||||
name: 'new-agent',
|
||||
description: 'A brand new agent',
|
||||
systemPrompt: 'Do new things.',
|
||||
level: 'project',
|
||||
filePath: '/project/.qwen/agents/new-agent.md',
|
||||
},
|
||||
];
|
||||
|
||||
vi.mocked(mockSubagentManager.listSubagents).mockResolvedValueOnce(
|
||||
newSubagents,
|
||||
);
|
||||
|
||||
const listener = changeListeners[0];
|
||||
expect(listener).toBeDefined();
|
||||
|
||||
listener?.();
|
||||
await vi.runAllTimersAsync();
|
||||
|
||||
expect(taskTool.description).toContain('new-agent');
|
||||
expect(taskTool.description).toContain('A brand new agent');
|
||||
});
|
||||
|
||||
it('should refresh available subagents and update description', async () => {
|
||||
const newSubagents: SubagentConfig[] = [
|
||||
{
|
||||
|
||||
@@ -86,16 +86,19 @@ export class TaskTool extends BaseDeclarativeTool<TaskParams, ToolResult> {
|
||||
);
|
||||
|
||||
this.subagentManager = config.getSubagentManager();
|
||||
this.subagentManager.addChangeListener(() => {
|
||||
void this.refreshSubagents();
|
||||
});
|
||||
|
||||
// Initialize the tool asynchronously
|
||||
this.initializeAsync();
|
||||
this.refreshSubagents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously initializes the tool by loading available subagents
|
||||
* and updating the description and schema.
|
||||
*/
|
||||
private async initializeAsync(): Promise<void> {
|
||||
async refreshSubagents(): Promise<void> {
|
||||
try {
|
||||
this.availableSubagents = await this.subagentManager.listSubagents();
|
||||
this.updateDescriptionAndSchema();
|
||||
@@ -103,6 +106,12 @@ export class TaskTool extends BaseDeclarativeTool<TaskParams, ToolResult> {
|
||||
console.warn('Failed to load subagents for Task tool:', error);
|
||||
this.availableSubagents = [];
|
||||
this.updateDescriptionAndSchema();
|
||||
} finally {
|
||||
// Update the client with the new tools
|
||||
const geminiClient = this.config.getGeminiClient();
|
||||
if (geminiClient) {
|
||||
await geminiClient.setTools();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,14 +210,6 @@ assistant: "I'm going to use the Task tool to launch the with the greeting-respo
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the available subagents and updates the tool description.
|
||||
* This can be called when subagents are added or removed.
|
||||
*/
|
||||
async refreshSubagents(): Promise<void> {
|
||||
await this.initializeAsync();
|
||||
}
|
||||
|
||||
override validateToolParams(params: TaskParams): string | null {
|
||||
// Validate required fields
|
||||
if (
|
||||
|
||||
Reference in New Issue
Block a user