@1mbrain/sdk 0.1.0 → 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 +15 -0
- 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 -176
- 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 -99
- package/dist/index.d.ts.map +0 -1
package/dist/hermes.js
CHANGED
|
@@ -1,248 +1,213 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
client
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
1
|
+
import {
|
|
2
|
+
OneMBrainClient
|
|
3
|
+
} from "./chunk-TLPCKSTS.js";
|
|
4
|
+
|
|
5
|
+
// src/hermes.ts
|
|
6
|
+
var HermesMemoryAdapter = class {
|
|
7
|
+
client;
|
|
8
|
+
defaultImportance;
|
|
9
|
+
agentId;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.client = new OneMBrainClient({
|
|
12
|
+
apiUrl: config.apiUrl,
|
|
13
|
+
apiKey: config.apiKey,
|
|
14
|
+
agentId: config.agentId,
|
|
15
|
+
fetch: config.fetch
|
|
16
|
+
});
|
|
17
|
+
this.defaultImportance = config.defaultImportance ?? 0.6;
|
|
18
|
+
this.agentId = config.agentId;
|
|
19
|
+
}
|
|
20
|
+
// ------------------------------------------------------------------
|
|
21
|
+
// Specialised remember helpers
|
|
22
|
+
// ------------------------------------------------------------------
|
|
23
|
+
/**
|
|
24
|
+
* Store a conversation turn as an episodic memory.
|
|
25
|
+
* The content is formatted as a Q&A pair for rich recall later.
|
|
26
|
+
*/
|
|
27
|
+
async rememberTurn(turn, agentId) {
|
|
28
|
+
const content = turn.assistantReply ? `User: ${turn.userMessage}
|
|
29
|
+
Hermes: ${turn.assistantReply}` : `User: ${turn.userMessage}`;
|
|
30
|
+
const tags = ["episodic", "conversation-turn", ...turn.topics ?? []];
|
|
31
|
+
if (turn.sessionId) tags.push(`session:${turn.sessionId}`);
|
|
32
|
+
return this.client.remember({
|
|
33
|
+
content,
|
|
34
|
+
type: "episodic",
|
|
35
|
+
importance: this.defaultImportance,
|
|
36
|
+
tags,
|
|
37
|
+
agentId
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Store a durable user preference as a semantic memory.
|
|
42
|
+
* Semantic memories don't decay as fast and are weighted higher on recall.
|
|
43
|
+
*/
|
|
44
|
+
async rememberPreference(key, value, agentId) {
|
|
45
|
+
return this.client.remember({
|
|
46
|
+
content: `User preference \u2014 ${key}: ${value}`,
|
|
47
|
+
type: "semantic",
|
|
48
|
+
importance: 0.85,
|
|
49
|
+
tags: ["semantic", "preference", `pref:${key}`],
|
|
50
|
+
agentId
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Store a learned behavioural pattern or workflow as a procedural memory.
|
|
55
|
+
* Procedural memories carry high importance by default.
|
|
56
|
+
*/
|
|
57
|
+
async rememberProcedure(name, pattern, agentId) {
|
|
58
|
+
return this.client.remember({
|
|
59
|
+
content: `Procedure \u2014 ${name}: ${pattern}`,
|
|
60
|
+
type: "procedural",
|
|
61
|
+
importance: 0.9,
|
|
62
|
+
tags: ["procedural", "workflow", `proc:${name}`],
|
|
63
|
+
agentId
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* General-purpose remember — uses sensible Hermes defaults.
|
|
68
|
+
* Delegates directly to the underlying SDK client.
|
|
69
|
+
*/
|
|
70
|
+
async remember(content, options = {}) {
|
|
71
|
+
return this.client.remember({
|
|
72
|
+
content,
|
|
73
|
+
type: options.type ?? "episodic",
|
|
74
|
+
importance: options.importance ?? this.defaultImportance,
|
|
75
|
+
tags: ["source:hermes", ...options.tags ?? []],
|
|
76
|
+
agentId: options.agentId
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// ------------------------------------------------------------------
|
|
80
|
+
// Recall
|
|
81
|
+
// ------------------------------------------------------------------
|
|
82
|
+
/**
|
|
83
|
+
* Recall memories relevant to the given query.
|
|
84
|
+
* Automatically uses spreading activation (2 hops) for richer results.
|
|
85
|
+
*/
|
|
86
|
+
async recall(query, options = {}) {
|
|
87
|
+
return this.client.recall({
|
|
88
|
+
query,
|
|
89
|
+
limit: options.limit ?? 8,
|
|
90
|
+
type: options.type,
|
|
91
|
+
maxHops: options.maxHops ?? 2,
|
|
92
|
+
agentId: options.agentId
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Recall only episodic memories (conversation history).
|
|
97
|
+
*/
|
|
98
|
+
async recallHistory(query, limit = 5, agentId) {
|
|
99
|
+
return this.recall(query, { type: "episodic", limit, agentId });
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Recall only semantic memories (facts & preferences).
|
|
103
|
+
*/
|
|
104
|
+
async recallFacts(query, limit = 5, agentId) {
|
|
105
|
+
return this.recall(query, { type: "semantic", limit, agentId });
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Recall only procedural memories (learned workflows).
|
|
109
|
+
*/
|
|
110
|
+
async recallProcedures(query, limit = 5, agentId) {
|
|
111
|
+
return this.recall(query, { type: "procedural", limit, agentId });
|
|
112
|
+
}
|
|
113
|
+
// ------------------------------------------------------------------
|
|
114
|
+
// Forget
|
|
115
|
+
// ------------------------------------------------------------------
|
|
116
|
+
/** Hard-delete a memory by ID. */
|
|
117
|
+
async forget(memoryId, agentId) {
|
|
118
|
+
return this.client.forget(memoryId, { agentId });
|
|
119
|
+
}
|
|
120
|
+
// ------------------------------------------------------------------
|
|
121
|
+
// Associate
|
|
122
|
+
// ------------------------------------------------------------------
|
|
123
|
+
/** Create an explicit association between two memories. */
|
|
124
|
+
async associate(sourceId, targetId, strength = 0.5, agentId, relationType = "relates_to") {
|
|
125
|
+
return this.client.associate(sourceId, { targetId, strength, origin: "explicit", agentId, relationType });
|
|
126
|
+
}
|
|
127
|
+
// ------------------------------------------------------------------
|
|
128
|
+
// Context builder (for injecting memory into LLM prompts)
|
|
129
|
+
// ------------------------------------------------------------------
|
|
130
|
+
/**
|
|
131
|
+
* Build a formatted memory context block for injection into an LLM system prompt.
|
|
132
|
+
*
|
|
133
|
+
* Returns a markdown-formatted string listing the most relevant memories
|
|
134
|
+
* so Hermes can surface them to the model without manual formatting.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* const ctx = await memory.buildContext('user preferences');
|
|
138
|
+
* systemPrompt = `${baseSystemPrompt}\n\n${ctx}`;
|
|
139
|
+
*/
|
|
140
|
+
async buildContext(query, limit = 6, agentId) {
|
|
141
|
+
const results = await this.recall(query, { limit, agentId });
|
|
142
|
+
if (results.length === 0) return "";
|
|
143
|
+
if (results.confidence === "low") {
|
|
144
|
+
return "I don't have information about that in my memory.";
|
|
57
145
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
* Store a conversation turn as an episodic memory.
|
|
63
|
-
* The content is formatted as a Q&A pair for rich recall later.
|
|
64
|
-
*/
|
|
65
|
-
async rememberTurn(turn, agentId) {
|
|
66
|
-
const content = turn.assistantReply
|
|
67
|
-
? `User: ${turn.userMessage}\nHermes: ${turn.assistantReply}`
|
|
68
|
-
: `User: ${turn.userMessage}`;
|
|
69
|
-
const tags = ['episodic', 'conversation-turn', ...(turn.topics ?? [])];
|
|
70
|
-
if (turn.sessionId)
|
|
71
|
-
tags.push(`session:${turn.sessionId}`);
|
|
72
|
-
return this.client.remember({
|
|
73
|
-
content,
|
|
74
|
-
type: 'episodic',
|
|
75
|
-
importance: this.defaultImportance,
|
|
76
|
-
tags,
|
|
77
|
-
agentId,
|
|
78
|
-
});
|
|
146
|
+
const lines = ["## Relevant Memories", ""];
|
|
147
|
+
for (const { memory, score } of results) {
|
|
148
|
+
const typeLabel = memory.type.charAt(0).toUpperCase() + memory.type.slice(1);
|
|
149
|
+
lines.push(`- [${typeLabel}] (relevance: ${score.toFixed(2)}) ${memory.content}`);
|
|
79
150
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
* Recall only semantic memories (facts & preferences).
|
|
143
|
-
*/
|
|
144
|
-
async recallFacts(query, limit = 5, agentId) {
|
|
145
|
-
return this.recall(query, { type: 'semantic', limit, agentId });
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Recall only procedural memories (learned workflows).
|
|
149
|
-
*/
|
|
150
|
-
async recallProcedures(query, limit = 5, agentId) {
|
|
151
|
-
return this.recall(query, { type: 'procedural', limit, agentId });
|
|
152
|
-
}
|
|
153
|
-
// ------------------------------------------------------------------
|
|
154
|
-
// Forget
|
|
155
|
-
// ------------------------------------------------------------------
|
|
156
|
-
/** Hard-delete a memory by ID. */
|
|
157
|
-
async forget(memoryId, agentId) {
|
|
158
|
-
return this.client.forget(memoryId, { agentId });
|
|
159
|
-
}
|
|
160
|
-
// ------------------------------------------------------------------
|
|
161
|
-
// Associate
|
|
162
|
-
// ------------------------------------------------------------------
|
|
163
|
-
/** Create an explicit association between two memories. */
|
|
164
|
-
async associate(sourceId, targetId, strength = 0.5, agentId, relationType = 'relates_to') {
|
|
165
|
-
return this.client.associate(sourceId, { targetId, strength, origin: 'explicit', agentId, relationType });
|
|
166
|
-
}
|
|
167
|
-
// ------------------------------------------------------------------
|
|
168
|
-
// Context builder (for injecting memory into LLM prompts)
|
|
169
|
-
// ------------------------------------------------------------------
|
|
170
|
-
/**
|
|
171
|
-
* Build a formatted memory context block for injection into an LLM system prompt.
|
|
172
|
-
*
|
|
173
|
-
* Returns a markdown-formatted string listing the most relevant memories
|
|
174
|
-
* so Hermes can surface them to the model without manual formatting.
|
|
175
|
-
*
|
|
176
|
-
* @example
|
|
177
|
-
* const ctx = await memory.buildContext('user preferences');
|
|
178
|
-
* systemPrompt = `${baseSystemPrompt}\n\n${ctx}`;
|
|
179
|
-
*/
|
|
180
|
-
async buildContext(query, limit = 6, agentId) {
|
|
181
|
-
const results = await this.recall(query, { limit, agentId });
|
|
182
|
-
if (results.length === 0)
|
|
183
|
-
return '';
|
|
184
|
-
const lines = ['## Relevant Memories', ''];
|
|
185
|
-
for (const { memory, score } of results) {
|
|
186
|
-
const typeLabel = memory.type.charAt(0).toUpperCase() + memory.type.slice(1);
|
|
187
|
-
lines.push(`- [${typeLabel}] (relevance: ${score.toFixed(2)}) ${memory.content}`);
|
|
188
|
-
}
|
|
189
|
-
return lines.join('\n');
|
|
190
|
-
}
|
|
191
|
-
// ------------------------------------------------------------------
|
|
192
|
-
// Web Page Ingestion (Phase 6)
|
|
193
|
-
// ------------------------------------------------------------------
|
|
194
|
-
/**
|
|
195
|
-
* Ingest a web page URL and store its factual content as memories.
|
|
196
|
-
*
|
|
197
|
-
* The server-side pipeline automatically:
|
|
198
|
-
* 1. Fetches the URL
|
|
199
|
-
* 2. Converts HTML → Markdown (noise stripped)
|
|
200
|
-
* 3. Chunks the content
|
|
201
|
-
* 4. Extracts factual claims via LLM (using your configured provider)
|
|
202
|
-
* 5. Stores facts with type/importance/metadata auto-set
|
|
203
|
-
* 6. Deduplicates (won't re-ingest the same page content twice)
|
|
204
|
-
*
|
|
205
|
-
* Works from any gateway: Telegram, Discord, browser extension, CLI.
|
|
206
|
-
*
|
|
207
|
-
* @example
|
|
208
|
-
* // Telegram bot handler
|
|
209
|
-
* if (message.startsWith('/learn ')) {
|
|
210
|
-
* const url = message.slice(7).trim();
|
|
211
|
-
* const result = await memory.learnFromUrl(url);
|
|
212
|
-
* return `✅ Learned ${result.storedCount} facts from "${result.title}"`;
|
|
213
|
-
* }
|
|
214
|
-
*/
|
|
215
|
-
async learnFromUrl(url, options = {}) {
|
|
216
|
-
const agentId = options.agentId ?? this.agentId;
|
|
217
|
-
const result = await this.client.ingestUrl(url, {
|
|
218
|
-
agentId,
|
|
219
|
-
confidenceThreshold: options.confidenceThreshold,
|
|
220
|
-
maxChunkChars: options.maxChunkChars,
|
|
221
|
-
deduplicate: options.deduplicate,
|
|
222
|
-
});
|
|
223
|
-
return {
|
|
224
|
-
ok: true,
|
|
225
|
-
title: result.title,
|
|
226
|
-
url: result.url,
|
|
227
|
-
storedCount: result.storedCount,
|
|
228
|
-
deduplicated: result.deduplicated,
|
|
229
|
-
memoryIds: result.memoryIds,
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Recall memories that were ingested from a specific source domain or URL pattern.
|
|
234
|
-
*
|
|
235
|
-
* Uses the `domain:` tag automatically added during ingestion.
|
|
236
|
-
*
|
|
237
|
-
* @example
|
|
238
|
-
* const newsFromKompas = await memory.recallFromSource('kompas.com', 'AI regulation');
|
|
239
|
-
*/
|
|
240
|
-
async recallFromSource(domain, query, limit = 8, agentId) {
|
|
241
|
-
return this.recall(query, {
|
|
242
|
-
limit,
|
|
243
|
-
agentId,
|
|
244
|
-
tags: [`domain:${domain}`],
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
}
|
|
151
|
+
return lines.join("\n");
|
|
152
|
+
}
|
|
153
|
+
// ------------------------------------------------------------------
|
|
154
|
+
// Web Page Ingestion (Phase 6)
|
|
155
|
+
// ------------------------------------------------------------------
|
|
156
|
+
/**
|
|
157
|
+
* Ingest a web page URL and store its factual content as memories.
|
|
158
|
+
*
|
|
159
|
+
* The server-side pipeline automatically:
|
|
160
|
+
* 1. Fetches the URL
|
|
161
|
+
* 2. Converts HTML → Markdown (noise stripped)
|
|
162
|
+
* 3. Chunks the content
|
|
163
|
+
* 4. Extracts factual claims via LLM (using your configured provider)
|
|
164
|
+
* 5. Stores facts with type/importance/metadata auto-set
|
|
165
|
+
* 6. Deduplicates (won't re-ingest the same page content twice)
|
|
166
|
+
*
|
|
167
|
+
* Works from any gateway: Telegram, Discord, browser extension, CLI.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* // Telegram bot handler
|
|
171
|
+
* if (message.startsWith('/learn ')) {
|
|
172
|
+
* const url = message.slice(7).trim();
|
|
173
|
+
* const result = await memory.learnFromUrl(url);
|
|
174
|
+
* return `✅ Learned ${result.storedCount} facts from "${result.title}"`;
|
|
175
|
+
* }
|
|
176
|
+
*/
|
|
177
|
+
async learnFromUrl(url, options = {}) {
|
|
178
|
+
const agentId = options.agentId ?? this.agentId;
|
|
179
|
+
const result = await this.client.ingestUrl(url, {
|
|
180
|
+
agentId,
|
|
181
|
+
confidenceThreshold: options.confidenceThreshold,
|
|
182
|
+
maxChunkChars: options.maxChunkChars,
|
|
183
|
+
deduplicate: options.deduplicate
|
|
184
|
+
});
|
|
185
|
+
return {
|
|
186
|
+
ok: true,
|
|
187
|
+
title: result.title,
|
|
188
|
+
url: result.url,
|
|
189
|
+
storedCount: result.storedCount,
|
|
190
|
+
deduplicated: result.deduplicated,
|
|
191
|
+
memoryIds: result.memoryIds
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Recall memories that were ingested from a specific source domain or URL pattern.
|
|
196
|
+
*
|
|
197
|
+
* Uses the `domain:` tag automatically added during ingestion.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* const newsFromKompas = await memory.recallFromSource('kompas.com', 'AI regulation');
|
|
201
|
+
*/
|
|
202
|
+
async recallFromSource(domain, query, limit = 8, agentId) {
|
|
203
|
+
return this.recall(query, {
|
|
204
|
+
limit,
|
|
205
|
+
agentId,
|
|
206
|
+
tags: [`domain:${domain}`]
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
export {
|
|
211
|
+
HermesMemoryAdapter
|
|
212
|
+
};
|
|
248
213
|
//# sourceMappingURL=hermes.js.map
|
package/dist/hermes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hermes.js","sourceRoot":"","sources":["../src/hermes.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/hermes.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"],"mappings":"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","names":[]}
|