@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 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,