@strands-agents/sdk 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/agent/__tests__/agent.context-manager.test.js +0 -1
- package/dist/src/agent/__tests__/agent.context-manager.test.js.map +1 -1
- package/dist/src/memory/__tests__/memory-manager.test.js +7 -7
- package/dist/src/memory/__tests__/memory-manager.test.js.map +1 -1
- package/dist/src/memory/__tests__/memory-tracing.test.d.ts +2 -0
- package/dist/src/memory/__tests__/memory-tracing.test.d.ts.map +1 -0
- package/dist/src/memory/__tests__/memory-tracing.test.js +250 -0
- package/dist/src/memory/__tests__/memory-tracing.test.js.map +1 -0
- package/dist/src/memory/extraction/__tests__/extraction.test.js +41 -39
- package/dist/src/memory/extraction/__tests__/extraction.test.js.map +1 -1
- package/dist/src/memory/extraction/__tests__/model-extractor.test.js +37 -1
- package/dist/src/memory/extraction/__tests__/model-extractor.test.js.map +1 -1
- package/dist/src/memory/extraction/coordinator.d.ts +6 -1
- package/dist/src/memory/extraction/coordinator.d.ts.map +1 -1
- package/dist/src/memory/extraction/coordinator.js +48 -10
- package/dist/src/memory/extraction/coordinator.js.map +1 -1
- package/dist/src/memory/extraction/model-extractor.d.ts.map +1 -1
- package/dist/src/memory/extraction/model-extractor.js +30 -9
- package/dist/src/memory/extraction/model-extractor.js.map +1 -1
- package/dist/src/memory/extraction/types.d.ts +7 -0
- package/dist/src/memory/extraction/types.d.ts.map +1 -1
- package/dist/src/memory/extraction/types.js.map +1 -1
- package/dist/src/memory/memory-manager.d.ts +15 -2
- package/dist/src/memory/memory-manager.d.ts.map +1 -1
- package/dist/src/memory/memory-manager.js +123 -45
- package/dist/src/memory/memory-manager.js.map +1 -1
- package/dist/src/memory/types.d.ts +7 -0
- package/dist/src/memory/types.d.ts.map +1 -1
- package/dist/src/models/__tests__/google.test.js +41 -0
- package/dist/src/models/__tests__/google.test.js.map +1 -1
- package/dist/src/models/google/adapters.d.ts.map +1 -1
- package/dist/src/models/google/adapters.js +21 -3
- package/dist/src/models/google/adapters.js.map +1 -1
- package/dist/src/models/openai/__tests__/errors.test.js +9 -0
- package/dist/src/models/openai/__tests__/errors.test.js.map +1 -1
- package/dist/src/models/openai/__tests__/responses.test.js +47 -0
- package/dist/src/models/openai/__tests__/responses.test.js.map +1 -1
- package/dist/src/models/openai/errors.d.ts.map +1 -1
- package/dist/src/models/openai/errors.js +4 -1
- package/dist/src/models/openai/errors.js.map +1 -1
- package/dist/src/models/openai/responses-adapter.d.ts +1 -0
- package/dist/src/models/openai/responses-adapter.d.ts.map +1 -1
- package/dist/src/models/openai/responses-adapter.js +24 -10
- package/dist/src/models/openai/responses-adapter.js.map +1 -1
- package/dist/src/multiagent/__tests__/graph.test.js +22 -1
- package/dist/src/multiagent/__tests__/graph.test.js.map +1 -1
- package/dist/src/multiagent/graph.d.ts.map +1 -1
- package/dist/src/multiagent/graph.js +4 -1
- package/dist/src/multiagent/graph.js.map +1 -1
- package/dist/src/telemetry/__tests__/tracer.test.node.js +207 -9
- package/dist/src/telemetry/__tests__/tracer.test.node.js.map +1 -1
- package/dist/src/telemetry/tracer.d.ts +82 -2
- package/dist/src/telemetry/tracer.d.ts.map +1 -1
- package/dist/src/telemetry/tracer.js +242 -3
- package/dist/src/telemetry/tracer.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +86 -1
- package/dist/src/telemetry/types.d.ts.map +1 -1
- package/dist/src/tsconfig.tsbuildinfo +1 -1
- package/dist/src/types/json.js +2 -2
- package/dist/src/types/json.js.map +1 -1
- package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.js +81 -0
- package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.js.map +1 -1
- package/dist/src/vended-interventions/cedar/cedar.d.ts +12 -0
- package/dist/src/vended-interventions/cedar/cedar.d.ts.map +1 -1
- package/dist/src/vended-interventions/cedar/cedar.js +15 -4
- package/dist/src/vended-interventions/cedar/cedar.js.map +1 -1
- package/dist/src/vended-interventions/cedar/schema-generator.d.ts +1 -1
- package/dist/src/vended-interventions/cedar/schema-generator.d.ts.map +1 -1
- package/dist/src/vended-interventions/cedar/schema-generator.js +8 -3
- package/dist/src/vended-interventions/cedar/schema-generator.js.map +1 -1
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.node.d.ts +2 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.node.d.ts.map +1 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/{bedrock-knowledge-base-store.test.js → bedrock-knowledge-base-store.test.node.js} +154 -7
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.node.js.map +1 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/index.d.ts +1 -1
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/index.d.ts.map +1 -1
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/index.js.map +1 -1
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/store.d.ts +57 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/store.d.ts.map +1 -1
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/store.js +86 -11
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/store.js.map +1 -1
- package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.js +5 -1
- package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.js.map +1 -1
- package/dist/src/vended-plugins/context-offloader/storage.d.ts.map +1 -1
- package/dist/src/vended-plugins/context-offloader/storage.js +15 -2
- package/dist/src/vended-plugins/context-offloader/storage.js.map +1 -1
- package/dist/src/vended-plugins/skills/skill.d.ts.map +1 -1
- package/dist/src/vended-plugins/skills/skill.js +4 -2
- package/dist/src/vended-plugins/skills/skill.js.map +1 -1
- package/dist/src/vended-tools/http-request/http-request.js +1 -1
- package/dist/src/vended-tools/http-request/http-request.js.map +1 -1
- package/package.json +36 -36
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.d.ts +0 -2
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.d.ts.map +0 -1
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.js.map +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { context, trace } from '@opentelemetry/api';
|
|
1
2
|
import { logger } from '../../logging/logger.js';
|
|
2
3
|
import { normalizeError } from '../../errors.js';
|
|
3
4
|
/**
|
|
@@ -73,6 +74,7 @@ export class ExtractionCoordinator {
|
|
|
73
74
|
/** Per store: its resolved extraction config (triggers, extractor, filter). */
|
|
74
75
|
_storeToExtractionConfig = new Map();
|
|
75
76
|
_defaultModel;
|
|
77
|
+
_tracer;
|
|
76
78
|
/** The shared list of messages waiting to be saved, oldest first. Each is tagged with its `seq`. */
|
|
77
79
|
_pending = [];
|
|
78
80
|
/** The number to give the next message added to the buffer. Only ever increases. */
|
|
@@ -88,10 +90,12 @@ export class ExtractionCoordinator {
|
|
|
88
90
|
/**
|
|
89
91
|
* @param stores - The extraction-configured stores this coordinator manages, each with its resolved config
|
|
90
92
|
* @param defaultModel - The agent's model, passed to extractors that don't configure their own
|
|
93
|
+
* @param tracer - Tracer for extraction spans, shared with the {@link MemoryManager}
|
|
91
94
|
*/
|
|
92
|
-
constructor(stores, defaultModel) {
|
|
95
|
+
constructor(stores, defaultModel, tracer) {
|
|
93
96
|
this._stores = stores.map((s) => s.store);
|
|
94
97
|
this._defaultModel = defaultModel;
|
|
98
|
+
this._tracer = tracer;
|
|
95
99
|
for (const { store, config } of stores) {
|
|
96
100
|
this._storeToExtractionConfig.set(store, config);
|
|
97
101
|
this._marks.set(store, -1);
|
|
@@ -110,12 +114,15 @@ export class ExtractionCoordinator {
|
|
|
110
114
|
if (!this._shouldAttempt(store)) {
|
|
111
115
|
return Promise.resolve();
|
|
112
116
|
}
|
|
113
|
-
|
|
117
|
+
// Capture the agent span synchronously: this runs inside the live agent span (via the trigger
|
|
118
|
+
// hook), but the save itself runs detached after that span may have ended.
|
|
119
|
+
const linkContext = this._tracer.currentSpanContext();
|
|
120
|
+
return this._enqueue(store, linkContext);
|
|
114
121
|
}
|
|
115
122
|
/** Queues a save for the store behind its previous one, so saves never overlap or reorder. */
|
|
116
|
-
_enqueue(store) {
|
|
123
|
+
_enqueue(store, linkContext) {
|
|
117
124
|
const previous = this._chains.get(store) ?? Promise.resolve();
|
|
118
|
-
const next = previous.then(() => this._extract(store));
|
|
125
|
+
const next = previous.then(() => this._extract(store, linkContext));
|
|
119
126
|
this._chains.set(store, next);
|
|
120
127
|
return next;
|
|
121
128
|
}
|
|
@@ -154,7 +161,7 @@ export class ExtractionCoordinator {
|
|
|
154
161
|
}
|
|
155
162
|
}
|
|
156
163
|
}
|
|
157
|
-
async _extract(store) {
|
|
164
|
+
async _extract(store, linkContext) {
|
|
158
165
|
const mark = this._marks.get(store) ?? -1;
|
|
159
166
|
const fresh = this._pending.filter((buffered) => buffered.seq > mark);
|
|
160
167
|
if (fresh.length === 0) {
|
|
@@ -164,11 +171,22 @@ export class ExtractionCoordinator {
|
|
|
164
171
|
// pick them up again. If the save fails we put the mark back (below) and they retry.
|
|
165
172
|
const highestSeq = fresh[fresh.length - 1].seq;
|
|
166
173
|
this._marks.set(store, highestSeq);
|
|
167
|
-
const
|
|
168
|
-
const filtered = _filterMessages(fresh, filter);
|
|
174
|
+
const config = this._storeToExtractionConfig.get(store);
|
|
175
|
+
const filtered = _filterMessages(fresh, config.filter);
|
|
176
|
+
const span = this._tracer.startMemoryExtractSpan({
|
|
177
|
+
storeName: store.name,
|
|
178
|
+
messageCount: filtered.length,
|
|
179
|
+
filteredCount: fresh.length - filtered.length,
|
|
180
|
+
...(config.extractor && { extractor: config.extractor.constructor.name }),
|
|
181
|
+
...(linkContext && { agentSpanContext: linkContext }),
|
|
182
|
+
});
|
|
183
|
+
let saveError;
|
|
184
|
+
let entryCount = 0;
|
|
169
185
|
try {
|
|
170
186
|
if (filtered.length > 0) {
|
|
171
|
-
|
|
187
|
+
// Set the extract span active so the model-extractor's invoke span parents under it.
|
|
188
|
+
const write = () => this._write(store, filtered);
|
|
189
|
+
entryCount = span ? await context.with(trace.setSpan(context.active(), span), write) : await write();
|
|
172
190
|
// A successful write clears the failure streak and ends any backoff. Only a real write counts
|
|
173
191
|
// as recovery - a fully-filtered (empty) turn never touched the backend, so it leaves backoff
|
|
174
192
|
// state untouched (it still advances the mark above; those messages had nothing to save).
|
|
@@ -177,11 +195,25 @@ export class ExtractionCoordinator {
|
|
|
177
195
|
}
|
|
178
196
|
}
|
|
179
197
|
catch (err) {
|
|
198
|
+
saveError = err;
|
|
180
199
|
this._onSaveFailed(store, mark, err);
|
|
181
200
|
}
|
|
182
201
|
finally {
|
|
183
202
|
this._trim();
|
|
184
203
|
}
|
|
204
|
+
// End the span after the save resolves and best-effort, so span bookkeeping is decoupled from the
|
|
205
|
+
// save outcome and can never break this detached background task.
|
|
206
|
+
try {
|
|
207
|
+
if (saveError === undefined) {
|
|
208
|
+
this._tracer.endMemoryExtractSpan(span, { entryCount });
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
this._tracer.endMemoryExtractSpan(span, { error: normalizeError(saveError) });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
logger.debug(`store=<${store.name}>, reason=<${normalizeError(err).message}> | memory extract span end failed`);
|
|
216
|
+
}
|
|
185
217
|
}
|
|
186
218
|
/**
|
|
187
219
|
* Handles a failed save. Puts the mark back so the messages retry next time. Once a store has failed
|
|
@@ -208,21 +240,27 @@ export class ExtractionCoordinator {
|
|
|
208
240
|
*
|
|
209
241
|
* Fact writes run in parallel. If any fails we throw, which makes the caller retry the whole batch
|
|
210
242
|
* next time - so a fact that already saved may be written again (stores should expect duplicates).
|
|
243
|
+
*
|
|
244
|
+
* @returns The number of entries written (extracted facts, or raw messages).
|
|
211
245
|
*/
|
|
212
246
|
async _write(store, buffered) {
|
|
213
247
|
const extractor = this._storeToExtractionConfig.get(store).extractor;
|
|
214
248
|
const messages = buffered.map((buffer) => buffer.message);
|
|
215
249
|
if (extractor) {
|
|
216
|
-
const entries = await extractor.extract(messages, {
|
|
250
|
+
const entries = await extractor.extract(messages, {
|
|
251
|
+
defaultModel: this._defaultModel,
|
|
252
|
+
tracer: this._tracer,
|
|
253
|
+
});
|
|
217
254
|
const settled = await Promise.allSettled(entries.map((entry) => store.add(entry.content, entry.metadata)));
|
|
218
255
|
const failures = settled.filter((r) => r.status === 'rejected');
|
|
219
256
|
if (failures.length > 0) {
|
|
220
257
|
throw new AggregateError(failures.map((failure) => failure.reason), `failed to write ${failures.length} of ${entries.length} extracted entries`);
|
|
221
258
|
}
|
|
222
|
-
return;
|
|
259
|
+
return entries.length;
|
|
223
260
|
}
|
|
224
261
|
// Pass each message's sequence number so a store can build an idempotency key surviving retries.
|
|
225
262
|
await store.addMessages(messages, { sequenceNumbers: buffered.map((buffer) => buffer.seq) });
|
|
263
|
+
return messages.length;
|
|
226
264
|
}
|
|
227
265
|
/**
|
|
228
266
|
* Removes messages from the buffer once every store has saved them (so none still needs them).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coordinator.js","sourceRoot":"","sources":["../../../../src/memory/extraction/coordinator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"coordinator.js","sourceRoot":"","sources":["../../../../src/memory/extraction/coordinator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-extractor.d.ts","sourceRoot":"","sources":["../../../../src/memory/extraction/model-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC9E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"model-extractor.d.ts","sourceRoot":"","sources":["../../../../src/memory/extraction/model-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC9E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAIlD,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAO/E,0CAA0C;AAC1C,MAAM,WAAW,qBAAqB;IACpC,qGAAqG;IACrG,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,kGAAkG;IAClG,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,cAAe,YAAW,SAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAO;IAC/B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;gBAE1B,OAAO,GAAE,qBAA0B;IAOzC,OAAO,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CA6DhG"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Message, TextBlock } from '../../types/messages.js';
|
|
2
2
|
import { logger } from '../../logging/logger.js';
|
|
3
|
+
import { normalizeError } from '../../errors.js';
|
|
3
4
|
/** Default instruction guiding the model to emit discrete, durable facts as a JSON array. */
|
|
4
5
|
const DEFAULT_SYSTEM_PROMPT = `You extract durable facts worth remembering across future conversations from a transcript.
|
|
5
6
|
|
|
@@ -45,19 +46,39 @@ export class ModelExtractor {
|
|
|
45
46
|
content: [new TextBlock(`Extract facts from the following transcript:\n\n${transcript}`)],
|
|
46
47
|
}),
|
|
47
48
|
];
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
const span = context?.tracer?.startModelInvokeSpan({
|
|
50
|
+
messages: promptMessages,
|
|
51
|
+
...(model.modelId !== undefined && { modelId: model.modelId }),
|
|
52
|
+
systemPrompt: this._systemPrompt,
|
|
53
|
+
}) ?? null;
|
|
51
54
|
let result;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
try {
|
|
56
|
+
const stream = model.streamAggregated(promptMessages, { systemPrompt: this._systemPrompt });
|
|
57
|
+
// Manual .next() loop: streamAggregated returns its result as the generator return value
|
|
58
|
+
// (done:true), which for-await-of discards.
|
|
59
|
+
for (;;) {
|
|
60
|
+
result = await stream.next();
|
|
61
|
+
if (result.done)
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
context?.tracer?.endModelInvokeSpan(span, { error: normalizeError(error) });
|
|
67
|
+
throw error;
|
|
56
68
|
}
|
|
57
69
|
if (!result?.done || !result.value) {
|
|
58
|
-
|
|
70
|
+
const noResponseError = new Error('ModelExtractor: model returned no response');
|
|
71
|
+
context?.tracer?.endModelInvokeSpan(span, { error: noResponseError });
|
|
72
|
+
throw noResponseError;
|
|
59
73
|
}
|
|
60
|
-
const
|
|
74
|
+
const { message, stopReason, metadata } = result.value;
|
|
75
|
+
context?.tracer?.endModelInvokeSpan(span, {
|
|
76
|
+
output: message,
|
|
77
|
+
stopReason,
|
|
78
|
+
...(metadata?.usage !== undefined && { usage: metadata.usage }),
|
|
79
|
+
...(metadata?.metrics !== undefined && { metrics: metadata.metrics }),
|
|
80
|
+
});
|
|
81
|
+
const text = message.content
|
|
61
82
|
.map((block) => ('text' in block ? block.text : ''))
|
|
62
83
|
.join('')
|
|
63
84
|
.trim();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-extractor.js","sourceRoot":"","sources":["../../../../src/memory/extraction/model-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAoB,MAAM,yBAAyB,CAAA;AAG9E,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAGhD,6FAA6F;AAC7F,MAAM,qBAAqB,GAAG;;kTAEoR,CAAA;AAUlT;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,cAAc;IACR,MAAM,CAAQ;IACd,aAAa,CAAQ;IAEtC,YAAY,UAAiC,EAAE;QAC7C,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAA;QAC7B,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,YAAY,IAAI,qBAAqB,CAAA;IACpE,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAAuB,EAAE,OAA0B;QAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,EAAE,YAAY,CAAA;QAClD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAA;QACvF,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,EAAE,CAAA;QACX,CAAC;QAED,+FAA+F;QAC/F,0DAA0D;QAC1D,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAChF,MAAM,cAAc,GAAG;YACrB,IAAI,OAAO,CAAC;gBACV,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,CAAC,IAAI,SAAS,CAAC,mDAAmD,UAAU,EAAE,CAAC,CAAC;aAC1F,CAAC;SACH,CAAA;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,gBAAgB,CAAC,cAAc,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"model-extractor.js","sourceRoot":"","sources":["../../../../src/memory/extraction/model-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import type { JSONValue } from '../../types/json.js';
|
|
|
2
2
|
import type { MessageData, ContentBlockData } from '../../types/messages.js';
|
|
3
3
|
import type { Model } from '../../models/model.js';
|
|
4
4
|
import type { LocalAgent } from '../../types/agent.js';
|
|
5
|
+
import type { Tracer } from '../../telemetry/tracer.js';
|
|
5
6
|
type DistributedKeyof<Union> = Union extends unknown ? keyof Union : never;
|
|
6
7
|
/**
|
|
7
8
|
* Content block kinds that {@link MemoryMessageFilter} can exclude before messages reach an
|
|
@@ -44,6 +45,12 @@ export interface ExtractionResult {
|
|
|
44
45
|
export interface ExtractorContext {
|
|
45
46
|
/** The agent's model, supplied so an extractor can default to it. */
|
|
46
47
|
defaultModel?: Model;
|
|
48
|
+
/**
|
|
49
|
+
* Tracer for wrapping the extractor's model call in a span, parented to the active extraction
|
|
50
|
+
* span. Supplied by the {@link ExtractionCoordinator}; omitted for direct/standalone use.
|
|
51
|
+
* @internal
|
|
52
|
+
*/
|
|
53
|
+
tracer?: Tracer;
|
|
47
54
|
}
|
|
48
55
|
/**
|
|
49
56
|
* Transforms conversation messages into discrete, searchable entries.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/memory/extraction/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC5E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/memory/extraction/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC5E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAIvD,KAAK,gBAAgB,CAAC,KAAK,IAAI,KAAK,SAAS,OAAO,GAAG,MAAM,KAAK,GAAG,KAAK,CAAA;AAE1E;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAA;AAEvE;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,sDAAsD;IACtD,OAAO,EAAE,sBAAsB,EAAE,CAAA;CAClC;AAED,6FAA6F;AAC7F,eAAO,MAAM,6BAA6B,EAAE,mBAE3C,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAA;IACf,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CACrC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAA;IACpB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAA;CAC1F;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,mDAAmD;IACnD,KAAK,EAAE,UAAU,CAAA;IACjB,sMAAsM;IACtM,IAAI,EAAE,MAAM,IAAI,CAAA;CACjB;AAED;;;;;;;;;;;GAWG;AACH,8BAAsB,iBAAiB;IACrC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAE9B;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI;CACzD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,OAAO,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,CAAA;IACjD;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,mBAAmB,CAAA;CAC7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/memory/extraction/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/memory/extraction/types.ts"],"names":[],"mappings":"AAgCA,6FAA6F;AAC7F,MAAM,CAAC,MAAM,6BAA6B,GAAwB;IAChE,OAAO,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC;CACnC,CAAA;AA4DD;;;;;;;;;;;GAWG;AACH,MAAM,OAAgB,iBAAiB;CAatC"}
|
|
@@ -45,6 +45,13 @@ export declare class MemoryManager implements Plugin {
|
|
|
45
45
|
private _coordinator;
|
|
46
46
|
/** Resolved injection config, or `false` when injection is disabled. */
|
|
47
47
|
private readonly _injectionConfig;
|
|
48
|
+
/**
|
|
49
|
+
* Tracer for memory operation spans, shared with the extraction coordinator. A per-instance
|
|
50
|
+
* Tracer is intentional: it wraps the same global OTel provider, and parent-child nesting is
|
|
51
|
+
* established via OTel context (context.active() / context.with()), not instance hierarchy — so a
|
|
52
|
+
* fresh instance routes spans to the same exporter and parents correctly without fragmenting traces.
|
|
53
|
+
*/
|
|
54
|
+
private readonly _tracer;
|
|
48
55
|
constructor(config: MemoryManagerConfig);
|
|
49
56
|
/**
|
|
50
57
|
* Resolves the writable stores the `add_memory` tool may write to. When `stores` is given, each
|
|
@@ -64,7 +71,9 @@ export declare class MemoryManager implements Plugin {
|
|
|
64
71
|
*
|
|
65
72
|
* @param agent - The agent this plugin is being attached to
|
|
66
73
|
*/
|
|
67
|
-
initAgent(agent: LocalAgent): void
|
|
74
|
+
initAgent(agent: LocalAgent): Promise<void>;
|
|
75
|
+
/** Call `initialize()` on each store that implements it. */
|
|
76
|
+
private _initStores;
|
|
68
77
|
/** Wires background extraction for stores configured with {@link ExtractionConfig}. */
|
|
69
78
|
private _initExtraction;
|
|
70
79
|
/**
|
|
@@ -157,8 +166,12 @@ export declare class MemoryManager implements Plugin {
|
|
|
157
166
|
*
|
|
158
167
|
* @param content - The text content to add
|
|
159
168
|
* @param options - Optional metadata and store name filter
|
|
169
|
+
* @param detached - Internal. When the write runs detached from the call that scheduled it (the
|
|
170
|
+
* fire-and-forget add tool path), start the span as a trace root rather than parenting to a
|
|
171
|
+
* possibly-ended span.
|
|
172
|
+
* @internal
|
|
160
173
|
*/
|
|
161
|
-
add(content: string, options?: MemoryAddOptions): Promise<void>;
|
|
174
|
+
add(content: string, options?: MemoryAddOptions, detached?: boolean): Promise<void>;
|
|
162
175
|
/**
|
|
163
176
|
* Resolves the store names that a tool callback should target against the tool's scoped set.
|
|
164
177
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-manager.d.ts","sourceRoot":"","sources":["../../../src/memory/memory-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,KAAK,EACV,WAAW,EAEX,mBAAmB,EACnB,mBAAmB,EAEnB,gBAAgB,EAGjB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"memory-manager.d.ts","sourceRoot":"","sources":["../../../src/memory/memory-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,KAAK,EACV,WAAW,EAEX,mBAAmB,EACnB,mBAAmB,EAEnB,gBAAgB,EAGjB,MAAM,YAAY,CAAA;AAsBnB;;;GAGG;AACH,eAAO,MAAM,0BAA0B,IAAI,CAAA;AAyB3C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,aAAc,YAAW,MAAM;IAC1C,QAAQ,CAAC,IAAI,4BAA2B;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,6FAA6F;IAC7F,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAC1C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA0B;IAC5D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAC5D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAe;IAC9C,2GAA2G;IAC3G,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;IACvD,qGAAqG;IACrG,OAAO,CAAC,YAAY,CAAmC;IACvD,wEAAwE;IACxE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA+B;IAChE;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;gBAE3B,MAAM,EAAE,mBAAmB;IAuEvC;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;;;;;;;;;;OAWG;IACG,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjD,4DAA4D;YAC9C,WAAW;IAQzB,uFAAuF;IACvF,OAAO,CAAC,eAAe;IAoBvB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IActB;;;;;;;;;;;OAWG;YACW,qBAAqB;IA+CnC;;;;;;;;;;;OAWG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;;;;;;;OAQG;IACH,OAAO,CAAC,sBAAsB;IAsB9B;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;IAS/B,yEAAyE;IACzE,OAAO,CAAC,cAAc;IAStB;;;;;;;OAOG;IACH,QAAQ,IAAI,IAAI,EAAE;IAmBlB;;;;;;;;;;;;;;;;OAgBG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA4DlF;;;;;;;;;;;;;;;OAeG;IACG,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,EAAE,QAAQ,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA2DvF;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,mBAAmB;IAqB3B,OAAO,CAAC,iBAAiB;IAyCzB,OAAO,CAAC,cAAc;CAsDvB"}
|
|
@@ -8,6 +8,8 @@ import { normalizeError } from '../errors.js';
|
|
|
8
8
|
import { isUserTurn, createInjectionMiddleware } from '../injection/message-injection.js';
|
|
9
9
|
import { escapeXmlText, escapeXmlAttr } from '../injection/xml.js';
|
|
10
10
|
import { InvokeModelStage } from '../middleware/index.js';
|
|
11
|
+
import { Tracer } from '../telemetry/tracer.js';
|
|
12
|
+
import { context, trace } from '@opentelemetry/api';
|
|
11
13
|
const SEARCH_TOOL_DESCRIPTION = 'Search long-term memory for facts, preferences, or context from previous conversations. Use when you need background about the user or topic that may have been discussed before.';
|
|
12
14
|
const ADD_TOOL_DESCRIPTION = 'Add facts, preferences, or decisions to long-term memory so they are remembered across conversations. Use when the user shares something worth recalling later.';
|
|
13
15
|
/**
|
|
@@ -73,6 +75,13 @@ export class MemoryManager {
|
|
|
73
75
|
_coordinator;
|
|
74
76
|
/** Resolved injection config, or `false` when injection is disabled. */
|
|
75
77
|
_injectionConfig;
|
|
78
|
+
/**
|
|
79
|
+
* Tracer for memory operation spans, shared with the extraction coordinator. A per-instance
|
|
80
|
+
* Tracer is intentional: it wraps the same global OTel provider, and parent-child nesting is
|
|
81
|
+
* established via OTel context (context.active() / context.with()), not instance hierarchy — so a
|
|
82
|
+
* fresh instance routes spans to the same exporter and parents correctly without fragmenting traces.
|
|
83
|
+
*/
|
|
84
|
+
_tracer = new Tracer();
|
|
76
85
|
constructor(config) {
|
|
77
86
|
if (config.stores.length === 0) {
|
|
78
87
|
throw new Error('MemoryManager: at least one store is required');
|
|
@@ -170,16 +179,25 @@ export class MemoryManager {
|
|
|
170
179
|
*
|
|
171
180
|
* @param agent - The agent this plugin is being attached to
|
|
172
181
|
*/
|
|
173
|
-
initAgent(agent) {
|
|
182
|
+
async initAgent(agent) {
|
|
183
|
+
await this._initStores();
|
|
174
184
|
this._initExtraction(agent);
|
|
175
185
|
this._initInjection(agent);
|
|
176
186
|
}
|
|
187
|
+
/** Call `initialize()` on each store that implements it. */
|
|
188
|
+
async _initStores() {
|
|
189
|
+
for (const store of this._searchStores) {
|
|
190
|
+
if (store.initialize) {
|
|
191
|
+
await store.initialize();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
177
195
|
/** Wires background extraction for stores configured with {@link ExtractionConfig}. */
|
|
178
196
|
_initExtraction(agent) {
|
|
179
197
|
if (this._extractionStores.length === 0) {
|
|
180
198
|
return;
|
|
181
199
|
}
|
|
182
|
-
const coordinator = new ExtractionCoordinator(this._extractionStores, agent.model);
|
|
200
|
+
const coordinator = new ExtractionCoordinator(this._extractionStores, agent.model, this._tracer);
|
|
183
201
|
this._coordinator = coordinator;
|
|
184
202
|
// Buffer every message the agent adds, so extraction has its own copy to save from.
|
|
185
203
|
agent.addHook(MessageAddedEvent, (event) => {
|
|
@@ -219,21 +237,43 @@ export class MemoryManager {
|
|
|
219
237
|
* @returns The injected text, or `undefined` when there is nothing to inject
|
|
220
238
|
*/
|
|
221
239
|
async _provideMemoryContext(messages, config) {
|
|
222
|
-
const query = this._resolveInjectionQuery(messages, config);
|
|
223
|
-
if (!query?.trim()) {
|
|
224
|
-
return undefined;
|
|
225
|
-
}
|
|
226
240
|
const maxResults = config.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
241
|
+
const span = this._tracer.startMemoryInjectSpan({ maxEntries: maxResults });
|
|
242
|
+
// End the inject span on every path (skip, fail-open, success). Injection fails open, so a
|
|
243
|
+
// format failure ends OK with a flag; only callers above us treat a thrown search as an error.
|
|
244
|
+
const end = (injected, entryCount = 0, formatError = false) => {
|
|
245
|
+
this._tracer.endMemoryInjectSpan(span, { injected, entryCount, formatError });
|
|
246
|
+
};
|
|
247
|
+
// Set the inject span active so the nested search span parents under it.
|
|
248
|
+
const run = async () => {
|
|
249
|
+
const query = this._resolveInjectionQuery(messages, config);
|
|
250
|
+
if (!query?.trim()) {
|
|
251
|
+
end(false);
|
|
252
|
+
return undefined;
|
|
253
|
+
}
|
|
254
|
+
const entries = (await this.search(query, { maxSearchResults: maxResults })).slice(0, maxResults);
|
|
255
|
+
if (entries.length === 0) {
|
|
256
|
+
end(false);
|
|
257
|
+
return undefined;
|
|
258
|
+
}
|
|
259
|
+
try {
|
|
260
|
+
const rendered = config.format ? config.format({ entries }) : this._defaultInjectionFormat(entries);
|
|
261
|
+
end(true, entries.length);
|
|
262
|
+
return rendered;
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
logger.warn(`reason=<${normalizeError(error).message}> | injection format threw; skipping injection`);
|
|
266
|
+
end(false, 0, true);
|
|
267
|
+
return undefined;
|
|
268
|
+
}
|
|
269
|
+
};
|
|
231
270
|
try {
|
|
232
|
-
return
|
|
271
|
+
return span ? await context.with(trace.setSpan(context.active(), span), run) : await run();
|
|
233
272
|
}
|
|
234
273
|
catch (error) {
|
|
235
|
-
|
|
236
|
-
|
|
274
|
+
// search (or anything else here) throwing must not leak the span; end it and rethrow.
|
|
275
|
+
end(false);
|
|
276
|
+
throw error;
|
|
237
277
|
}
|
|
238
278
|
}
|
|
239
279
|
/**
|
|
@@ -344,30 +384,48 @@ export class MemoryManager {
|
|
|
344
384
|
*/
|
|
345
385
|
async search(query, options) {
|
|
346
386
|
logger.debug(`query=<${query}>, max_search_results=<${options?.maxSearchResults}>, stores=<${options?.stores}> | searching stores`);
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
387
|
+
const spanStoreNames = options?.stores ?? this._config.stores.map((s) => s.name);
|
|
388
|
+
const span = this._tracer.startMemorySearchSpan({
|
|
389
|
+
query,
|
|
390
|
+
storeNames: spanStoreNames,
|
|
391
|
+
...(options?.maxSearchResults !== undefined && { maxSearchResults: options.maxSearchResults }),
|
|
392
|
+
});
|
|
393
|
+
let targetStores;
|
|
394
|
+
let settled;
|
|
395
|
+
try {
|
|
396
|
+
targetStores =
|
|
397
|
+
options?.stores !== undefined
|
|
398
|
+
? [...new Set(options.stores)].map((name) => {
|
|
399
|
+
const found = this._config.stores.find((s) => s.name === name);
|
|
400
|
+
if (!found) {
|
|
401
|
+
throw new Error(`MemoryManager: store '${name}' not found`);
|
|
402
|
+
}
|
|
403
|
+
return found;
|
|
404
|
+
})
|
|
405
|
+
: this._config.stores;
|
|
406
|
+
settled = await Promise.allSettled(targetStores.map((store) => store.search(query, {
|
|
407
|
+
maxSearchResults: options?.maxSearchResults ?? store.maxSearchResults ?? DEFAULT_MAX_SEARCH_RESULTS,
|
|
408
|
+
})));
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
this._tracer.endMemorySearchSpan(span, { error: normalizeError(error) });
|
|
412
|
+
throw error;
|
|
413
|
+
}
|
|
359
414
|
const results = [];
|
|
415
|
+
let storeFailureCount = 0;
|
|
360
416
|
for (let i = 0; i < settled.length; i++) {
|
|
361
417
|
const settledResult = settled[i];
|
|
362
418
|
const storeName = targetStores[i].name;
|
|
363
419
|
if (settledResult.status === 'rejected') {
|
|
364
420
|
logger.warn(`store=<${storeName}>, reason=<${normalizeError(settledResult.reason).message}> | store search failed`);
|
|
421
|
+
storeFailureCount++;
|
|
365
422
|
continue;
|
|
366
423
|
}
|
|
367
424
|
for (const entry of settledResult.value) {
|
|
368
425
|
results.push({ ...entry, storeName });
|
|
369
426
|
}
|
|
370
427
|
}
|
|
428
|
+
this._tracer.endMemorySearchSpan(span, { entries: results, storeFailureCount });
|
|
371
429
|
logger.debug(`results=<${results.length}> | search complete`);
|
|
372
430
|
return results;
|
|
373
431
|
}
|
|
@@ -382,28 +440,45 @@ export class MemoryManager {
|
|
|
382
440
|
*
|
|
383
441
|
* @param content - The text content to add
|
|
384
442
|
* @param options - Optional metadata and store name filter
|
|
443
|
+
* @param detached - Internal. When the write runs detached from the call that scheduled it (the
|
|
444
|
+
* fire-and-forget add tool path), start the span as a trace root rather than parenting to a
|
|
445
|
+
* possibly-ended span.
|
|
446
|
+
* @internal
|
|
385
447
|
*/
|
|
386
|
-
async add(content, options) {
|
|
448
|
+
async add(content, options, detached = false) {
|
|
449
|
+
const spanStoreNames = options?.stores ?? this._addStores.map((s) => s.name);
|
|
450
|
+
const span = this._tracer.startMemoryAddSpan({
|
|
451
|
+
content,
|
|
452
|
+
storeNames: spanStoreNames,
|
|
453
|
+
...(detached && { forceRoot: true }),
|
|
454
|
+
});
|
|
387
455
|
let writableStores;
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
456
|
+
let settled;
|
|
457
|
+
try {
|
|
458
|
+
if (options?.stores !== undefined) {
|
|
459
|
+
writableStores = [...new Set(options.stores)].map((name) => {
|
|
460
|
+
const found = this._config.stores.find((s) => s.name === name);
|
|
461
|
+
if (!found) {
|
|
462
|
+
throw new Error(`MemoryManager: store '${name}' not found`);
|
|
463
|
+
}
|
|
464
|
+
if (!found.writable) {
|
|
465
|
+
throw new Error(`MemoryManager: store '${name}' is read-only`);
|
|
466
|
+
}
|
|
467
|
+
return found;
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
writableStores = this._addStores;
|
|
472
|
+
}
|
|
473
|
+
if (writableStores.length === 0) {
|
|
474
|
+
throw new Error('MemoryManager: no writable store matched');
|
|
475
|
+
}
|
|
476
|
+
settled = await Promise.allSettled(writableStores.map((store) => store.add(content, options?.metadata)));
|
|
402
477
|
}
|
|
403
|
-
|
|
404
|
-
|
|
478
|
+
catch (error) {
|
|
479
|
+
this._tracer.endMemoryAddSpan(span, { error: normalizeError(error) });
|
|
480
|
+
throw error;
|
|
405
481
|
}
|
|
406
|
-
const settled = await Promise.allSettled(writableStores.map((store) => store.add(content, options?.metadata)));
|
|
407
482
|
const failures = [];
|
|
408
483
|
for (let i = 0; i < settled.length; i++) {
|
|
409
484
|
const settledResult = settled[i];
|
|
@@ -414,8 +489,11 @@ export class MemoryManager {
|
|
|
414
489
|
}
|
|
415
490
|
}
|
|
416
491
|
if (failures.length > 0) {
|
|
417
|
-
|
|
492
|
+
const aggregateError = new AggregateError(failures.map((failure) => failure.reason), `MemoryManager: store writes failed: ${failures.map((failure) => failure.store).join(', ')}`);
|
|
493
|
+
this._tracer.endMemoryAddSpan(span, { storeFailureCount: failures.length, error: aggregateError });
|
|
494
|
+
throw aggregateError;
|
|
418
495
|
}
|
|
496
|
+
this._tracer.endMemoryAddSpan(span);
|
|
419
497
|
}
|
|
420
498
|
/**
|
|
421
499
|
* Resolves the store names that a tool callback should target against the tool's scoped set.
|
|
@@ -507,7 +585,7 @@ export class MemoryManager {
|
|
|
507
585
|
// Fire-and-forget: dispatch the writes without awaiting so the agent loop isn't blocked.
|
|
508
586
|
// add() logs per-store failures; swallow the rejection so it isn't an unhandled rejection.
|
|
509
587
|
for (const content of input.entries) {
|
|
510
|
-
void this.add(content, { stores }).catch(() => { });
|
|
588
|
+
void this.add(content, { stores }, true).catch(() => { });
|
|
511
589
|
}
|
|
512
590
|
return { accepted: input.entries.length };
|
|
513
591
|
}
|