@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.
- package/LICENSE +21 -0
- package/README.md +280 -0
- package/dist/agent/agent.d.ts +121 -0
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/agent/agent.js +294 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/pool.d.ts +128 -0
- package/dist/agent/pool.d.ts.map +1 -0
- package/dist/agent/pool.js +236 -0
- package/dist/agent/pool.js.map +1 -0
- package/dist/agent/runner.d.ts +120 -0
- package/dist/agent/runner.d.ts.map +1 -0
- package/dist/agent/runner.js +274 -0
- package/dist/agent/runner.js.map +1 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +87 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/adapter.d.ts +38 -0
- package/dist/llm/adapter.d.ts.map +1 -0
- package/dist/llm/adapter.js +46 -0
- package/dist/llm/adapter.js.map +1 -0
- package/dist/llm/anthropic.d.ts +56 -0
- package/dist/llm/anthropic.d.ts.map +1 -0
- package/dist/llm/anthropic.js +307 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/openai.d.ts +62 -0
- package/dist/llm/openai.d.ts.map +1 -0
- package/dist/llm/openai.js +424 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/memory/shared.d.ts +86 -0
- package/dist/memory/shared.d.ts.map +1 -0
- package/dist/memory/shared.js +155 -0
- package/dist/memory/shared.js.map +1 -0
- package/dist/memory/store.d.ts +64 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +103 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/orchestrator/orchestrator.d.ts +173 -0
- package/dist/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator.js +698 -0
- package/dist/orchestrator/orchestrator.js.map +1 -0
- package/dist/orchestrator/scheduler.d.ts +112 -0
- package/dist/orchestrator/scheduler.d.ts.map +1 -0
- package/dist/orchestrator/scheduler.js +282 -0
- package/dist/orchestrator/scheduler.js.map +1 -0
- package/dist/task/queue.d.ts +160 -0
- package/dist/task/queue.d.ts.map +1 -0
- package/dist/task/queue.js +337 -0
- package/dist/task/queue.js.map +1 -0
- package/dist/task/task.d.ts +86 -0
- package/dist/task/task.d.ts.map +1 -0
- package/dist/task/task.js +201 -0
- package/dist/task/task.js.map +1 -0
- package/dist/team/messaging.d.ts +106 -0
- package/dist/team/messaging.d.ts.map +1 -0
- package/dist/team/messaging.js +182 -0
- package/dist/team/messaging.js.map +1 -0
- package/dist/team/team.d.ts +141 -0
- package/dist/team/team.d.ts.map +1 -0
- package/dist/team/team.js +282 -0
- package/dist/team/team.js.map +1 -0
- package/dist/tool/built-in/bash.d.ts +12 -0
- package/dist/tool/built-in/bash.d.ts.map +1 -0
- package/dist/tool/built-in/bash.js +133 -0
- package/dist/tool/built-in/bash.js.map +1 -0
- package/dist/tool/built-in/file-edit.d.ts +14 -0
- package/dist/tool/built-in/file-edit.d.ts.map +1 -0
- package/dist/tool/built-in/file-edit.js +130 -0
- package/dist/tool/built-in/file-edit.js.map +1 -0
- package/dist/tool/built-in/file-read.d.ts +12 -0
- package/dist/tool/built-in/file-read.d.ts.map +1 -0
- package/dist/tool/built-in/file-read.js +82 -0
- package/dist/tool/built-in/file-read.js.map +1 -0
- package/dist/tool/built-in/file-write.d.ts +11 -0
- package/dist/tool/built-in/file-write.d.ts.map +1 -0
- package/dist/tool/built-in/file-write.js +70 -0
- package/dist/tool/built-in/file-write.js.map +1 -0
- package/dist/tool/built-in/grep.d.ts +15 -0
- package/dist/tool/built-in/grep.d.ts.map +1 -0
- package/dist/tool/built-in/grep.js +287 -0
- package/dist/tool/built-in/grep.js.map +1 -0
- package/dist/tool/built-in/index.d.ts +36 -0
- package/dist/tool/built-in/index.d.ts.map +1 -0
- package/dist/tool/built-in/index.js +45 -0
- package/dist/tool/built-in/index.js.map +1 -0
- package/dist/tool/executor.d.ts +71 -0
- package/dist/tool/executor.d.ts.map +1 -0
- package/dist/tool/executor.js +116 -0
- package/dist/tool/executor.js.map +1 -0
- package/dist/tool/framework.d.ts +143 -0
- package/dist/tool/framework.d.ts.map +1 -0
- package/dist/tool/framework.js +371 -0
- package/dist/tool/framework.js.map +1 -0
- package/dist/types.d.ts +285 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/semaphore.d.ts +47 -0
- package/dist/utils/semaphore.d.ts.map +1 -0
- package/dist/utils/semaphore.js +85 -0
- package/dist/utils/semaphore.js.map +1 -0
- package/examples/01-single-agent.ts +131 -0
- package/examples/02-team-collaboration.ts +167 -0
- package/examples/03-task-pipeline.ts +201 -0
- package/examples/04-multi-model-team.ts +261 -0
- package/package.json +49 -0
- package/src/agent/agent.ts +364 -0
- package/src/agent/pool.ts +278 -0
- package/src/agent/runner.ts +413 -0
- package/src/index.ts +166 -0
- package/src/llm/adapter.ts +74 -0
- package/src/llm/anthropic.ts +388 -0
- package/src/llm/openai.ts +522 -0
- package/src/memory/shared.ts +181 -0
- package/src/memory/store.ts +124 -0
- package/src/orchestrator/orchestrator.ts +851 -0
- package/src/orchestrator/scheduler.ts +352 -0
- package/src/task/queue.ts +394 -0
- package/src/task/task.ts +232 -0
- package/src/team/messaging.ts +230 -0
- package/src/team/team.ts +334 -0
- package/src/tool/built-in/bash.ts +187 -0
- package/src/tool/built-in/file-edit.ts +154 -0
- package/src/tool/built-in/file-read.ts +105 -0
- package/src/tool/built-in/file-write.ts +81 -0
- package/src/tool/built-in/grep.ts +362 -0
- package/src/tool/built-in/index.ts +50 -0
- package/src/tool/executor.ts +178 -0
- package/src/tool/framework.ts +557 -0
- package/src/types.ts +362 -0
- package/src/utils/semaphore.ts +89 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared memory layer for teams of cooperating agents.
|
|
3
|
+
*
|
|
4
|
+
* Each agent writes under its own namespace (`<agentName>/<key>`) so entries
|
|
5
|
+
* remain attributable, while any agent may read any entry. The
|
|
6
|
+
* {@link SharedMemory.getSummary} method produces a human-readable digest
|
|
7
|
+
* suitable for injecting into an agent's context window.
|
|
8
|
+
*/
|
|
9
|
+
import { InMemoryStore } from './store.js';
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// SharedMemory
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
/**
|
|
14
|
+
* Namespaced shared memory for a team of agents.
|
|
15
|
+
*
|
|
16
|
+
* Writes are namespaced as `<agentName>/<key>` so that entries from different
|
|
17
|
+
* agents never collide and are always attributable. Reads are namespace-aware
|
|
18
|
+
* but also accept fully-qualified keys, making cross-agent reads straightforward.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const mem = new SharedMemory()
|
|
23
|
+
*
|
|
24
|
+
* await mem.write('researcher', 'findings', 'TypeScript 5.5 ships const type params')
|
|
25
|
+
* await mem.write('coder', 'plan', 'Implement feature X using const type params')
|
|
26
|
+
*
|
|
27
|
+
* const entry = await mem.read('researcher/findings')
|
|
28
|
+
* const all = await mem.listByAgent('researcher')
|
|
29
|
+
* const summary = await mem.getSummary()
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export class SharedMemory {
|
|
33
|
+
store;
|
|
34
|
+
constructor() {
|
|
35
|
+
this.store = new InMemoryStore();
|
|
36
|
+
}
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Write
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
/**
|
|
41
|
+
* Write `value` under the namespaced key `<agentName>/<key>`.
|
|
42
|
+
*
|
|
43
|
+
* Metadata is merged with a `{ agent: agentName }` marker so consumers can
|
|
44
|
+
* identify provenance when iterating all entries.
|
|
45
|
+
*
|
|
46
|
+
* @param agentName - The writing agent's name (used as a namespace prefix).
|
|
47
|
+
* @param key - Logical key within the agent's namespace.
|
|
48
|
+
* @param value - String value to store (serialise objects before writing).
|
|
49
|
+
* @param metadata - Optional extra metadata stored alongside the entry.
|
|
50
|
+
*/
|
|
51
|
+
async write(agentName, key, value, metadata) {
|
|
52
|
+
const namespacedKey = SharedMemory.namespaceKey(agentName, key);
|
|
53
|
+
await this.store.set(namespacedKey, value, {
|
|
54
|
+
...metadata,
|
|
55
|
+
agent: agentName,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Read
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
/**
|
|
62
|
+
* Read an entry by its fully-qualified key (`<agentName>/<key>`).
|
|
63
|
+
*
|
|
64
|
+
* Returns `null` when the key is absent.
|
|
65
|
+
*/
|
|
66
|
+
async read(key) {
|
|
67
|
+
return this.store.get(key);
|
|
68
|
+
}
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// List
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
/** Returns every entry in the shared store, regardless of agent. */
|
|
73
|
+
async listAll() {
|
|
74
|
+
return this.store.list();
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Returns all entries written by `agentName` (i.e. those whose key starts
|
|
78
|
+
* with `<agentName>/`).
|
|
79
|
+
*/
|
|
80
|
+
async listByAgent(agentName) {
|
|
81
|
+
const prefix = SharedMemory.namespaceKey(agentName, '');
|
|
82
|
+
const all = await this.store.list();
|
|
83
|
+
return all.filter((entry) => entry.key.startsWith(prefix));
|
|
84
|
+
}
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// Summary
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
/**
|
|
89
|
+
* Produces a human-readable summary of all entries in the store.
|
|
90
|
+
*
|
|
91
|
+
* The output is structured as a markdown-style block, grouped by agent, and
|
|
92
|
+
* is designed to be prepended to an agent's system prompt or injected as a
|
|
93
|
+
* user turn so the agent has context about what its teammates know.
|
|
94
|
+
*
|
|
95
|
+
* Returns an empty string when the store is empty.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```
|
|
99
|
+
* ## Shared Team Memory
|
|
100
|
+
*
|
|
101
|
+
* ### researcher
|
|
102
|
+
* - findings: TypeScript 5.5 ships const type params
|
|
103
|
+
*
|
|
104
|
+
* ### coder
|
|
105
|
+
* - plan: Implement feature X using const type params
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
async getSummary() {
|
|
109
|
+
const all = await this.store.list();
|
|
110
|
+
if (all.length === 0)
|
|
111
|
+
return '';
|
|
112
|
+
// Group entries by agent name.
|
|
113
|
+
const byAgent = new Map();
|
|
114
|
+
for (const entry of all) {
|
|
115
|
+
const slashIdx = entry.key.indexOf('/');
|
|
116
|
+
const agent = slashIdx === -1 ? '_unknown' : entry.key.slice(0, slashIdx);
|
|
117
|
+
const localKey = slashIdx === -1 ? entry.key : entry.key.slice(slashIdx + 1);
|
|
118
|
+
let group = byAgent.get(agent);
|
|
119
|
+
if (!group) {
|
|
120
|
+
group = [];
|
|
121
|
+
byAgent.set(agent, group);
|
|
122
|
+
}
|
|
123
|
+
group.push({ localKey, value: entry.value });
|
|
124
|
+
}
|
|
125
|
+
const lines = ['## Shared Team Memory', ''];
|
|
126
|
+
for (const [agent, entries] of byAgent) {
|
|
127
|
+
lines.push(`### ${agent}`);
|
|
128
|
+
for (const { localKey, value } of entries) {
|
|
129
|
+
// Truncate long values so the summary stays readable in a context window.
|
|
130
|
+
const displayValue = value.length > 200 ? `${value.slice(0, 197)}…` : value;
|
|
131
|
+
lines.push(`- ${localKey}: ${displayValue}`);
|
|
132
|
+
}
|
|
133
|
+
lines.push('');
|
|
134
|
+
}
|
|
135
|
+
return lines.join('\n').trimEnd();
|
|
136
|
+
}
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
// Store access
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
/**
|
|
141
|
+
* Returns the underlying {@link MemoryStore} so callers that only need the
|
|
142
|
+
* raw key-value interface can receive a properly typed reference without
|
|
143
|
+
* accessing private fields via bracket notation.
|
|
144
|
+
*/
|
|
145
|
+
getStore() {
|
|
146
|
+
return this.store;
|
|
147
|
+
}
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
// Private helpers
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
static namespaceKey(agentName, key) {
|
|
152
|
+
return `${agentName}/${key}`;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/memory/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview In-memory implementation of {@link MemoryStore}.
|
|
3
|
+
*
|
|
4
|
+
* All data lives in a plain `Map` and is never persisted to disk. This is the
|
|
5
|
+
* default store used by {@link SharedMemory} and is suitable for testing and
|
|
6
|
+
* single-process use-cases. Swap it for a Redis or SQLite-backed implementation
|
|
7
|
+
* in production by satisfying the same {@link MemoryStore} interface.
|
|
8
|
+
*/
|
|
9
|
+
import type { MemoryEntry, MemoryStore } from '../types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Synchronous-under-the-hood key/value store that exposes an `async` surface
|
|
12
|
+
* so implementations can be swapped for async-native backends without changing
|
|
13
|
+
* callers.
|
|
14
|
+
*
|
|
15
|
+
* All keys are treated as opaque strings. Values are always strings; structured
|
|
16
|
+
* data must be serialised by the caller (e.g. `JSON.stringify`).
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const store = new InMemoryStore()
|
|
21
|
+
* await store.set('config', JSON.stringify({ model: 'claude-opus-4-6' }))
|
|
22
|
+
* const entry = await store.get('config')
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare class InMemoryStore implements MemoryStore {
|
|
26
|
+
private readonly data;
|
|
27
|
+
/** Returns the entry for `key`, or `null` if not present. */
|
|
28
|
+
get(key: string): Promise<MemoryEntry | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Upserts `key` with `value` and optional `metadata`.
|
|
31
|
+
*
|
|
32
|
+
* If the key already exists its `createdAt` is **preserved** so callers can
|
|
33
|
+
* detect when a value was first written.
|
|
34
|
+
*/
|
|
35
|
+
set(key: string, value: string, metadata?: Record<string, unknown>): Promise<void>;
|
|
36
|
+
/** Returns a snapshot of all entries in insertion order. */
|
|
37
|
+
list(): Promise<MemoryEntry[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Removes the entry for `key`.
|
|
40
|
+
* Deleting a non-existent key is a no-op.
|
|
41
|
+
*/
|
|
42
|
+
delete(key: string): Promise<void>;
|
|
43
|
+
/** Removes **all** entries from the store. */
|
|
44
|
+
clear(): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Returns entries whose `key` starts with `query` **or** whose `value`
|
|
47
|
+
* contains `query` (case-insensitive substring match).
|
|
48
|
+
*
|
|
49
|
+
* This is a simple linear scan; it is not suitable for very large stores
|
|
50
|
+
* without an index layer on top.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* // Find all entries related to "research"
|
|
55
|
+
* const hits = await store.search('research')
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
search(query: string): Promise<MemoryEntry[]>;
|
|
59
|
+
/** Returns the number of entries currently held in the store. */
|
|
60
|
+
get size(): number;
|
|
61
|
+
/** Returns `true` if `key` exists in the store. */
|
|
62
|
+
has(key: string): boolean;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/memory/store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAM3D;;;;;;;;;;;;;;GAcG;AACH,qBAAa,aAAc,YAAW,WAAW;IAC/C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiC;IAMtD,6DAA6D;IACvD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAInD;;;;;OAKG;IACG,GAAG,CACP,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAWhB,4DAA4D;IACtD,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAIpC;;;OAGG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,8CAA8C;IACxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B;;;;;;;;;;;;OAYG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAgBnD,iEAAiE;IACjE,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,mDAAmD;IACnD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;CAG1B"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview In-memory implementation of {@link MemoryStore}.
|
|
3
|
+
*
|
|
4
|
+
* All data lives in a plain `Map` and is never persisted to disk. This is the
|
|
5
|
+
* default store used by {@link SharedMemory} and is suitable for testing and
|
|
6
|
+
* single-process use-cases. Swap it for a Redis or SQLite-backed implementation
|
|
7
|
+
* in production by satisfying the same {@link MemoryStore} interface.
|
|
8
|
+
*/
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// InMemoryStore
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* Synchronous-under-the-hood key/value store that exposes an `async` surface
|
|
14
|
+
* so implementations can be swapped for async-native backends without changing
|
|
15
|
+
* callers.
|
|
16
|
+
*
|
|
17
|
+
* All keys are treated as opaque strings. Values are always strings; structured
|
|
18
|
+
* data must be serialised by the caller (e.g. `JSON.stringify`).
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const store = new InMemoryStore()
|
|
23
|
+
* await store.set('config', JSON.stringify({ model: 'claude-opus-4-6' }))
|
|
24
|
+
* const entry = await store.get('config')
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export class InMemoryStore {
|
|
28
|
+
data = new Map();
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// MemoryStore interface
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
/** Returns the entry for `key`, or `null` if not present. */
|
|
33
|
+
async get(key) {
|
|
34
|
+
return this.data.get(key) ?? null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Upserts `key` with `value` and optional `metadata`.
|
|
38
|
+
*
|
|
39
|
+
* If the key already exists its `createdAt` is **preserved** so callers can
|
|
40
|
+
* detect when a value was first written.
|
|
41
|
+
*/
|
|
42
|
+
async set(key, value, metadata) {
|
|
43
|
+
const existing = this.data.get(key);
|
|
44
|
+
const entry = {
|
|
45
|
+
key,
|
|
46
|
+
value,
|
|
47
|
+
metadata: metadata !== undefined ? { ...metadata } : undefined,
|
|
48
|
+
createdAt: existing?.createdAt ?? new Date(),
|
|
49
|
+
};
|
|
50
|
+
this.data.set(key, entry);
|
|
51
|
+
}
|
|
52
|
+
/** Returns a snapshot of all entries in insertion order. */
|
|
53
|
+
async list() {
|
|
54
|
+
return Array.from(this.data.values());
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Removes the entry for `key`.
|
|
58
|
+
* Deleting a non-existent key is a no-op.
|
|
59
|
+
*/
|
|
60
|
+
async delete(key) {
|
|
61
|
+
this.data.delete(key);
|
|
62
|
+
}
|
|
63
|
+
/** Removes **all** entries from the store. */
|
|
64
|
+
async clear() {
|
|
65
|
+
this.data.clear();
|
|
66
|
+
}
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// Extensions beyond the base MemoryStore interface
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
/**
|
|
71
|
+
* Returns entries whose `key` starts with `query` **or** whose `value`
|
|
72
|
+
* contains `query` (case-insensitive substring match).
|
|
73
|
+
*
|
|
74
|
+
* This is a simple linear scan; it is not suitable for very large stores
|
|
75
|
+
* without an index layer on top.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* // Find all entries related to "research"
|
|
80
|
+
* const hits = await store.search('research')
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
async search(query) {
|
|
84
|
+
if (query.length === 0) {
|
|
85
|
+
return this.list();
|
|
86
|
+
}
|
|
87
|
+
const lower = query.toLowerCase();
|
|
88
|
+
return Array.from(this.data.values()).filter((entry) => entry.key.toLowerCase().includes(lower) ||
|
|
89
|
+
entry.value.toLowerCase().includes(lower));
|
|
90
|
+
}
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Convenience helpers (not part of MemoryStore)
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
/** Returns the number of entries currently held in the store. */
|
|
95
|
+
get size() {
|
|
96
|
+
return this.data.size;
|
|
97
|
+
}
|
|
98
|
+
/** Returns `true` if `key` exists in the store. */
|
|
99
|
+
has(key) {
|
|
100
|
+
return this.data.has(key);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/memory/store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,aAAa;IACP,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAA;IAEtD,8EAA8E;IAC9E,wBAAwB;IACxB,8EAA8E;IAE9E,6DAA6D;IAC7D,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAA;IACnC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,GAAG,CACP,GAAW,EACX,KAAa,EACb,QAAkC;QAElC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACnC,MAAM,KAAK,GAAgB;YACzB,GAAG;YACH,KAAK;YACL,QAAQ,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS;YAC9D,SAAS,EAAE,QAAQ,EAAE,SAAS,IAAI,IAAI,IAAI,EAAE;SAC7C,CAAA;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAC3B,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,IAAI;QACR,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IACvC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACvB,CAAC;IAED,8CAA8C;IAC9C,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAA;IACnB,CAAC;IAED,8EAA8E;IAC9E,mDAAmD;IACnD,8EAA8E;IAE9E;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,MAAM,CAAC,KAAa;QACxB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,IAAI,EAAE,CAAA;QACpB,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA;QACjC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAC1C,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;YACvC,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAC5C,CAAA;IACH,CAAC;IAED,8EAA8E;IAC9E,gDAAgD;IAChD,8EAA8E;IAE9E,iEAAiE;IACjE,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAA;IACvB,CAAC;IAED,mDAAmD;IACnD,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview OpenMultiAgent — the top-level multi-agent orchestration class.
|
|
3
|
+
*
|
|
4
|
+
* {@link OpenMultiAgent} is the primary public API of the open-multi-agent framework.
|
|
5
|
+
* It ties together every subsystem:
|
|
6
|
+
*
|
|
7
|
+
* - {@link Team} — Agent roster, shared memory, inter-agent messaging
|
|
8
|
+
* - {@link TaskQueue} — Dependency-aware work queue
|
|
9
|
+
* - {@link Scheduler} — Task-to-agent assignment strategies
|
|
10
|
+
* - {@link AgentPool} — Concurrency-controlled execution pool
|
|
11
|
+
* - {@link Agent} — Conversation + tool-execution loop
|
|
12
|
+
*
|
|
13
|
+
* ## Quick start
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* const orchestrator = new OpenMultiAgent({ defaultModel: 'claude-opus-4-6' })
|
|
17
|
+
*
|
|
18
|
+
* const team = orchestrator.createTeam('research', {
|
|
19
|
+
* name: 'research',
|
|
20
|
+
* agents: [
|
|
21
|
+
* { name: 'researcher', model: 'claude-opus-4-6', systemPrompt: 'You are a researcher.' },
|
|
22
|
+
* { name: 'writer', model: 'claude-opus-4-6', systemPrompt: 'You are a technical writer.' },
|
|
23
|
+
* ],
|
|
24
|
+
* sharedMemory: true,
|
|
25
|
+
* })
|
|
26
|
+
*
|
|
27
|
+
* const result = await orchestrator.runTeam(team, 'Produce a report on TypeScript 5.5.')
|
|
28
|
+
* console.log(result.agentResults.get('coordinator')?.output)
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* ## Key design decisions
|
|
32
|
+
*
|
|
33
|
+
* - **Coordinator pattern** — `runTeam()` spins up a temporary "coordinator" agent
|
|
34
|
+
* that breaks the high-level goal into tasks, assigns them, and synthesises the
|
|
35
|
+
* final answer. This is the framework's killer feature.
|
|
36
|
+
* - **Parallel-by-default** — Independent tasks (no shared dependency) run in
|
|
37
|
+
* parallel up to `maxConcurrency`.
|
|
38
|
+
* - **Graceful failure** — A failed task marks itself `'failed'` and its direct
|
|
39
|
+
* dependents remain `'blocked'` indefinitely; all non-dependent tasks continue.
|
|
40
|
+
* - **Progress callbacks** — Callers can pass `onProgress` in the config to receive
|
|
41
|
+
* structured {@link OrchestratorEvent}s without polling.
|
|
42
|
+
*/
|
|
43
|
+
import type { AgentConfig, AgentRunResult, OrchestratorConfig, TeamConfig, TeamRunResult } from '../types.js';
|
|
44
|
+
import { Team } from '../team/team.js';
|
|
45
|
+
/**
|
|
46
|
+
* Top-level orchestrator for the open-multi-agent framework.
|
|
47
|
+
*
|
|
48
|
+
* Manages teams, coordinates task execution, and surfaces progress events.
|
|
49
|
+
* Most users will interact with this class exclusively.
|
|
50
|
+
*/
|
|
51
|
+
export declare class OpenMultiAgent {
|
|
52
|
+
private readonly config;
|
|
53
|
+
private readonly teams;
|
|
54
|
+
private completedTaskCount;
|
|
55
|
+
/**
|
|
56
|
+
* @param config - Optional top-level configuration.
|
|
57
|
+
*
|
|
58
|
+
* Sensible defaults:
|
|
59
|
+
* - `maxConcurrency`: 5
|
|
60
|
+
* - `defaultModel`: `'claude-opus-4-6'`
|
|
61
|
+
* - `defaultProvider`: `'anthropic'`
|
|
62
|
+
*/
|
|
63
|
+
constructor(config?: OrchestratorConfig);
|
|
64
|
+
/**
|
|
65
|
+
* Create and register a {@link Team} with the orchestrator.
|
|
66
|
+
*
|
|
67
|
+
* The team is stored internally so {@link getStatus} can report aggregate
|
|
68
|
+
* agent counts. Returns the new {@link Team} for further configuration.
|
|
69
|
+
*
|
|
70
|
+
* @param name - Unique team identifier. Throws if already registered.
|
|
71
|
+
* @param config - Team configuration (agents, shared memory, concurrency).
|
|
72
|
+
*/
|
|
73
|
+
createTeam(name: string, config: TeamConfig): Team;
|
|
74
|
+
/**
|
|
75
|
+
* Run a single prompt with a one-off agent.
|
|
76
|
+
*
|
|
77
|
+
* Constructs a fresh agent from `config`, runs `prompt` in a single turn,
|
|
78
|
+
* and returns the result. The agent is not registered with any pool or team.
|
|
79
|
+
*
|
|
80
|
+
* Useful for simple one-shot queries that do not need team orchestration.
|
|
81
|
+
*
|
|
82
|
+
* @param config - Agent configuration.
|
|
83
|
+
* @param prompt - The user prompt to send.
|
|
84
|
+
*/
|
|
85
|
+
runAgent(config: AgentConfig, prompt: string): Promise<AgentRunResult>;
|
|
86
|
+
/**
|
|
87
|
+
* Run a team on a high-level goal with full automatic orchestration.
|
|
88
|
+
*
|
|
89
|
+
* This is the flagship method of the framework. It works as follows:
|
|
90
|
+
*
|
|
91
|
+
* 1. A temporary "coordinator" agent receives the goal and the team's agent
|
|
92
|
+
* roster, and is asked to decompose it into an ordered list of tasks with
|
|
93
|
+
* JSON output.
|
|
94
|
+
* 2. The tasks are loaded into a {@link TaskQueue}. Title-based dependency
|
|
95
|
+
* tokens in the coordinator's output are resolved to task IDs.
|
|
96
|
+
* 3. The {@link Scheduler} assigns unassigned tasks to team agents.
|
|
97
|
+
* 4. Tasks are executed in dependency order, with independent tasks running
|
|
98
|
+
* in parallel up to `maxConcurrency`.
|
|
99
|
+
* 5. Results are persisted to shared memory after each task so subsequent
|
|
100
|
+
* agents can read them.
|
|
101
|
+
* 6. The coordinator synthesises a final answer from all task outputs.
|
|
102
|
+
* 7. A {@link TeamRunResult} is returned.
|
|
103
|
+
*
|
|
104
|
+
* @param team - A team created via {@link createTeam} (or `new Team(...)`).
|
|
105
|
+
* @param goal - High-level natural-language goal for the team.
|
|
106
|
+
*/
|
|
107
|
+
runTeam(team: Team, goal: string): Promise<TeamRunResult>;
|
|
108
|
+
/**
|
|
109
|
+
* Run a team with an explicitly provided task list.
|
|
110
|
+
*
|
|
111
|
+
* Simpler than {@link runTeam}: no coordinator agent is involved. Tasks are
|
|
112
|
+
* loaded directly into the queue, unassigned tasks are auto-assigned via the
|
|
113
|
+
* {@link Scheduler}, and execution proceeds in dependency order.
|
|
114
|
+
*
|
|
115
|
+
* @param team - A team created via {@link createTeam}.
|
|
116
|
+
* @param tasks - Array of task descriptors.
|
|
117
|
+
*/
|
|
118
|
+
runTasks(team: Team, tasks: ReadonlyArray<{
|
|
119
|
+
title: string;
|
|
120
|
+
description: string;
|
|
121
|
+
assignee?: string;
|
|
122
|
+
dependsOn?: string[];
|
|
123
|
+
}>): Promise<TeamRunResult>;
|
|
124
|
+
/**
|
|
125
|
+
* Returns a lightweight status snapshot.
|
|
126
|
+
*
|
|
127
|
+
* - `teams` — Number of teams registered with this orchestrator.
|
|
128
|
+
* - `activeAgents` — Total agents currently in `running` state.
|
|
129
|
+
* - `completedTasks` — Cumulative count of successfully completed tasks
|
|
130
|
+
* (coordinator meta-steps excluded).
|
|
131
|
+
*/
|
|
132
|
+
getStatus(): {
|
|
133
|
+
teams: number;
|
|
134
|
+
activeAgents: number;
|
|
135
|
+
completedTasks: number;
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Deregister all teams and reset internal counters.
|
|
139
|
+
*
|
|
140
|
+
* Does not cancel in-flight runs. Call this when you want to reuse the
|
|
141
|
+
* orchestrator instance for a fresh set of teams.
|
|
142
|
+
*
|
|
143
|
+
* Async for forward compatibility — shutdown may need to perform async
|
|
144
|
+
* cleanup (e.g. graceful agent drain) in future versions.
|
|
145
|
+
*/
|
|
146
|
+
shutdown(): Promise<void>;
|
|
147
|
+
/** Build the system prompt given to the coordinator agent. */
|
|
148
|
+
private buildCoordinatorSystemPrompt;
|
|
149
|
+
/** Build the decomposition prompt for the coordinator. */
|
|
150
|
+
private buildDecompositionPrompt;
|
|
151
|
+
/** Build the synthesis prompt shown to the coordinator after all tasks complete. */
|
|
152
|
+
private buildSynthesisPrompt;
|
|
153
|
+
/**
|
|
154
|
+
* Load a list of task specs into a queue.
|
|
155
|
+
*
|
|
156
|
+
* Handles title-based `dependsOn` references by building a title→id map first,
|
|
157
|
+
* then resolving them to real IDs before adding tasks to the queue.
|
|
158
|
+
*/
|
|
159
|
+
private loadSpecsIntoQueue;
|
|
160
|
+
/** Build an {@link AgentPool} from a list of agent configurations. */
|
|
161
|
+
private buildPool;
|
|
162
|
+
/**
|
|
163
|
+
* Aggregate the per-run `agentResults` map into a {@link TeamRunResult}.
|
|
164
|
+
*
|
|
165
|
+
* Merges results keyed as `agentName:taskId` back into a per-agent map
|
|
166
|
+
* by agent name for the public result surface.
|
|
167
|
+
*
|
|
168
|
+
* Only non-coordinator entries are counted toward `completedTaskCount` to
|
|
169
|
+
* avoid double-counting the coordinator's internal decompose/synthesis steps.
|
|
170
|
+
*/
|
|
171
|
+
private buildTeamRunResult;
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/orchestrator/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,kBAAkB,EAIlB,UAAU,EACV,aAAa,EAEd,MAAM,aAAa,CAAA;AAMpB,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAoRtC;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAEmB;IAE1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA+B;IACrD,OAAO,CAAC,kBAAkB,CAAI;IAE9B;;;;;;;OAOG;gBACS,MAAM,GAAE,kBAAuB;IAa3C;;;;;;;;OAQG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAgBlD;;;;;;;;;;OAUG;IACG,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IA2B5E;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA+F/D;;;;;;;;;OASG;IACG,QAAQ,CACZ,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,aAAa,CAAC;QACnB,KAAK,EAAE,MAAM,CAAA;QACb,WAAW,EAAE,MAAM,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;KACrB,CAAC,GACD,OAAO,CAAC,aAAa,CAAC;IAqCzB;;;;;;;OAOG;IACH,SAAS,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE;IAY5E;;;;;;;;OAQG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAS/B,8DAA8D;IAC9D,OAAO,CAAC,4BAA4B;IAgCpC,0DAA0D;IAC1D,OAAO,CAAC,wBAAwB;IAYhC,oFAAoF;YACtE,oBAAoB;IAuClC;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAoD1B,sEAAsE;IACtE,OAAO,CAAC,SAAS;IAajB;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;CAyC3B"}
|