@clinebot/agents 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -0
- package/dist/agent-input.d.ts +2 -0
- package/dist/agent.d.ts +56 -0
- package/dist/extensions.d.ts +21 -0
- package/dist/hooks/engine.d.ts +42 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/lifecycle.d.ts +5 -0
- package/dist/hooks/node.d.ts +2 -0
- package/dist/hooks/subprocess-runner.d.ts +16 -0
- package/dist/hooks/subprocess.d.ts +268 -0
- package/dist/index.browser.d.ts +1 -0
- package/dist/index.browser.js +49 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +49 -0
- package/dist/index.node.d.ts +5 -0
- package/dist/index.node.js +49 -0
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/policies.d.ts +14 -0
- package/dist/mcp/tools.d.ts +9 -0
- package/dist/mcp/types.d.ts +35 -0
- package/dist/message-builder.d.ts +31 -0
- package/dist/prompts/cline.d.ts +1 -0
- package/dist/prompts/index.d.ts +1 -0
- package/dist/runtime/agent-runtime-bus.d.ts +13 -0
- package/dist/runtime/conversation-store.d.ts +16 -0
- package/dist/runtime/lifecycle-orchestrator.d.ts +28 -0
- package/dist/runtime/tool-orchestrator.d.ts +39 -0
- package/dist/runtime/turn-processor.d.ts +21 -0
- package/dist/teams/index.d.ts +3 -0
- package/dist/teams/multi-agent.d.ts +566 -0
- package/dist/teams/spawn-agent-tool.d.ts +85 -0
- package/dist/teams/team-tools.d.ts +51 -0
- package/dist/tools/ask-question.d.ts +12 -0
- package/dist/tools/create.d.ts +59 -0
- package/dist/tools/execution.d.ts +61 -0
- package/dist/tools/formatting.d.ts +20 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/registry.d.ts +26 -0
- package/dist/tools/validation.d.ts +27 -0
- package/dist/types.d.ts +826 -0
- package/package.json +54 -0
- package/src/agent-input.ts +116 -0
- package/src/agent.test.ts +931 -0
- package/src/agent.ts +1050 -0
- package/src/example.test.ts +564 -0
- package/src/extensions.ts +337 -0
- package/src/hooks/engine.test.ts +163 -0
- package/src/hooks/engine.ts +537 -0
- package/src/hooks/index.ts +6 -0
- package/src/hooks/lifecycle.ts +239 -0
- package/src/hooks/node.ts +18 -0
- package/src/hooks/subprocess-runner.ts +140 -0
- package/src/hooks/subprocess.test.ts +180 -0
- package/src/hooks/subprocess.ts +620 -0
- package/src/index.browser.ts +1 -0
- package/src/index.node.ts +21 -0
- package/src/index.ts +133 -0
- package/src/mcp/index.ts +17 -0
- package/src/mcp/policies.test.ts +51 -0
- package/src/mcp/policies.ts +53 -0
- package/src/mcp/tools.test.ts +76 -0
- package/src/mcp/tools.ts +60 -0
- package/src/mcp/types.ts +41 -0
- package/src/message-builder.test.ts +175 -0
- package/src/message-builder.ts +429 -0
- package/src/prompts/cline.ts +49 -0
- package/src/prompts/index.ts +1 -0
- package/src/runtime/agent-runtime-bus.ts +53 -0
- package/src/runtime/conversation-store.ts +61 -0
- package/src/runtime/lifecycle-orchestrator.ts +90 -0
- package/src/runtime/tool-orchestrator.ts +177 -0
- package/src/runtime/turn-processor.ts +250 -0
- package/src/streaming.test.ts +197 -0
- package/src/streaming.ts +307 -0
- package/src/teams/index.ts +63 -0
- package/src/teams/multi-agent.lifecycle.test.ts +48 -0
- package/src/teams/multi-agent.ts +1866 -0
- package/src/teams/spawn-agent-tool.test.ts +172 -0
- package/src/teams/spawn-agent-tool.ts +223 -0
- package/src/teams/team-tools.test.ts +448 -0
- package/src/teams/team-tools.ts +929 -0
- package/src/tools/ask-question.ts +78 -0
- package/src/tools/create.ts +104 -0
- package/src/tools/execution.ts +311 -0
- package/src/tools/formatting.ts +73 -0
- package/src/tools/index.ts +45 -0
- package/src/tools/registry.ts +52 -0
- package/src/tools/tools.test.ts +292 -0
- package/src/tools/validation.ts +73 -0
- package/src/types.ts +966 -0
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Agent Coordination
|
|
3
|
+
*
|
|
4
|
+
* Utilities for orchestrating multiple agents working together.
|
|
5
|
+
*/
|
|
6
|
+
import { type Agent } from "../agent.js";
|
|
7
|
+
import type { AgentConfig, AgentEvent, AgentResult } from "../types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for a team member agent
|
|
10
|
+
*/
|
|
11
|
+
export interface TeamMemberConfig extends AgentConfig {
|
|
12
|
+
/** Optional role description for this agent */
|
|
13
|
+
role?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Task to execute on a specific agent
|
|
17
|
+
*/
|
|
18
|
+
export interface AgentTask {
|
|
19
|
+
/** ID of the agent to run the task */
|
|
20
|
+
agentId: string;
|
|
21
|
+
/** Message to send to the agent */
|
|
22
|
+
message: string;
|
|
23
|
+
/** Optional metadata for the task */
|
|
24
|
+
metadata?: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Result from a task execution
|
|
28
|
+
*/
|
|
29
|
+
export interface TaskResult {
|
|
30
|
+
/** ID of the agent that executed the task */
|
|
31
|
+
agentId: string;
|
|
32
|
+
/** The agent result */
|
|
33
|
+
result: AgentResult;
|
|
34
|
+
/** Any error that occurred */
|
|
35
|
+
error?: Error;
|
|
36
|
+
/** Task metadata */
|
|
37
|
+
metadata?: Record<string, unknown>;
|
|
38
|
+
}
|
|
39
|
+
export declare enum TeamMessageType {
|
|
40
|
+
TaskStart = "task_start",
|
|
41
|
+
TaskEnd = "task_end",
|
|
42
|
+
AgentEvent = "agent_event",
|
|
43
|
+
TeammateSpawned = "teammate_spawned",
|
|
44
|
+
TeammateShutdown = "teammate_shutdown",
|
|
45
|
+
TeamTaskUpdated = "team_task_updated",
|
|
46
|
+
TeamMessage = "team_message",
|
|
47
|
+
TeamMissionLog = "team_mission_log",
|
|
48
|
+
TeamTaskCompleted = "team_task_completed",
|
|
49
|
+
RunStarted = "run_started",
|
|
50
|
+
RunQueued = "run_queued",
|
|
51
|
+
RunProgress = "run_progress",
|
|
52
|
+
RunCompleted = "run_completed",
|
|
53
|
+
RunFailed = "run_failed",
|
|
54
|
+
RunCancelled = "run_cancelled",
|
|
55
|
+
RunInterrupted = "run_interrupted",
|
|
56
|
+
OutcomeCreated = "outcome_created",
|
|
57
|
+
OutcomeFragmentAttached = "outcome_fragment_attached",
|
|
58
|
+
OutcomeFragmentReviewed = "outcome_fragment_reviewed",
|
|
59
|
+
OutcomeFinalized = "outcome_finalized"
|
|
60
|
+
}
|
|
61
|
+
export interface TeammateLifecycleSpec {
|
|
62
|
+
rolePrompt: string;
|
|
63
|
+
modelId?: string;
|
|
64
|
+
maxIterations?: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Event emitted during team execution
|
|
68
|
+
*/
|
|
69
|
+
export type TeamEvent = {
|
|
70
|
+
type: TeamMessageType.TaskStart;
|
|
71
|
+
agentId: string;
|
|
72
|
+
message: string;
|
|
73
|
+
} | {
|
|
74
|
+
type: TeamMessageType.TaskEnd;
|
|
75
|
+
agentId: string;
|
|
76
|
+
result?: AgentResult;
|
|
77
|
+
error?: Error;
|
|
78
|
+
} | {
|
|
79
|
+
type: TeamMessageType.AgentEvent;
|
|
80
|
+
agentId: string;
|
|
81
|
+
event: AgentEvent;
|
|
82
|
+
} | {
|
|
83
|
+
type: TeamMessageType.TeammateSpawned;
|
|
84
|
+
agentId: string;
|
|
85
|
+
role?: string;
|
|
86
|
+
teammate: TeammateLifecycleSpec;
|
|
87
|
+
} | {
|
|
88
|
+
type: TeamMessageType.TeammateShutdown;
|
|
89
|
+
agentId: string;
|
|
90
|
+
reason?: string;
|
|
91
|
+
} | {
|
|
92
|
+
type: TeamMessageType.TeamTaskUpdated;
|
|
93
|
+
task: TeamTask;
|
|
94
|
+
} | {
|
|
95
|
+
type: TeamMessageType.TeamMessage;
|
|
96
|
+
message: TeamMailboxMessage;
|
|
97
|
+
} | {
|
|
98
|
+
type: TeamMessageType.TeamMissionLog;
|
|
99
|
+
entry: MissionLogEntry;
|
|
100
|
+
} | {
|
|
101
|
+
type: TeamMessageType.RunQueued;
|
|
102
|
+
run: TeamRunRecord;
|
|
103
|
+
} | {
|
|
104
|
+
type: TeamMessageType.RunStarted;
|
|
105
|
+
run: TeamRunRecord;
|
|
106
|
+
} | {
|
|
107
|
+
type: TeamMessageType.RunProgress;
|
|
108
|
+
run: TeamRunRecord;
|
|
109
|
+
message: string;
|
|
110
|
+
} | {
|
|
111
|
+
type: TeamMessageType.RunCompleted;
|
|
112
|
+
run: TeamRunRecord;
|
|
113
|
+
} | {
|
|
114
|
+
type: TeamMessageType.RunFailed;
|
|
115
|
+
run: TeamRunRecord;
|
|
116
|
+
} | {
|
|
117
|
+
type: TeamMessageType.RunCancelled;
|
|
118
|
+
run: TeamRunRecord;
|
|
119
|
+
reason?: string;
|
|
120
|
+
} | {
|
|
121
|
+
type: TeamMessageType.RunInterrupted;
|
|
122
|
+
run: TeamRunRecord;
|
|
123
|
+
reason?: string;
|
|
124
|
+
} | {
|
|
125
|
+
type: TeamMessageType.OutcomeCreated;
|
|
126
|
+
outcome: TeamOutcome;
|
|
127
|
+
} | {
|
|
128
|
+
type: TeamMessageType.OutcomeFragmentAttached;
|
|
129
|
+
fragment: TeamOutcomeFragment;
|
|
130
|
+
} | {
|
|
131
|
+
type: TeamMessageType.OutcomeFragmentReviewed;
|
|
132
|
+
fragment: TeamOutcomeFragment;
|
|
133
|
+
} | {
|
|
134
|
+
type: TeamMessageType.OutcomeFinalized;
|
|
135
|
+
outcome: TeamOutcome;
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* A team of agents that can work together
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* const team = createAgentTeam({
|
|
143
|
+
* coder: {
|
|
144
|
+
* providerId: "anthropic",
|
|
145
|
+
* modelId: "claude-sonnet-4-20250514",
|
|
146
|
+
* systemPrompt: "You are a coding expert.",
|
|
147
|
+
* tools: [readFile, writeFile],
|
|
148
|
+
* },
|
|
149
|
+
* reviewer: {
|
|
150
|
+
* providerId: "openai",
|
|
151
|
+
* modelId: "gpt-4o",
|
|
152
|
+
* systemPrompt: "You are a code reviewer.",
|
|
153
|
+
* tools: [readFile],
|
|
154
|
+
* }
|
|
155
|
+
* })
|
|
156
|
+
*
|
|
157
|
+
* const result = await team.routeTo("coder", "Write a function")
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
export declare class AgentTeam {
|
|
161
|
+
private agents;
|
|
162
|
+
private configs;
|
|
163
|
+
private onTeamEvent?;
|
|
164
|
+
constructor(configs?: Record<string, TeamMemberConfig>, onTeamEvent?: (event: TeamEvent) => void);
|
|
165
|
+
/**
|
|
166
|
+
* Add an agent to the team
|
|
167
|
+
*
|
|
168
|
+
* @param id - Unique identifier for the agent
|
|
169
|
+
* @param config - Agent configuration
|
|
170
|
+
*/
|
|
171
|
+
addAgent(id: string, config: TeamMemberConfig): void;
|
|
172
|
+
/**
|
|
173
|
+
* Remove an agent from the team
|
|
174
|
+
*/
|
|
175
|
+
removeAgent(id: string): boolean;
|
|
176
|
+
/**
|
|
177
|
+
* Get an agent by ID
|
|
178
|
+
*/
|
|
179
|
+
getAgent(id: string): Agent | undefined;
|
|
180
|
+
/**
|
|
181
|
+
* Get all agent IDs in the team
|
|
182
|
+
*/
|
|
183
|
+
getAgentIds(): string[];
|
|
184
|
+
/**
|
|
185
|
+
* Get the number of agents in the team
|
|
186
|
+
*/
|
|
187
|
+
get size(): number;
|
|
188
|
+
/**
|
|
189
|
+
* Route a message to a specific agent
|
|
190
|
+
*
|
|
191
|
+
* @param agentId - ID of the agent to send the message to
|
|
192
|
+
* @param message - The message to send
|
|
193
|
+
* @returns The agent result
|
|
194
|
+
*/
|
|
195
|
+
routeTo(agentId: string, message: string): Promise<AgentResult>;
|
|
196
|
+
/**
|
|
197
|
+
* Continue a conversation with a specific agent
|
|
198
|
+
*
|
|
199
|
+
* @param agentId - ID of the agent to continue with
|
|
200
|
+
* @param message - The message to send
|
|
201
|
+
* @returns The agent result
|
|
202
|
+
*/
|
|
203
|
+
continueTo(agentId: string, message: string): Promise<AgentResult>;
|
|
204
|
+
/**
|
|
205
|
+
* Run multiple tasks in parallel across different agents
|
|
206
|
+
*
|
|
207
|
+
* @param tasks - Array of tasks to execute
|
|
208
|
+
* @returns Array of task results in the same order
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```typescript
|
|
212
|
+
* const results = await team.runParallel([
|
|
213
|
+
* { agentId: "coder", message: "Implement feature X" },
|
|
214
|
+
* { agentId: "reviewer", message: "Review the code" },
|
|
215
|
+
* ])
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
runParallel(tasks: AgentTask[]): Promise<TaskResult[]>;
|
|
219
|
+
/**
|
|
220
|
+
* Run tasks sequentially across agents
|
|
221
|
+
*
|
|
222
|
+
* Tasks are executed in order, and the result of each task is available
|
|
223
|
+
* to the next task via the context parameter.
|
|
224
|
+
*
|
|
225
|
+
* @param tasks - Array of tasks to execute in order
|
|
226
|
+
* @returns Array of task results in the same order
|
|
227
|
+
*/
|
|
228
|
+
runSequential(tasks: AgentTask[]): Promise<TaskResult[]>;
|
|
229
|
+
/**
|
|
230
|
+
* Run a pipeline of agents where output from one becomes input to the next
|
|
231
|
+
*
|
|
232
|
+
* @param pipeline - Array of agent IDs in pipeline order
|
|
233
|
+
* @param initialMessage - The starting message
|
|
234
|
+
* @param messageTransformer - Optional function to transform output to input
|
|
235
|
+
* @returns Array of all results from the pipeline
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* const results = await team.runPipeline(
|
|
240
|
+
* ["planner", "coder", "reviewer"],
|
|
241
|
+
* "Create a REST API for user management",
|
|
242
|
+
* (prevResult, agentId) => {
|
|
243
|
+
* if (agentId === "coder") {
|
|
244
|
+
* return `Implement this plan:\n${prevResult.text}`
|
|
245
|
+
* }
|
|
246
|
+
* return `Review this code:\n${prevResult.text}`
|
|
247
|
+
* }
|
|
248
|
+
* )
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
runPipeline(pipeline: string[], initialMessage: string, messageTransformer?: (prevResult: AgentResult, nextAgentId: string) => string): Promise<TaskResult[]>;
|
|
252
|
+
/**
|
|
253
|
+
* Abort all running agents
|
|
254
|
+
*/
|
|
255
|
+
abortAll(): void;
|
|
256
|
+
/**
|
|
257
|
+
* Clear all agents from the team
|
|
258
|
+
*/
|
|
259
|
+
clear(): void;
|
|
260
|
+
private emitEvent;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Create a new agent team
|
|
264
|
+
*
|
|
265
|
+
* @param configs - Map of agent ID to configuration
|
|
266
|
+
* @param onTeamEvent - Optional callback for team events
|
|
267
|
+
* @returns A new AgentTeam instance
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* ```typescript
|
|
271
|
+
* const team = createAgentTeam({
|
|
272
|
+
* coder: {
|
|
273
|
+
* providerId: "anthropic",
|
|
274
|
+
* modelId: "claude-sonnet-4-20250514",
|
|
275
|
+
* systemPrompt: "You are a coding expert.",
|
|
276
|
+
* tools: [readFile, writeFile],
|
|
277
|
+
* },
|
|
278
|
+
* reviewer: {
|
|
279
|
+
* providerId: "anthropic",
|
|
280
|
+
* modelId: "claude-sonnet-4-20250514",
|
|
281
|
+
* systemPrompt: "You are a code reviewer.",
|
|
282
|
+
* tools: [readFile],
|
|
283
|
+
* }
|
|
284
|
+
* })
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
export declare function createAgentTeam(configs: Record<string, TeamMemberConfig>, onTeamEvent?: (event: TeamEvent) => void): AgentTeam;
|
|
288
|
+
/**
|
|
289
|
+
* Create a simple two-agent team with a worker and reviewer
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
* ```typescript
|
|
293
|
+
* const team = createWorkerReviewerTeam({
|
|
294
|
+
* worker: {
|
|
295
|
+
* providerId: "anthropic",
|
|
296
|
+
* modelId: "claude-sonnet-4-20250514",
|
|
297
|
+
* systemPrompt: "You are a coding expert.",
|
|
298
|
+
* tools: [...],
|
|
299
|
+
* },
|
|
300
|
+
* reviewer: {
|
|
301
|
+
* providerId: "anthropic",
|
|
302
|
+
* modelId: "claude-sonnet-4-20250514",
|
|
303
|
+
* systemPrompt: "You review code for issues.",
|
|
304
|
+
* tools: [...],
|
|
305
|
+
* }
|
|
306
|
+
* })
|
|
307
|
+
*
|
|
308
|
+
* const result = await team.doAndReview("Implement feature X")
|
|
309
|
+
* ```
|
|
310
|
+
*/
|
|
311
|
+
export declare function createWorkerReviewerTeam(configs: {
|
|
312
|
+
worker: TeamMemberConfig;
|
|
313
|
+
reviewer: TeamMemberConfig;
|
|
314
|
+
}): AgentTeam & {
|
|
315
|
+
doAndReview: (message: string) => Promise<{
|
|
316
|
+
workerResult: AgentResult;
|
|
317
|
+
reviewResult: AgentResult;
|
|
318
|
+
}>;
|
|
319
|
+
};
|
|
320
|
+
export type TeamTaskStatus = "pending" | "in_progress" | "blocked" | "completed";
|
|
321
|
+
export interface TeamTask {
|
|
322
|
+
id: string;
|
|
323
|
+
title: string;
|
|
324
|
+
description: string;
|
|
325
|
+
status: TeamTaskStatus;
|
|
326
|
+
createdAt: Date;
|
|
327
|
+
updatedAt: Date;
|
|
328
|
+
createdBy: string;
|
|
329
|
+
assignee?: string;
|
|
330
|
+
dependsOn: string[];
|
|
331
|
+
summary?: string;
|
|
332
|
+
}
|
|
333
|
+
export type MissionLogKind = "progress" | "handoff" | "blocked" | "decision" | "done" | "error";
|
|
334
|
+
export interface MissionLogEntry {
|
|
335
|
+
id: string;
|
|
336
|
+
ts: Date;
|
|
337
|
+
teamId: string;
|
|
338
|
+
agentId: string;
|
|
339
|
+
taskId?: string;
|
|
340
|
+
kind: MissionLogKind;
|
|
341
|
+
summary: string;
|
|
342
|
+
evidence?: string[];
|
|
343
|
+
nextAction?: string;
|
|
344
|
+
}
|
|
345
|
+
export interface TeamMailboxMessage {
|
|
346
|
+
id: string;
|
|
347
|
+
teamId: string;
|
|
348
|
+
fromAgentId: string;
|
|
349
|
+
toAgentId: string;
|
|
350
|
+
subject: string;
|
|
351
|
+
body: string;
|
|
352
|
+
taskId?: string;
|
|
353
|
+
sentAt: Date;
|
|
354
|
+
readAt?: Date;
|
|
355
|
+
}
|
|
356
|
+
export interface TeamMemberSnapshot {
|
|
357
|
+
agentId: string;
|
|
358
|
+
role: "lead" | "teammate";
|
|
359
|
+
description?: string;
|
|
360
|
+
status: "idle" | "running" | "stopped";
|
|
361
|
+
}
|
|
362
|
+
export interface TeamRuntimeSnapshot {
|
|
363
|
+
teamId: string;
|
|
364
|
+
teamName: string;
|
|
365
|
+
members: TeamMemberSnapshot[];
|
|
366
|
+
taskCounts: Record<TeamTaskStatus, number>;
|
|
367
|
+
unreadMessages: number;
|
|
368
|
+
missionLogEntries: number;
|
|
369
|
+
activeRuns: number;
|
|
370
|
+
queuedRuns: number;
|
|
371
|
+
outcomeCounts: Record<TeamOutcomeStatus, number>;
|
|
372
|
+
}
|
|
373
|
+
export interface TeamRuntimeState {
|
|
374
|
+
teamId: string;
|
|
375
|
+
teamName: string;
|
|
376
|
+
members: TeamMemberSnapshot[];
|
|
377
|
+
tasks: TeamTask[];
|
|
378
|
+
mailbox: TeamMailboxMessage[];
|
|
379
|
+
missionLog: MissionLogEntry[];
|
|
380
|
+
runs: TeamRunRecord[];
|
|
381
|
+
outcomes: TeamOutcome[];
|
|
382
|
+
outcomeFragments: TeamOutcomeFragment[];
|
|
383
|
+
}
|
|
384
|
+
export interface AgentTeamsRuntimeOptions {
|
|
385
|
+
teamName: string;
|
|
386
|
+
leadAgentId?: string;
|
|
387
|
+
missionLogIntervalSteps?: number;
|
|
388
|
+
missionLogIntervalMs?: number;
|
|
389
|
+
maxConcurrentRuns?: number;
|
|
390
|
+
onTeamEvent?: (event: TeamEvent) => void;
|
|
391
|
+
}
|
|
392
|
+
export interface SpawnTeammateOptions {
|
|
393
|
+
agentId: string;
|
|
394
|
+
config: TeamMemberConfig;
|
|
395
|
+
}
|
|
396
|
+
export interface RouteToTeammateOptions {
|
|
397
|
+
taskId?: string;
|
|
398
|
+
fromAgentId?: string;
|
|
399
|
+
continueConversation?: boolean;
|
|
400
|
+
}
|
|
401
|
+
export type TeamRunStatus = "queued" | "running" | "completed" | "failed" | "cancelled" | "interrupted";
|
|
402
|
+
export interface TeamRunRecord {
|
|
403
|
+
id: string;
|
|
404
|
+
agentId: string;
|
|
405
|
+
taskId?: string;
|
|
406
|
+
status: TeamRunStatus;
|
|
407
|
+
message: string;
|
|
408
|
+
priority: number;
|
|
409
|
+
retryCount: number;
|
|
410
|
+
maxRetries: number;
|
|
411
|
+
nextAttemptAt?: Date;
|
|
412
|
+
continueConversation?: boolean;
|
|
413
|
+
startedAt: Date;
|
|
414
|
+
endedAt?: Date;
|
|
415
|
+
leaseOwner?: string;
|
|
416
|
+
heartbeatAt?: Date;
|
|
417
|
+
result?: AgentResult;
|
|
418
|
+
error?: string;
|
|
419
|
+
}
|
|
420
|
+
export type TeamOutcomeStatus = "draft" | "in_review" | "finalized";
|
|
421
|
+
export interface TeamOutcome {
|
|
422
|
+
id: string;
|
|
423
|
+
teamId: string;
|
|
424
|
+
title: string;
|
|
425
|
+
status: TeamOutcomeStatus;
|
|
426
|
+
requiredSections: string[];
|
|
427
|
+
createdBy: string;
|
|
428
|
+
createdAt: Date;
|
|
429
|
+
finalizedAt?: Date;
|
|
430
|
+
}
|
|
431
|
+
export type TeamOutcomeFragmentStatus = "draft" | "reviewed" | "rejected";
|
|
432
|
+
export interface TeamOutcomeFragment {
|
|
433
|
+
id: string;
|
|
434
|
+
teamId: string;
|
|
435
|
+
outcomeId: string;
|
|
436
|
+
section: string;
|
|
437
|
+
sourceAgentId: string;
|
|
438
|
+
sourceRunId?: string;
|
|
439
|
+
content: string;
|
|
440
|
+
status: TeamOutcomeFragmentStatus;
|
|
441
|
+
reviewedBy?: string;
|
|
442
|
+
reviewedAt?: Date;
|
|
443
|
+
createdAt: Date;
|
|
444
|
+
}
|
|
445
|
+
export interface AppendMissionLogInput {
|
|
446
|
+
agentId: string;
|
|
447
|
+
taskId?: string;
|
|
448
|
+
kind: MissionLogKind;
|
|
449
|
+
summary: string;
|
|
450
|
+
evidence?: string[];
|
|
451
|
+
nextAction?: string;
|
|
452
|
+
}
|
|
453
|
+
export interface CreateTeamTaskInput {
|
|
454
|
+
title: string;
|
|
455
|
+
description: string;
|
|
456
|
+
createdBy: string;
|
|
457
|
+
dependsOn?: string[];
|
|
458
|
+
assignee?: string;
|
|
459
|
+
}
|
|
460
|
+
export interface CreateTeamOutcomeInput {
|
|
461
|
+
title: string;
|
|
462
|
+
requiredSections: string[];
|
|
463
|
+
createdBy: string;
|
|
464
|
+
}
|
|
465
|
+
export interface AttachTeamOutcomeFragmentInput {
|
|
466
|
+
outcomeId: string;
|
|
467
|
+
section: string;
|
|
468
|
+
sourceAgentId: string;
|
|
469
|
+
sourceRunId?: string;
|
|
470
|
+
content: string;
|
|
471
|
+
}
|
|
472
|
+
export interface ReviewTeamOutcomeFragmentInput {
|
|
473
|
+
fragmentId: string;
|
|
474
|
+
reviewedBy: string;
|
|
475
|
+
approved: boolean;
|
|
476
|
+
}
|
|
477
|
+
export declare class AgentTeamsRuntime {
|
|
478
|
+
private readonly teamId;
|
|
479
|
+
private readonly teamName;
|
|
480
|
+
private readonly onTeamEvent?;
|
|
481
|
+
private readonly members;
|
|
482
|
+
private readonly tasks;
|
|
483
|
+
private readonly missionLog;
|
|
484
|
+
private readonly mailbox;
|
|
485
|
+
private missionStepCounter;
|
|
486
|
+
private taskCounter;
|
|
487
|
+
private messageCounter;
|
|
488
|
+
private missionCounter;
|
|
489
|
+
private runCounter;
|
|
490
|
+
private outcomeCounter;
|
|
491
|
+
private outcomeFragmentCounter;
|
|
492
|
+
private readonly runs;
|
|
493
|
+
private readonly runQueue;
|
|
494
|
+
private readonly outcomes;
|
|
495
|
+
private readonly outcomeFragments;
|
|
496
|
+
private readonly missionLogIntervalSteps;
|
|
497
|
+
private readonly missionLogIntervalMs;
|
|
498
|
+
private readonly maxConcurrentRuns;
|
|
499
|
+
constructor(options: AgentTeamsRuntimeOptions);
|
|
500
|
+
getTeamId(): string;
|
|
501
|
+
getTeamName(): string;
|
|
502
|
+
getMemberRole(agentId: string): "lead" | "teammate" | undefined;
|
|
503
|
+
getMemberIds(): string[];
|
|
504
|
+
getTeammateIds(): string[];
|
|
505
|
+
getTask(taskId: string): TeamTask | undefined;
|
|
506
|
+
listTasks(): TeamTask[];
|
|
507
|
+
listMissionLog(limit?: number): MissionLogEntry[];
|
|
508
|
+
listMailbox(agentId: string, options?: {
|
|
509
|
+
unreadOnly?: boolean;
|
|
510
|
+
markRead?: boolean;
|
|
511
|
+
limit?: number;
|
|
512
|
+
}): TeamMailboxMessage[];
|
|
513
|
+
getSnapshot(): TeamRuntimeSnapshot;
|
|
514
|
+
exportState(): TeamRuntimeState;
|
|
515
|
+
hydrateState(state: TeamRuntimeState): void;
|
|
516
|
+
isTeammateActive(agentId: string): boolean;
|
|
517
|
+
spawnTeammate({ agentId, config }: SpawnTeammateOptions): TeamMemberSnapshot;
|
|
518
|
+
shutdownTeammate(agentId: string, reason?: string): void;
|
|
519
|
+
/**
|
|
520
|
+
* Update connection overrides (e.g. refreshed API key) on all active
|
|
521
|
+
* teammate agents so they stay in sync with the lead agent's credentials.
|
|
522
|
+
*/
|
|
523
|
+
updateTeammateConnections(overrides: Partial<Pick<AgentConfig, "apiKey" | "baseUrl" | "headers">>): void;
|
|
524
|
+
createTask(input: CreateTeamTaskInput): TeamTask;
|
|
525
|
+
claimTask(taskId: string, agentId: string): TeamTask;
|
|
526
|
+
blockTask(taskId: string, agentId: string, reason: string): TeamTask;
|
|
527
|
+
completeTask(taskId: string, agentId: string, summary: string): TeamTask;
|
|
528
|
+
routeToTeammate(agentId: string, message: string, options?: RouteToTeammateOptions): Promise<AgentResult>;
|
|
529
|
+
startTeammateRun(agentId: string, message: string, options?: RouteToTeammateOptions & {
|
|
530
|
+
priority?: number;
|
|
531
|
+
maxRetries?: number;
|
|
532
|
+
leaseOwner?: string;
|
|
533
|
+
}): TeamRunRecord;
|
|
534
|
+
private dispatchQueuedRuns;
|
|
535
|
+
private selectNextQueuedRunIndex;
|
|
536
|
+
private countActiveRuns;
|
|
537
|
+
private executeQueuedRun;
|
|
538
|
+
listRuns(options?: {
|
|
539
|
+
status?: TeamRunStatus;
|
|
540
|
+
agentId?: string;
|
|
541
|
+
includeCompleted?: boolean;
|
|
542
|
+
}): TeamRunRecord[];
|
|
543
|
+
getRun(runId: string): TeamRunRecord | undefined;
|
|
544
|
+
awaitRun(runId: string, pollIntervalMs?: number): Promise<TeamRunRecord>;
|
|
545
|
+
awaitAllRuns(pollIntervalMs?: number): Promise<TeamRunRecord[]>;
|
|
546
|
+
cancelRun(runId: string, reason?: string): TeamRunRecord;
|
|
547
|
+
markStaleRunsInterrupted(reason?: string): TeamRunRecord[];
|
|
548
|
+
sendMessage(fromAgentId: string, toAgentId: string, subject: string, body: string, taskId?: string): TeamMailboxMessage;
|
|
549
|
+
broadcast(fromAgentId: string, subject: string, body: string, options?: {
|
|
550
|
+
includeLead?: boolean;
|
|
551
|
+
taskId?: string;
|
|
552
|
+
}): TeamMailboxMessage[];
|
|
553
|
+
appendMissionLog(input: AppendMissionLogInput): MissionLogEntry;
|
|
554
|
+
createOutcome(input: CreateTeamOutcomeInput): TeamOutcome;
|
|
555
|
+
listOutcomes(): TeamOutcome[];
|
|
556
|
+
attachOutcomeFragment(input: AttachTeamOutcomeFragmentInput): TeamOutcomeFragment;
|
|
557
|
+
reviewOutcomeFragment(input: ReviewTeamOutcomeFragmentInput): TeamOutcomeFragment;
|
|
558
|
+
listOutcomeFragments(outcomeId: string): TeamOutcomeFragment[];
|
|
559
|
+
finalizeOutcome(outcomeId: string): TeamOutcome;
|
|
560
|
+
cleanup(): void;
|
|
561
|
+
private requireTask;
|
|
562
|
+
private assertDependenciesResolved;
|
|
563
|
+
private trackMeaningfulEvent;
|
|
564
|
+
private recordProgressStep;
|
|
565
|
+
private emitEvent;
|
|
566
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reusable spawn_agent tool for delegating tasks to sub-agents.
|
|
3
|
+
*/
|
|
4
|
+
import type { providers as LlmsProviders } from "@clinebot/llms";
|
|
5
|
+
import type { Tool, ToolApprovalRequest, ToolApprovalResult, ToolContext, ToolPolicy } from "@clinebot/shared";
|
|
6
|
+
import type { AgentEvent, AgentExtension, AgentFinishReason, AgentHooks, BasicLogger, HookErrorMode } from "../types.js";
|
|
7
|
+
export interface SpawnAgentInput {
|
|
8
|
+
systemPrompt: string;
|
|
9
|
+
task: string;
|
|
10
|
+
maxIterations?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface SpawnAgentOutput {
|
|
13
|
+
text: string;
|
|
14
|
+
iterations: number;
|
|
15
|
+
finishReason: AgentFinishReason;
|
|
16
|
+
usage: {
|
|
17
|
+
inputTokens: number;
|
|
18
|
+
outputTokens: number;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export interface SubAgentStartContext {
|
|
22
|
+
subAgentId: string;
|
|
23
|
+
conversationId: string;
|
|
24
|
+
parentAgentId: string;
|
|
25
|
+
input: SpawnAgentInput;
|
|
26
|
+
}
|
|
27
|
+
export interface SubAgentEndContext {
|
|
28
|
+
subAgentId: string;
|
|
29
|
+
conversationId: string;
|
|
30
|
+
parentAgentId: string;
|
|
31
|
+
input: SpawnAgentInput;
|
|
32
|
+
result?: SpawnAgentOutput;
|
|
33
|
+
error?: Error;
|
|
34
|
+
}
|
|
35
|
+
export interface SpawnAgentToolConfig {
|
|
36
|
+
providerId: string;
|
|
37
|
+
modelId: string;
|
|
38
|
+
apiKey?: string;
|
|
39
|
+
baseUrl?: string;
|
|
40
|
+
providerConfig?: LlmsProviders.ProviderConfig;
|
|
41
|
+
knownModels?: Record<string, LlmsProviders.ModelInfo>;
|
|
42
|
+
thinking?: boolean;
|
|
43
|
+
defaultMaxIterations?: number;
|
|
44
|
+
subAgentTools?: Tool[];
|
|
45
|
+
createSubAgentTools?: (input: SpawnAgentInput, context: ToolContext) => Tool[] | Promise<Tool[]>;
|
|
46
|
+
onSubAgentEvent?: (event: AgentEvent) => void;
|
|
47
|
+
/**
|
|
48
|
+
* Lifecycle hooks forwarded to spawned sub-agent runs.
|
|
49
|
+
*/
|
|
50
|
+
hooks?: AgentHooks;
|
|
51
|
+
/**
|
|
52
|
+
* Extension list forwarded to spawned sub-agent runs.
|
|
53
|
+
*/
|
|
54
|
+
extensions?: AgentExtension[];
|
|
55
|
+
/**
|
|
56
|
+
* Error handling mode for forwarded lifecycle hooks.
|
|
57
|
+
*/
|
|
58
|
+
hookErrorMode?: HookErrorMode;
|
|
59
|
+
/**
|
|
60
|
+
* Called after a sub-agent instance is created and before it starts running.
|
|
61
|
+
* Errors are ignored so lifecycle observers cannot break task execution.
|
|
62
|
+
*/
|
|
63
|
+
onSubAgentStart?: (context: SubAgentStartContext) => void | Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Called once a sub-agent run finishes (success or error).
|
|
66
|
+
* Errors are ignored so lifecycle observers cannot break task execution.
|
|
67
|
+
*/
|
|
68
|
+
onSubAgentEnd?: (context: SubAgentEndContext) => void | Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Optional per-tool policy for spawned sub-agents.
|
|
71
|
+
*/
|
|
72
|
+
toolPolicies?: Record<string, ToolPolicy>;
|
|
73
|
+
/**
|
|
74
|
+
* Optional approval callback for spawned sub-agent tool calls.
|
|
75
|
+
*/
|
|
76
|
+
requestToolApproval?: (request: ToolApprovalRequest) => Promise<ToolApprovalResult> | ToolApprovalResult;
|
|
77
|
+
/**
|
|
78
|
+
* Optional logger forwarded to spawned sub-agent runs.
|
|
79
|
+
*/
|
|
80
|
+
logger?: BasicLogger;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Create a spawn_agent tool that can run a delegated task with a focused sub-agent.
|
|
84
|
+
*/
|
|
85
|
+
export declare function createSpawnAgentTool(config: SpawnAgentToolConfig): Tool<SpawnAgentInput, SpawnAgentOutput>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { providers as LlmsProviders } from "@clinebot/llms";
|
|
2
|
+
import { type Tool } from "@clinebot/shared";
|
|
3
|
+
import type { AgentConfig, AgentHooks, BasicLogger } from "../types.js";
|
|
4
|
+
import type { AgentTeamsRuntime, TeamRuntimeState } from "./multi-agent.js";
|
|
5
|
+
export interface TeamTeammateSpec {
|
|
6
|
+
agentId: string;
|
|
7
|
+
rolePrompt: string;
|
|
8
|
+
modelId?: string;
|
|
9
|
+
maxIterations?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface TeamTeammateRuntimeConfig {
|
|
12
|
+
providerId: string;
|
|
13
|
+
modelId: string;
|
|
14
|
+
cwd?: string;
|
|
15
|
+
apiKey?: string;
|
|
16
|
+
baseUrl?: string;
|
|
17
|
+
headers?: Record<string, string>;
|
|
18
|
+
providerConfig?: LlmsProviders.ProviderConfig;
|
|
19
|
+
knownModels?: Record<string, LlmsProviders.ModelInfo>;
|
|
20
|
+
thinking?: boolean;
|
|
21
|
+
clineWorkspaceMetadata?: string;
|
|
22
|
+
clineIdeName?: string;
|
|
23
|
+
maxIterations?: number;
|
|
24
|
+
hooks?: AgentHooks;
|
|
25
|
+
extensions?: AgentConfig["extensions"];
|
|
26
|
+
logger?: BasicLogger;
|
|
27
|
+
}
|
|
28
|
+
export interface CreateAgentTeamsToolsOptions {
|
|
29
|
+
runtime: AgentTeamsRuntime;
|
|
30
|
+
requesterId: string;
|
|
31
|
+
teammateRuntime: TeamTeammateRuntimeConfig;
|
|
32
|
+
createBaseTools?: () => Tool[];
|
|
33
|
+
allowSpawn?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface BootstrapAgentTeamsOptions {
|
|
36
|
+
runtime: AgentTeamsRuntime;
|
|
37
|
+
teammateRuntime: TeamTeammateRuntimeConfig;
|
|
38
|
+
createBaseTools?: () => Tool[];
|
|
39
|
+
leadAgentId?: string;
|
|
40
|
+
restoredTeammates?: TeamTeammateSpec[];
|
|
41
|
+
restoredFromPersistence?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface BootstrapAgentTeamsResult {
|
|
44
|
+
tools: Tool[];
|
|
45
|
+
restoredFromPersistence: boolean;
|
|
46
|
+
restoredTeammates: string[];
|
|
47
|
+
}
|
|
48
|
+
export declare function bootstrapAgentTeams(options: BootstrapAgentTeamsOptions): BootstrapAgentTeamsResult;
|
|
49
|
+
export declare function createAgentTeamsTools(options: CreateAgentTeamsToolsOptions): Tool[];
|
|
50
|
+
export declare function reviveTeamStateDates(state: TeamRuntimeState): TeamRuntimeState;
|
|
51
|
+
export declare function sanitizeTeamName(name: string): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Tool, type ToolContext } from "@clinebot/shared";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export declare const AskQuestionInputSchema: z.ZodObject<{
|
|
4
|
+
question: z.ZodString;
|
|
5
|
+
options: z.ZodArray<z.ZodString>;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
export type AskQuestionInput = z.infer<typeof AskQuestionInputSchema>;
|
|
8
|
+
export type AskQuestionExecutor = (question: string, options: string[], context: ToolContext) => Promise<string>;
|
|
9
|
+
export interface AskQuestionToolConfig {
|
|
10
|
+
askQuestionTimeoutMs?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function createAskQuestionTool(executor: AskQuestionExecutor, config?: AskQuestionToolConfig): Tool<AskQuestionInput, string>;
|