@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.
Files changed (90) hide show
  1. package/README.md +145 -0
  2. package/dist/agent-input.d.ts +2 -0
  3. package/dist/agent.d.ts +56 -0
  4. package/dist/extensions.d.ts +21 -0
  5. package/dist/hooks/engine.d.ts +42 -0
  6. package/dist/hooks/index.d.ts +2 -0
  7. package/dist/hooks/lifecycle.d.ts +5 -0
  8. package/dist/hooks/node.d.ts +2 -0
  9. package/dist/hooks/subprocess-runner.d.ts +16 -0
  10. package/dist/hooks/subprocess.d.ts +268 -0
  11. package/dist/index.browser.d.ts +1 -0
  12. package/dist/index.browser.js +49 -0
  13. package/dist/index.d.ts +15 -0
  14. package/dist/index.js +49 -0
  15. package/dist/index.node.d.ts +5 -0
  16. package/dist/index.node.js +49 -0
  17. package/dist/mcp/index.d.ts +4 -0
  18. package/dist/mcp/policies.d.ts +14 -0
  19. package/dist/mcp/tools.d.ts +9 -0
  20. package/dist/mcp/types.d.ts +35 -0
  21. package/dist/message-builder.d.ts +31 -0
  22. package/dist/prompts/cline.d.ts +1 -0
  23. package/dist/prompts/index.d.ts +1 -0
  24. package/dist/runtime/agent-runtime-bus.d.ts +13 -0
  25. package/dist/runtime/conversation-store.d.ts +16 -0
  26. package/dist/runtime/lifecycle-orchestrator.d.ts +28 -0
  27. package/dist/runtime/tool-orchestrator.d.ts +39 -0
  28. package/dist/runtime/turn-processor.d.ts +21 -0
  29. package/dist/teams/index.d.ts +3 -0
  30. package/dist/teams/multi-agent.d.ts +566 -0
  31. package/dist/teams/spawn-agent-tool.d.ts +85 -0
  32. package/dist/teams/team-tools.d.ts +51 -0
  33. package/dist/tools/ask-question.d.ts +12 -0
  34. package/dist/tools/create.d.ts +59 -0
  35. package/dist/tools/execution.d.ts +61 -0
  36. package/dist/tools/formatting.d.ts +20 -0
  37. package/dist/tools/index.d.ts +11 -0
  38. package/dist/tools/registry.d.ts +26 -0
  39. package/dist/tools/validation.d.ts +27 -0
  40. package/dist/types.d.ts +826 -0
  41. package/package.json +54 -0
  42. package/src/agent-input.ts +116 -0
  43. package/src/agent.test.ts +931 -0
  44. package/src/agent.ts +1050 -0
  45. package/src/example.test.ts +564 -0
  46. package/src/extensions.ts +337 -0
  47. package/src/hooks/engine.test.ts +163 -0
  48. package/src/hooks/engine.ts +537 -0
  49. package/src/hooks/index.ts +6 -0
  50. package/src/hooks/lifecycle.ts +239 -0
  51. package/src/hooks/node.ts +18 -0
  52. package/src/hooks/subprocess-runner.ts +140 -0
  53. package/src/hooks/subprocess.test.ts +180 -0
  54. package/src/hooks/subprocess.ts +620 -0
  55. package/src/index.browser.ts +1 -0
  56. package/src/index.node.ts +21 -0
  57. package/src/index.ts +133 -0
  58. package/src/mcp/index.ts +17 -0
  59. package/src/mcp/policies.test.ts +51 -0
  60. package/src/mcp/policies.ts +53 -0
  61. package/src/mcp/tools.test.ts +76 -0
  62. package/src/mcp/tools.ts +60 -0
  63. package/src/mcp/types.ts +41 -0
  64. package/src/message-builder.test.ts +175 -0
  65. package/src/message-builder.ts +429 -0
  66. package/src/prompts/cline.ts +49 -0
  67. package/src/prompts/index.ts +1 -0
  68. package/src/runtime/agent-runtime-bus.ts +53 -0
  69. package/src/runtime/conversation-store.ts +61 -0
  70. package/src/runtime/lifecycle-orchestrator.ts +90 -0
  71. package/src/runtime/tool-orchestrator.ts +177 -0
  72. package/src/runtime/turn-processor.ts +250 -0
  73. package/src/streaming.test.ts +197 -0
  74. package/src/streaming.ts +307 -0
  75. package/src/teams/index.ts +63 -0
  76. package/src/teams/multi-agent.lifecycle.test.ts +48 -0
  77. package/src/teams/multi-agent.ts +1866 -0
  78. package/src/teams/spawn-agent-tool.test.ts +172 -0
  79. package/src/teams/spawn-agent-tool.ts +223 -0
  80. package/src/teams/team-tools.test.ts +448 -0
  81. package/src/teams/team-tools.ts +929 -0
  82. package/src/tools/ask-question.ts +78 -0
  83. package/src/tools/create.ts +104 -0
  84. package/src/tools/execution.ts +311 -0
  85. package/src/tools/formatting.ts +73 -0
  86. package/src/tools/index.ts +45 -0
  87. package/src/tools/registry.ts +52 -0
  88. package/src/tools/tools.test.ts +292 -0
  89. package/src/tools/validation.ts +73 -0
  90. 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>;