async execution
设计理念
问题
解决方案
主 Agent → 启动子 Agent → 继续工作
↓
后台执行
↓
完成后通知主 Agent → 启动子 Agent → 继续工作
↓
后台执行
↓
完成后通知async function executeAsyncAgent(
input: AgentInput,
context: AgentContext
): Promise<ToolResult> {
// 1. 创建 worktree (隔离环境)
const worktree = await createWorktree(context.cwd);
// 2. 生成 Agent ID
const agentId = generateId();
// 3. 注册后台 Agent
backgroundAgents.set(agentId, {
status: 'running',
worktree: worktree,
startTime: Date.now(),
input: input,
});
// 4. 异步执行
executeAgentInBackground(agentId, input, context)
.then(result => {
backgroundAgents.get(agentId).status = 'completed';
backgroundAgents.get(agentId).result = result;
})
.catch(error => {
backgroundAgents.get(agentId).status = 'failed';
backgroundAgents.get(agentId).error = error;
});
// 5. 立即返回
return {
success: true,
output: `Agent ${agentId} started. Use 'agent status ${agentId}' to check progress.`,
};
}async function executeAgentInBackground(
agentId: string,
input: AgentInput,
context: AgentContext
): Promise<AgentResult> {
// 在 worktree 中执行
const messages = [{ role: 'user', content: input.prompt }];
let output = '';
for await (const event of query(messages, context.tools, {
system: context.systemPrompt,
cwd: context.worktree,
})) {
if (event.type === 'content') {
output += event.content;
}
// 更新进度
updateAgentProgress(agentId, event);
}
return { output };
}function updateAgentProgress(
agentId: string,
event: QueryEvent
): void {
const agent = backgroundAgents.get(agentId);
if (event.type === 'tool_use') {
agent.currentTool = event.tool;
} else if (event.type === 'content') {
agent.outputLength += event.content.length;
}
// 通知主 Agent
notifyMainAgent(agentId, agent);
}function getAgentStatus(agentId: string): AgentStatus {
const agent = backgroundAgents.get(agentId);
if (!agent) {
return { status: 'not_found' };
}
return {
status: agent.status,
startTime: agent.startTime,
currentTool: agent.currentTool,
outputLength: agent.outputLength,
};
}async function waitForAgent(
agentId: string,
timeout?: number
): Promise<AgentResult> {
const agent = backgroundAgents.get(agentId);
// 如果已完成,直接返回
if (agent.status === 'completed') {
return agent.result;
}
// 等待完成
return new Promise((resolve, reject) => {
const checkInterval = setInterval(() => {
if (agent.status === 'completed') {
clearInterval(checkInterval);
resolve(agent.result);
} else if (agent.status === 'failed') {
clearInterval(checkInterval);
reject(agent.error);
}
}, 100);
if (timeout) {
setTimeout(() => {
clearInterval(checkInterval);
reject(new Error('Timeout'));
}, timeout);
}
});
}async function createWorktree(basePath: string): Promise<string> {
const worktreePath = path.join(
basePath,
'.git',
'worktrees',
`agent-${Date.now()}`
);
await exec(`git worktree add ${worktreePath}`);
return worktreePath;
}async function mergeWorktree(
worktreePath: string,
basePath: string
): Promise<void> {
// 1. 在 worktree 中提交更改
await exec('git add -A', { cwd: worktreePath });
await exec('git commit -m "Agent changes"', { cwd: worktreePath });
// 2. 切换到主分支
await exec('git checkout main', { cwd: basePath });
// 3. 合并更改
await exec(`git merge ${worktreePath}`, { cwd: basePath });
// 4. 清理 worktree
await exec(`git worktree remove ${worktreePath}`);
}// 启动测试 Agent
const testAgentId = await invokeSubAgent({
name: 'test-runner',
prompt: 'Run all tests',
mode: 'async',
});
// 启动文档生成 Agent
const docsAgentId = await invokeSubAgent({
name: 'doc-generator',
prompt: 'Generate API documentation',
mode: 'async',
});
// 主 Agent 继续其他工作
await doOtherWork();
// 等待两个 Agent 完成
const [testResult, docsResult] = await Promise.all([
waitForAgent(testAgentId),
waitForAgent(docsAgentId),
]);