@tangle-network/agent-knowledge 3.2.1 → 4.0.1
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/CHANGELOG.md +49 -0
- package/README.md +306 -40
- package/dist/benchmarks/index.d.ts +51 -4
- package/dist/benchmarks/index.js +1 -4
- package/dist/chunk-3CAAGJCE.js +4784 -0
- package/dist/chunk-3CAAGJCE.js.map +1 -0
- package/dist/chunk-BBCIB4UL.js +3321 -0
- package/dist/chunk-BBCIB4UL.js.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +44 -8
- package/dist/index.js.map +1 -1
- package/dist/memory/index.d.ts +618 -5
- package/dist/memory/index.js +44 -3
- package/dist/types-ZzY_x0r7.d.ts +661 -0
- package/package.json +7 -5
- package/dist/chunk-RIHIYCX2.js +0 -1853
- package/dist/chunk-RIHIYCX2.js.map +0 -1
- package/dist/chunk-VN2OGUUP.js +0 -851
- package/dist/chunk-VN2OGUUP.js.map +0 -1
- package/dist/chunk-XVU5FFQA.js +0 -49
- package/dist/chunk-XVU5FFQA.js.map +0 -1
- package/dist/index-BHQk7jOT.d.ts +0 -429
- package/dist/types-BFRyr390.d.ts +0 -319
package/dist/chunk-VN2OGUUP.js
DELETED
|
@@ -1,851 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
memoryHitToSourceRecord,
|
|
3
|
-
memoryWriteResultToSourceRecord
|
|
4
|
-
} from "./chunk-XVU5FFQA.js";
|
|
5
|
-
import {
|
|
6
|
-
sha256,
|
|
7
|
-
stableId
|
|
8
|
-
} from "./chunk-YMKHCTS2.js";
|
|
9
|
-
|
|
10
|
-
// src/memory/holdout.ts
|
|
11
|
-
import { randomUUID } from "crypto";
|
|
12
|
-
import { mulberry32 } from "@tangle-network/agent-eval";
|
|
13
|
-
function deterministicRng(key) {
|
|
14
|
-
return mulberry32(Number.parseInt(sha256(key).slice(0, 8), 16))();
|
|
15
|
-
}
|
|
16
|
-
function canonicalJson(value) {
|
|
17
|
-
if (typeof value === "bigint") {
|
|
18
|
-
throw new TypeError("canonicalJson: bigint values are not supported in holdout hashing");
|
|
19
|
-
}
|
|
20
|
-
if (value === void 0) return "null";
|
|
21
|
-
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
22
|
-
if (value !== null && typeof value === "object") {
|
|
23
|
-
const entries = Object.entries(value).filter(([, v]) => v !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`);
|
|
24
|
-
return `{${entries.join(",")}}`;
|
|
25
|
-
}
|
|
26
|
-
return JSON.stringify(value);
|
|
27
|
-
}
|
|
28
|
-
function retrievalHoldoutConfigHash(config) {
|
|
29
|
-
return sha256(
|
|
30
|
-
canonicalJson({ epsilon: config.epsilon, watchlist: [...config.watchlist ?? []].sort() })
|
|
31
|
-
).slice(0, 16);
|
|
32
|
-
}
|
|
33
|
-
function assertValidHoldoutConfig(config) {
|
|
34
|
-
const { epsilon, watchlist } = config;
|
|
35
|
-
if (typeof epsilon !== "number" || !Number.isFinite(epsilon) || epsilon < 0 || epsilon > 1) {
|
|
36
|
-
throw new Error(`retrieval holdout epsilon must be a number in [0, 1], got ${String(epsilon)}`);
|
|
37
|
-
}
|
|
38
|
-
if (watchlist !== void 0 && (!Array.isArray(watchlist) || watchlist.some((id) => typeof id !== "string"))) {
|
|
39
|
-
throw new Error("retrieval holdout watchlist must be an array of item-id strings");
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
function safeEmit(config, event) {
|
|
43
|
-
try {
|
|
44
|
-
config.onEvent(event);
|
|
45
|
-
} catch (error) {
|
|
46
|
-
console.error(
|
|
47
|
-
"[agent-knowledge] retrieval holdout onEvent sink threw; retrieval continues",
|
|
48
|
-
error
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
function applyRetrievalHoldout(hits, config, ctx = {}) {
|
|
53
|
-
assertValidHoldoutConfig(config);
|
|
54
|
-
const rng = config.rng ?? deterministicRng;
|
|
55
|
-
const sessionId = ctx.sessionId ?? ctx.scope?.sessionId;
|
|
56
|
-
const holdoutEligible = typeof sessionId === "string" && sessionId.length > 0;
|
|
57
|
-
const base = holdoutEventBase(hits, config, ctx);
|
|
58
|
-
let session;
|
|
59
|
-
if (holdoutEligible) {
|
|
60
|
-
const prior = ctx.session?.sessionId === sessionId ? ctx.session : void 0;
|
|
61
|
-
session = prior ?? {
|
|
62
|
-
sessionId,
|
|
63
|
-
callCount: 0,
|
|
64
|
-
// The epsilon coin depends only on sessionId, so assignment is independent of task
|
|
65
|
-
// features by construction and exactly replayable (design rules D1 + D5).
|
|
66
|
-
sessionHoldout: rng(`${sessionId}#holdout`) < config.epsilon,
|
|
67
|
-
targetId: null,
|
|
68
|
-
pickPropensity: null
|
|
69
|
-
};
|
|
70
|
-
session = { ...session, callCount: session.callCount + 1 };
|
|
71
|
-
}
|
|
72
|
-
const watchlistEligible = base.watchlistEligible;
|
|
73
|
-
if (session?.sessionHoldout && session.targetId === null && watchlistEligible.length > 0) {
|
|
74
|
-
const candidates = [...watchlistEligible].sort();
|
|
75
|
-
const index = Math.min(
|
|
76
|
-
Math.floor(rng(`${session.sessionId}#pick`) * candidates.length),
|
|
77
|
-
candidates.length - 1
|
|
78
|
-
);
|
|
79
|
-
const picked = candidates[index];
|
|
80
|
-
if (picked !== void 0) {
|
|
81
|
-
session = { ...session, targetId: picked, pickPropensity: 1 / candidates.length };
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
const targetId = session?.sessionHoldout ? session.targetId ?? null : null;
|
|
85
|
-
const droppedId = targetId !== null && hits.some((hit) => hit.id === targetId) ? targetId : null;
|
|
86
|
-
const delivered = droppedId === null ? hits : hits.filter((hit) => hit.id !== droppedId);
|
|
87
|
-
const pickPropensity = session?.sessionHoldout ? session.pickPropensity ?? null : null;
|
|
88
|
-
const event = {
|
|
89
|
-
...base,
|
|
90
|
-
callIndex: session?.callCount ?? 0,
|
|
91
|
-
holdoutEligible,
|
|
92
|
-
sessionHoldout: session?.sessionHoldout ?? false,
|
|
93
|
-
sessionTargetId: targetId,
|
|
94
|
-
droppedId,
|
|
95
|
-
pickPropensity,
|
|
96
|
-
dropPropensity: pickPropensity !== null ? config.epsilon * pickPropensity : null,
|
|
97
|
-
deliveredIds: delivered.map((hit) => hit.id)
|
|
98
|
-
};
|
|
99
|
-
safeEmit(config, event);
|
|
100
|
-
return droppedId === null ? { delivered: hits, event, ...session !== void 0 ? { session } : {} } : { delivered, event, ...session !== void 0 ? { session } : {} };
|
|
101
|
-
}
|
|
102
|
-
function holdoutEventBase(hits, config, ctx) {
|
|
103
|
-
const sessionId = ctx.sessionId ?? ctx.scope?.sessionId;
|
|
104
|
-
const watchlist = config.watchlist ?? [];
|
|
105
|
-
const watchlistSet = new Set(watchlist);
|
|
106
|
-
const plaintext = config.includePlaintextIdentifiers === true;
|
|
107
|
-
return {
|
|
108
|
-
v: 1,
|
|
109
|
-
eventId: randomUUID(),
|
|
110
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
111
|
-
...config.adapterId !== void 0 ? { adapterId: config.adapterId } : {},
|
|
112
|
-
...plaintext && sessionId !== void 0 ? { sessionId } : {},
|
|
113
|
-
...ctx.taskId !== void 0 ? { taskId: ctx.taskId } : {},
|
|
114
|
-
...sessionId !== void 0 ? { sessionIdHash: sha256(sessionId).slice(0, 16) } : {},
|
|
115
|
-
...ctx.query !== void 0 ? { queryHash: sha256(ctx.query).slice(0, 16) } : {},
|
|
116
|
-
...plaintext && ctx.scope !== void 0 ? { scope: ctx.scope } : {},
|
|
117
|
-
...ctx.scope !== void 0 ? { scopeHash: sha256(canonicalJson(ctx.scope)).slice(0, 16) } : {},
|
|
118
|
-
config: {
|
|
119
|
-
epsilon: config.epsilon,
|
|
120
|
-
watchlist: [...watchlist],
|
|
121
|
-
...config.configVersion !== void 0 ? { configVersion: config.configVersion } : {}
|
|
122
|
-
},
|
|
123
|
-
configHash: retrievalHoldoutConfigHash(config),
|
|
124
|
-
eligible: hits.map((hit, index) => ({
|
|
125
|
-
id: hit.id,
|
|
126
|
-
rank: index + 1,
|
|
127
|
-
...typeof (hit.normalizedScore ?? hit.score) === "number" ? { score: hit.normalizedScore ?? hit.score } : {},
|
|
128
|
-
kind: hit.kind,
|
|
129
|
-
contentHash: sha256(hit.text).slice(0, 16)
|
|
130
|
-
})),
|
|
131
|
-
watchlistEligible: hits.filter((hit) => watchlistSet.has(hit.id)).map((hit) => hit.id),
|
|
132
|
-
...config.corpusVersion !== void 0 ? { corpusVersion: config.corpusVersion } : {}
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
function emitRetrievalHoldoutBypass(hits, config, ctx, bypassReason) {
|
|
136
|
-
assertValidHoldoutConfig(config);
|
|
137
|
-
const event = {
|
|
138
|
-
...holdoutEventBase(hits, config, ctx),
|
|
139
|
-
callIndex: 0,
|
|
140
|
-
holdoutEligible: false,
|
|
141
|
-
sessionHoldout: false,
|
|
142
|
-
sessionTargetId: null,
|
|
143
|
-
droppedId: null,
|
|
144
|
-
pickPropensity: null,
|
|
145
|
-
dropPropensity: null,
|
|
146
|
-
deliveredIds: hits.map((hit) => hit.id),
|
|
147
|
-
bypassReason
|
|
148
|
-
};
|
|
149
|
-
safeEmit(config, event);
|
|
150
|
-
return event;
|
|
151
|
-
}
|
|
152
|
-
var DEFAULT_MAX_TRACKED_SESSIONS = 1e4;
|
|
153
|
-
var sessionRegistry = /* @__PURE__ */ new Map();
|
|
154
|
-
function resetRetrievalHoldoutRegistry() {
|
|
155
|
-
sessionRegistry.clear();
|
|
156
|
-
}
|
|
157
|
-
function applySessionStickyRetrievalHoldout(hits, config, ctx = {}) {
|
|
158
|
-
assertValidHoldoutConfig(config);
|
|
159
|
-
const sessionId = ctx.sessionId ?? ctx.scope?.sessionId;
|
|
160
|
-
const configHash = retrievalHoldoutConfigHash(config);
|
|
161
|
-
let sessions = sessionRegistry.get(configHash);
|
|
162
|
-
if (!sessions) {
|
|
163
|
-
sessions = /* @__PURE__ */ new Map();
|
|
164
|
-
sessionRegistry.set(configHash, sessions);
|
|
165
|
-
}
|
|
166
|
-
const prior = sessionId !== void 0 ? sessions.get(sessionId) : void 0;
|
|
167
|
-
const result = applyRetrievalHoldout(hits, config, {
|
|
168
|
-
...ctx,
|
|
169
|
-
...prior ? { session: prior } : {}
|
|
170
|
-
});
|
|
171
|
-
if (sessionId !== void 0 && result.session) {
|
|
172
|
-
const cap = config.maxTrackedSessions ?? DEFAULT_MAX_TRACKED_SESSIONS;
|
|
173
|
-
if (!sessions.has(sessionId) && sessions.size >= cap) {
|
|
174
|
-
const oldest = sessions.keys().next().value;
|
|
175
|
-
if (oldest !== void 0) sessions.delete(oldest);
|
|
176
|
-
}
|
|
177
|
-
sessions.set(sessionId, result.session);
|
|
178
|
-
}
|
|
179
|
-
return result;
|
|
180
|
-
}
|
|
181
|
-
function toOffPolicyTrajectory(events, options) {
|
|
182
|
-
const groups = /* @__PURE__ */ new Map();
|
|
183
|
-
let unattributableEvents = 0;
|
|
184
|
-
for (const event of events) {
|
|
185
|
-
if (event.sessionIdHash === void 0) {
|
|
186
|
-
unattributableEvents += 1;
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
const key = `${event.configHash}:${event.sessionIdHash}`;
|
|
190
|
-
const group = groups.get(key);
|
|
191
|
-
if (group) group.push(event);
|
|
192
|
-
else groups.set(key, [event]);
|
|
193
|
-
}
|
|
194
|
-
const trajectories = [];
|
|
195
|
-
const sessions = [];
|
|
196
|
-
const excluded = [];
|
|
197
|
-
for (const [runId, group] of groups) {
|
|
198
|
-
const ordered = [...group].sort((a, b) => a.callIndex - b.callIndex || a.ts.localeCompare(b.ts));
|
|
199
|
-
const randomized = ordered.filter((event) => event.holdoutEligible);
|
|
200
|
-
const firstEvent = ordered[0];
|
|
201
|
-
if (firstEvent?.sessionIdHash === void 0) continue;
|
|
202
|
-
const base = {
|
|
203
|
-
runId,
|
|
204
|
-
configHash: firstEvent.configHash,
|
|
205
|
-
sessionIdHash: firstEvent.sessionIdHash,
|
|
206
|
-
callCount: randomized.length,
|
|
207
|
-
bypassCallCount: ordered.length - randomized.length
|
|
208
|
-
};
|
|
209
|
-
const first = randomized[0];
|
|
210
|
-
if (first === void 0) {
|
|
211
|
-
excluded.push({
|
|
212
|
-
...base,
|
|
213
|
-
sessionHoldout: false,
|
|
214
|
-
sessionTargetId: null,
|
|
215
|
-
droppedId: null,
|
|
216
|
-
firstCandidateCount: 0,
|
|
217
|
-
behaviorProb: 1,
|
|
218
|
-
mixedExposure: false,
|
|
219
|
-
exclusionReason: "no-randomized-calls"
|
|
220
|
-
});
|
|
221
|
-
continue;
|
|
222
|
-
}
|
|
223
|
-
const targets = new Set(
|
|
224
|
-
randomized.map((event) => event.sessionTargetId).filter((target) => target !== null)
|
|
225
|
-
);
|
|
226
|
-
const arms = new Set(randomized.map((event) => event.sessionHoldout));
|
|
227
|
-
const mixedExposure = targets.size > 1 || arms.size > 1;
|
|
228
|
-
const dropEvent = randomized.find((event) => event.droppedId !== null);
|
|
229
|
-
const firstIntersecting = randomized.find((event) => event.watchlistEligible.length > 0);
|
|
230
|
-
const sessionTargetId = dropEvent?.sessionTargetId ?? [...targets][0] ?? null;
|
|
231
|
-
let behaviorProb;
|
|
232
|
-
if (dropEvent !== void 0) {
|
|
233
|
-
if (dropEvent.dropPropensity === null) {
|
|
234
|
-
throw new Error(`holdout event ${dropEvent.eventId} recorded a drop without dropPropensity`);
|
|
235
|
-
}
|
|
236
|
-
behaviorProb = dropEvent.dropPropensity;
|
|
237
|
-
} else if (!mixedExposure && sessionTargetId !== null) {
|
|
238
|
-
throw new Error(
|
|
239
|
-
`holdout session ${base.sessionIdHash} has a drawn target but no drop event: the event batch is missing this session draw call`
|
|
240
|
-
);
|
|
241
|
-
} else if (firstIntersecting === void 0) {
|
|
242
|
-
behaviorProb = 1;
|
|
243
|
-
} else {
|
|
244
|
-
behaviorProb = 1 - first.config.epsilon;
|
|
245
|
-
}
|
|
246
|
-
const summary = {
|
|
247
|
-
...base,
|
|
248
|
-
sessionHoldout: first.sessionHoldout,
|
|
249
|
-
sessionTargetId,
|
|
250
|
-
droppedId: dropEvent?.droppedId ?? null,
|
|
251
|
-
firstCandidateCount: firstIntersecting ? new Set(firstIntersecting.watchlistEligible).size : 0,
|
|
252
|
-
behaviorProb,
|
|
253
|
-
mixedExposure,
|
|
254
|
-
...mixedExposure ? { exclusionReason: "mixed-exposure" } : {}
|
|
255
|
-
};
|
|
256
|
-
if (mixedExposure) {
|
|
257
|
-
excluded.push(summary);
|
|
258
|
-
continue;
|
|
259
|
-
}
|
|
260
|
-
const reward = options.rewards[summary.sessionIdHash];
|
|
261
|
-
if (reward === void 0) {
|
|
262
|
-
throw new Error(
|
|
263
|
-
`no reward for session ${summary.sessionIdHash}: filter events to scored sessions before converting`
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
trajectories.push({
|
|
267
|
-
runId,
|
|
268
|
-
reward,
|
|
269
|
-
behaviorProb,
|
|
270
|
-
targetProb: options.targetProb?.(summary) ?? (summary.droppedId === null ? 1 : 0),
|
|
271
|
-
qHat: options.qHat?.(summary) ?? null
|
|
272
|
-
});
|
|
273
|
-
sessions.push(summary);
|
|
274
|
-
}
|
|
275
|
-
return { trajectories, sessions, excluded, unattributableEvents };
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// src/memory/adapter.ts
|
|
279
|
-
async function defaultGetMemoryContext(adapter, query, options = {}) {
|
|
280
|
-
const hits = await adapter.search(query, options);
|
|
281
|
-
const delivered = options.holdout ? applySessionStickyRetrievalHoldout(hits, options.holdout, {
|
|
282
|
-
query,
|
|
283
|
-
...options.scope !== void 0 ? { scope: options.scope } : {},
|
|
284
|
-
...options.scope?.tags?.taskId !== void 0 ? { taskId: options.scope.tags.taskId } : {}
|
|
285
|
-
}).delivered : hits;
|
|
286
|
-
return {
|
|
287
|
-
query,
|
|
288
|
-
hits: delivered,
|
|
289
|
-
sourceRecords: delivered.map((hit) => memoryHitToSourceRecord(hit, { scope: options.scope })),
|
|
290
|
-
text: renderMemoryContext(delivered)
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
function renderMemoryContext(hits) {
|
|
294
|
-
return hits.map((hit, index) => {
|
|
295
|
-
const label = hit.title ?? `${hit.kind}:${hit.id}`;
|
|
296
|
-
const score = typeof hit.normalizedScore === "number" ? ` score=${hit.normalizedScore.toFixed(3)}` : "";
|
|
297
|
-
return [`[${index + 1}] ${label}${score}`, hit.text].join("\n");
|
|
298
|
-
}).join("\n\n");
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// src/memory/neo4j.ts
|
|
302
|
-
function createNeo4jAgentMemoryAdapter(options) {
|
|
303
|
-
const client = options.client;
|
|
304
|
-
const id = options.id ?? "neo4j-agent-memory";
|
|
305
|
-
return {
|
|
306
|
-
id,
|
|
307
|
-
async search(query, searchOptions = {}) {
|
|
308
|
-
const sdkHits = await searchNeo4jMemory(client, query, searchOptions, id);
|
|
309
|
-
if (sdkHits.length > 0) return sdkHits;
|
|
310
|
-
const result = await callOptional(
|
|
311
|
-
client,
|
|
312
|
-
["search", "memory_search"],
|
|
313
|
-
[query, neo4jOptions(searchOptions)]
|
|
314
|
-
);
|
|
315
|
-
if (result !== void 0) return normalizeHits(result, searchOptions, id);
|
|
316
|
-
const context = await callOptional(
|
|
317
|
-
client,
|
|
318
|
-
["getContext", "get_context"],
|
|
319
|
-
[query, neo4jOptions(searchOptions)]
|
|
320
|
-
);
|
|
321
|
-
if (context !== void 0) return normalizeHits(context, searchOptions, id);
|
|
322
|
-
return [];
|
|
323
|
-
},
|
|
324
|
-
async getContext(query, searchOptions = {}) {
|
|
325
|
-
const shortTerm = nested(client, ["shortTerm", "short_term"], {});
|
|
326
|
-
const sessionId = searchOptions.scope?.sessionId;
|
|
327
|
-
if (sessionId) {
|
|
328
|
-
const conversationContext = await callOptional(
|
|
329
|
-
shortTerm,
|
|
330
|
-
["getContext", "get_context"],
|
|
331
|
-
[sessionId]
|
|
332
|
-
);
|
|
333
|
-
if (conversationContext !== void 0) {
|
|
334
|
-
const hits2 = normalizeConversationContextHits(conversationContext, searchOptions, id);
|
|
335
|
-
const text = textFromConversationContext(conversationContext) ?? (typeof conversationContext === "string" ? conversationContext : hits2.length > 0 ? renderHits(hits2) : "");
|
|
336
|
-
if (searchOptions.holdout) {
|
|
337
|
-
emitRetrievalHoldoutBypass(
|
|
338
|
-
hits2,
|
|
339
|
-
searchOptions.holdout,
|
|
340
|
-
holdoutBypassContext(query, searchOptions),
|
|
341
|
-
"short-term-context"
|
|
342
|
-
);
|
|
343
|
-
}
|
|
344
|
-
return {
|
|
345
|
-
query,
|
|
346
|
-
text,
|
|
347
|
-
hits: hits2,
|
|
348
|
-
sourceRecords: hits2.map(
|
|
349
|
-
(hit) => memoryHitToSourceRecord(hit, { scope: searchOptions.scope })
|
|
350
|
-
),
|
|
351
|
-
metadata: { adapter: id, rawContext: conversationContext }
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
const result = await callOptional(
|
|
356
|
-
client,
|
|
357
|
-
["getContext", "get_context"],
|
|
358
|
-
[query, neo4jOptions(searchOptions)]
|
|
359
|
-
);
|
|
360
|
-
if (result === void 0) {
|
|
361
|
-
return defaultGetMemoryContext(
|
|
362
|
-
{
|
|
363
|
-
search: async () => {
|
|
364
|
-
const sdkHits = await searchNeo4jMemory(client, query, searchOptions, id);
|
|
365
|
-
if (sdkHits.length > 0) return sdkHits;
|
|
366
|
-
const searchResult = await callOptional(
|
|
367
|
-
client,
|
|
368
|
-
["search", "memory_search"],
|
|
369
|
-
[query, neo4jOptions(searchOptions)]
|
|
370
|
-
);
|
|
371
|
-
return normalizeHits(searchResult, searchOptions, id);
|
|
372
|
-
}
|
|
373
|
-
},
|
|
374
|
-
query,
|
|
375
|
-
searchOptions
|
|
376
|
-
);
|
|
377
|
-
}
|
|
378
|
-
if (typeof result === "string") {
|
|
379
|
-
const hit = {
|
|
380
|
-
id: stableId("mem", `${id}:${query}:${result}`),
|
|
381
|
-
uri: `memory://${id}/context/${stableId("ctx", query)}`,
|
|
382
|
-
kind: "fact",
|
|
383
|
-
text: result,
|
|
384
|
-
title: "Memory context",
|
|
385
|
-
normalizedScore: 1
|
|
386
|
-
};
|
|
387
|
-
if (searchOptions.holdout) {
|
|
388
|
-
emitRetrievalHoldoutBypass(
|
|
389
|
-
[hit],
|
|
390
|
-
searchOptions.holdout,
|
|
391
|
-
holdoutBypassContext(query, searchOptions),
|
|
392
|
-
"raw-string-context"
|
|
393
|
-
);
|
|
394
|
-
}
|
|
395
|
-
return {
|
|
396
|
-
query,
|
|
397
|
-
text: result,
|
|
398
|
-
hits: [hit],
|
|
399
|
-
sourceRecords: [memoryHitToSourceRecord(hit, { scope: searchOptions.scope })],
|
|
400
|
-
metadata: { adapter: id }
|
|
401
|
-
};
|
|
402
|
-
}
|
|
403
|
-
const hits = normalizeHits(result, searchOptions, id);
|
|
404
|
-
if (hits.length > 0)
|
|
405
|
-
return defaultGetMemoryContext({ search: async () => hits }, query, searchOptions);
|
|
406
|
-
return defaultGetMemoryContext({ search: async () => [] }, query, searchOptions);
|
|
407
|
-
},
|
|
408
|
-
async write(input) {
|
|
409
|
-
const result = await writeNeo4jMemory(client, input, id);
|
|
410
|
-
return {
|
|
411
|
-
...result,
|
|
412
|
-
sourceRecord: memoryWriteResultToSourceRecord(result, input.text, { scope: input.scope })
|
|
413
|
-
};
|
|
414
|
-
}
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
async function writeNeo4jMemory(client, input, adapterId) {
|
|
418
|
-
const scope = input.scope ?? {};
|
|
419
|
-
const sessionId = scope.sessionId ?? input.metadata?.sessionId;
|
|
420
|
-
let result;
|
|
421
|
-
if (input.kind === "message") {
|
|
422
|
-
const shortTerm = nested(client, ["shortTerm", "short_term"], client);
|
|
423
|
-
result = await callOptional(
|
|
424
|
-
shortTerm,
|
|
425
|
-
["addMessage"],
|
|
426
|
-
[
|
|
427
|
-
sessionId,
|
|
428
|
-
input.role ?? "user",
|
|
429
|
-
input.text,
|
|
430
|
-
{
|
|
431
|
-
metadata: input.metadata,
|
|
432
|
-
conversationId: sessionId,
|
|
433
|
-
userId: scope.userId
|
|
434
|
-
}
|
|
435
|
-
]
|
|
436
|
-
);
|
|
437
|
-
if (result === void 0) {
|
|
438
|
-
result = await callRequired(
|
|
439
|
-
shortTerm,
|
|
440
|
-
["add_message"],
|
|
441
|
-
[
|
|
442
|
-
{
|
|
443
|
-
session_id: sessionId,
|
|
444
|
-
sessionId,
|
|
445
|
-
role: input.role ?? "user",
|
|
446
|
-
content: input.text,
|
|
447
|
-
user_identifier: scope.userId,
|
|
448
|
-
userIdentifier: scope.userId,
|
|
449
|
-
metadata: input.metadata
|
|
450
|
-
}
|
|
451
|
-
]
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
} else if (input.kind === "entity") {
|
|
455
|
-
const longTerm = nested(client, ["longTerm", "long_term"], client);
|
|
456
|
-
result = await callOptional(
|
|
457
|
-
longTerm,
|
|
458
|
-
["addEntity"],
|
|
459
|
-
[
|
|
460
|
-
input.entityName ?? input.title ?? input.text,
|
|
461
|
-
input.entityType ?? "ENTITY",
|
|
462
|
-
neo4jEntityOptions(input)
|
|
463
|
-
]
|
|
464
|
-
);
|
|
465
|
-
if (result === void 0) {
|
|
466
|
-
result = await callRequired(
|
|
467
|
-
longTerm,
|
|
468
|
-
["add_entity"],
|
|
469
|
-
[
|
|
470
|
-
input.entityName ?? input.title ?? input.text,
|
|
471
|
-
input.entityType ?? "ENTITY",
|
|
472
|
-
neo4jWriteOptions(input)
|
|
473
|
-
]
|
|
474
|
-
);
|
|
475
|
-
}
|
|
476
|
-
} else if (input.kind === "preference") {
|
|
477
|
-
const longTerm = nested(client, ["longTerm", "long_term"], client);
|
|
478
|
-
result = await callOptional(
|
|
479
|
-
longTerm,
|
|
480
|
-
["addPreference"],
|
|
481
|
-
[input.category ?? "general", input.text, neo4jPreferenceOptions(input)]
|
|
482
|
-
);
|
|
483
|
-
if (result === void 0) {
|
|
484
|
-
result = await callRequired(
|
|
485
|
-
longTerm,
|
|
486
|
-
["add_preference"],
|
|
487
|
-
[input.category ?? "general", input.text, neo4jWriteOptions(input)]
|
|
488
|
-
);
|
|
489
|
-
}
|
|
490
|
-
} else {
|
|
491
|
-
result = await callRequired(
|
|
492
|
-
nested(client, ["longTerm", "long_term"], client),
|
|
493
|
-
["addFact", "add_fact"],
|
|
494
|
-
[
|
|
495
|
-
input.subject ?? input.title ?? input.kind,
|
|
496
|
-
input.predicate ?? "states",
|
|
497
|
-
input.object ?? input.text
|
|
498
|
-
]
|
|
499
|
-
);
|
|
500
|
-
}
|
|
501
|
-
const id = idFromResult(result) ?? input.id ?? stableId("mem", `${input.kind}:${input.text}`);
|
|
502
|
-
return {
|
|
503
|
-
accepted: true,
|
|
504
|
-
id,
|
|
505
|
-
uri: `memory://${adapterId}/${encodeURIComponent(id)}`,
|
|
506
|
-
kind: input.kind,
|
|
507
|
-
metadata: { rawResult: result }
|
|
508
|
-
};
|
|
509
|
-
}
|
|
510
|
-
async function searchNeo4jMemory(client, query, options, adapterId) {
|
|
511
|
-
const searches = [];
|
|
512
|
-
const kinds = options.kinds;
|
|
513
|
-
const includeKind = (kind) => !kinds?.length || kinds.includes(kind);
|
|
514
|
-
const shortTerm = nested(client, ["shortTerm", "short_term"], {});
|
|
515
|
-
const longTerm = nested(client, ["longTerm", "long_term"], {});
|
|
516
|
-
const reasoning = nested(client, ["reasoning"], {});
|
|
517
|
-
if (includeKind("message")) {
|
|
518
|
-
searches.push(
|
|
519
|
-
callOptional(
|
|
520
|
-
shortTerm,
|
|
521
|
-
["searchMessages", "search_messages"],
|
|
522
|
-
[query, searchMessagesOptions(options)]
|
|
523
|
-
).then((result) => normalizeHits(result, { ...options, kinds: ["message"] }, adapterId))
|
|
524
|
-
);
|
|
525
|
-
}
|
|
526
|
-
if (includeKind("entity")) {
|
|
527
|
-
searches.push(
|
|
528
|
-
callOptional(
|
|
529
|
-
longTerm,
|
|
530
|
-
["searchEntities", "search_entities"],
|
|
531
|
-
[query, searchEntitiesOptions(options)]
|
|
532
|
-
).then((result) => normalizeHits(result, { ...options, kinds: ["entity"] }, adapterId))
|
|
533
|
-
);
|
|
534
|
-
}
|
|
535
|
-
if (includeKind("preference")) {
|
|
536
|
-
searches.push(
|
|
537
|
-
callOptional(
|
|
538
|
-
longTerm,
|
|
539
|
-
["searchPreferences", "search_preferences"],
|
|
540
|
-
[query, searchPreferencesOptions(options)]
|
|
541
|
-
).then((result) => normalizeHits(result, { ...options, kinds: ["preference"] }, adapterId))
|
|
542
|
-
);
|
|
543
|
-
}
|
|
544
|
-
if (includeKind("reasoning-trace")) {
|
|
545
|
-
searches.push(
|
|
546
|
-
callOptional(
|
|
547
|
-
reasoning,
|
|
548
|
-
["getSimilarTraces", "get_similar_traces"],
|
|
549
|
-
[query, similarTracesOptions(options)]
|
|
550
|
-
).then(
|
|
551
|
-
(result) => normalizeHits(result, { ...options, kinds: ["reasoning-trace"] }, adapterId)
|
|
552
|
-
)
|
|
553
|
-
);
|
|
554
|
-
}
|
|
555
|
-
const hits = (await Promise.all(searches)).flat();
|
|
556
|
-
return hits.sort((a, b) => (b.normalizedScore ?? b.score ?? 0) - (a.normalizedScore ?? a.score ?? 0)).slice(0, options.limit);
|
|
557
|
-
}
|
|
558
|
-
function holdoutBypassContext(query, options) {
|
|
559
|
-
return {
|
|
560
|
-
query,
|
|
561
|
-
...options.scope !== void 0 ? { scope: options.scope } : {},
|
|
562
|
-
...options.scope?.tags?.taskId !== void 0 ? { taskId: options.scope.tags.taskId } : {}
|
|
563
|
-
};
|
|
564
|
-
}
|
|
565
|
-
function neo4jOptions(options) {
|
|
566
|
-
return {
|
|
567
|
-
limit: options.limit,
|
|
568
|
-
k: options.limit,
|
|
569
|
-
min_score: options.minScore,
|
|
570
|
-
minScore: options.minScore,
|
|
571
|
-
user_identifier: options.scope?.userId,
|
|
572
|
-
userIdentifier: options.scope?.userId,
|
|
573
|
-
session_id: options.scope?.sessionId,
|
|
574
|
-
sessionId: options.scope?.sessionId,
|
|
575
|
-
namespace: options.scope?.namespace,
|
|
576
|
-
tenant_id: options.scope?.tenantId,
|
|
577
|
-
tenantId: options.scope?.tenantId,
|
|
578
|
-
kinds: options.kinds,
|
|
579
|
-
metadata: options.metadata
|
|
580
|
-
};
|
|
581
|
-
}
|
|
582
|
-
function searchMessagesOptions(options) {
|
|
583
|
-
return {
|
|
584
|
-
limit: options.limit,
|
|
585
|
-
sessionId: options.scope?.sessionId,
|
|
586
|
-
conversationId: options.scope?.sessionId,
|
|
587
|
-
threshold: options.minScore,
|
|
588
|
-
metadata: options.metadata
|
|
589
|
-
};
|
|
590
|
-
}
|
|
591
|
-
function searchEntitiesOptions(options) {
|
|
592
|
-
return {
|
|
593
|
-
limit: options.limit,
|
|
594
|
-
type: options.metadata?.type
|
|
595
|
-
};
|
|
596
|
-
}
|
|
597
|
-
function searchPreferencesOptions(options) {
|
|
598
|
-
return {
|
|
599
|
-
limit: options.limit,
|
|
600
|
-
category: options.metadata?.category
|
|
601
|
-
};
|
|
602
|
-
}
|
|
603
|
-
function similarTracesOptions(options) {
|
|
604
|
-
return {
|
|
605
|
-
limit: options.limit,
|
|
606
|
-
sessionId: options.scope?.sessionId,
|
|
607
|
-
successOnly: options.metadata?.successOnly
|
|
608
|
-
};
|
|
609
|
-
}
|
|
610
|
-
function neo4jWriteOptions(input) {
|
|
611
|
-
return {
|
|
612
|
-
user_identifier: input.scope?.userId,
|
|
613
|
-
userIdentifier: input.scope?.userId,
|
|
614
|
-
session_id: input.scope?.sessionId,
|
|
615
|
-
sessionId: input.scope?.sessionId,
|
|
616
|
-
namespace: input.scope?.namespace,
|
|
617
|
-
confidence: input.confidence,
|
|
618
|
-
metadata: input.metadata
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
function neo4jEntityOptions(input) {
|
|
622
|
-
return {
|
|
623
|
-
description: input.metadata?.description ?? input.title
|
|
624
|
-
};
|
|
625
|
-
}
|
|
626
|
-
function neo4jPreferenceOptions(input) {
|
|
627
|
-
return {
|
|
628
|
-
context: input.metadata?.context ?? input.title
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
async function callOptional(target, names, args) {
|
|
632
|
-
for (const name of names) {
|
|
633
|
-
const fn = target[name];
|
|
634
|
-
if (typeof fn === "function") return await fn.apply(target, args);
|
|
635
|
-
}
|
|
636
|
-
return void 0;
|
|
637
|
-
}
|
|
638
|
-
async function callRequired(target, names, args) {
|
|
639
|
-
const result = await callOptional(target, names, args);
|
|
640
|
-
if (result !== void 0) return result;
|
|
641
|
-
throw new Error(`Neo4j agent-memory client is missing method ${names.join(" or ")}`);
|
|
642
|
-
}
|
|
643
|
-
function nested(target, names, fallback) {
|
|
644
|
-
for (const name of names) {
|
|
645
|
-
const value = target[name];
|
|
646
|
-
if (value && typeof value === "object") return value;
|
|
647
|
-
}
|
|
648
|
-
return fallback;
|
|
649
|
-
}
|
|
650
|
-
function normalizeHits(value, options, adapterId) {
|
|
651
|
-
const rawHits = rawHitsFrom(value);
|
|
652
|
-
return rawHits.map((hit, index) => normalizeHit(hit, index, adapterId)).filter((hit) => hit !== null).filter(
|
|
653
|
-
(hit) => options.minScore === void 0 ? true : (hit.normalizedScore ?? hit.score ?? 0) >= options.minScore
|
|
654
|
-
).filter((hit) => options.kinds?.length ? options.kinds.includes(hit.kind) : true).slice(0, options.limit);
|
|
655
|
-
}
|
|
656
|
-
function normalizeHit(value, index, adapterId) {
|
|
657
|
-
if (typeof value === "string") {
|
|
658
|
-
return {
|
|
659
|
-
id: stableId("mem", value),
|
|
660
|
-
uri: `memory://${adapterId}/${stableId("mem", value)}`,
|
|
661
|
-
kind: "fact",
|
|
662
|
-
text: value,
|
|
663
|
-
normalizedScore: index === 0 ? 1 : void 0
|
|
664
|
-
};
|
|
665
|
-
}
|
|
666
|
-
const obj = record(value);
|
|
667
|
-
if (!obj) return null;
|
|
668
|
-
const kind = memoryKind(stringField(obj, ["kind", "type", "label"]), obj);
|
|
669
|
-
const text = textFromHitObject(obj, kind);
|
|
670
|
-
if (!text) return null;
|
|
671
|
-
const id = stringField(obj, ["id", "memoryId", "uuid"]) ?? stableId("mem", text);
|
|
672
|
-
return {
|
|
673
|
-
id,
|
|
674
|
-
uri: stringField(obj, ["uri"]) ?? `memory://${adapterId}/${encodeURIComponent(id)}`,
|
|
675
|
-
kind,
|
|
676
|
-
text,
|
|
677
|
-
title: stringField(obj, ["title", "name", "task", "subject"]),
|
|
678
|
-
score: numberField(obj, ["score"]),
|
|
679
|
-
normalizedScore: numberField(obj, ["normalizedScore", "normalized_score"]),
|
|
680
|
-
confidence: numberField(obj, ["confidence"]),
|
|
681
|
-
createdAt: stringField(obj, ["createdAt", "created_at"]),
|
|
682
|
-
validUntil: stringField(obj, ["validUntil", "valid_until"]),
|
|
683
|
-
lastVerifiedAt: stringField(obj, ["lastVerifiedAt", "last_verified_at"]),
|
|
684
|
-
metadata: obj
|
|
685
|
-
};
|
|
686
|
-
}
|
|
687
|
-
function memoryKind(value, obj = {}) {
|
|
688
|
-
if (value === "message" || value === "entity" || value === "fact" || value === "preference" || value === "observation" || value === "reasoning-trace") {
|
|
689
|
-
return value;
|
|
690
|
-
}
|
|
691
|
-
if ("role" in obj && "content" in obj) return "message";
|
|
692
|
-
if ("name" in obj && ("type" in obj || "entityType" in obj)) return "entity";
|
|
693
|
-
if ("preference" in obj && "category" in obj) return "preference";
|
|
694
|
-
if ("task" in obj && "steps" in obj) return "reasoning-trace";
|
|
695
|
-
return "fact";
|
|
696
|
-
}
|
|
697
|
-
function rawHitsFrom(value) {
|
|
698
|
-
if (Array.isArray(value)) return value;
|
|
699
|
-
const obj = record(value);
|
|
700
|
-
if (!obj) return typeof value === "string" ? [value] : [];
|
|
701
|
-
if (Array.isArray(obj.hits)) return obj.hits;
|
|
702
|
-
if (Array.isArray(obj.results)) return obj.results;
|
|
703
|
-
if (Array.isArray(obj.messages)) return obj.messages;
|
|
704
|
-
if (Array.isArray(obj.recentMessages)) return obj.recentMessages;
|
|
705
|
-
if (Array.isArray(obj.observations)) return obj.observations;
|
|
706
|
-
if (Array.isArray(obj.reflections)) return obj.reflections;
|
|
707
|
-
if (typeof obj.content === "string" || typeof obj.text === "string") return [obj];
|
|
708
|
-
return [];
|
|
709
|
-
}
|
|
710
|
-
function textFromHitObject(obj, kind) {
|
|
711
|
-
const direct = stringField(obj, [
|
|
712
|
-
"text",
|
|
713
|
-
"content",
|
|
714
|
-
"body",
|
|
715
|
-
"summary",
|
|
716
|
-
"preference",
|
|
717
|
-
"description"
|
|
718
|
-
]);
|
|
719
|
-
if (direct) return direct;
|
|
720
|
-
if (kind === "entity") return stringField(obj, ["name"]);
|
|
721
|
-
if (kind === "fact") {
|
|
722
|
-
const subject = stringField(obj, ["subject"]);
|
|
723
|
-
const predicate = stringField(obj, ["predicate"]);
|
|
724
|
-
const object = stringField(obj, ["object", "obj"]);
|
|
725
|
-
if (subject && predicate && object) return `${subject} ${predicate} ${object}`;
|
|
726
|
-
}
|
|
727
|
-
if (kind === "reasoning-trace") {
|
|
728
|
-
const task = stringField(obj, ["task"]);
|
|
729
|
-
const outcome = stringField(obj, ["outcome"]);
|
|
730
|
-
return [task, outcome].filter(Boolean).join("\n") || void 0;
|
|
731
|
-
}
|
|
732
|
-
return void 0;
|
|
733
|
-
}
|
|
734
|
-
function textFromConversationContext(value) {
|
|
735
|
-
const obj = record(value);
|
|
736
|
-
if (!obj) return void 0;
|
|
737
|
-
const parts = [
|
|
738
|
-
...rawHitsFrom(obj.reflections).map((hit) => normalizeContextPart(hit)),
|
|
739
|
-
...rawHitsFrom(obj.observations).map((hit) => normalizeContextPart(hit)),
|
|
740
|
-
...rawHitsFrom(obj.recentMessages).map((hit) => normalizeContextPart(hit))
|
|
741
|
-
].filter(Boolean);
|
|
742
|
-
return parts.length > 0 ? parts.join("\n\n") : void 0;
|
|
743
|
-
}
|
|
744
|
-
function normalizeConversationContextHits(value, options, adapterId) {
|
|
745
|
-
const obj = record(value);
|
|
746
|
-
if (!obj) return normalizeHits(value, options, adapterId);
|
|
747
|
-
const raw = [
|
|
748
|
-
...rawHitsFrom(obj.reflections).map((hit) => tagContextHit(hit, "observation", "Reflection")),
|
|
749
|
-
...rawHitsFrom(obj.observations).map((hit) => tagContextHit(hit, "observation", "Observation")),
|
|
750
|
-
...rawHitsFrom(obj.recentMessages).map((hit) => tagContextHit(hit, "message"))
|
|
751
|
-
];
|
|
752
|
-
return raw.length > 0 ? normalizeHits(raw, options, adapterId) : normalizeHits(value, options, adapterId);
|
|
753
|
-
}
|
|
754
|
-
function tagContextHit(value, kind, title) {
|
|
755
|
-
return value && typeof value === "object" && !Array.isArray(value) ? { kind, title, ...value } : { kind, title, content: value };
|
|
756
|
-
}
|
|
757
|
-
function normalizeContextPart(value) {
|
|
758
|
-
if (typeof value === "string") return value;
|
|
759
|
-
const obj = record(value);
|
|
760
|
-
return obj ? textFromHitObject(obj, memoryKind(stringField(obj, ["kind", "type", "label"]), obj)) : void 0;
|
|
761
|
-
}
|
|
762
|
-
function renderHits(hits) {
|
|
763
|
-
return hits.map((hit) => hit.text).join("\n\n");
|
|
764
|
-
}
|
|
765
|
-
function idFromResult(value) {
|
|
766
|
-
const obj = record(value);
|
|
767
|
-
return obj ? stringField(obj, ["id", "memoryId", "uuid"]) : void 0;
|
|
768
|
-
}
|
|
769
|
-
function record(value) {
|
|
770
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
771
|
-
}
|
|
772
|
-
function stringField(obj, names) {
|
|
773
|
-
for (const name of names) {
|
|
774
|
-
const value = obj[name];
|
|
775
|
-
if (typeof value === "string" && value.length > 0) return value;
|
|
776
|
-
}
|
|
777
|
-
return void 0;
|
|
778
|
-
}
|
|
779
|
-
function numberField(obj, names) {
|
|
780
|
-
for (const name of names) {
|
|
781
|
-
const value = obj[name];
|
|
782
|
-
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
783
|
-
}
|
|
784
|
-
return void 0;
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
// src/memory/schemas.ts
|
|
788
|
-
import { z } from "zod";
|
|
789
|
-
var AgentMemoryKindSchema = z.enum([
|
|
790
|
-
"message",
|
|
791
|
-
"entity",
|
|
792
|
-
"fact",
|
|
793
|
-
"preference",
|
|
794
|
-
"observation",
|
|
795
|
-
"reasoning-trace"
|
|
796
|
-
]);
|
|
797
|
-
var AgentMemoryScopeSchema = z.object({
|
|
798
|
-
tenantId: z.string().optional(),
|
|
799
|
-
userId: z.string().optional(),
|
|
800
|
-
sessionId: z.string().optional(),
|
|
801
|
-
namespace: z.string().optional(),
|
|
802
|
-
tags: z.record(z.string(), z.string()).optional()
|
|
803
|
-
});
|
|
804
|
-
var AgentMemoryHitSchema = z.object({
|
|
805
|
-
id: z.string().min(1),
|
|
806
|
-
uri: z.string().min(1),
|
|
807
|
-
kind: AgentMemoryKindSchema,
|
|
808
|
-
text: z.string().min(1),
|
|
809
|
-
title: z.string().optional(),
|
|
810
|
-
score: z.number().optional(),
|
|
811
|
-
normalizedScore: z.number().optional(),
|
|
812
|
-
confidence: z.number().optional(),
|
|
813
|
-
createdAt: z.string().optional(),
|
|
814
|
-
validUntil: z.string().optional(),
|
|
815
|
-
lastVerifiedAt: z.string().optional(),
|
|
816
|
-
metadata: z.record(z.string(), z.unknown()).optional()
|
|
817
|
-
});
|
|
818
|
-
var AgentMemoryWriteInputSchema = z.object({
|
|
819
|
-
kind: AgentMemoryKindSchema,
|
|
820
|
-
text: z.string().min(1),
|
|
821
|
-
id: z.string().optional(),
|
|
822
|
-
title: z.string().optional(),
|
|
823
|
-
role: z.enum(["system", "user", "assistant", "tool"]).optional(),
|
|
824
|
-
entityName: z.string().optional(),
|
|
825
|
-
entityType: z.string().optional(),
|
|
826
|
-
category: z.string().optional(),
|
|
827
|
-
predicate: z.string().optional(),
|
|
828
|
-
subject: z.string().optional(),
|
|
829
|
-
object: z.string().optional(),
|
|
830
|
-
confidence: z.number().min(0).max(1).optional(),
|
|
831
|
-
scope: AgentMemoryScopeSchema.optional(),
|
|
832
|
-
metadata: z.record(z.string(), z.unknown()).optional()
|
|
833
|
-
});
|
|
834
|
-
|
|
835
|
-
export {
|
|
836
|
-
deterministicRng,
|
|
837
|
-
retrievalHoldoutConfigHash,
|
|
838
|
-
applyRetrievalHoldout,
|
|
839
|
-
emitRetrievalHoldoutBypass,
|
|
840
|
-
resetRetrievalHoldoutRegistry,
|
|
841
|
-
applySessionStickyRetrievalHoldout,
|
|
842
|
-
toOffPolicyTrajectory,
|
|
843
|
-
defaultGetMemoryContext,
|
|
844
|
-
renderMemoryContext,
|
|
845
|
-
createNeo4jAgentMemoryAdapter,
|
|
846
|
-
AgentMemoryKindSchema,
|
|
847
|
-
AgentMemoryScopeSchema,
|
|
848
|
-
AgentMemoryHitSchema,
|
|
849
|
-
AgentMemoryWriteInputSchema
|
|
850
|
-
};
|
|
851
|
-
//# sourceMappingURL=chunk-VN2OGUUP.js.map
|