-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Expand file tree
/
Copy pathsubagent.ts
More file actions
115 lines (99 loc) · 3.2 KB
/
subagent.ts
File metadata and controls
115 lines (99 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { services } from "../services/index.js";
import { serviceContainer } from "../services/ServiceContainer.js";
import { ModelServiceState, SERVICE_NAMES } from "../services/types.js";
import { executeSubAgent } from "../subagent/executor.js";
import {
generateSubagentToolDescription,
getSubagent,
getAgentNames as getSubagentNames,
} from "../subagent/getAgents.js";
import { SUBAGENT_TOOL_META } from "../subagent/index.js";
import { logger } from "../util/logger.js";
import { Tool } from "./types.js";
export const subagentTool = async (): Promise<Tool> => {
const modelServiceState = await serviceContainer.get<ModelServiceState>(
SERVICE_NAMES.MODEL,
);
return {
...SUBAGENT_TOOL_META,
description: generateSubagentToolDescription(modelServiceState),
parameters: {
...SUBAGENT_TOOL_META.parameters,
properties: {
...SUBAGENT_TOOL_META.parameters.properties,
subagent_name: {
type: "string",
description: `The type of specialized agent to use for this task. Available agents: ${
modelServiceState
? getSubagentNames(modelServiceState).join(", ")
: ""
}`,
},
},
},
preprocess: async (args: any) => {
const { description, subagent_name } = args;
const agent = getSubagent(modelServiceState, subagent_name);
if (!agent) {
throw new Error(
`Unknown agent type: ${subagent_name}. Available agents: ${getSubagentNames(
modelServiceState,
).join(", ")}`,
);
}
return {
args,
preview: [
{
type: "text",
content: `Spawning ${agent.model.name} to: ${description}`,
},
],
};
},
run: async (args: any, context?: { toolCallId: string }) => {
const { prompt, subagent_name } = args;
logger.debug("subagent args", { args, context });
// get agent configuration
const agent = getSubagent(modelServiceState, subagent_name);
if (!agent) {
throw new Error(`Unknown agent type: ${subagent_name}`);
}
const chatHistoryService = services.chatHistory;
const parentSessionId = chatHistoryService.getSessionId();
if (!parentSessionId) {
throw new Error("No active session found");
}
// Execute subagent with output streaming
const result = await executeSubAgent({
agent,
prompt,
parentSessionId,
abortController: new AbortController(),
onOutputUpdate: context?.toolCallId
? (output: string) => {
try {
chatHistoryService.addToolResult(
context.toolCallId,
output,
"calling",
);
} catch {
// Ignore errors during streaming updates
}
}
: undefined,
});
logger.debug("subagent result", { result });
const output = [
result.response,
"<task_metadata>",
`status: ${result.success ? "completed" : "failed"}`,
"</task_metadata>",
]
.filter(Boolean)
.join("\n");
return output;
},
};
};