@1mbrain/sdk 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/dist/.tsbuildinfo +1 -1
- package/dist/chunk-TLPCKSTS.js +211 -0
- package/dist/chunk-TLPCKSTS.js.map +1 -0
- package/dist/hermes.cjs +429 -0
- package/dist/hermes.cjs.map +1 -0
- package/dist/hermes.js +210 -245
- package/dist/hermes.js.map +1 -1
- package/dist/index.cjs +239 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +10 -177
- package/dist/index.js.map +1 -1
- package/package.json +10 -6
- package/dist/hermes.d.ts +0 -185
- package/dist/hermes.d.ts.map +0 -1
- package/dist/index.d.ts +0 -100
- package/dist/index.d.ts.map +0 -1
- package/dist/prompts.d.ts +0 -2
- package/dist/prompts.d.ts.map +0 -1
- package/dist/prompts.js +0 -11
- package/dist/prompts.js.map +0 -1
package/dist/hermes.cjs
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/hermes.ts
|
|
21
|
+
var hermes_exports = {};
|
|
22
|
+
__export(hermes_exports, {
|
|
23
|
+
HermesMemoryAdapter: () => HermesMemoryAdapter
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(hermes_exports);
|
|
26
|
+
|
|
27
|
+
// src/index.ts
|
|
28
|
+
var OneMBrainError = class extends Error {
|
|
29
|
+
constructor(message, status, details) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.status = status;
|
|
32
|
+
this.details = details;
|
|
33
|
+
this.name = "OneMBrainError";
|
|
34
|
+
}
|
|
35
|
+
status;
|
|
36
|
+
details;
|
|
37
|
+
};
|
|
38
|
+
var OneMBrainClient = class {
|
|
39
|
+
apiUrl;
|
|
40
|
+
apiKey;
|
|
41
|
+
agentId;
|
|
42
|
+
fetchFn;
|
|
43
|
+
constructor(config) {
|
|
44
|
+
if (!config.apiUrl) {
|
|
45
|
+
throw new Error("apiUrl is required");
|
|
46
|
+
}
|
|
47
|
+
if (!config.apiKey) {
|
|
48
|
+
throw new Error("apiKey is required");
|
|
49
|
+
}
|
|
50
|
+
this.apiUrl = config.apiUrl.replace(/\/+$/, "");
|
|
51
|
+
this.apiKey = config.apiKey;
|
|
52
|
+
this.agentId = config.agentId;
|
|
53
|
+
this.fetchFn = config.fetch ?? fetch;
|
|
54
|
+
}
|
|
55
|
+
async remember(input) {
|
|
56
|
+
const agentId = this.resolveAgentId(input.agentId);
|
|
57
|
+
const envelope = await this.request("/v1/memories", {
|
|
58
|
+
method: "POST",
|
|
59
|
+
agentId,
|
|
60
|
+
body: {
|
|
61
|
+
...input,
|
|
62
|
+
agentId
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return deserializeMemory(envelope.data);
|
|
66
|
+
}
|
|
67
|
+
async recall(input) {
|
|
68
|
+
const agentId = this.resolveAgentId(input.agentId);
|
|
69
|
+
const params = toSearchParams({
|
|
70
|
+
...input,
|
|
71
|
+
agentId,
|
|
72
|
+
q: input.query,
|
|
73
|
+
query: void 0
|
|
74
|
+
});
|
|
75
|
+
const envelope = await this.request(
|
|
76
|
+
`/v1/memories/search?${params.toString()}`,
|
|
77
|
+
{
|
|
78
|
+
method: "GET",
|
|
79
|
+
agentId
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
const results = envelope.data.map((result) => ({
|
|
83
|
+
...result,
|
|
84
|
+
memory: deserializeMemory(result.memory)
|
|
85
|
+
}));
|
|
86
|
+
if (envelope.meta) {
|
|
87
|
+
results.confidence = envelope.meta.confidence;
|
|
88
|
+
results.reason = envelope.meta.reason;
|
|
89
|
+
}
|
|
90
|
+
return results;
|
|
91
|
+
}
|
|
92
|
+
async forget(id, options = {}) {
|
|
93
|
+
const envelope = await this.request(`/v1/memories/${id}`, {
|
|
94
|
+
method: "DELETE",
|
|
95
|
+
agentId: this.resolveAgentId(options.agentId)
|
|
96
|
+
});
|
|
97
|
+
return envelope.success;
|
|
98
|
+
}
|
|
99
|
+
async associate(sourceId, input) {
|
|
100
|
+
const envelope = await this.request(
|
|
101
|
+
`/v1/memories/${sourceId}/associate`,
|
|
102
|
+
{
|
|
103
|
+
method: "POST",
|
|
104
|
+
agentId: this.resolveAgentId(input.agentId),
|
|
105
|
+
body: {
|
|
106
|
+
targetId: input.targetId,
|
|
107
|
+
strength: input.strength,
|
|
108
|
+
origin: input.origin,
|
|
109
|
+
relationType: input.relationType
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
return envelope.success;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Ingest a web page URL into memory.
|
|
117
|
+
*
|
|
118
|
+
* The server-side pipeline will:
|
|
119
|
+
* 1. Fetch the page HTML
|
|
120
|
+
* 2. Extract main content → Markdown
|
|
121
|
+
* 3. Chunk and extract factual claims via LLM
|
|
122
|
+
* 4. Store facts as memories (type, importance, metadata auto-set)
|
|
123
|
+
*
|
|
124
|
+
* Works from any gateway: Telegram, Discord, browser extension, CLI.
|
|
125
|
+
*
|
|
126
|
+
* @param url - The URL to ingest
|
|
127
|
+
* @param options - Optional overrides (agentId, confidenceThreshold, etc.)
|
|
128
|
+
*/
|
|
129
|
+
async ingestUrl(url, options = {}) {
|
|
130
|
+
const agentId = this.resolveAgentId(options.agentId);
|
|
131
|
+
const envelope = await this.request("/v1/ingest/url", {
|
|
132
|
+
method: "POST",
|
|
133
|
+
agentId,
|
|
134
|
+
body: {
|
|
135
|
+
url,
|
|
136
|
+
agentId,
|
|
137
|
+
confidenceThreshold: options.confidenceThreshold,
|
|
138
|
+
maxChunkChars: options.maxChunkChars,
|
|
139
|
+
deduplicate: options.deduplicate
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
return envelope.data;
|
|
143
|
+
}
|
|
144
|
+
async consolidate(options = {}) {
|
|
145
|
+
const agentId = this.resolveAgentId(options.agentId);
|
|
146
|
+
const envelope = await this.request("/v1/consolidate", {
|
|
147
|
+
method: "POST",
|
|
148
|
+
agentId,
|
|
149
|
+
body: {
|
|
150
|
+
agentId,
|
|
151
|
+
dryRun: options.dryRun,
|
|
152
|
+
clusterStrategy: options.clusterStrategy
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
return envelope.data;
|
|
156
|
+
}
|
|
157
|
+
resolveAgentId(agentId) {
|
|
158
|
+
const resolved = agentId ?? this.agentId;
|
|
159
|
+
if (!resolved) {
|
|
160
|
+
throw new Error("agentId is required");
|
|
161
|
+
}
|
|
162
|
+
return resolved;
|
|
163
|
+
}
|
|
164
|
+
async request(path, options) {
|
|
165
|
+
const response = await this.fetchFn(`${this.apiUrl}${path}`, {
|
|
166
|
+
method: options.method,
|
|
167
|
+
headers: {
|
|
168
|
+
"content-type": "application/json",
|
|
169
|
+
"x-api-key": this.apiKey,
|
|
170
|
+
"x-agent-id": options.agentId
|
|
171
|
+
},
|
|
172
|
+
body: options.body === void 0 ? void 0 : JSON.stringify(options.body)
|
|
173
|
+
});
|
|
174
|
+
const payload = await readJson(response);
|
|
175
|
+
if (!response.ok) {
|
|
176
|
+
throw new OneMBrainError(
|
|
177
|
+
extractErrorMessage(payload, response.statusText),
|
|
178
|
+
response.status,
|
|
179
|
+
payload
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
return payload;
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
function deserializeMemory(memory) {
|
|
186
|
+
return {
|
|
187
|
+
...memory,
|
|
188
|
+
createdAt: new Date(memory.createdAt),
|
|
189
|
+
lastAccessedAt: new Date(memory.lastAccessedAt)
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function toSearchParams(input) {
|
|
193
|
+
const params = new URLSearchParams();
|
|
194
|
+
for (const [key, value] of Object.entries(input)) {
|
|
195
|
+
if (value === void 0 || value === null) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (Array.isArray(value)) {
|
|
199
|
+
params.set(key, value.join(","));
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
params.set(key, String(value));
|
|
203
|
+
}
|
|
204
|
+
return params;
|
|
205
|
+
}
|
|
206
|
+
async function readJson(response) {
|
|
207
|
+
const text = await response.text();
|
|
208
|
+
return text ? JSON.parse(text) : {};
|
|
209
|
+
}
|
|
210
|
+
function extractErrorMessage(payload, fallback) {
|
|
211
|
+
if (payload && typeof payload === "object" && "error" in payload) {
|
|
212
|
+
return String(payload.error);
|
|
213
|
+
}
|
|
214
|
+
if (payload && typeof payload === "object" && "message" in payload) {
|
|
215
|
+
return String(payload.message);
|
|
216
|
+
}
|
|
217
|
+
return fallback || "1MBrain request failed";
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// src/hermes.ts
|
|
221
|
+
var HermesMemoryAdapter = class {
|
|
222
|
+
client;
|
|
223
|
+
defaultImportance;
|
|
224
|
+
agentId;
|
|
225
|
+
constructor(config) {
|
|
226
|
+
this.client = new OneMBrainClient({
|
|
227
|
+
apiUrl: config.apiUrl,
|
|
228
|
+
apiKey: config.apiKey,
|
|
229
|
+
agentId: config.agentId,
|
|
230
|
+
fetch: config.fetch
|
|
231
|
+
});
|
|
232
|
+
this.defaultImportance = config.defaultImportance ?? 0.6;
|
|
233
|
+
this.agentId = config.agentId;
|
|
234
|
+
}
|
|
235
|
+
// ------------------------------------------------------------------
|
|
236
|
+
// Specialised remember helpers
|
|
237
|
+
// ------------------------------------------------------------------
|
|
238
|
+
/**
|
|
239
|
+
* Store a conversation turn as an episodic memory.
|
|
240
|
+
* The content is formatted as a Q&A pair for rich recall later.
|
|
241
|
+
*/
|
|
242
|
+
async rememberTurn(turn, agentId) {
|
|
243
|
+
const content = turn.assistantReply ? `User: ${turn.userMessage}
|
|
244
|
+
Hermes: ${turn.assistantReply}` : `User: ${turn.userMessage}`;
|
|
245
|
+
const tags = ["episodic", "conversation-turn", ...turn.topics ?? []];
|
|
246
|
+
if (turn.sessionId) tags.push(`session:${turn.sessionId}`);
|
|
247
|
+
return this.client.remember({
|
|
248
|
+
content,
|
|
249
|
+
type: "episodic",
|
|
250
|
+
importance: this.defaultImportance,
|
|
251
|
+
tags,
|
|
252
|
+
agentId
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Store a durable user preference as a semantic memory.
|
|
257
|
+
* Semantic memories don't decay as fast and are weighted higher on recall.
|
|
258
|
+
*/
|
|
259
|
+
async rememberPreference(key, value, agentId) {
|
|
260
|
+
return this.client.remember({
|
|
261
|
+
content: `User preference \u2014 ${key}: ${value}`,
|
|
262
|
+
type: "semantic",
|
|
263
|
+
importance: 0.85,
|
|
264
|
+
tags: ["semantic", "preference", `pref:${key}`],
|
|
265
|
+
agentId
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Store a learned behavioural pattern or workflow as a procedural memory.
|
|
270
|
+
* Procedural memories carry high importance by default.
|
|
271
|
+
*/
|
|
272
|
+
async rememberProcedure(name, pattern, agentId) {
|
|
273
|
+
return this.client.remember({
|
|
274
|
+
content: `Procedure \u2014 ${name}: ${pattern}`,
|
|
275
|
+
type: "procedural",
|
|
276
|
+
importance: 0.9,
|
|
277
|
+
tags: ["procedural", "workflow", `proc:${name}`],
|
|
278
|
+
agentId
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* General-purpose remember — uses sensible Hermes defaults.
|
|
283
|
+
* Delegates directly to the underlying SDK client.
|
|
284
|
+
*/
|
|
285
|
+
async remember(content, options = {}) {
|
|
286
|
+
return this.client.remember({
|
|
287
|
+
content,
|
|
288
|
+
type: options.type ?? "episodic",
|
|
289
|
+
importance: options.importance ?? this.defaultImportance,
|
|
290
|
+
tags: ["source:hermes", ...options.tags ?? []],
|
|
291
|
+
agentId: options.agentId
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
// ------------------------------------------------------------------
|
|
295
|
+
// Recall
|
|
296
|
+
// ------------------------------------------------------------------
|
|
297
|
+
/**
|
|
298
|
+
* Recall memories relevant to the given query.
|
|
299
|
+
* Automatically uses spreading activation (2 hops) for richer results.
|
|
300
|
+
*/
|
|
301
|
+
async recall(query, options = {}) {
|
|
302
|
+
return this.client.recall({
|
|
303
|
+
query,
|
|
304
|
+
limit: options.limit ?? 8,
|
|
305
|
+
type: options.type,
|
|
306
|
+
maxHops: options.maxHops ?? 2,
|
|
307
|
+
agentId: options.agentId
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Recall only episodic memories (conversation history).
|
|
312
|
+
*/
|
|
313
|
+
async recallHistory(query, limit = 5, agentId) {
|
|
314
|
+
return this.recall(query, { type: "episodic", limit, agentId });
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Recall only semantic memories (facts & preferences).
|
|
318
|
+
*/
|
|
319
|
+
async recallFacts(query, limit = 5, agentId) {
|
|
320
|
+
return this.recall(query, { type: "semantic", limit, agentId });
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Recall only procedural memories (learned workflows).
|
|
324
|
+
*/
|
|
325
|
+
async recallProcedures(query, limit = 5, agentId) {
|
|
326
|
+
return this.recall(query, { type: "procedural", limit, agentId });
|
|
327
|
+
}
|
|
328
|
+
// ------------------------------------------------------------------
|
|
329
|
+
// Forget
|
|
330
|
+
// ------------------------------------------------------------------
|
|
331
|
+
/** Hard-delete a memory by ID. */
|
|
332
|
+
async forget(memoryId, agentId) {
|
|
333
|
+
return this.client.forget(memoryId, { agentId });
|
|
334
|
+
}
|
|
335
|
+
// ------------------------------------------------------------------
|
|
336
|
+
// Associate
|
|
337
|
+
// ------------------------------------------------------------------
|
|
338
|
+
/** Create an explicit association between two memories. */
|
|
339
|
+
async associate(sourceId, targetId, strength = 0.5, agentId, relationType = "relates_to") {
|
|
340
|
+
return this.client.associate(sourceId, { targetId, strength, origin: "explicit", agentId, relationType });
|
|
341
|
+
}
|
|
342
|
+
// ------------------------------------------------------------------
|
|
343
|
+
// Context builder (for injecting memory into LLM prompts)
|
|
344
|
+
// ------------------------------------------------------------------
|
|
345
|
+
/**
|
|
346
|
+
* Build a formatted memory context block for injection into an LLM system prompt.
|
|
347
|
+
*
|
|
348
|
+
* Returns a markdown-formatted string listing the most relevant memories
|
|
349
|
+
* so Hermes can surface them to the model without manual formatting.
|
|
350
|
+
*
|
|
351
|
+
* @example
|
|
352
|
+
* const ctx = await memory.buildContext('user preferences');
|
|
353
|
+
* systemPrompt = `${baseSystemPrompt}\n\n${ctx}`;
|
|
354
|
+
*/
|
|
355
|
+
async buildContext(query, limit = 6, agentId) {
|
|
356
|
+
const results = await this.recall(query, { limit, agentId });
|
|
357
|
+
if (results.length === 0) return "";
|
|
358
|
+
if (results.confidence === "low") {
|
|
359
|
+
return "I don't have information about that in my memory.";
|
|
360
|
+
}
|
|
361
|
+
const lines = ["## Relevant Memories", ""];
|
|
362
|
+
for (const { memory, score } of results) {
|
|
363
|
+
const typeLabel = memory.type.charAt(0).toUpperCase() + memory.type.slice(1);
|
|
364
|
+
lines.push(`- [${typeLabel}] (relevance: ${score.toFixed(2)}) ${memory.content}`);
|
|
365
|
+
}
|
|
366
|
+
return lines.join("\n");
|
|
367
|
+
}
|
|
368
|
+
// ------------------------------------------------------------------
|
|
369
|
+
// Web Page Ingestion (Phase 6)
|
|
370
|
+
// ------------------------------------------------------------------
|
|
371
|
+
/**
|
|
372
|
+
* Ingest a web page URL and store its factual content as memories.
|
|
373
|
+
*
|
|
374
|
+
* The server-side pipeline automatically:
|
|
375
|
+
* 1. Fetches the URL
|
|
376
|
+
* 2. Converts HTML → Markdown (noise stripped)
|
|
377
|
+
* 3. Chunks the content
|
|
378
|
+
* 4. Extracts factual claims via LLM (using your configured provider)
|
|
379
|
+
* 5. Stores facts with type/importance/metadata auto-set
|
|
380
|
+
* 6. Deduplicates (won't re-ingest the same page content twice)
|
|
381
|
+
*
|
|
382
|
+
* Works from any gateway: Telegram, Discord, browser extension, CLI.
|
|
383
|
+
*
|
|
384
|
+
* @example
|
|
385
|
+
* // Telegram bot handler
|
|
386
|
+
* if (message.startsWith('/learn ')) {
|
|
387
|
+
* const url = message.slice(7).trim();
|
|
388
|
+
* const result = await memory.learnFromUrl(url);
|
|
389
|
+
* return `✅ Learned ${result.storedCount} facts from "${result.title}"`;
|
|
390
|
+
* }
|
|
391
|
+
*/
|
|
392
|
+
async learnFromUrl(url, options = {}) {
|
|
393
|
+
const agentId = options.agentId ?? this.agentId;
|
|
394
|
+
const result = await this.client.ingestUrl(url, {
|
|
395
|
+
agentId,
|
|
396
|
+
confidenceThreshold: options.confidenceThreshold,
|
|
397
|
+
maxChunkChars: options.maxChunkChars,
|
|
398
|
+
deduplicate: options.deduplicate
|
|
399
|
+
});
|
|
400
|
+
return {
|
|
401
|
+
ok: true,
|
|
402
|
+
title: result.title,
|
|
403
|
+
url: result.url,
|
|
404
|
+
storedCount: result.storedCount,
|
|
405
|
+
deduplicated: result.deduplicated,
|
|
406
|
+
memoryIds: result.memoryIds
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Recall memories that were ingested from a specific source domain or URL pattern.
|
|
411
|
+
*
|
|
412
|
+
* Uses the `domain:` tag automatically added during ingestion.
|
|
413
|
+
*
|
|
414
|
+
* @example
|
|
415
|
+
* const newsFromKompas = await memory.recallFromSource('kompas.com', 'AI regulation');
|
|
416
|
+
*/
|
|
417
|
+
async recallFromSource(domain, query, limit = 8, agentId) {
|
|
418
|
+
return this.recall(query, {
|
|
419
|
+
limit,
|
|
420
|
+
agentId,
|
|
421
|
+
tags: [`domain:${domain}`]
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
426
|
+
0 && (module.exports = {
|
|
427
|
+
HermesMemoryAdapter
|
|
428
|
+
});
|
|
429
|
+
//# sourceMappingURL=hermes.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hermes.ts","../src/index.ts"],"sourcesContent":["/**\n * @1mbrain/hermes-adapter\n *\n * NOTE: This is an optional convenience wrapper tailored specifically for the Hermes \n * agent framework. It serves as a reference/blueprint. For other frameworks or gateways, \n * use the generic `OneMBrainClient` directly from '@1mbrain/sdk'.\n *\n * Hermes context objects are automatically mapped to the correct 1MBrain memory type, \n * importance score, and metadata tags, so you never have to think about them in your \n * agent code.\n *\n * Quick start:\n *\n * ```ts\n * import { HermesMemoryAdapter } from '@1mbrain/sdk/hermes';\n *\n * const memory = new HermesMemoryAdapter({\n * apiUrl: process.env.ONEMILLION_API_URL!,\n * apiKey: process.env.ONEMILLION_API_KEY!,\n * agentId: 'hermes-agent-1', // your instance name/namespace\n * defaultImportance: 0.6,\n * });\n *\n * // Store an episodic memory from a conversation turn\n * await memory.rememberTurn({\n * userMessage: \"What is VibeAman pricing?\",\n * assistantReply: \"VibeAman starts at Rp 150k/month.\",\n * });\n *\n * // Store a persistent user preference\n * await memory.rememberPreference('preferred_language', 'Bahasa Indonesia');\n *\n * // Store a procedural pattern\n * await memory.rememberProcedure('push_to_github', 'Create PRD → push markdown deliverable');\n *\n * // Recall with automatic context enrichment\n * const results = await memory.recall('pricing');\n * ```\n */\n\nimport { OneMBrainClient } from './index.js';\nimport type { AssociateInput, Memory, SearchResult } from './index.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface HermesMemoryAdapterConfig {\n apiUrl: string;\n apiKey: string;\n agentId?: string;\n /** Default importance score for new memories (0–1). Defaults to 0.6. */\n defaultImportance?: number;\n /** Custom fetch implementation (useful in Cloudflare Workers / Edge). */\n fetch?: typeof fetch;\n}\n\nexport interface HermesTurn {\n /** The raw user message from the current conversation turn. */\n userMessage: string;\n /** The assistant reply that was generated for this turn. */\n assistantReply?: string;\n /** Optional topic tags to attach to this episodic memory. */\n topics?: string[];\n /** Optional conversation / session ID for grouping. */\n sessionId?: string;\n}\n\nexport interface HermesRecallOptions {\n /** Maximum number of results (default: 8). */\n limit?: number;\n /**\n * Restrict recall to a specific memory type.\n * When omitted, all types are searched.\n */\n type?: 'episodic' | 'semantic' | 'procedural' | 'entity' | 'warning';\n /** Filter by tags. */\n tags?: string[];\n /** Number of graph hops for spreading activation (default: 2). */\n maxHops?: number;\n /**\n * If provided, override the default agentId for this call.\n * Useful when querying another Hermes instance's memory.\n */\n agentId?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Adapter\n// ---------------------------------------------------------------------------\n\nexport class HermesMemoryAdapter {\n private readonly client: OneMBrainClient;\n private readonly defaultImportance: number;\n private readonly agentId?: string;\n\n constructor(config: HermesMemoryAdapterConfig) {\n this.client = new OneMBrainClient({\n apiUrl: config.apiUrl,\n apiKey: config.apiKey,\n agentId: config.agentId,\n fetch: config.fetch,\n });\n this.defaultImportance = config.defaultImportance ?? 0.6;\n this.agentId = config.agentId;\n }\n\n // ------------------------------------------------------------------\n // Specialised remember helpers\n // ------------------------------------------------------------------\n\n /**\n * Store a conversation turn as an episodic memory.\n * The content is formatted as a Q&A pair for rich recall later.\n */\n async rememberTurn(turn: HermesTurn, agentId?: string): Promise<Memory> {\n const content = turn.assistantReply\n ? `User: ${turn.userMessage}\\nHermes: ${turn.assistantReply}`\n : `User: ${turn.userMessage}`;\n\n const tags = ['episodic', 'conversation-turn', ...(turn.topics ?? [])];\n if (turn.sessionId) tags.push(`session:${turn.sessionId}`);\n\n return this.client.remember({\n content,\n type: 'episodic',\n importance: this.defaultImportance,\n tags,\n agentId,\n });\n }\n\n /**\n * Store a durable user preference as a semantic memory.\n * Semantic memories don't decay as fast and are weighted higher on recall.\n */\n async rememberPreference(key: string, value: string, agentId?: string): Promise<Memory> {\n return this.client.remember({\n content: `User preference — ${key}: ${value}`,\n type: 'semantic',\n importance: 0.85,\n tags: ['semantic', 'preference', `pref:${key}`],\n agentId,\n });\n }\n\n /**\n * Store a learned behavioural pattern or workflow as a procedural memory.\n * Procedural memories carry high importance by default.\n */\n async rememberProcedure(name: string, pattern: string, agentId?: string): Promise<Memory> {\n return this.client.remember({\n content: `Procedure — ${name}: ${pattern}`,\n type: 'procedural',\n importance: 0.9,\n tags: ['procedural', 'workflow', `proc:${name}`],\n agentId,\n });\n }\n\n /**\n * General-purpose remember — uses sensible Hermes defaults.\n * Delegates directly to the underlying SDK client.\n */\n async remember(\n content: string,\n options: {\n type?: 'episodic' | 'semantic' | 'procedural';\n importance?: number;\n tags?: string[];\n agentId?: string;\n } = {},\n ): Promise<Memory> {\n return this.client.remember({\n content,\n type: options.type ?? 'episodic',\n importance: options.importance ?? this.defaultImportance,\n tags: ['source:hermes', ...(options.tags ?? [])],\n agentId: options.agentId,\n });\n }\n\n // ------------------------------------------------------------------\n // Recall\n // ------------------------------------------------------------------\n\n /**\n * Recall memories relevant to the given query.\n * Automatically uses spreading activation (2 hops) for richer results.\n */\n async recall(query: string, options: HermesRecallOptions = {}): Promise<SearchResult[]> {\n return this.client.recall({\n query,\n limit: options.limit ?? 8,\n type: options.type,\n maxHops: options.maxHops ?? 2,\n agentId: options.agentId,\n });\n }\n\n /**\n * Recall only episodic memories (conversation history).\n */\n async recallHistory(query: string, limit = 5, agentId?: string): Promise<SearchResult[]> {\n return this.recall(query, { type: 'episodic', limit, agentId });\n }\n\n /**\n * Recall only semantic memories (facts & preferences).\n */\n async recallFacts(query: string, limit = 5, agentId?: string): Promise<SearchResult[]> {\n return this.recall(query, { type: 'semantic', limit, agentId });\n }\n\n /**\n * Recall only procedural memories (learned workflows).\n */\n async recallProcedures(query: string, limit = 5, agentId?: string): Promise<SearchResult[]> {\n return this.recall(query, { type: 'procedural', limit, agentId });\n }\n\n // ------------------------------------------------------------------\n // Forget\n // ------------------------------------------------------------------\n\n /** Hard-delete a memory by ID. */\n async forget(memoryId: string, agentId?: string): Promise<boolean> {\n return this.client.forget(memoryId, { agentId });\n }\n\n // ------------------------------------------------------------------\n // Associate\n // ------------------------------------------------------------------\n\n /** Create an explicit association between two memories. */\n async associate(\n sourceId: string,\n targetId: string,\n strength = 0.5,\n agentId?: string,\n relationType: AssociateInput['relationType'] = 'relates_to',\n ): Promise<boolean> {\n return this.client.associate(sourceId, { targetId, strength, origin: 'explicit', agentId, relationType });\n }\n\n // ------------------------------------------------------------------\n // Context builder (for injecting memory into LLM prompts)\n // ------------------------------------------------------------------\n\n /**\n * Build a formatted memory context block for injection into an LLM system prompt.\n *\n * Returns a markdown-formatted string listing the most relevant memories\n * so Hermes can surface them to the model without manual formatting.\n *\n * @example\n * const ctx = await memory.buildContext('user preferences');\n * systemPrompt = `${baseSystemPrompt}\\n\\n${ctx}`;\n */\n async buildContext(query: string, limit = 6, agentId?: string): Promise<string> {\n const results = await this.recall(query, { limit, agentId });\n if (results.length === 0) return '';\n \n // R5.2 Explicit \"No Evidence\" Signal\n if ((results as any).confidence === 'low') {\n return \"I don't have information about that in my memory.\";\n }\n\n const lines: string[] = ['## Relevant Memories', ''];\n for (const { memory, score } of results) {\n const typeLabel = memory.type.charAt(0).toUpperCase() + memory.type.slice(1);\n lines.push(`- [${typeLabel}] (relevance: ${score.toFixed(2)}) ${memory.content}`);\n }\n\n return lines.join('\\n');\n }\n\n // ------------------------------------------------------------------\n // Web Page Ingestion (Phase 6)\n // ------------------------------------------------------------------\n\n\n /**\n * Ingest a web page URL and store its factual content as memories.\n *\n * The server-side pipeline automatically:\n * 1. Fetches the URL\n * 2. Converts HTML → Markdown (noise stripped)\n * 3. Chunks the content\n * 4. Extracts factual claims via LLM (using your configured provider)\n * 5. Stores facts with type/importance/metadata auto-set\n * 6. Deduplicates (won't re-ingest the same page content twice)\n *\n * Works from any gateway: Telegram, Discord, browser extension, CLI.\n *\n * @example\n * // Telegram bot handler\n * if (message.startsWith('/learn ')) {\n * const url = message.slice(7).trim();\n * const result = await memory.learnFromUrl(url);\n * return `✅ Learned ${result.storedCount} facts from \"${result.title}\"`;\n * }\n */\n async learnFromUrl(\n url: string,\n options: {\n agentId?: string;\n confidenceThreshold?: number;\n maxChunkChars?: number;\n deduplicate?: boolean;\n } = {},\n ): Promise<{\n ok: boolean;\n title: string;\n url: string;\n storedCount: number;\n deduplicated: boolean;\n memoryIds: string[];\n error?: string;\n }> {\n const agentId = options.agentId ?? this.agentId;\n const result = await this.client.ingestUrl(url, {\n agentId,\n confidenceThreshold: options.confidenceThreshold,\n maxChunkChars: options.maxChunkChars,\n deduplicate: options.deduplicate,\n });\n\n return {\n ok: true,\n title: result.title,\n url: result.url,\n storedCount: result.storedCount,\n deduplicated: result.deduplicated,\n memoryIds: result.memoryIds,\n };\n }\n\n /**\n * Recall memories that were ingested from a specific source domain or URL pattern.\n *\n * Uses the `domain:` tag automatically added during ingestion.\n *\n * @example\n * const newsFromKompas = await memory.recallFromSource('kompas.com', 'AI regulation');\n */\n async recallFromSource(\n domain: string,\n query: string,\n limit = 8,\n agentId?: string,\n ): Promise<SearchResult[]> {\n return this.recall(query, {\n limit,\n agentId,\n tags: [`domain:${domain}`],\n });\n }\n}\n","import type {\n CreateAssociationInput,\n CreateMemoryInput,\n Memory,\n SearchMemoryInput,\n SearchResult,\n} from '@1mbrain/core';\n\nexport interface OneMBrainClientConfig {\n apiUrl: string;\n apiKey: string;\n agentId?: string;\n fetch?: typeof fetch;\n}\n\nexport type RememberInput = Omit<CreateMemoryInput, 'agentId'> & {\n agentId?: string;\n};\n\nexport type RecallInput = Omit<SearchMemoryInput, 'agentId'> & {\n agentId?: string;\n};\n\nexport type AssociateInput = Omit<CreateAssociationInput, 'sourceId' | 'agentId'> & {\n agentId?: string;\n};\n\nexport interface IngestUrlOptions {\n agentId?: string;\n confidenceThreshold?: number;\n maxChunkChars?: number;\n deduplicate?: boolean;\n}\n\nexport interface IngestResult {\n title: string;\n url: string;\n sourceHash: string;\n chunkCount: number;\n extractedCount: number;\n storedCount: number;\n skippedCount: number;\n errorCount: number;\n deduplicated: boolean;\n memoryIds: string[];\n}\n\nexport interface ConsolidateOptions {\n agentId?: string;\n dryRun?: boolean;\n clusterStrategy?: 'tags' | 'graph' | 'hybrid';\n}\n\nexport interface ConsolidationResult {\n agentId: string;\n triggerReason: 'sleep-cycle' | 'threshold';\n dryRun: boolean;\n storedCount: number;\n archivedCount: number;\n clustersProcessed: number;\n skipped: {\n noCandidates: number;\n tooSmallClusters: number;\n summarizationFailed: number;\n dryRun: number;\n };\n errors: string[];\n summaryIds: string[];\n}\n\nexport interface ApiEnvelope<T> {\n success: boolean;\n data: T;\n meta?: Record<string, unknown>;\n message?: string;\n}\n\nexport class OneMBrainError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly details?: unknown,\n ) {\n super(message);\n this.name = 'OneMBrainError';\n }\n}\n\nexport class OneMBrainClient {\n private readonly apiUrl: string;\n private readonly apiKey: string;\n private readonly agentId?: string;\n private readonly fetchFn: typeof fetch;\n\n constructor(config: OneMBrainClientConfig) {\n if (!config.apiUrl) {\n throw new Error('apiUrl is required');\n }\n\n if (!config.apiKey) {\n throw new Error('apiKey is required');\n }\n\n this.apiUrl = config.apiUrl.replace(/\\/+$/, '');\n this.apiKey = config.apiKey;\n this.agentId = config.agentId;\n this.fetchFn = config.fetch ?? fetch;\n }\n\n async remember(input: RememberInput): Promise<Memory> {\n const agentId = this.resolveAgentId(input.agentId);\n const envelope = await this.request<ApiEnvelope<SerializedMemory>>('/v1/memories', {\n method: 'POST',\n agentId,\n body: {\n ...input,\n agentId,\n },\n });\n\n return deserializeMemory(envelope.data);\n }\n\n async recall(input: RecallInput): Promise<SearchResult[]> {\n const agentId = this.resolveAgentId(input.agentId);\n const params = toSearchParams({\n ...input,\n agentId,\n q: input.query,\n query: undefined,\n });\n const envelope = await this.request<ApiEnvelope<SerializedSearchResult[]>>(\n `/v1/memories/search?${params.toString()}`,\n {\n method: 'GET',\n agentId,\n },\n );\n\n const results = envelope.data.map((result) => ({\n ...result,\n memory: deserializeMemory(result.memory),\n })) as SearchResult[] & { confidence?: string; reason?: string };\n\n if (envelope.meta) {\n results.confidence = envelope.meta.confidence as string | undefined;\n results.reason = envelope.meta.reason as string | undefined;\n }\n\n return results;\n }\n\n async forget(id: string, options: { agentId?: string } = {}): Promise<boolean> {\n const envelope = await this.request<ApiEnvelope<unknown>>(`/v1/memories/${id}`, {\n method: 'DELETE',\n agentId: this.resolveAgentId(options.agentId),\n });\n\n return envelope.success;\n }\n\n async associate(sourceId: string, input: AssociateInput): Promise<boolean> {\n const envelope = await this.request<ApiEnvelope<unknown>>(\n `/v1/memories/${sourceId}/associate`,\n {\n method: 'POST',\n agentId: this.resolveAgentId(input.agentId),\n body: {\n targetId: input.targetId,\n strength: input.strength,\n origin: input.origin,\n relationType: input.relationType,\n },\n },\n );\n\n return envelope.success;\n }\n\n /**\n * Ingest a web page URL into memory.\n *\n * The server-side pipeline will:\n * 1. Fetch the page HTML\n * 2. Extract main content → Markdown\n * 3. Chunk and extract factual claims via LLM\n * 4. Store facts as memories (type, importance, metadata auto-set)\n *\n * Works from any gateway: Telegram, Discord, browser extension, CLI.\n *\n * @param url - The URL to ingest\n * @param options - Optional overrides (agentId, confidenceThreshold, etc.)\n */\n async ingestUrl(url: string, options: IngestUrlOptions = {}): Promise<IngestResult> {\n const agentId = this.resolveAgentId(options.agentId);\n const envelope = await this.request<ApiEnvelope<IngestResult>>('/v1/ingest/url', {\n method: 'POST',\n agentId,\n body: {\n url,\n agentId,\n confidenceThreshold: options.confidenceThreshold,\n maxChunkChars: options.maxChunkChars,\n deduplicate: options.deduplicate,\n },\n });\n\n return envelope.data;\n }\n\n async consolidate(options: ConsolidateOptions = {}): Promise<ConsolidationResult> {\n const agentId = this.resolveAgentId(options.agentId);\n const envelope = await this.request<ApiEnvelope<ConsolidationResult>>('/v1/consolidate', {\n method: 'POST',\n agentId,\n body: {\n agentId,\n dryRun: options.dryRun,\n clusterStrategy: options.clusterStrategy,\n },\n });\n\n return envelope.data;\n }\n\n private resolveAgentId(agentId?: string): string {\n const resolved = agentId ?? this.agentId;\n\n if (!resolved) {\n throw new Error('agentId is required');\n }\n\n return resolved;\n }\n\n private async request<T>(\n path: string,\n options: {\n method: 'GET' | 'POST' | 'DELETE';\n agentId: string;\n body?: unknown;\n },\n ): Promise<T> {\n const response = await this.fetchFn(`${this.apiUrl}${path}`, {\n method: options.method,\n headers: {\n 'content-type': 'application/json',\n 'x-api-key': this.apiKey,\n 'x-agent-id': options.agentId,\n },\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n });\n\n const payload = await readJson(response);\n\n if (!response.ok) {\n throw new OneMBrainError(\n extractErrorMessage(payload, response.statusText),\n response.status,\n payload,\n );\n }\n\n return payload as T;\n }\n}\n\ntype SerializedMemory = Omit<Memory, 'createdAt' | 'lastAccessedAt'> & {\n createdAt: string;\n lastAccessedAt: string;\n};\n\ntype SerializedSearchResult = Omit<SearchResult, 'memory'> & {\n memory: SerializedMemory;\n};\n\nfunction deserializeMemory(memory: SerializedMemory): Memory {\n return {\n ...memory,\n createdAt: new Date(memory.createdAt),\n lastAccessedAt: new Date(memory.lastAccessedAt),\n };\n}\n\nfunction toSearchParams(input: Record<string, unknown>): URLSearchParams {\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(input)) {\n if (value === undefined || value === null) {\n continue;\n }\n\n if (Array.isArray(value)) {\n params.set(key, value.join(','));\n continue;\n }\n\n params.set(key, String(value));\n }\n\n return params;\n}\n\nasync function readJson(response: Response): Promise<unknown> {\n const text = await response.text();\n return text ? JSON.parse(text) : {};\n}\n\nfunction extractErrorMessage(payload: unknown, fallback: string): string {\n if (payload && typeof payload === 'object' && 'error' in payload) {\n return String((payload as { error: unknown }).error);\n }\n\n if (payload && typeof payload === 'object' && 'message' in payload) {\n return String((payload as { message: unknown }).message);\n }\n\n return fallback || '1MBrain request failed';\n}\n\nexport type { Memory, SearchResult };\nexport { AGENT_SYSTEM_PROMPT } from './prompts.js';\n"],"mappings":"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","names":[]}
|