@jackchen_me/open-multi-agent 0.1.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 (133) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +280 -0
  3. package/dist/agent/agent.d.ts +121 -0
  4. package/dist/agent/agent.d.ts.map +1 -0
  5. package/dist/agent/agent.js +294 -0
  6. package/dist/agent/agent.js.map +1 -0
  7. package/dist/agent/pool.d.ts +128 -0
  8. package/dist/agent/pool.d.ts.map +1 -0
  9. package/dist/agent/pool.js +236 -0
  10. package/dist/agent/pool.js.map +1 -0
  11. package/dist/agent/runner.d.ts +120 -0
  12. package/dist/agent/runner.d.ts.map +1 -0
  13. package/dist/agent/runner.js +274 -0
  14. package/dist/agent/runner.js.map +1 -0
  15. package/dist/index.d.ts +73 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +87 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/llm/adapter.d.ts +38 -0
  20. package/dist/llm/adapter.d.ts.map +1 -0
  21. package/dist/llm/adapter.js +46 -0
  22. package/dist/llm/adapter.js.map +1 -0
  23. package/dist/llm/anthropic.d.ts +56 -0
  24. package/dist/llm/anthropic.d.ts.map +1 -0
  25. package/dist/llm/anthropic.js +307 -0
  26. package/dist/llm/anthropic.js.map +1 -0
  27. package/dist/llm/openai.d.ts +62 -0
  28. package/dist/llm/openai.d.ts.map +1 -0
  29. package/dist/llm/openai.js +424 -0
  30. package/dist/llm/openai.js.map +1 -0
  31. package/dist/memory/shared.d.ts +86 -0
  32. package/dist/memory/shared.d.ts.map +1 -0
  33. package/dist/memory/shared.js +155 -0
  34. package/dist/memory/shared.js.map +1 -0
  35. package/dist/memory/store.d.ts +64 -0
  36. package/dist/memory/store.d.ts.map +1 -0
  37. package/dist/memory/store.js +103 -0
  38. package/dist/memory/store.js.map +1 -0
  39. package/dist/orchestrator/orchestrator.d.ts +173 -0
  40. package/dist/orchestrator/orchestrator.d.ts.map +1 -0
  41. package/dist/orchestrator/orchestrator.js +698 -0
  42. package/dist/orchestrator/orchestrator.js.map +1 -0
  43. package/dist/orchestrator/scheduler.d.ts +112 -0
  44. package/dist/orchestrator/scheduler.d.ts.map +1 -0
  45. package/dist/orchestrator/scheduler.js +282 -0
  46. package/dist/orchestrator/scheduler.js.map +1 -0
  47. package/dist/task/queue.d.ts +160 -0
  48. package/dist/task/queue.d.ts.map +1 -0
  49. package/dist/task/queue.js +337 -0
  50. package/dist/task/queue.js.map +1 -0
  51. package/dist/task/task.d.ts +86 -0
  52. package/dist/task/task.d.ts.map +1 -0
  53. package/dist/task/task.js +201 -0
  54. package/dist/task/task.js.map +1 -0
  55. package/dist/team/messaging.d.ts +106 -0
  56. package/dist/team/messaging.d.ts.map +1 -0
  57. package/dist/team/messaging.js +182 -0
  58. package/dist/team/messaging.js.map +1 -0
  59. package/dist/team/team.d.ts +141 -0
  60. package/dist/team/team.d.ts.map +1 -0
  61. package/dist/team/team.js +282 -0
  62. package/dist/team/team.js.map +1 -0
  63. package/dist/tool/built-in/bash.d.ts +12 -0
  64. package/dist/tool/built-in/bash.d.ts.map +1 -0
  65. package/dist/tool/built-in/bash.js +133 -0
  66. package/dist/tool/built-in/bash.js.map +1 -0
  67. package/dist/tool/built-in/file-edit.d.ts +14 -0
  68. package/dist/tool/built-in/file-edit.d.ts.map +1 -0
  69. package/dist/tool/built-in/file-edit.js +130 -0
  70. package/dist/tool/built-in/file-edit.js.map +1 -0
  71. package/dist/tool/built-in/file-read.d.ts +12 -0
  72. package/dist/tool/built-in/file-read.d.ts.map +1 -0
  73. package/dist/tool/built-in/file-read.js +82 -0
  74. package/dist/tool/built-in/file-read.js.map +1 -0
  75. package/dist/tool/built-in/file-write.d.ts +11 -0
  76. package/dist/tool/built-in/file-write.d.ts.map +1 -0
  77. package/dist/tool/built-in/file-write.js +70 -0
  78. package/dist/tool/built-in/file-write.js.map +1 -0
  79. package/dist/tool/built-in/grep.d.ts +15 -0
  80. package/dist/tool/built-in/grep.d.ts.map +1 -0
  81. package/dist/tool/built-in/grep.js +287 -0
  82. package/dist/tool/built-in/grep.js.map +1 -0
  83. package/dist/tool/built-in/index.d.ts +36 -0
  84. package/dist/tool/built-in/index.d.ts.map +1 -0
  85. package/dist/tool/built-in/index.js +45 -0
  86. package/dist/tool/built-in/index.js.map +1 -0
  87. package/dist/tool/executor.d.ts +71 -0
  88. package/dist/tool/executor.d.ts.map +1 -0
  89. package/dist/tool/executor.js +116 -0
  90. package/dist/tool/executor.js.map +1 -0
  91. package/dist/tool/framework.d.ts +143 -0
  92. package/dist/tool/framework.d.ts.map +1 -0
  93. package/dist/tool/framework.js +371 -0
  94. package/dist/tool/framework.js.map +1 -0
  95. package/dist/types.d.ts +285 -0
  96. package/dist/types.d.ts.map +1 -0
  97. package/dist/types.js +8 -0
  98. package/dist/types.js.map +1 -0
  99. package/dist/utils/semaphore.d.ts +47 -0
  100. package/dist/utils/semaphore.d.ts.map +1 -0
  101. package/dist/utils/semaphore.js +85 -0
  102. package/dist/utils/semaphore.js.map +1 -0
  103. package/examples/01-single-agent.ts +131 -0
  104. package/examples/02-team-collaboration.ts +167 -0
  105. package/examples/03-task-pipeline.ts +201 -0
  106. package/examples/04-multi-model-team.ts +261 -0
  107. package/package.json +49 -0
  108. package/src/agent/agent.ts +364 -0
  109. package/src/agent/pool.ts +278 -0
  110. package/src/agent/runner.ts +413 -0
  111. package/src/index.ts +166 -0
  112. package/src/llm/adapter.ts +74 -0
  113. package/src/llm/anthropic.ts +388 -0
  114. package/src/llm/openai.ts +522 -0
  115. package/src/memory/shared.ts +181 -0
  116. package/src/memory/store.ts +124 -0
  117. package/src/orchestrator/orchestrator.ts +851 -0
  118. package/src/orchestrator/scheduler.ts +352 -0
  119. package/src/task/queue.ts +394 -0
  120. package/src/task/task.ts +232 -0
  121. package/src/team/messaging.ts +230 -0
  122. package/src/team/team.ts +334 -0
  123. package/src/tool/built-in/bash.ts +187 -0
  124. package/src/tool/built-in/file-edit.ts +154 -0
  125. package/src/tool/built-in/file-read.ts +105 -0
  126. package/src/tool/built-in/file-write.ts +81 -0
  127. package/src/tool/built-in/grep.ts +362 -0
  128. package/src/tool/built-in/index.ts +50 -0
  129. package/src/tool/executor.ts +178 -0
  130. package/src/tool/framework.ts +557 -0
  131. package/src/types.ts +362 -0
  132. package/src/utils/semaphore.ts +89 -0
  133. package/tsconfig.json +25 -0
@@ -0,0 +1,337 @@
1
+ /**
2
+ * @fileoverview Dependency-aware task queue.
3
+ *
4
+ * {@link TaskQueue} owns the mutable lifecycle of every task it holds.
5
+ * Completing a task automatically unblocks dependents and fires events so
6
+ * orchestrators can react without polling.
7
+ */
8
+ import { isTaskReady } from './task.js';
9
+ // ---------------------------------------------------------------------------
10
+ // TaskQueue
11
+ // ---------------------------------------------------------------------------
12
+ /**
13
+ * Mutable, event-driven queue with topological dependency resolution.
14
+ *
15
+ * Tasks enter in `'pending'` state. The queue promotes them to `'blocked'`
16
+ * when unresolved dependencies exist, and back to `'pending'` (firing
17
+ * `'task:ready'`) when those dependencies complete. Callers drive execution by
18
+ * calling {@link next} / {@link nextAvailable} and updating task state via
19
+ * {@link complete} or {@link fail}.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const queue = new TaskQueue()
24
+ * queue.on('task:ready', (task) => scheduleExecution(task))
25
+ * queue.on('all:complete', () => shutdown())
26
+ *
27
+ * queue.addBatch(tasks)
28
+ * ```
29
+ */
30
+ export class TaskQueue {
31
+ tasks = new Map();
32
+ /** Listeners keyed by event type, stored as symbol → handler pairs. */
33
+ listeners = new Map();
34
+ // ---------------------------------------------------------------------------
35
+ // Mutation: add
36
+ // ---------------------------------------------------------------------------
37
+ /**
38
+ * Adds a single task.
39
+ *
40
+ * If the task has unresolved dependencies it is immediately promoted to
41
+ * `'blocked'`; otherwise it stays `'pending'` and `'task:ready'` fires.
42
+ */
43
+ add(task) {
44
+ const resolved = this.resolveInitialStatus(task);
45
+ this.tasks.set(resolved.id, resolved);
46
+ if (resolved.status === 'pending') {
47
+ this.emit('task:ready', resolved);
48
+ }
49
+ }
50
+ /**
51
+ * Adds multiple tasks at once.
52
+ *
53
+ * Processing each task re-evaluates the current map state, so inserting a
54
+ * batch where some tasks satisfy others' dependencies produces correct initial
55
+ * statuses when the dependencies appear first in the array. Use
56
+ * {@link getTaskDependencyOrder} from `task.ts` to pre-sort if needed.
57
+ */
58
+ addBatch(tasks) {
59
+ for (const task of tasks) {
60
+ this.add(task);
61
+ }
62
+ }
63
+ // ---------------------------------------------------------------------------
64
+ // Mutation: update / complete / fail
65
+ // ---------------------------------------------------------------------------
66
+ /**
67
+ * Applies a partial update to an existing task.
68
+ *
69
+ * Only `status`, `result`, and `assignee` are accepted to keep the update
70
+ * surface narrow. Use {@link complete} and {@link fail} for terminal states.
71
+ *
72
+ * @throws {Error} when `taskId` is not found.
73
+ */
74
+ update(taskId, update) {
75
+ const task = this.requireTask(taskId);
76
+ const updated = {
77
+ ...task,
78
+ ...update,
79
+ updatedAt: new Date(),
80
+ };
81
+ this.tasks.set(taskId, updated);
82
+ return updated;
83
+ }
84
+ /**
85
+ * Marks `taskId` as `'completed'`, records an optional `result` string, and
86
+ * unblocks any dependents that are now ready to run.
87
+ *
88
+ * Fires `'task:complete'`, then `'task:ready'` for each newly-unblocked task,
89
+ * then `'all:complete'` when the queue is fully resolved.
90
+ *
91
+ * @throws {Error} when `taskId` is not found.
92
+ */
93
+ complete(taskId, result) {
94
+ const completed = this.update(taskId, { status: 'completed', result });
95
+ this.emit('task:complete', completed);
96
+ this.unblockDependents(taskId);
97
+ if (this.isComplete()) {
98
+ this.emitAllComplete();
99
+ }
100
+ return completed;
101
+ }
102
+ /**
103
+ * Marks `taskId` as `'failed'` and records `error` in the `result` field.
104
+ *
105
+ * Fires `'task:failed'` for the failed task and for every downstream task
106
+ * that transitively depended on it (cascade failure). This prevents blocked
107
+ * tasks from remaining stuck indefinitely when an upstream dependency fails.
108
+ *
109
+ * @throws {Error} when `taskId` is not found.
110
+ */
111
+ fail(taskId, error) {
112
+ const failed = this.update(taskId, { status: 'failed', result: error });
113
+ this.emit('task:failed', failed);
114
+ this.cascadeFailure(taskId);
115
+ if (this.isComplete()) {
116
+ this.emitAllComplete();
117
+ }
118
+ return failed;
119
+ }
120
+ /**
121
+ * Recursively marks all tasks that (transitively) depend on `failedTaskId`
122
+ * as `'failed'` with an informative message, firing `'task:failed'` for each.
123
+ *
124
+ * Only tasks in `'blocked'` or `'pending'` state are affected; tasks already
125
+ * in a terminal state are left untouched.
126
+ */
127
+ cascadeFailure(failedTaskId) {
128
+ for (const task of this.tasks.values()) {
129
+ if (task.status !== 'blocked' && task.status !== 'pending')
130
+ continue;
131
+ if (!task.dependsOn?.includes(failedTaskId))
132
+ continue;
133
+ const cascaded = this.update(task.id, {
134
+ status: 'failed',
135
+ result: `Cancelled: dependency "${failedTaskId}" failed.`,
136
+ });
137
+ this.emit('task:failed', cascaded);
138
+ // Recurse to handle transitive dependents.
139
+ this.cascadeFailure(task.id);
140
+ }
141
+ }
142
+ // ---------------------------------------------------------------------------
143
+ // Queries
144
+ // ---------------------------------------------------------------------------
145
+ /**
146
+ * Returns the next `'pending'` task for `assignee` (matched against
147
+ * `task.assignee`), or `undefined` if none exists.
148
+ *
149
+ * If `assignee` is omitted, behaves like {@link nextAvailable}.
150
+ */
151
+ next(assignee) {
152
+ if (assignee === undefined)
153
+ return this.nextAvailable();
154
+ for (const task of this.tasks.values()) {
155
+ if (task.status === 'pending' && task.assignee === assignee) {
156
+ return task;
157
+ }
158
+ }
159
+ return undefined;
160
+ }
161
+ /**
162
+ * Returns the next `'pending'` task that has no `assignee` restriction, or
163
+ * the first `'pending'` task overall when all pending tasks have an assignee.
164
+ */
165
+ nextAvailable() {
166
+ let fallback;
167
+ for (const task of this.tasks.values()) {
168
+ if (task.status !== 'pending')
169
+ continue;
170
+ if (!task.assignee)
171
+ return task;
172
+ if (!fallback)
173
+ fallback = task;
174
+ }
175
+ return fallback;
176
+ }
177
+ /** Returns a snapshot array of all tasks (any status). */
178
+ list() {
179
+ return Array.from(this.tasks.values());
180
+ }
181
+ /** Returns all tasks whose `status` matches `status`. */
182
+ getByStatus(status) {
183
+ return this.list().filter((t) => t.status === status);
184
+ }
185
+ /**
186
+ * Returns `true` when every task in the queue has reached a terminal state
187
+ * (`'completed'` or `'failed'`), **or** the queue is empty.
188
+ */
189
+ isComplete() {
190
+ for (const task of this.tasks.values()) {
191
+ if (task.status !== 'completed' && task.status !== 'failed')
192
+ return false;
193
+ }
194
+ return true;
195
+ }
196
+ /**
197
+ * Returns a progress snapshot.
198
+ *
199
+ * @example
200
+ * ```ts
201
+ * const { completed, total } = queue.getProgress()
202
+ * console.log(`${completed}/${total} tasks done`)
203
+ * ```
204
+ */
205
+ getProgress() {
206
+ let completed = 0;
207
+ let failed = 0;
208
+ let inProgress = 0;
209
+ let pending = 0;
210
+ let blocked = 0;
211
+ for (const task of this.tasks.values()) {
212
+ switch (task.status) {
213
+ case 'completed':
214
+ completed++;
215
+ break;
216
+ case 'failed':
217
+ failed++;
218
+ break;
219
+ case 'in_progress':
220
+ inProgress++;
221
+ break;
222
+ case 'pending':
223
+ pending++;
224
+ break;
225
+ case 'blocked':
226
+ blocked++;
227
+ break;
228
+ }
229
+ }
230
+ return {
231
+ total: this.tasks.size,
232
+ completed,
233
+ failed,
234
+ inProgress,
235
+ pending,
236
+ blocked,
237
+ };
238
+ }
239
+ // ---------------------------------------------------------------------------
240
+ // Events
241
+ // ---------------------------------------------------------------------------
242
+ /**
243
+ * Subscribes to a queue event.
244
+ *
245
+ * @returns An unsubscribe function. Calling it is idempotent.
246
+ *
247
+ * @example
248
+ * ```ts
249
+ * const off = queue.on('task:ready', (task) => execute(task))
250
+ * // later…
251
+ * off()
252
+ * ```
253
+ */
254
+ on(event, handler) {
255
+ let map = this.listeners.get(event);
256
+ if (!map) {
257
+ map = new Map();
258
+ this.listeners.set(event, map);
259
+ }
260
+ const id = Symbol();
261
+ map.set(id, handler);
262
+ return () => {
263
+ map.delete(id);
264
+ };
265
+ }
266
+ // ---------------------------------------------------------------------------
267
+ // Private helpers
268
+ // ---------------------------------------------------------------------------
269
+ /**
270
+ * Evaluates whether `task` should start as `'blocked'` based on the tasks
271
+ * already registered in the queue.
272
+ */
273
+ resolveInitialStatus(task) {
274
+ if (!task.dependsOn || task.dependsOn.length === 0)
275
+ return task;
276
+ const allCurrent = Array.from(this.tasks.values());
277
+ const ready = isTaskReady(task, allCurrent);
278
+ if (ready)
279
+ return task;
280
+ return { ...task, status: 'blocked', updatedAt: new Date() };
281
+ }
282
+ /**
283
+ * After a task completes, scan all `'blocked'` tasks and promote any that are
284
+ * now fully satisfied to `'pending'`, firing `'task:ready'` for each.
285
+ *
286
+ * The task array and lookup map are built once for the entire scan to keep
287
+ * the operation O(n) rather than O(n²).
288
+ */
289
+ unblockDependents(completedId) {
290
+ const allTasks = Array.from(this.tasks.values());
291
+ const taskById = new Map(allTasks.map((t) => [t.id, t]));
292
+ for (const task of allTasks) {
293
+ if (task.status !== 'blocked')
294
+ continue;
295
+ if (!task.dependsOn?.includes(completedId))
296
+ continue;
297
+ // Re-check against the current state of the whole task set.
298
+ // Pass the pre-built map to avoid rebuilding it for every candidate task.
299
+ if (isTaskReady(task, allTasks, taskById)) {
300
+ const unblocked = {
301
+ ...task,
302
+ status: 'pending',
303
+ updatedAt: new Date(),
304
+ };
305
+ this.tasks.set(task.id, unblocked);
306
+ // Update the map so subsequent iterations in the same call see the new status.
307
+ taskById.set(task.id, unblocked);
308
+ this.emit('task:ready', unblocked);
309
+ }
310
+ }
311
+ }
312
+ emit(event, task) {
313
+ const map = this.listeners.get(event);
314
+ if (!map)
315
+ return;
316
+ for (const handler of map.values()) {
317
+ ;
318
+ handler(task);
319
+ }
320
+ }
321
+ emitAllComplete() {
322
+ const map = this.listeners.get('all:complete');
323
+ if (!map)
324
+ return;
325
+ for (const handler of map.values()) {
326
+ ;
327
+ handler();
328
+ }
329
+ }
330
+ requireTask(taskId) {
331
+ const task = this.tasks.get(taskId);
332
+ if (!task)
333
+ throw new Error(`TaskQueue: task "${taskId}" not found.`);
334
+ return task;
335
+ }
336
+ }
337
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/task/queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @fileoverview Pure task utility functions.
3
+ *
4
+ * These helpers operate on plain {@link Task} values without any mutable
5
+ * state, making them safe to use in reducers, tests, and reactive pipelines.
6
+ * Stateful orchestration belongs in {@link TaskQueue}.
7
+ */
8
+ import type { Task } from '../types.js';
9
+ /**
10
+ * Creates a new {@link Task} with a generated UUID, `'pending'` status, and
11
+ * `createdAt`/`updatedAt` timestamps set to the current instant.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const task = createTask({
16
+ * title: 'Research competitors',
17
+ * description: 'Identify the top 5 competitors and their pricing',
18
+ * assignee: 'researcher',
19
+ * })
20
+ * ```
21
+ */
22
+ export declare function createTask(input: {
23
+ title: string;
24
+ description: string;
25
+ assignee?: string;
26
+ dependsOn?: string[];
27
+ }): Task;
28
+ /**
29
+ * Returns `true` when `task` can be started immediately.
30
+ *
31
+ * A task is considered ready when:
32
+ * 1. Its status is `'pending'`.
33
+ * 2. Every task listed in `task.dependsOn` has status `'completed'`.
34
+ *
35
+ * Tasks whose dependencies are missing from `allTasks` are treated as
36
+ * unresolvable and therefore **not** ready.
37
+ *
38
+ * @param task - The task to evaluate.
39
+ * @param allTasks - The full collection of tasks in the current queue/plan.
40
+ * @param taskById - Optional pre-built id→task map. When provided the function
41
+ * skips rebuilding the map, reducing the complexity of
42
+ * call-sites that invoke `isTaskReady` inside a loop from
43
+ * O(n²) to O(n).
44
+ */
45
+ export declare function isTaskReady(task: Task, allTasks: Task[], taskById?: Map<string, Task>): boolean;
46
+ /**
47
+ * Returns `tasks` sorted so that each task appears after all of its
48
+ * dependencies — a standard topological (Kahn's algorithm) ordering.
49
+ *
50
+ * Tasks with no dependencies come first. If the graph contains a cycle the
51
+ * function returns a partial result containing only the tasks that could be
52
+ * ordered; use {@link validateTaskDependencies} to detect cycles before calling
53
+ * this function in production paths.
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * const ordered = getTaskDependencyOrder(tasks)
58
+ * for (const task of ordered) {
59
+ * await run(task)
60
+ * }
61
+ * ```
62
+ */
63
+ export declare function getTaskDependencyOrder(tasks: Task[]): Task[];
64
+ /**
65
+ * Validates the dependency graph of a task collection.
66
+ *
67
+ * Checks for:
68
+ * - References to unknown task IDs in `dependsOn`.
69
+ * - Cycles (a task depending on itself, directly or transitively).
70
+ * - Self-dependencies (`task.dependsOn` includes its own `id`).
71
+ *
72
+ * @returns An object with `valid: true` when no issues were found, or
73
+ * `valid: false` with a non-empty `errors` array describing each
74
+ * problem.
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * const { valid, errors } = validateTaskDependencies(tasks)
79
+ * if (!valid) throw new Error(errors.join('\n'))
80
+ * ```
81
+ */
82
+ export declare function validateTaskDependencies(tasks: Task[]): {
83
+ valid: boolean;
84
+ errors: string[];
85
+ };
86
+ //# sourceMappingURL=task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../src/task/task.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,aAAa,CAAA;AAMnD;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB,GAAG,IAAI,CAaP;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,IAAI,EAAE,EAChB,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,GAC3B,OAAO,CAYT;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CA6C5D;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG;IACvD,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB,CAoDA"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * @fileoverview Pure task utility functions.
3
+ *
4
+ * These helpers operate on plain {@link Task} values without any mutable
5
+ * state, making them safe to use in reducers, tests, and reactive pipelines.
6
+ * Stateful orchestration belongs in {@link TaskQueue}.
7
+ */
8
+ // ---------------------------------------------------------------------------
9
+ // Factory
10
+ // ---------------------------------------------------------------------------
11
+ /**
12
+ * Creates a new {@link Task} with a generated UUID, `'pending'` status, and
13
+ * `createdAt`/`updatedAt` timestamps set to the current instant.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const task = createTask({
18
+ * title: 'Research competitors',
19
+ * description: 'Identify the top 5 competitors and their pricing',
20
+ * assignee: 'researcher',
21
+ * })
22
+ * ```
23
+ */
24
+ export function createTask(input) {
25
+ const now = new Date();
26
+ return {
27
+ id: crypto.randomUUID(),
28
+ title: input.title,
29
+ description: input.description,
30
+ status: 'pending',
31
+ assignee: input.assignee,
32
+ dependsOn: input.dependsOn ? [...input.dependsOn] : undefined,
33
+ result: undefined,
34
+ createdAt: now,
35
+ updatedAt: now,
36
+ };
37
+ }
38
+ // ---------------------------------------------------------------------------
39
+ // Readiness
40
+ // ---------------------------------------------------------------------------
41
+ /**
42
+ * Returns `true` when `task` can be started immediately.
43
+ *
44
+ * A task is considered ready when:
45
+ * 1. Its status is `'pending'`.
46
+ * 2. Every task listed in `task.dependsOn` has status `'completed'`.
47
+ *
48
+ * Tasks whose dependencies are missing from `allTasks` are treated as
49
+ * unresolvable and therefore **not** ready.
50
+ *
51
+ * @param task - The task to evaluate.
52
+ * @param allTasks - The full collection of tasks in the current queue/plan.
53
+ * @param taskById - Optional pre-built id→task map. When provided the function
54
+ * skips rebuilding the map, reducing the complexity of
55
+ * call-sites that invoke `isTaskReady` inside a loop from
56
+ * O(n²) to O(n).
57
+ */
58
+ export function isTaskReady(task, allTasks, taskById) {
59
+ if (task.status !== 'pending')
60
+ return false;
61
+ if (!task.dependsOn || task.dependsOn.length === 0)
62
+ return true;
63
+ const map = taskById ?? new Map(allTasks.map((t) => [t.id, t]));
64
+ for (const depId of task.dependsOn) {
65
+ const dep = map.get(depId);
66
+ if (!dep || dep.status !== 'completed')
67
+ return false;
68
+ }
69
+ return true;
70
+ }
71
+ // ---------------------------------------------------------------------------
72
+ // Topological sort
73
+ // ---------------------------------------------------------------------------
74
+ /**
75
+ * Returns `tasks` sorted so that each task appears after all of its
76
+ * dependencies — a standard topological (Kahn's algorithm) ordering.
77
+ *
78
+ * Tasks with no dependencies come first. If the graph contains a cycle the
79
+ * function returns a partial result containing only the tasks that could be
80
+ * ordered; use {@link validateTaskDependencies} to detect cycles before calling
81
+ * this function in production paths.
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * const ordered = getTaskDependencyOrder(tasks)
86
+ * for (const task of ordered) {
87
+ * await run(task)
88
+ * }
89
+ * ```
90
+ */
91
+ export function getTaskDependencyOrder(tasks) {
92
+ if (tasks.length === 0)
93
+ return [];
94
+ const taskById = new Map(tasks.map((t) => [t.id, t]));
95
+ // Build adjacency: dependsOn edges become "predecessors" for in-degree count.
96
+ const inDegree = new Map();
97
+ // successors[id] = list of task IDs that depend on `id`
98
+ const successors = new Map();
99
+ for (const task of tasks) {
100
+ if (!inDegree.has(task.id))
101
+ inDegree.set(task.id, 0);
102
+ if (!successors.has(task.id))
103
+ successors.set(task.id, []);
104
+ for (const depId of task.dependsOn ?? []) {
105
+ // Only count dependencies that exist in this task set.
106
+ if (taskById.has(depId)) {
107
+ inDegree.set(task.id, (inDegree.get(task.id) ?? 0) + 1);
108
+ const deps = successors.get(depId) ?? [];
109
+ deps.push(task.id);
110
+ successors.set(depId, deps);
111
+ }
112
+ }
113
+ }
114
+ // Kahn's algorithm: start with all nodes of in-degree 0.
115
+ const queue = [];
116
+ for (const [id, degree] of inDegree) {
117
+ if (degree === 0)
118
+ queue.push(id);
119
+ }
120
+ const ordered = [];
121
+ while (queue.length > 0) {
122
+ const id = queue.shift();
123
+ const task = taskById.get(id);
124
+ if (task)
125
+ ordered.push(task);
126
+ for (const successorId of successors.get(id) ?? []) {
127
+ const newDegree = (inDegree.get(successorId) ?? 0) - 1;
128
+ inDegree.set(successorId, newDegree);
129
+ if (newDegree === 0)
130
+ queue.push(successorId);
131
+ }
132
+ }
133
+ return ordered;
134
+ }
135
+ // ---------------------------------------------------------------------------
136
+ // Validation
137
+ // ---------------------------------------------------------------------------
138
+ /**
139
+ * Validates the dependency graph of a task collection.
140
+ *
141
+ * Checks for:
142
+ * - References to unknown task IDs in `dependsOn`.
143
+ * - Cycles (a task depending on itself, directly or transitively).
144
+ * - Self-dependencies (`task.dependsOn` includes its own `id`).
145
+ *
146
+ * @returns An object with `valid: true` when no issues were found, or
147
+ * `valid: false` with a non-empty `errors` array describing each
148
+ * problem.
149
+ *
150
+ * @example
151
+ * ```ts
152
+ * const { valid, errors } = validateTaskDependencies(tasks)
153
+ * if (!valid) throw new Error(errors.join('\n'))
154
+ * ```
155
+ */
156
+ export function validateTaskDependencies(tasks) {
157
+ const errors = [];
158
+ const taskById = new Map(tasks.map((t) => [t.id, t]));
159
+ // Pass 1: check for unknown references and self-dependencies.
160
+ for (const task of tasks) {
161
+ for (const depId of task.dependsOn ?? []) {
162
+ if (depId === task.id) {
163
+ errors.push(`Task "${task.title}" (${task.id}) depends on itself.`);
164
+ continue;
165
+ }
166
+ if (!taskById.has(depId)) {
167
+ errors.push(`Task "${task.title}" (${task.id}) references unknown dependency "${depId}".`);
168
+ }
169
+ }
170
+ }
171
+ // Pass 2: cycle detection via DFS colouring (white=0, grey=1, black=2).
172
+ const colour = new Map();
173
+ for (const task of tasks)
174
+ colour.set(task.id, 0);
175
+ const visit = (id, path) => {
176
+ if (colour.get(id) === 2)
177
+ return; // Already fully explored.
178
+ if (colour.get(id) === 1) {
179
+ // Found a back-edge — cycle.
180
+ const cycleStart = path.indexOf(id);
181
+ const cycle = path.slice(cycleStart).concat(id);
182
+ errors.push(`Cyclic dependency detected: ${cycle.join(' -> ')}`);
183
+ return;
184
+ }
185
+ colour.set(id, 1);
186
+ const task = taskById.get(id);
187
+ for (const depId of task?.dependsOn ?? []) {
188
+ if (taskById.has(depId)) {
189
+ visit(depId, [...path, id]);
190
+ }
191
+ }
192
+ colour.set(id, 2);
193
+ };
194
+ for (const task of tasks) {
195
+ if (colour.get(task.id) === 0) {
196
+ visit(task.id, []);
197
+ }
198
+ }
199
+ return { valid: errors.length === 0, errors };
200
+ }
201
+ //# sourceMappingURL=task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/task/task.ts"],"names":[],"mappings":"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"}