mengram-ai 2.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 +72 -0
- package/index.d.ts +131 -0
- package/index.js +430 -0
- package/package.json +16 -0
package/README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# mengram-ai
|
|
2
|
+
|
|
3
|
+
JavaScript / TypeScript SDK for [Mengram](https://mengram.io) — AI Memory Layer with Autonomous Agents.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install mengram-ai
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
const { MengramClient } = require('mengram-ai');
|
|
15
|
+
|
|
16
|
+
const m = new MengramClient('mg-your-api-key');
|
|
17
|
+
|
|
18
|
+
// Add memories from conversation
|
|
19
|
+
await m.add([
|
|
20
|
+
{ role: 'user', content: 'I work at Acme Corp as a senior engineer. I prefer dark mode.' },
|
|
21
|
+
{ role: 'assistant', content: 'Noted your preferences!' }
|
|
22
|
+
], { userId: 'ali' });
|
|
23
|
+
|
|
24
|
+
// Search memories
|
|
25
|
+
const results = await m.search('work preferences', { userId: 'ali' });
|
|
26
|
+
console.log(results);
|
|
27
|
+
// [{ entity: 'User', type: 'person', score: 0.92, facts: ['Works at Acme Corp', 'Prefers dark mode'] }]
|
|
28
|
+
|
|
29
|
+
// Multi-agent memory
|
|
30
|
+
await m.add(messages, {
|
|
31
|
+
userId: 'ali',
|
|
32
|
+
agentId: 'support-bot',
|
|
33
|
+
appId: 'helpdesk'
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## TypeScript
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { MengramClient, SearchResult } from 'mengram-ai';
|
|
41
|
+
|
|
42
|
+
const m = new MengramClient('mg-...');
|
|
43
|
+
const results: SearchResult[] = await m.search('preferences');
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## API
|
|
47
|
+
|
|
48
|
+
| Method | Description |
|
|
49
|
+
|--------|-------------|
|
|
50
|
+
| `add(messages, options?)` | Add memories from conversation |
|
|
51
|
+
| `addText(text, options?)` | Add memories from plain text |
|
|
52
|
+
| `search(query, options?)` | Semantic search |
|
|
53
|
+
| `getAll(options?)` | List all memories |
|
|
54
|
+
| `get(name)` | Get specific entity |
|
|
55
|
+
| `delete(name)` | Delete entity |
|
|
56
|
+
| `stats()` | Usage statistics |
|
|
57
|
+
| `graph()` | Knowledge graph |
|
|
58
|
+
| `runAgents(options?)` | Run memory agents |
|
|
59
|
+
| `insights()` | AI-generated reflections |
|
|
60
|
+
| `createTeam(name)` | Create shared team |
|
|
61
|
+
| `joinTeam(code)` | Join team with invite code |
|
|
62
|
+
| `shareMemory(entity, teamId)` | Share memory with team |
|
|
63
|
+
| `listKeys()` | List API keys |
|
|
64
|
+
| `createKey(name?)` | Create new API key |
|
|
65
|
+
|
|
66
|
+
All methods support `userId`, `agentId`, `runId`, `appId` options for multi-agent systems.
|
|
67
|
+
|
|
68
|
+
## Links
|
|
69
|
+
|
|
70
|
+
- [Documentation](https://mengram.io/docs)
|
|
71
|
+
- [Python SDK](https://pypi.org/project/mengram-ai/)
|
|
72
|
+
- [GitHub](https://github.com/alibaizhanov/mengram)
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
export interface MengramOptions {
|
|
2
|
+
baseUrl?: string;
|
|
3
|
+
timeout?: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface Message {
|
|
7
|
+
role: 'user' | 'assistant' | 'system';
|
|
8
|
+
content: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface MemoryOptions {
|
|
12
|
+
userId?: string;
|
|
13
|
+
agentId?: string;
|
|
14
|
+
runId?: string;
|
|
15
|
+
appId?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface SearchOptions extends MemoryOptions {
|
|
19
|
+
limit?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface AddResult {
|
|
23
|
+
status: string;
|
|
24
|
+
message?: string;
|
|
25
|
+
job_id?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface SearchResult {
|
|
29
|
+
entity: string;
|
|
30
|
+
type: string;
|
|
31
|
+
score: number;
|
|
32
|
+
facts: string[];
|
|
33
|
+
knowledge: any[];
|
|
34
|
+
relations: any[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface Entity {
|
|
38
|
+
name: string;
|
|
39
|
+
type: string;
|
|
40
|
+
facts: string[];
|
|
41
|
+
knowledge: any[];
|
|
42
|
+
relations: any[];
|
|
43
|
+
created_at: string;
|
|
44
|
+
updated_at: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface Stats {
|
|
48
|
+
entities: number;
|
|
49
|
+
facts: number;
|
|
50
|
+
knowledge: number;
|
|
51
|
+
relations: number;
|
|
52
|
+
embeddings: number;
|
|
53
|
+
by_type: Record<string, number>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface ApiKey {
|
|
57
|
+
id: number;
|
|
58
|
+
name: string;
|
|
59
|
+
prefix: string;
|
|
60
|
+
active: boolean;
|
|
61
|
+
created_at: string | null;
|
|
62
|
+
last_used: string | null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface JobStatus {
|
|
66
|
+
status: 'pending' | 'processing' | 'completed' | 'failed';
|
|
67
|
+
result?: any;
|
|
68
|
+
error?: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface Webhook {
|
|
72
|
+
id: number;
|
|
73
|
+
url: string;
|
|
74
|
+
name: string;
|
|
75
|
+
event_types: string[];
|
|
76
|
+
active: boolean;
|
|
77
|
+
trigger_count: number;
|
|
78
|
+
last_triggered: string | null;
|
|
79
|
+
last_error: string | null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export declare class MengramError extends Error {
|
|
83
|
+
statusCode: number;
|
|
84
|
+
constructor(message: string, statusCode: number);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export declare class MengramClient {
|
|
88
|
+
constructor(apiKey: string, options?: MengramOptions);
|
|
89
|
+
|
|
90
|
+
// Memory
|
|
91
|
+
add(messages: Message[], options?: MemoryOptions): Promise<AddResult>;
|
|
92
|
+
addText(text: string, options?: MemoryOptions): Promise<AddResult>;
|
|
93
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
94
|
+
getAll(options?: MemoryOptions): Promise<Entity[]>;
|
|
95
|
+
getAllFull(): Promise<Entity[]>;
|
|
96
|
+
get(name: string): Promise<Entity | null>;
|
|
97
|
+
delete(name: string): Promise<boolean>;
|
|
98
|
+
stats(): Promise<Stats>;
|
|
99
|
+
graph(): Promise<{ nodes: any[]; edges: any[] }>;
|
|
100
|
+
timeline(options?: { after?: string; before?: string; limit?: number }): Promise<any[]>;
|
|
101
|
+
|
|
102
|
+
// Agents
|
|
103
|
+
runAgents(options?: { agent?: string; autoFix?: boolean }): Promise<any>;
|
|
104
|
+
agentHistory(options?: { agent?: string; limit?: number }): Promise<any[]>;
|
|
105
|
+
|
|
106
|
+
// Insights
|
|
107
|
+
insights(): Promise<any>;
|
|
108
|
+
reflect(): Promise<any>;
|
|
109
|
+
|
|
110
|
+
// Webhooks
|
|
111
|
+
listWebhooks(): Promise<Webhook[]>;
|
|
112
|
+
createWebhook(webhook: { url: string; eventTypes: string[]; name?: string; secret?: string }): Promise<any>;
|
|
113
|
+
deleteWebhook(webhookId: number): Promise<boolean>;
|
|
114
|
+
|
|
115
|
+
// Teams
|
|
116
|
+
createTeam(name: string, description?: string): Promise<any>;
|
|
117
|
+
joinTeam(inviteCode: string): Promise<any>;
|
|
118
|
+
listTeams(): Promise<any[]>;
|
|
119
|
+
shareMemory(entityName: string, teamId: number): Promise<any>;
|
|
120
|
+
|
|
121
|
+
// API Keys
|
|
122
|
+
listKeys(): Promise<ApiKey[]>;
|
|
123
|
+
createKey(name?: string): Promise<{ key: string; name: string }>;
|
|
124
|
+
revokeKey(keyId: number): Promise<any>;
|
|
125
|
+
|
|
126
|
+
// Jobs
|
|
127
|
+
jobStatus(jobId: string): Promise<JobStatus>;
|
|
128
|
+
waitForJob(jobId: string, options?: { pollInterval?: number; maxWait?: number }): Promise<any>;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export default MengramClient;
|
package/index.js
ADDED
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mengram Cloud SDK for JavaScript / TypeScript
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* const { MengramClient } = require('mengram-ai');
|
|
6
|
+
* // or: import { MengramClient } from 'mengram-ai';
|
|
7
|
+
*
|
|
8
|
+
* const m = new MengramClient('mg-...');
|
|
9
|
+
*
|
|
10
|
+
* await m.add([
|
|
11
|
+
* { role: 'user', content: 'I prefer dark mode and use Vim.' },
|
|
12
|
+
* { role: 'assistant', content: 'Noted!' }
|
|
13
|
+
* ], { userId: 'ali' });
|
|
14
|
+
*
|
|
15
|
+
* const results = await m.search('editor preferences', { userId: 'ali' });
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
class MengramClient {
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} apiKey - Your Mengram API key (mg-...)
|
|
21
|
+
* @param {object} [options]
|
|
22
|
+
* @param {string} [options.baseUrl] - API base URL (default: https://mengram.io)
|
|
23
|
+
* @param {number} [options.timeout] - Request timeout in ms (default: 30000)
|
|
24
|
+
*/
|
|
25
|
+
constructor(apiKey, options = {}) {
|
|
26
|
+
if (!apiKey) throw new Error('API key is required');
|
|
27
|
+
this.apiKey = apiKey;
|
|
28
|
+
this.baseUrl = (options.baseUrl || 'https://mengram.io').replace(/\/$/, '');
|
|
29
|
+
this.timeout = options.timeout || 30000;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async _request(method, path, body = null, params = null) {
|
|
33
|
+
let url = `${this.baseUrl}${path}`;
|
|
34
|
+
|
|
35
|
+
if (params) {
|
|
36
|
+
const qs = Object.entries(params)
|
|
37
|
+
.filter(([, v]) => v !== undefined && v !== null)
|
|
38
|
+
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
|
|
39
|
+
.join('&');
|
|
40
|
+
if (qs) url += `?${qs}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const headers = {
|
|
44
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
45
|
+
'Content-Type': 'application/json',
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const controller = new AbortController();
|
|
49
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const res = await fetch(url, {
|
|
53
|
+
method,
|
|
54
|
+
headers,
|
|
55
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
56
|
+
signal: controller.signal,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const data = await res.json();
|
|
60
|
+
if (!res.ok) {
|
|
61
|
+
throw new MengramError(data.detail || `HTTP ${res.status}`, res.status);
|
|
62
|
+
}
|
|
63
|
+
return data;
|
|
64
|
+
} catch (err) {
|
|
65
|
+
if (err instanceof MengramError) throw err;
|
|
66
|
+
if (err.name === 'AbortError') {
|
|
67
|
+
throw new MengramError(`Request timeout after ${this.timeout}ms`, 408);
|
|
68
|
+
}
|
|
69
|
+
throw new MengramError(err.message, 0);
|
|
70
|
+
} finally {
|
|
71
|
+
clearTimeout(timer);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ---- Memory ----
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Add memories from conversation.
|
|
79
|
+
* @param {Array<{role: string, content: string}>} messages
|
|
80
|
+
* @param {object} [options]
|
|
81
|
+
* @param {string} [options.userId] - User ID (default: 'default')
|
|
82
|
+
* @param {string} [options.agentId] - Agent ID for multi-agent systems
|
|
83
|
+
* @param {string} [options.runId] - Run/session ID
|
|
84
|
+
* @param {string} [options.appId] - Application ID
|
|
85
|
+
* @returns {Promise<{status: string, job_id?: string}>}
|
|
86
|
+
*/
|
|
87
|
+
async add(messages, options = {}) {
|
|
88
|
+
return this._request('POST', '/v1/add', {
|
|
89
|
+
messages,
|
|
90
|
+
user_id: options.userId || 'default',
|
|
91
|
+
agent_id: options.agentId || null,
|
|
92
|
+
run_id: options.runId || null,
|
|
93
|
+
app_id: options.appId || null,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Add memory from plain text.
|
|
99
|
+
* @param {string} text
|
|
100
|
+
* @param {object} [options]
|
|
101
|
+
* @param {string} [options.userId]
|
|
102
|
+
* @param {string} [options.agentId]
|
|
103
|
+
* @param {string} [options.runId]
|
|
104
|
+
* @param {string} [options.appId]
|
|
105
|
+
* @returns {Promise<{status: string}>}
|
|
106
|
+
*/
|
|
107
|
+
async addText(text, options = {}) {
|
|
108
|
+
return this._request('POST', '/v1/add_text', {
|
|
109
|
+
text,
|
|
110
|
+
user_id: options.userId || 'default',
|
|
111
|
+
agent_id: options.agentId || null,
|
|
112
|
+
run_id: options.runId || null,
|
|
113
|
+
app_id: options.appId || null,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Semantic search across memories.
|
|
119
|
+
* @param {string} query
|
|
120
|
+
* @param {object} [options]
|
|
121
|
+
* @param {string} [options.userId]
|
|
122
|
+
* @param {string} [options.agentId]
|
|
123
|
+
* @param {string} [options.runId]
|
|
124
|
+
* @param {string} [options.appId]
|
|
125
|
+
* @param {number} [options.limit] - Max results (default: 5)
|
|
126
|
+
* @returns {Promise<Array>}
|
|
127
|
+
*/
|
|
128
|
+
async search(query, options = {}) {
|
|
129
|
+
const data = await this._request('POST', '/v1/search', {
|
|
130
|
+
query,
|
|
131
|
+
user_id: options.userId || 'default',
|
|
132
|
+
agent_id: options.agentId || null,
|
|
133
|
+
run_id: options.runId || null,
|
|
134
|
+
app_id: options.appId || null,
|
|
135
|
+
limit: options.limit || 5,
|
|
136
|
+
});
|
|
137
|
+
return data.results || [];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get all memories.
|
|
142
|
+
* @param {object} [options]
|
|
143
|
+
* @param {string} [options.userId]
|
|
144
|
+
* @param {string} [options.agentId]
|
|
145
|
+
* @param {string} [options.appId]
|
|
146
|
+
* @returns {Promise<Array>}
|
|
147
|
+
*/
|
|
148
|
+
async getAll(options = {}) {
|
|
149
|
+
const params = {};
|
|
150
|
+
if (options.userId) params.user_id_param = options.userId;
|
|
151
|
+
if (options.agentId) params.agent_id = options.agentId;
|
|
152
|
+
if (options.appId) params.app_id = options.appId;
|
|
153
|
+
const data = await this._request('GET', '/v1/memories', null, params);
|
|
154
|
+
return data.memories || [];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Get all memories with full details.
|
|
159
|
+
* @returns {Promise<Array>}
|
|
160
|
+
*/
|
|
161
|
+
async getAllFull() {
|
|
162
|
+
const data = await this._request('GET', '/v1/memories/full');
|
|
163
|
+
return data.memories || [];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Get specific entity.
|
|
168
|
+
* @param {string} name - Entity name
|
|
169
|
+
* @returns {Promise<object|null>}
|
|
170
|
+
*/
|
|
171
|
+
async get(name) {
|
|
172
|
+
try {
|
|
173
|
+
return await this._request('GET', `/v1/memory/${encodeURIComponent(name)}`);
|
|
174
|
+
} catch {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Delete a memory entity.
|
|
181
|
+
* @param {string} name
|
|
182
|
+
* @returns {Promise<boolean>}
|
|
183
|
+
*/
|
|
184
|
+
async delete(name) {
|
|
185
|
+
try {
|
|
186
|
+
await this._request('DELETE', `/v1/entity/${encodeURIComponent(name)}`);
|
|
187
|
+
return true;
|
|
188
|
+
} catch {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Get usage statistics.
|
|
195
|
+
* @returns {Promise<object>}
|
|
196
|
+
*/
|
|
197
|
+
async stats() {
|
|
198
|
+
return this._request('GET', '/v1/stats');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Get knowledge graph.
|
|
203
|
+
* @returns {Promise<{nodes: Array, edges: Array}>}
|
|
204
|
+
*/
|
|
205
|
+
async graph() {
|
|
206
|
+
return this._request('GET', '/v1/graph');
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Timeline search.
|
|
211
|
+
* @param {object} [options]
|
|
212
|
+
* @param {string} [options.after] - ISO date
|
|
213
|
+
* @param {string} [options.before] - ISO date
|
|
214
|
+
* @param {number} [options.limit]
|
|
215
|
+
* @returns {Promise<Array>}
|
|
216
|
+
*/
|
|
217
|
+
async timeline(options = {}) {
|
|
218
|
+
const params = { limit: options.limit || 20 };
|
|
219
|
+
if (options.after) params.after = options.after;
|
|
220
|
+
if (options.before) params.before = options.before;
|
|
221
|
+
const data = await this._request('GET', '/v1/timeline', null, params);
|
|
222
|
+
return data.results || [];
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ---- Agents ----
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Run memory agents.
|
|
229
|
+
* @param {object} [options]
|
|
230
|
+
* @param {string} [options.agent] - 'curator', 'connector', 'digest', or 'all'
|
|
231
|
+
* @param {boolean} [options.autoFix] - Auto-archive bad facts
|
|
232
|
+
* @returns {Promise<object>}
|
|
233
|
+
*/
|
|
234
|
+
async runAgents(options = {}) {
|
|
235
|
+
return this._request('POST', '/v1/agents/run', null, {
|
|
236
|
+
agent: options.agent || 'all',
|
|
237
|
+
auto_fix: options.autoFix ? 'true' : 'false',
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Get agent run history.
|
|
243
|
+
* @param {object} [options]
|
|
244
|
+
* @param {string} [options.agent]
|
|
245
|
+
* @param {number} [options.limit]
|
|
246
|
+
* @returns {Promise<Array>}
|
|
247
|
+
*/
|
|
248
|
+
async agentHistory(options = {}) {
|
|
249
|
+
const params = { limit: options.limit || 10 };
|
|
250
|
+
if (options.agent) params.agent = options.agent;
|
|
251
|
+
const data = await this._request('GET', '/v1/agents/history', null, params);
|
|
252
|
+
return data.runs || [];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// ---- Insights ----
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Get AI insights and reflections.
|
|
259
|
+
* @returns {Promise<object>}
|
|
260
|
+
*/
|
|
261
|
+
async insights() {
|
|
262
|
+
return this._request('GET', '/v1/insights');
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Trigger reflection generation.
|
|
267
|
+
* @returns {Promise<object>}
|
|
268
|
+
*/
|
|
269
|
+
async reflect() {
|
|
270
|
+
return this._request('POST', '/v1/reflect');
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// ---- Webhooks ----
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* List webhooks.
|
|
277
|
+
* @returns {Promise<Array>}
|
|
278
|
+
*/
|
|
279
|
+
async listWebhooks() {
|
|
280
|
+
const data = await this._request('GET', '/v1/webhooks');
|
|
281
|
+
return data.webhooks || [];
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Create webhook.
|
|
286
|
+
* @param {object} webhook
|
|
287
|
+
* @param {string} webhook.url
|
|
288
|
+
* @param {string[]} webhook.eventTypes
|
|
289
|
+
* @param {string} [webhook.name]
|
|
290
|
+
* @param {string} [webhook.secret]
|
|
291
|
+
* @returns {Promise<object>}
|
|
292
|
+
*/
|
|
293
|
+
async createWebhook(webhook) {
|
|
294
|
+
return this._request('POST', '/v1/webhooks', {
|
|
295
|
+
url: webhook.url,
|
|
296
|
+
event_types: webhook.eventTypes,
|
|
297
|
+
name: webhook.name || '',
|
|
298
|
+
secret: webhook.secret || '',
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Delete webhook.
|
|
304
|
+
* @param {number} webhookId
|
|
305
|
+
* @returns {Promise<boolean>}
|
|
306
|
+
*/
|
|
307
|
+
async deleteWebhook(webhookId) {
|
|
308
|
+
try {
|
|
309
|
+
await this._request('DELETE', `/v1/webhooks/${webhookId}`);
|
|
310
|
+
return true;
|
|
311
|
+
} catch {
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// ---- Teams ----
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Create a team.
|
|
320
|
+
* @param {string} name
|
|
321
|
+
* @param {string} [description]
|
|
322
|
+
* @returns {Promise<object>}
|
|
323
|
+
*/
|
|
324
|
+
async createTeam(name, description = '') {
|
|
325
|
+
return this._request('POST', '/v1/teams', { name, description });
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Join a team with invite code.
|
|
330
|
+
* @param {string} inviteCode
|
|
331
|
+
* @returns {Promise<object>}
|
|
332
|
+
*/
|
|
333
|
+
async joinTeam(inviteCode) {
|
|
334
|
+
return this._request('POST', '/v1/teams/join', { invite_code: inviteCode });
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* List your teams.
|
|
339
|
+
* @returns {Promise<Array>}
|
|
340
|
+
*/
|
|
341
|
+
async listTeams() {
|
|
342
|
+
const data = await this._request('GET', '/v1/teams');
|
|
343
|
+
return data.teams || [];
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Share memory with a team.
|
|
348
|
+
* @param {string} entityName
|
|
349
|
+
* @param {number} teamId
|
|
350
|
+
* @returns {Promise<object>}
|
|
351
|
+
*/
|
|
352
|
+
async shareMemory(entityName, teamId) {
|
|
353
|
+
return this._request('POST', `/v1/teams/${teamId}/share`, { entity: entityName });
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// ---- API Keys ----
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* List API keys.
|
|
360
|
+
* @returns {Promise<Array>}
|
|
361
|
+
*/
|
|
362
|
+
async listKeys() {
|
|
363
|
+
const data = await this._request('GET', '/v1/keys');
|
|
364
|
+
return data.keys || [];
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Create a new API key.
|
|
369
|
+
* @param {string} [name] - Key name
|
|
370
|
+
* @returns {Promise<{key: string, name: string}>}
|
|
371
|
+
*/
|
|
372
|
+
async createKey(name = 'default') {
|
|
373
|
+
return this._request('POST', '/v1/keys', { name });
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Revoke an API key.
|
|
378
|
+
* @param {number} keyId
|
|
379
|
+
* @returns {Promise<object>}
|
|
380
|
+
*/
|
|
381
|
+
async revokeKey(keyId) {
|
|
382
|
+
return this._request('DELETE', `/v1/keys/${keyId}`);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// ---- Jobs (Async) ----
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Check status of a background job.
|
|
389
|
+
* @param {string} jobId
|
|
390
|
+
* @returns {Promise<{status: string, result?: object}>}
|
|
391
|
+
*/
|
|
392
|
+
async jobStatus(jobId) {
|
|
393
|
+
return this._request('GET', `/v1/jobs/${jobId}`);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Wait for a job to complete.
|
|
398
|
+
* @param {string} jobId
|
|
399
|
+
* @param {object} [options]
|
|
400
|
+
* @param {number} [options.pollInterval] - ms between polls (default: 1000)
|
|
401
|
+
* @param {number} [options.maxWait] - max ms to wait (default: 60000)
|
|
402
|
+
* @returns {Promise<object>}
|
|
403
|
+
*/
|
|
404
|
+
async waitForJob(jobId, options = {}) {
|
|
405
|
+
const interval = options.pollInterval || 1000;
|
|
406
|
+
const maxWait = options.maxWait || 60000;
|
|
407
|
+
const start = Date.now();
|
|
408
|
+
|
|
409
|
+
while (Date.now() - start < maxWait) {
|
|
410
|
+
const job = await this.jobStatus(jobId);
|
|
411
|
+
if (job.status === 'completed' || job.status === 'failed') {
|
|
412
|
+
return job;
|
|
413
|
+
}
|
|
414
|
+
await new Promise(r => setTimeout(r, interval));
|
|
415
|
+
}
|
|
416
|
+
throw new MengramError('Job timed out', 408);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
class MengramError extends Error {
|
|
421
|
+
constructor(message, statusCode) {
|
|
422
|
+
super(message);
|
|
423
|
+
this.name = 'MengramError';
|
|
424
|
+
this.statusCode = statusCode;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Export for both CommonJS and ESM
|
|
429
|
+
module.exports = { MengramClient, MengramError };
|
|
430
|
+
module.exports.default = MengramClient;
|
package/package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mengram-ai",
|
|
3
|
+
"version": "2.2.0",
|
|
4
|
+
"description": "AI Memory Layer with Autonomous Agents — JavaScript SDK",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"license": "Apache-2.0",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/alibaizhanov/mengram"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://mengram.io",
|
|
13
|
+
"keywords": ["ai", "memory", "llm", "agents", "knowledge-graph", "mcp", "mengram"],
|
|
14
|
+
"author": "Ali Baizhanov",
|
|
15
|
+
"files": ["index.js", "index.d.ts", "README.md"]
|
|
16
|
+
}
|