Skip to content

Commit 3b11db1

Browse files
committed
feat: add parent-to-subagent communication in agentMessage tool
1 parent 2f1a84c commit 3b11db1

File tree

5 files changed

+65
-6
lines changed

5 files changed

+65
-6
lines changed

packages/agent/src/core/toolAgent/toolAgentCore.ts

+28
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,34 @@ export const toolAgent = async (
6161

6262
interactions++;
6363

64+
// Check for messages from parent agent
65+
// This assumes the context has an agentTracker and the current agent's ID
66+
if (context.agentTracker && context.currentAgentId) {
67+
const agentState = context.agentTracker.getAgentState(
68+
context.currentAgentId,
69+
);
70+
71+
// Process any new parent messages
72+
if (
73+
agentState &&
74+
agentState.parentMessages &&
75+
agentState.parentMessages.length > 0
76+
) {
77+
// Get all parent messages and clear the queue
78+
const parentMessages = [...agentState.parentMessages];
79+
agentState.parentMessages = [];
80+
81+
// Add each message to the conversation
82+
for (const message of parentMessages) {
83+
logger.info(`Message from parent agent: ${message}`);
84+
messages.push({
85+
role: 'user',
86+
content: `[Message from parent agent]: ${message}`,
87+
});
88+
}
89+
}
90+
}
91+
6492
// Convert tools to function definitions
6593
const functionDefinitions = tools.map((tool) => ({
6694
name: tool.name,

packages/agent/src/core/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export type ToolContext = {
2626
userPrompt?: boolean;
2727
agentId?: string; // Unique identifier for the agent, used for background tool tracking
2828
agentName?: string; // Name of the agent, used for browser tracker
29+
currentAgentId?: string; // ID of the current agent, used for parent-to-subagent communication
2930
provider: ModelProvider;
3031
model?: string;
3132
baseUrl?: string;

packages/agent/src/tools/agent/AgentTracker.ts

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export interface AgentState {
3333
workingDirectory: string;
3434
tools: unknown[];
3535
aborted: boolean;
36+
parentMessages: string[]; // Messages from parent agent
3637
}
3738

3839
export class AgentTracker {

packages/agent/src/tools/agent/agentMessage.ts

+33-6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ const returnSchema = z.object({
3333
.boolean()
3434
.optional()
3535
.describe('Whether the sub-agent was terminated by this message'),
36+
messageSent: z
37+
.boolean()
38+
.optional()
39+
.describe('Whether a message was sent to the sub-agent'),
40+
messageCount: z
41+
.number()
42+
.optional()
43+
.describe("The number of messages in the sub-agent's queue"),
3644
});
3745

3846
type Parameters = z.infer<typeof parameterSchema>;
@@ -68,6 +76,8 @@ export const agentMessageTool: Tool<Parameters, ReturnType> = {
6876
output: agentState.output || 'Sub-agent was previously terminated',
6977
completed: true,
7078
terminated: true,
79+
messageSent: false,
80+
messageCount: 0,
7181
};
7282
}
7383

@@ -80,19 +90,24 @@ export const agentMessageTool: Tool<Parameters, ReturnType> = {
8090
output: agentState.output || 'Sub-agent terminated before completion',
8191
completed: true,
8292
terminated: true,
93+
messageSent: false,
94+
messageCount: 0,
8395
};
8496
}
8597

86-
// Add guidance to the agent state for future implementation
87-
// In a more advanced implementation, this could inject the guidance
88-
// into the agent's execution context
98+
// Add guidance to the agent state's parentMessages array
99+
// The sub-agent will check for these messages on each iteration
89100
if (guidance) {
90101
logger.info(
91102
`Guidance provided to sub-agent ${instanceId}: ${guidance}`,
92103
);
93-
// This is a placeholder for future implementation
94-
// In a real implementation, we would need to interrupt the agent's
95-
// execution and inject this guidance
104+
105+
// Add the guidance to the parentMessages array
106+
agentState.parentMessages.push(guidance);
107+
108+
logger.verbose(
109+
`Added message to sub-agent ${instanceId}'s parentMessages queue. Total messages: ${agentState.parentMessages.length}`,
110+
);
96111
}
97112

98113
// Get the current output
@@ -103,6 +118,8 @@ export const agentMessageTool: Tool<Parameters, ReturnType> = {
103118
output,
104119
completed: agentState.completed,
105120
...(agentState.error && { error: agentState.error }),
121+
messageSent: guidance ? true : false,
122+
messageCount: agentState.parentMessages.length,
106123
};
107124
} catch (error) {
108125
if (error instanceof Error) {
@@ -112,6 +129,8 @@ export const agentMessageTool: Tool<Parameters, ReturnType> = {
112129
output: '',
113130
completed: false,
114131
error: error.message,
132+
messageSent: false,
133+
messageCount: 0,
115134
};
116135
}
117136

@@ -123,6 +142,8 @@ export const agentMessageTool: Tool<Parameters, ReturnType> = {
123142
output: '',
124143
completed: false,
125144
error: `Unknown error occurred: ${errorMessage}`,
145+
messageSent: false,
146+
messageCount: 0,
126147
};
127148
}
128149
},
@@ -142,5 +163,11 @@ export const agentMessageTool: Tool<Parameters, ReturnType> = {
142163
} else {
143164
logger.info('Sub-agent is still running');
144165
}
166+
167+
if (output.messageSent) {
168+
logger.info(
169+
`Message sent to sub-agent. Queue now has ${output.messageCount || 0} message(s).`,
170+
);
171+
}
145172
},
146173
};

packages/agent/src/tools/agent/agentStart.ts

+2
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ export const agentStartTool: Tool<Parameters, ReturnType> = {
116116
workingDirectory: workingDirectory ?? context.workingDirectory,
117117
tools,
118118
aborted: false,
119+
parentMessages: [], // Initialize empty array for parent messages
119120
};
120121

121122
// Register agent state with the tracker
@@ -131,6 +132,7 @@ export const agentStartTool: Tool<Parameters, ReturnType> = {
131132
const result = await toolAgent(prompt, tools, agentConfig, {
132133
...context,
133134
workingDirectory: workingDirectory ?? context.workingDirectory,
135+
currentAgentId: instanceId, // Pass the agent's ID to the context
134136
});
135137

136138
// Update agent state with the result

0 commit comments

Comments
 (0)