@agent-diaries/core 0.1.1 → 0.1.3

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
@@ -4,6 +4,7 @@
4
4
 
5
5
  [![NPM Version](https://img.shields.io/npm/v/@agent-diaries/core?style=for-the-badge&logo=npm&color=CB3837)](https://www.npmjs.com/package/@agent-diaries/core)
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
7
+ [![Cloud Tested](https://img.shields.io/badge/Tested-Cloud%20Ready-success?style=for-the-badge&logo=icloud&logoColor=white)](#-200-agent-real-world-cloud-benchmarks)
7
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=for-the-badge)](https://opensource.org/licenses/MIT)
8
9
  </div>
9
10
 
@@ -17,7 +18,7 @@
17
18
 
18
19
  - **🚫 Deduplication & Loop Prevention:** Automatically filter out tasks your agent has already seen.
19
20
  - **🔒 Fully Lock-Safe:** Uses atomic spin-locks and advisory locks to completely eliminate race conditions, even with 50+ concurrent agents processing the exact same task simultaneously.
20
- - **☁️ Cloud-Native Adapters:** Comes with official adapters for **Redis** and **PostgreSQL** for Vercel/AWS Lambda deployments, plus a local file adapter for development.
21
+ - **☁️ Cloud-Native Adapters:** Comes with official adapters for **Redis** and **MongoDB** for Vercel/AWS Lambda deployments, plus a local file adapter for development.
21
22
  - **⚡ Ultra-Lightweight:** Negligible bundle size, zero heavy dependencies.
22
23
 
23
24
  ## 📦 Installation
@@ -32,7 +33,7 @@ If you plan to use a specific cloud adapter, install its peer dependency:
32
33
 
33
34
  ```bash
34
35
  npm install ioredis # For Redis Storage
35
- npm install pg # For PostgreSQL Storage
36
+ npm install mongodb # For MongoDB Storage
36
37
  ```
37
38
 
38
39
  ## 🚀 Quick Start
@@ -104,6 +105,76 @@ const diary = new AgentDiary({
104
105
  });
105
106
  ```
106
107
 
108
+ ## 📊 200-Agent Real-World Cloud Benchmarks
109
+
110
+ Agent Diaries Core is mathematically proven to handle massive concurrent agent swarms without race conditions or database corruption.
111
+
112
+ To prove its viability for enterprise serverless deployments, we rigorously stress-tested the library against a **Live Cloud Upstash Redis Database**, blasting it with **200 serverless agents** executing distributed lock requests across the internet at the exact same millisecond.
113
+
114
+ ### The Real-Life Architecture
115
+ ```typescript
116
+ const NUM_AGENTS = 200;
117
+ let agents = Array.from({ length: NUM_AGENTS }, () => getDiary());
118
+ const viralTask = `Analyze breaking news: OpenAI releases GPT-5 - ${Date.now()}`;
119
+
120
+ // Fire 200 distributed agents at the exact same millisecond
121
+ let results = await Promise.all(
122
+ agents.map(agent => agent.claimTask(viralTask).catch(() => false))
123
+ );
124
+
125
+ let successful = results.filter(r => r === true).length;
126
+ console.log(` Actual Locks: ${successful}`); // Always exactly 1.
127
+ ```
128
+
129
+ ### The Results (Zero Race Conditions)
130
+ > *Tested via WAN connection to an Upstash Serverless Redis instance and a Free Tier MongoDB Atlas Cluster*
131
+
132
+ ```text
133
+ =================================
134
+ 🌪️ INITIALIZING 200-AGENT SWARM: Upstash Redis (Cloud)
135
+ =================================
136
+ [Test 1] The Herd Effect: 200 Agents competing for exactly ONE viral task...
137
+ Expected Locks: 1
138
+ Actual Locks: 1
139
+ Resolution Time: 13254ms
140
+ 🟢 PASSED (199 race conditions prevented)
141
+
142
+ [Test 2] Real World Distribution: 200 Agents processing 10 common data tasks...
143
+ Expected Locks: 10
144
+ Actual Locks: 10
145
+ Resolution Time: 12828ms
146
+ 🟢 PASSED (190 duplicate LLM calls prevented)
147
+
148
+ [Test 3] Extreme Write Contention: 200 Agents blasting state updates at the exact same time...
149
+ Expected Written: 200
150
+ Actual Written: 200
151
+ Write Duration: 16267ms
152
+ 🟢 PASSED (Zero data corruption)
153
+
154
+ =================================
155
+ 🌪️ INITIALIZING 200-AGENT SWARM: MongoDB Atlas (Cloud Free Tier)
156
+ =================================
157
+ [Test 1] The Herd Effect: 200 Agents competing for exactly ONE viral task...
158
+ Expected Locks: 1
159
+ Actual Locks: 1
160
+ Resolution Time: 7362ms
161
+ 🟢 PASSED (199 race conditions prevented)
162
+
163
+ [Test 2] Real World Distribution: 200 Agents processing 10 common data tasks...
164
+ Expected Locks: 10
165
+ Actual Locks: 10
166
+ Resolution Time: 5545ms
167
+ 🟢 PASSED (190 duplicate LLM calls prevented)
168
+
169
+ [Test 3] Extreme Write Contention: 200 Agents blasting state updates at the exact same time...
170
+ Expected Written: 200
171
+ Actual Written: 200
172
+ Write Duration: 9410ms
173
+ 🟢 PASSED (Zero data corruption)
174
+ ```
175
+
176
+ **💡 Engineering Insight:** While SQL databases perform well on local network environments, relational connection poolers (like pgBouncer or Supavisor) completely buckle under the massive concurrent TCP bursts generated by serverless AI swarms. **Redis or MongoDB (via atomic upserts)** are strictly required for reliable lock management in high-concurrency serverless edge environments.
177
+
107
178
  ## 📚 API Reference
108
179
 
109
180
  - **`diary.claimTask(title: string): Promise<boolean>`**
@@ -0,0 +1,12 @@
1
+ import { StorageAdapter } from '../storage';
2
+ import { Collection } from 'mongodb';
3
+ export declare class MongoStorage<T> implements StorageAdapter<T> {
4
+ private collection;
5
+ constructor(config: {
6
+ collection: Collection;
7
+ });
8
+ private hashString;
9
+ get(key: string): Promise<T | null>;
10
+ set(key: string, data: T): Promise<void>;
11
+ withLock<R>(key: string, fn: () => Promise<R>): Promise<R>;
12
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MongoStorage = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ class MongoStorage {
9
+ collection;
10
+ constructor(config) {
11
+ this.collection = config.collection;
12
+ }
13
+ hashString(str) {
14
+ return crypto_1.default.createHash('sha256').update(str).digest('hex');
15
+ }
16
+ async get(key) {
17
+ const hash = this.hashString(key);
18
+ const doc = await this.collection.findOne({ _id: hash });
19
+ if (!doc || !doc.data)
20
+ return null;
21
+ return JSON.parse(doc.data);
22
+ }
23
+ async set(key, data) {
24
+ const hash = this.hashString(key);
25
+ await this.collection.updateOne({ _id: hash }, { $set: { data: JSON.stringify(data) } }, { upsert: true });
26
+ }
27
+ async withLock(key, fn) {
28
+ const hash = this.hashString(key);
29
+ const lockId = `lock:${hash}`;
30
+ const acquireLock = async () => {
31
+ try {
32
+ await this.collection.insertOne({ _id: lockId, lockedAt: new Date() });
33
+ return true;
34
+ }
35
+ catch (error) {
36
+ if (error.code === 11000)
37
+ return false;
38
+ throw error;
39
+ }
40
+ };
41
+ while (!(await acquireLock())) {
42
+ await new Promise(resolve => setTimeout(resolve, 50));
43
+ }
44
+ try {
45
+ return await fn();
46
+ }
47
+ finally {
48
+ await this.collection.deleteOne({ _id: lockId });
49
+ }
50
+ }
51
+ }
52
+ exports.MongoStorage = MongoStorage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-diaries/core",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "The lightweight, framework-agnostic memory layer for edge AI agents.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -31,8 +31,8 @@
31
31
  "homepage": "https://github.com/swapwarick/agent-diaries-core#readme",
32
32
  "license": "MIT",
33
33
  "devDependencies": {
34
+ "@types/dotenv": "^6.1.1",
34
35
  "@types/node": "^20.0.0",
35
- "@types/pg": "^8.20.0",
36
36
  "@types/proper-lockfile": "^4.1.4",
37
37
  "@vitest/coverage-v8": "^4.1.5",
38
38
  "ts-node": "^10.9.2",
@@ -40,8 +40,9 @@
40
40
  "vitest": "^4.1.5"
41
41
  },
42
42
  "dependencies": {
43
+ "dotenv": "^17.4.2",
43
44
  "ioredis": "^5.10.1",
44
- "pg": "^8.20.0",
45
+ "mongodb": "^7.2.0",
45
46
  "proper-lockfile": "^4.1.2"
46
47
  }
47
- }
48
+ }