@avee1234/agent-kit 0.1.0 → 0.2.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 +73 -9
- package/dist/index.cjs +273 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -10
- package/dist/index.d.ts +42 -10
- package/dist/index.js +272 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
TypeScript-first library for building stateful, persistent AI agents.
|
|
4
4
|
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="assets/demo.svg" alt="agent-kit demo — memory persists across sessions" width="750" />
|
|
7
|
+
</p>
|
|
8
|
+
|
|
5
9
|
## Why agent-kit?
|
|
6
10
|
|
|
7
11
|
- **Persistent memory across sessions** — SQLite store keeps conversation history and auto-summarizes old exchanges. Restart your process; the agent still remembers.
|
|
@@ -12,13 +16,13 @@ TypeScript-first library for building stateful, persistent AI agents.
|
|
|
12
16
|
## Installation
|
|
13
17
|
|
|
14
18
|
```bash
|
|
15
|
-
npm install agent-kit
|
|
19
|
+
npm install @avee1234/agent-kit
|
|
16
20
|
```
|
|
17
21
|
|
|
18
22
|
## Quick Start
|
|
19
23
|
|
|
20
24
|
```typescript
|
|
21
|
-
import { Agent, Tool, Memory } from 'agent-kit';
|
|
25
|
+
import { Agent, Tool, Memory } from '@avee1234/agent-kit';
|
|
22
26
|
|
|
23
27
|
const echo = Tool.create({
|
|
24
28
|
name: 'echo',
|
|
@@ -67,7 +71,7 @@ Kill the process and restart — memory persists in `research.db`.
|
|
|
67
71
|
The main class. Runs a tool-calling loop, manages memory context, and emits observability events.
|
|
68
72
|
|
|
69
73
|
```typescript
|
|
70
|
-
import { Agent } from 'agent-kit';
|
|
74
|
+
import { Agent } from '@avee1234/agent-kit';
|
|
71
75
|
|
|
72
76
|
const agent = new Agent({
|
|
73
77
|
name: 'assistant',
|
|
@@ -99,7 +103,7 @@ const agent = new Agent({
|
|
|
99
103
|
Wraps a function so the agent can call it.
|
|
100
104
|
|
|
101
105
|
```typescript
|
|
102
|
-
import { Tool } from 'agent-kit';
|
|
106
|
+
import { Tool } from '@avee1234/agent-kit';
|
|
103
107
|
|
|
104
108
|
const getWeather = Tool.create({
|
|
105
109
|
name: 'get_weather',
|
|
@@ -130,7 +134,7 @@ const getWeather = Tool.create({
|
|
|
130
134
|
Manages conversation persistence and context retrieval.
|
|
131
135
|
|
|
132
136
|
```typescript
|
|
133
|
-
import { Memory } from 'agent-kit';
|
|
137
|
+
import { Memory } from '@avee1234/agent-kit';
|
|
134
138
|
|
|
135
139
|
// In-memory (default, testing)
|
|
136
140
|
new Memory()
|
|
@@ -153,6 +157,66 @@ new Memory({ store: myCustomStore })
|
|
|
153
157
|
|
|
154
158
|
Auto-summarization: when `summarizeAfter` messages accumulate, the agent summarizes them and stores the summary. Older context is retrieved via `searchSummaries`.
|
|
155
159
|
|
|
160
|
+
### Team (Multi-Agent Coordination)
|
|
161
|
+
|
|
162
|
+
Coordinate multiple agents on a single task using four strategies.
|
|
163
|
+
|
|
164
|
+
**Sequential** — agents run in order, each getting the previous agent's output:
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
import { Agent, Team } from '@avee1234/agent-kit';
|
|
168
|
+
|
|
169
|
+
const team = new Team({
|
|
170
|
+
agents: [researcher, writer],
|
|
171
|
+
strategy: 'sequential',
|
|
172
|
+
});
|
|
173
|
+
const result = await team.run('Research AI frameworks and write a summary');
|
|
174
|
+
// writer receives researcher's output as context
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Parallel** — all agents run concurrently, results merged:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const team = new Team({
|
|
181
|
+
agents: [researcher, writer, critic],
|
|
182
|
+
strategy: 'parallel',
|
|
183
|
+
});
|
|
184
|
+
const result = await team.run('Analyze this codebase');
|
|
185
|
+
// result.responses has each agent's individual output
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Debate** — agents take turns critiquing and refining:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
const team = new Team({
|
|
192
|
+
agents: [proposer, critic],
|
|
193
|
+
strategy: 'debate',
|
|
194
|
+
maxRounds: 3,
|
|
195
|
+
});
|
|
196
|
+
const result = await team.run('What is the best database for embeddings?');
|
|
197
|
+
// 3 rounds of back-and-forth, then final answer
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Hierarchical** — a manager delegates tasks to specialists:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
const team = new Team({
|
|
204
|
+
agents: [researcher, writer, critic],
|
|
205
|
+
strategy: 'hierarchical',
|
|
206
|
+
manager: new Agent({ name: 'manager', system: 'You coordinate a team of specialists.' }),
|
|
207
|
+
});
|
|
208
|
+
const result = await team.run('Write a blog post about transformer alternatives');
|
|
209
|
+
// manager decides who does what and when
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
| Option | Type | Default | Description |
|
|
213
|
+
|--------|------|---------|-------------|
|
|
214
|
+
| `agents` | `Agent[]` | — | The agents to coordinate |
|
|
215
|
+
| `strategy` | `string` | — | `'sequential'`, `'parallel'`, `'debate'`, or `'hierarchical'` |
|
|
216
|
+
| `manager` | `Agent` | — | Required for hierarchical strategy |
|
|
217
|
+
| `maxRounds` | `number` | `3` | Number of debate rounds |
|
|
218
|
+
| `maxDelegations` | `number` | `10` | Max delegations for hierarchical |
|
|
219
|
+
|
|
156
220
|
## Model Configuration
|
|
157
221
|
|
|
158
222
|
### Mock (zero config, built-in)
|
|
@@ -160,7 +224,7 @@ Auto-summarization: when `summarizeAfter` messages accumulate, the agent summari
|
|
|
160
224
|
If you omit `model`, the agent uses `MockAdapter` — it echoes inputs and simulates tool calls. Useful for testing.
|
|
161
225
|
|
|
162
226
|
```typescript
|
|
163
|
-
import { MockAdapter } from 'agent-kit';
|
|
227
|
+
import { MockAdapter } from '@avee1234/agent-kit';
|
|
164
228
|
|
|
165
229
|
const agent = new Agent({ name: 'test', model: new MockAdapter() });
|
|
166
230
|
```
|
|
@@ -180,7 +244,7 @@ const agent = new Agent({
|
|
|
180
244
|
Works with Together AI, OpenRouter, Anyscale, LM Studio, and any other OpenAI-compatible API.
|
|
181
245
|
|
|
182
246
|
```typescript
|
|
183
|
-
import { OpenAICompatibleAdapter } from 'agent-kit';
|
|
247
|
+
import { OpenAICompatibleAdapter } from '@avee1234/agent-kit';
|
|
184
248
|
|
|
185
249
|
const agent = new Agent({
|
|
186
250
|
name: 'agent',
|
|
@@ -238,8 +302,8 @@ All events include `type`, `timestamp`, and `agentId` fields from `AgentEvent`.
|
|
|
238
302
|
Implement the `MemoryStore` interface to plug in any storage backend (PostgreSQL, Redis, DynamoDB, etc.).
|
|
239
303
|
|
|
240
304
|
```typescript
|
|
241
|
-
import type { MemoryStore } from 'agent-kit';
|
|
242
|
-
import type { Message, Summary } from 'agent-kit';
|
|
305
|
+
import type { MemoryStore } from '@avee1234/agent-kit';
|
|
306
|
+
import type { Message, Summary } from '@avee1234/agent-kit';
|
|
243
307
|
|
|
244
308
|
class MyStore implements MemoryStore {
|
|
245
309
|
async saveMessages(agentId: string, messages: Message[]): Promise<void> {
|
package/dist/index.cjs
CHANGED
|
@@ -27,6 +27,7 @@ __export(index_exports, {
|
|
|
27
27
|
MockAdapter: () => MockAdapter,
|
|
28
28
|
OpenAICompatibleAdapter: () => OpenAICompatibleAdapter,
|
|
29
29
|
SQLiteStore: () => SQLiteStore,
|
|
30
|
+
Team: () => Team,
|
|
30
31
|
Tool: () => Tool,
|
|
31
32
|
createMessage: () => createMessage,
|
|
32
33
|
createSummary: () => createSummary,
|
|
@@ -273,6 +274,9 @@ var Agent = class {
|
|
|
273
274
|
isModelAdapter(obj) {
|
|
274
275
|
return typeof obj.chat === "function";
|
|
275
276
|
}
|
|
277
|
+
getModel() {
|
|
278
|
+
return this.model;
|
|
279
|
+
}
|
|
276
280
|
on(type, handler) {
|
|
277
281
|
this.emitter.on(type, handler);
|
|
278
282
|
}
|
|
@@ -428,6 +432,144 @@ var Agent = class {
|
|
|
428
432
|
}
|
|
429
433
|
};
|
|
430
434
|
|
|
435
|
+
// src/strategy/sequential.ts
|
|
436
|
+
var SequentialStrategy = class {
|
|
437
|
+
async execute(agents, task, _options, emitter) {
|
|
438
|
+
const responses = [];
|
|
439
|
+
let previousOutput;
|
|
440
|
+
for (const agent of agents) {
|
|
441
|
+
const input = previousOutput !== void 0 ? `${task}
|
|
442
|
+
|
|
443
|
+
Previous agent output:
|
|
444
|
+
${previousOutput}` : task;
|
|
445
|
+
emitter.emit({
|
|
446
|
+
type: "team:agent:start",
|
|
447
|
+
timestamp: Date.now(),
|
|
448
|
+
agentId: "team",
|
|
449
|
+
data: { agentName: agent.name, input }
|
|
450
|
+
});
|
|
451
|
+
const startTime = Date.now();
|
|
452
|
+
const result = await agent.chat(input);
|
|
453
|
+
const latencyMs = Date.now() - startTime;
|
|
454
|
+
emitter.emit({
|
|
455
|
+
type: "team:agent:end",
|
|
456
|
+
timestamp: Date.now(),
|
|
457
|
+
agentId: "team",
|
|
458
|
+
data: { agentName: agent.name, output: result.content },
|
|
459
|
+
latencyMs
|
|
460
|
+
});
|
|
461
|
+
responses.push({ agent: agent.name, content: result.content });
|
|
462
|
+
previousOutput = result.content;
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
content: responses[responses.length - 1]?.content ?? "",
|
|
466
|
+
responses
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
// src/strategy/parallel.ts
|
|
472
|
+
var ParallelStrategy = class {
|
|
473
|
+
async execute(agents, task, _options, emitter) {
|
|
474
|
+
const agentPromises = agents.map(async (agent) => {
|
|
475
|
+
emitter.emit({
|
|
476
|
+
type: "team:agent:start",
|
|
477
|
+
timestamp: Date.now(),
|
|
478
|
+
agentId: "team",
|
|
479
|
+
data: { agentName: agent.name, input: task }
|
|
480
|
+
});
|
|
481
|
+
const startTime = Date.now();
|
|
482
|
+
const result = await agent.chat(task);
|
|
483
|
+
const latencyMs = Date.now() - startTime;
|
|
484
|
+
emitter.emit({
|
|
485
|
+
type: "team:agent:end",
|
|
486
|
+
timestamp: Date.now(),
|
|
487
|
+
agentId: "team",
|
|
488
|
+
data: { agentName: agent.name, output: result.content },
|
|
489
|
+
latencyMs
|
|
490
|
+
});
|
|
491
|
+
return { agent: agent.name, content: result.content };
|
|
492
|
+
});
|
|
493
|
+
const responses = await Promise.all(agentPromises);
|
|
494
|
+
const content = responses.map((r) => `[${r.agent}]: ${r.content}`).join("\n\n");
|
|
495
|
+
return { content, responses };
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
// src/strategy/debate.ts
|
|
500
|
+
var DebateStrategy = class {
|
|
501
|
+
async execute(agents, task, options, emitter) {
|
|
502
|
+
const maxRounds = options.maxRounds ?? 3;
|
|
503
|
+
const responses = [];
|
|
504
|
+
const priorOutputs = [];
|
|
505
|
+
for (let round = 1; round <= maxRounds; round++) {
|
|
506
|
+
emitter.emit({
|
|
507
|
+
type: "team:round",
|
|
508
|
+
timestamp: Date.now(),
|
|
509
|
+
agentId: "team",
|
|
510
|
+
data: { round, totalRounds: maxRounds }
|
|
511
|
+
});
|
|
512
|
+
for (const agent of agents) {
|
|
513
|
+
const context = priorOutputs.length > 0 ? `${task}
|
|
514
|
+
|
|
515
|
+
Debate so far:
|
|
516
|
+
${priorOutputs.join("\n\n")}
|
|
517
|
+
|
|
518
|
+
Your turn (Round ${round}):` : `${task}
|
|
519
|
+
|
|
520
|
+
(Round ${round}):`;
|
|
521
|
+
emitter.emit({
|
|
522
|
+
type: "team:agent:start",
|
|
523
|
+
timestamp: Date.now(),
|
|
524
|
+
agentId: "team",
|
|
525
|
+
data: { agentName: agent.name, round }
|
|
526
|
+
});
|
|
527
|
+
const startTime = Date.now();
|
|
528
|
+
const result = await agent.chat(context);
|
|
529
|
+
const latencyMs = Date.now() - startTime;
|
|
530
|
+
emitter.emit({
|
|
531
|
+
type: "team:agent:end",
|
|
532
|
+
timestamp: Date.now(),
|
|
533
|
+
agentId: "team",
|
|
534
|
+
data: { agentName: agent.name, output: result.content, round },
|
|
535
|
+
latencyMs
|
|
536
|
+
});
|
|
537
|
+
const agentResponse = {
|
|
538
|
+
agent: agent.name,
|
|
539
|
+
content: result.content,
|
|
540
|
+
round
|
|
541
|
+
};
|
|
542
|
+
responses.push(agentResponse);
|
|
543
|
+
priorOutputs.push(`[${agent.name}, Round ${round}]: ${result.content}`);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
const firstAgent = agents[0];
|
|
547
|
+
const synthesisInput = `${task}
|
|
548
|
+
|
|
549
|
+
Debate summary:
|
|
550
|
+
${priorOutputs.join("\n\n")}
|
|
551
|
+
|
|
552
|
+
Provide your final answer:`;
|
|
553
|
+
emitter.emit({
|
|
554
|
+
type: "team:agent:start",
|
|
555
|
+
timestamp: Date.now(),
|
|
556
|
+
agentId: "team",
|
|
557
|
+
data: { agentName: firstAgent.name, phase: "final" }
|
|
558
|
+
});
|
|
559
|
+
const finalResult = await firstAgent.chat(synthesisInput);
|
|
560
|
+
emitter.emit({
|
|
561
|
+
type: "team:agent:end",
|
|
562
|
+
timestamp: Date.now(),
|
|
563
|
+
agentId: "team",
|
|
564
|
+
data: { agentName: firstAgent.name, output: finalResult.content, phase: "final" }
|
|
565
|
+
});
|
|
566
|
+
return {
|
|
567
|
+
content: finalResult.content,
|
|
568
|
+
responses
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
};
|
|
572
|
+
|
|
431
573
|
// src/tool.ts
|
|
432
574
|
var Tool = class _Tool {
|
|
433
575
|
name;
|
|
@@ -452,6 +594,136 @@ var Tool = class _Tool {
|
|
|
452
594
|
}
|
|
453
595
|
};
|
|
454
596
|
|
|
597
|
+
// src/strategy/hierarchical.ts
|
|
598
|
+
var HierarchicalStrategy = class {
|
|
599
|
+
async execute(agents, task, options, emitter) {
|
|
600
|
+
const { manager, maxDelegations = 10 } = options;
|
|
601
|
+
if (!manager) {
|
|
602
|
+
throw new Error("HierarchicalStrategy requires a manager agent");
|
|
603
|
+
}
|
|
604
|
+
const agentMap = new Map(agents.map((a) => [a.name, a]));
|
|
605
|
+
const responses = [];
|
|
606
|
+
const delegateTool = Tool.create({
|
|
607
|
+
name: "delegate",
|
|
608
|
+
description: "Delegate a sub-task to a specialist agent. Use this to assign work to workers.",
|
|
609
|
+
parameters: {
|
|
610
|
+
agentName: {
|
|
611
|
+
type: "string",
|
|
612
|
+
description: "The name of the agent to delegate to",
|
|
613
|
+
required: true
|
|
614
|
+
},
|
|
615
|
+
task: {
|
|
616
|
+
type: "string",
|
|
617
|
+
description: "The task to assign to the agent",
|
|
618
|
+
required: true
|
|
619
|
+
}
|
|
620
|
+
},
|
|
621
|
+
execute: async (params) => {
|
|
622
|
+
const agentName = params.agentName;
|
|
623
|
+
const subTask = params.task;
|
|
624
|
+
const worker = agentMap.get(agentName);
|
|
625
|
+
if (!worker) {
|
|
626
|
+
return `Error: No agent named "${agentName}" found. Available agents: ${[...agentMap.keys()].join(", ")}`;
|
|
627
|
+
}
|
|
628
|
+
emitter.emit({
|
|
629
|
+
type: "team:delegate",
|
|
630
|
+
timestamp: Date.now(),
|
|
631
|
+
agentId: "team",
|
|
632
|
+
data: { agentName, task: subTask }
|
|
633
|
+
});
|
|
634
|
+
const result = await worker.chat(subTask);
|
|
635
|
+
const response = { agent: agentName, content: result.content };
|
|
636
|
+
responses.push(response);
|
|
637
|
+
return result.content;
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
const orchestratorAgent = new Agent({
|
|
641
|
+
name: manager.name,
|
|
642
|
+
model: manager.getModel(),
|
|
643
|
+
tools: [delegateTool],
|
|
644
|
+
system: `You are an orchestrating manager. You have access to specialist agents: ${[...agentMap.keys()].join(", ")}. Use the delegate tool to assign sub-tasks to them.`,
|
|
645
|
+
maxToolRounds: maxDelegations
|
|
646
|
+
});
|
|
647
|
+
const finalResult = await orchestratorAgent.chat(task);
|
|
648
|
+
return {
|
|
649
|
+
content: finalResult.content,
|
|
650
|
+
responses
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
// src/team.ts
|
|
656
|
+
var Team = class {
|
|
657
|
+
agents;
|
|
658
|
+
strategyName;
|
|
659
|
+
manager;
|
|
660
|
+
maxRounds;
|
|
661
|
+
maxDelegations;
|
|
662
|
+
emitter;
|
|
663
|
+
constructor(config) {
|
|
664
|
+
this.agents = config.agents;
|
|
665
|
+
this.strategyName = config.strategy;
|
|
666
|
+
this.manager = config.manager;
|
|
667
|
+
this.maxRounds = config.maxRounds;
|
|
668
|
+
this.maxDelegations = config.maxDelegations;
|
|
669
|
+
this.emitter = new AgentEventEmitter();
|
|
670
|
+
}
|
|
671
|
+
on(type, handler) {
|
|
672
|
+
this.emitter.on(type, handler);
|
|
673
|
+
}
|
|
674
|
+
off(type, handler) {
|
|
675
|
+
this.emitter.off(type, handler);
|
|
676
|
+
}
|
|
677
|
+
async run(task) {
|
|
678
|
+
this.emitter.emit({
|
|
679
|
+
type: "team:start",
|
|
680
|
+
timestamp: Date.now(),
|
|
681
|
+
agentId: "team",
|
|
682
|
+
data: {
|
|
683
|
+
strategy: this.strategyName,
|
|
684
|
+
agentCount: this.agents.length,
|
|
685
|
+
task
|
|
686
|
+
}
|
|
687
|
+
});
|
|
688
|
+
const startTime = Date.now();
|
|
689
|
+
const strategy = this.resolveStrategy();
|
|
690
|
+
const result = await strategy.execute(
|
|
691
|
+
this.agents,
|
|
692
|
+
task,
|
|
693
|
+
{
|
|
694
|
+
maxRounds: this.maxRounds,
|
|
695
|
+
maxDelegations: this.maxDelegations,
|
|
696
|
+
manager: this.manager
|
|
697
|
+
},
|
|
698
|
+
this.emitter
|
|
699
|
+
);
|
|
700
|
+
const latencyMs = Date.now() - startTime;
|
|
701
|
+
this.emitter.emit({
|
|
702
|
+
type: "team:end",
|
|
703
|
+
timestamp: Date.now(),
|
|
704
|
+
agentId: "team",
|
|
705
|
+
data: {
|
|
706
|
+
strategy: this.strategyName,
|
|
707
|
+
responseCount: result.responses.length
|
|
708
|
+
},
|
|
709
|
+
latencyMs
|
|
710
|
+
});
|
|
711
|
+
return result;
|
|
712
|
+
}
|
|
713
|
+
resolveStrategy() {
|
|
714
|
+
switch (this.strategyName) {
|
|
715
|
+
case "sequential":
|
|
716
|
+
return new SequentialStrategy();
|
|
717
|
+
case "parallel":
|
|
718
|
+
return new ParallelStrategy();
|
|
719
|
+
case "debate":
|
|
720
|
+
return new DebateStrategy();
|
|
721
|
+
case "hierarchical":
|
|
722
|
+
return new HierarchicalStrategy();
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
|
|
455
727
|
// src/store/in-memory.ts
|
|
456
728
|
var InMemoryStore = class {
|
|
457
729
|
messages = /* @__PURE__ */ new Map();
|
|
@@ -649,6 +921,7 @@ var Memory = class {
|
|
|
649
921
|
MockAdapter,
|
|
650
922
|
OpenAICompatibleAdapter,
|
|
651
923
|
SQLiteStore,
|
|
924
|
+
Team,
|
|
652
925
|
Tool,
|
|
653
926
|
createMessage,
|
|
654
927
|
createSummary,
|