Skip to content

Commit 2f1a84c

Browse files
authored
Merge pull request #310 from drivecore/refactor/remove-global-agent-states
refactor: remove global agentStates in favor of agentTracker
2 parents b8bf908 + 4c9dc6e commit 2f1a84c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+212
-215
lines changed

docs/tools/agent-tools.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
The agent tools provide ways to create and interact with sub-agents. There are two approaches available:
44

5-
1. The original `subAgent` tool (synchronous, blocking)
5+
1. The original `agentExecute` tool (synchronous, blocking)
66
2. The new `agentStart` and `agentMessage` tools (asynchronous, non-blocking)
77

8-
## subAgent Tool
8+
## agentExecute Tool
99

10-
The `subAgent` tool creates a sub-agent that runs synchronously until completion. The parent agent waits for the sub-agent to complete before continuing.
10+
The `agentExecute` tool creates a sub-agent that runs synchronously until completion. The parent agent waits for the sub-agent to complete before continuing.
1111

1212
```typescript
13-
subAgent({
13+
agentExecute({
1414
description: "A brief description of the sub-agent's purpose",
1515
goal: 'The main objective that the sub-agent needs to achieve',
1616
projectContext: 'Context about the problem or environment',
@@ -123,7 +123,7 @@ while (!agent1Completed || !agent2Completed) {
123123

124124
## Choosing Between Approaches
125125

126-
- Use `subAgent` for simpler tasks where blocking execution is acceptable
126+
- Use `agentExecute` for simpler tasks where blocking execution is acceptable
127127
- Use `agentStart` and `agentMessage` for:
128128
- Parallel execution of multiple sub-agents
129129
- Tasks where you need to monitor progress

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ export function getDefaultSystemPrompt(toolContext: ToolContext): string {
146146
githubModeInstructions,
147147
'',
148148
'You prefer to call tools in parallel when possible because it leads to faster execution and less resource usage.',
149-
'When done, call the sequenceComplete tool with your results to indicate that the sequence has completed.',
149+
'When done, call the agentDone tool with your results to indicate that the sequence has completed.',
150150
'',
151151
'For coding tasks:',
152152
'0. Try to break large tasks into smaller sub-tasks that can be completed and verified sequentially.',

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe('toolAgentCore empty response detection', () => {
1313
content: [
1414
{
1515
type: 'text',
16-
text: 'I notice you sent an empty response. If you are done with your tasks, please call the sequenceComplete tool with your results. If you are waiting for other tools to complete, you can use the sleep tool to wait before checking again.',
16+
text: 'I notice you sent an empty response. If you are done with your tasks, please call the agentDone tool with your results. If you are waiting for other tools to complete, you can use the sleep tool to wait before checking again.',
1717
},
1818
],
1919
});

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export const toolAgent = async (
100100
messages.push({
101101
role: 'user',
102102
content:
103-
'I notice you sent an empty response. If you are done with your tasks, please call the sequenceComplete tool with your results. If you are waiting for other tools to complete, you can use the sleep tool to wait before checking again.',
103+
'I notice you sent an empty response. If you are done with your tasks, please call the agentDone tool with your results. If you are waiting for other tools to complete, you can use the sleep tool to wait before checking again.',
104104
});
105105
continue;
106106
}
@@ -129,8 +129,12 @@ export const toolAgent = async (
129129
);
130130

131131
// Execute the tools and get results
132-
const { sequenceCompleted, completionResult, respawn } =
133-
await executeTools(toolCalls, tools, messages, localContext);
132+
const { agentDoned, completionResult, respawn } = await executeTools(
133+
toolCalls,
134+
tools,
135+
messages,
136+
localContext,
137+
);
134138

135139
if (respawn) {
136140
logger.info('Respawning agent with new context');
@@ -143,7 +147,7 @@ export const toolAgent = async (
143147
continue;
144148
}
145149

146-
if (sequenceCompleted) {
150+
if (agentDoned) {
147151
const result: ToolAgentResult = {
148152
result: completionResult ?? 'Sequence explicitly completed',
149153
interactions,

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

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export async function executeTools(
3232
context: ToolContext,
3333
): Promise<ToolCallResult> {
3434
if (toolCalls.length === 0) {
35-
return { sequenceCompleted: false, toolResults: [] };
35+
return { agentDoned: false, toolResults: [] };
3636
}
3737

3838
const { logger } = context;
@@ -46,7 +46,7 @@ export async function executeTools(
4646
addToolResultToMessages(messages, respawnCall.id, { success: true }, false);
4747

4848
return {
49-
sequenceCompleted: false,
49+
agentDoned: false,
5050
toolResults: [
5151
{
5252
toolCallId: respawnCall.id,
@@ -97,19 +97,17 @@ export async function executeTools(
9797
}),
9898
);
9999

100-
const sequenceCompletedTool = toolResults.find(
101-
(r) => r.toolName === 'sequenceComplete',
102-
);
103-
const completionResult = sequenceCompletedTool
104-
? (sequenceCompletedTool.result as { result: string }).result
100+
const agentDonedTool = toolResults.find((r) => r.toolName === 'agentDone');
101+
const completionResult = agentDonedTool
102+
? (agentDonedTool.result as { result: string }).result
105103
: undefined;
106104

107-
if (sequenceCompletedTool) {
105+
if (agentDonedTool) {
108106
logger.verbose('Sequence completed', { completionResult });
109107
}
110108

111109
return {
112-
sequenceCompleted: sequenceCompletedTool !== undefined,
110+
agentDoned: agentDonedTool !== undefined,
113111
completionResult,
114112
toolResults,
115113
};

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export interface ToolAgentResult {
77
}
88

99
export interface ToolCallResult {
10-
sequenceCompleted: boolean;
10+
agentDoned: boolean;
1111
completionResult?: string;
1212
toolResults: unknown[];
1313
respawn?: { context: string };

packages/agent/src/core/types.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { z } from 'zod';
22
import { JsonSchema7Type } from 'zod-to-json-schema';
33

4-
import { BrowserTracker } from '../tools/browser/browserTracker.js';
5-
import { AgentTracker } from '../tools/interaction/agentTracker.js';
6-
import { ShellTracker } from '../tools/system/shellTracker.js';
4+
import { AgentTracker } from '../tools/agent/AgentTracker.js';
5+
import { SessionTracker } from '../tools/session/SessionTracker.js';
6+
import { ShellTracker } from '../tools/shell/ShellTracker.js';
77
import { Logger } from '../utils/logger.js';
88

99
import { TokenTracker } from './tokens.js';
@@ -34,7 +34,7 @@ export type ToolContext = {
3434
temperature: number;
3535
agentTracker: AgentTracker;
3636
shellTracker: ShellTracker;
37-
browserTracker: BrowserTracker;
37+
browserTracker: SessionTracker;
3838
};
3939

4040
export type Tool<TParams = Record<string, any>, TReturn = any> = {

packages/agent/src/index.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,28 @@
33
export * from './tools/io/fetch.js';
44

55
// Tools - System
6-
export * from './tools/system/shellStart.js';
6+
export * from './tools/shell/shellStart.js';
77
export * from './tools/system/sleep.js';
88
export * from './tools/system/respawn.js';
9-
export * from './tools/system/sequenceComplete.js';
10-
export * from './tools/system/shellMessage.js';
11-
export * from './tools/system/shellExecute.js';
12-
export * from './tools/system/listShells.js';
13-
export * from './tools/system/shellTracker.js';
9+
export * from './tools/agent/agentDone.js';
10+
export * from './tools/shell/shellMessage.js';
11+
export * from './tools/shell/shellExecute.js';
12+
export * from './tools/shell/listShells.js';
13+
export * from './tools/shell/ShellTracker.js';
1414

1515
// Tools - Browser
16-
export * from './tools/browser/BrowserManager.js';
17-
export * from './tools/browser/types.js';
18-
export * from './tools/browser/browseMessage.js';
19-
export * from './tools/browser/browseStart.js';
20-
export * from './tools/browser/PageController.js';
21-
export * from './tools/browser/BrowserAutomation.js';
22-
export * from './tools/browser/listBrowsers.js';
23-
export * from './tools/browser/browserTracker.js';
16+
export * from './tools/session/lib/SessionManager.js';
17+
export * from './tools/session/lib/types.js';
18+
export * from './tools/session/sessionMessage.js';
19+
export * from './tools/session/sessionStart.js';
20+
export * from './tools/session/lib/PageController.js';
21+
export * from './tools/session/lib/BrowserAutomation.js';
22+
export * from './tools/session/listSessions.js';
23+
export * from './tools/session/SessionTracker.js';
2424

25-
export * from './tools/interaction/agentTracker.js';
25+
export * from './tools/agent/AgentTracker.js';
2626
// Tools - Interaction
27-
export * from './tools/interaction/subAgent.js';
27+
export * from './tools/agent/agentExecute.js';
2828
export * from './tools/interaction/userPrompt.js';
2929

3030
// Core

packages/agent/src/tools/system/sequenceComplete.ts renamed to packages/agent/src/tools/agent/agentDone.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ const returnSchema = z.object({
1616
type Parameters = z.infer<typeof parameterSchema>;
1717
type ReturnType = z.infer<typeof returnSchema>;
1818

19-
export const sequenceCompleteTool: Tool<Parameters, ReturnType> = {
20-
name: 'sequenceComplete',
19+
export const agentDoneTool: Tool<Parameters, ReturnType> = {
20+
name: 'agentDone',
2121
description: 'Completes the tool use sequence and returns the final result',
2222
logPrefix: '✅',
2323
parameters: parameterSchema,

packages/agent/src/tools/interaction/subAgent.test.ts renamed to packages/agent/src/tools/agent/agentExecute.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import { describe, expect, it, vi } from 'vitest';
33
import { TokenTracker } from '../../core/tokens.js';
44
import { ToolContext } from '../../core/types.js';
55
import { MockLogger } from '../../utils/mockLogger.js';
6-
import { BrowserTracker } from '../browser/browserTracker.js';
7-
import { ShellTracker } from '../system/shellTracker.js';
6+
import { SessionTracker } from '../session/SessionTracker.js';
7+
import { ShellTracker } from '../shell/ShellTracker.js';
88

9-
import { AgentTracker } from './agentTracker.js';
10-
import { subAgentTool } from './subAgent.js';
9+
import { agentExecuteTool } from './agentExecute.js';
10+
import { AgentTracker } from './AgentTracker.js';
1111

1212
// Mock the toolAgent function
1313
vi.mock('../../core/toolAgent/toolAgentCore.js', () => ({
@@ -37,12 +37,12 @@ const mockContext: ToolContext = {
3737
temperature: 0.7,
3838
agentTracker: new AgentTracker('test'),
3939
shellTracker: new ShellTracker('test'),
40-
browserTracker: new BrowserTracker('test'),
40+
browserTracker: new SessionTracker('test'),
4141
};
4242

43-
describe('subAgentTool', () => {
43+
describe('agentExecuteTool', () => {
4444
it('should create a sub-agent and return its response', async () => {
45-
const result = await subAgentTool.execute(
45+
const result = await agentExecuteTool.execute(
4646
{
4747
description: 'Test sub-agent',
4848
goal: 'Test the sub-agent tool',
@@ -58,7 +58,7 @@ describe('subAgentTool', () => {
5858
it('should use custom working directory when provided', async () => {
5959
const { toolAgent } = await import('../../core/toolAgent/toolAgentCore.js');
6060

61-
await subAgentTool.execute(
61+
await agentExecuteTool.execute(
6262
{
6363
description: 'Test sub-agent with custom directory',
6464
goal: 'Test the sub-agent tool',
@@ -82,7 +82,7 @@ describe('subAgentTool', () => {
8282
it('should include relevant files in the prompt when provided', async () => {
8383
const { toolAgent } = await import('../../core/toolAgent/toolAgentCore.js');
8484

85-
await subAgentTool.execute(
85+
await agentExecuteTool.execute(
8686
{
8787
description: 'Test sub-agent with relevant files',
8888
goal: 'Test the sub-agent tool',

packages/agent/src/tools/interaction/subAgent.ts renamed to packages/agent/src/tools/agent/agentExecute.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import {
77
} from '../../core/toolAgent/config.js';
88
import { toolAgent } from '../../core/toolAgent/toolAgentCore.js';
99
import { Tool, ToolContext } from '../../core/types.js';
10-
import { BrowserTracker } from '../browser/browserTracker.js';
1110
import { getTools } from '../getTools.js';
12-
import { ShellTracker } from '../system/shellTracker.js';
11+
import { SessionTracker } from '../session/SessionTracker.js';
12+
import { ShellTracker } from '../shell/ShellTracker.js';
1313

14-
import { AgentTracker } from './agentTracker.js';
14+
import { AgentTracker } from './AgentTracker.js';
1515

1616
const parameterSchema = z.object({
1717
description: z
@@ -45,22 +45,22 @@ type Parameters = z.infer<typeof parameterSchema>;
4545
type ReturnType = z.infer<typeof returnSchema>;
4646

4747
// Sub-agent specific configuration
48-
const subAgentConfig: AgentConfig = {
48+
const agentConfig: AgentConfig = {
4949
maxIterations: 200,
5050
getSystemPrompt: (context: ToolContext) => {
5151
return [
5252
getDefaultSystemPrompt(context),
5353
'You are a focused AI sub-agent handling a specific task.',
5454
'You have access to the same tools as the main agent but should focus only on your assigned task.',
55-
'When complete, call the sequenceComplete tool with your results.',
55+
'When complete, call the agentDone tool with your results.',
5656
'Follow any specific conventions or requirements provided in the task context.',
5757
'Ask the main agent for clarification if critical information is missing.',
5858
].join('\n');
5959
},
6060
};
6161

62-
export const subAgentTool: Tool<Parameters, ReturnType> = {
63-
name: 'subAgent',
62+
export const agentExecuteTool: Tool<Parameters, ReturnType> = {
63+
name: 'agentExecute',
6464
description:
6565
'Creates a sub-agent that has access to all tools to solve a specific task',
6666
logPrefix: '🤖',
@@ -89,7 +89,7 @@ export const subAgentTool: Tool<Parameters, ReturnType> = {
8989
workingDirectory: workingDirectory ?? context.workingDirectory,
9090
agentTracker: new AgentTracker(subAgentId),
9191
shellTracker: new ShellTracker(subAgentId),
92-
browserTracker: new BrowserTracker(subAgentId),
92+
browserTracker: new SessionTracker(subAgentId),
9393
};
9494

9595
// Construct a well-structured prompt
@@ -107,9 +107,9 @@ export const subAgentTool: Tool<Parameters, ReturnType> = {
107107

108108
const tools = getTools({ userPrompt: false });
109109

110-
// Use the subAgentConfig
110+
// Use the agentConfig
111111
const config: AgentConfig = {
112-
...subAgentConfig,
112+
...agentConfig,
113113
};
114114

115115
try {

packages/agent/src/tools/interaction/agentStart.ts renamed to packages/agent/src/tools/agent/agentStart.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { toolAgent } from '../../core/toolAgent/toolAgentCore.js';
99
import { Tool, ToolContext } from '../../core/types.js';
1010
import { getTools } from '../getTools.js';
1111

12-
import { AgentStatus, AgentState } from './agentTracker.js';
12+
import { AgentStatus, AgentState } from './AgentTracker.js';
1313

1414
// For backward compatibility
1515
export const agentStates = new Map<string, AgentState>();
@@ -49,14 +49,14 @@ type Parameters = z.infer<typeof parameterSchema>;
4949
type ReturnType = z.infer<typeof returnSchema>;
5050

5151
// Sub-agent specific configuration
52-
const subAgentConfig: AgentConfig = {
52+
const agentConfig: AgentConfig = {
5353
maxIterations: 200,
5454
getSystemPrompt: (context: ToolContext) => {
5555
return [
5656
getDefaultSystemPrompt(context),
5757
'You are a focused AI sub-agent handling a specific task.',
5858
'You have access to the same tools as the main agent but should focus only on your assigned task.',
59-
'When complete, call the sequenceComplete tool with your results.',
59+
'When complete, call the agentDone tool with your results.',
6060
'Follow any specific conventions or requirements provided in the task context.',
6161
'Ask the main agent for clarification if critical information is missing.',
6262
].join('\n');
@@ -128,7 +128,7 @@ export const agentStartTool: Tool<Parameters, ReturnType> = {
128128
// eslint-disable-next-line promise/catch-or-return
129129
Promise.resolve().then(async () => {
130130
try {
131-
const result = await toolAgent(prompt, tools, subAgentConfig, {
131+
const result = await toolAgent(prompt, tools, agentConfig, {
132132
...context,
133133
workingDirectory: workingDirectory ?? context.workingDirectory,
134134
});

packages/agent/src/tools/interaction/agentTools.test.ts renamed to packages/agent/src/tools/agent/agentTools.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import { describe, expect, it, vi } from 'vitest';
33
import { TokenTracker } from '../../core/tokens.js';
44
import { ToolContext } from '../../core/types.js';
55
import { MockLogger } from '../../utils/mockLogger.js';
6-
import { BrowserTracker } from '../browser/browserTracker.js';
7-
import { ShellTracker } from '../system/shellTracker.js';
6+
import { SessionTracker } from '../session/SessionTracker.js';
7+
import { ShellTracker } from '../shell/ShellTracker.js';
88

99
import { agentMessageTool } from './agentMessage.js';
1010
import { agentStartTool, agentStates } from './agentStart.js';
11-
import { AgentTracker } from './agentTracker.js';
11+
import { AgentTracker } from './AgentTracker.js';
1212

1313
// Mock the toolAgent function
1414
vi.mock('../../core/toolAgent/toolAgentCore.js', () => ({
@@ -33,7 +33,7 @@ const mockContext: ToolContext = {
3333
temperature: 0.7,
3434
agentTracker: new AgentTracker('test'),
3535
shellTracker: new ShellTracker('test'),
36-
browserTracker: new BrowserTracker('test'),
36+
browserTracker: new SessionTracker('test'),
3737
};
3838

3939
describe('Agent Tools', () => {

packages/agent/src/tools/system/listAgents.ts renamed to packages/agent/src/tools/agent/listAgents.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { z } from 'zod';
22
import { zodToJsonSchema } from 'zod-to-json-schema';
33

44
import { Tool } from '../../core/types.js';
5-
import { AgentStatus } from '../interaction/agentTracker.js';
5+
6+
import { AgentStatus } from './AgentTracker.js';
67

78
const parameterSchema = z.object({
89
status: z

0 commit comments

Comments
 (0)