memorylens 0.1.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/index.mjs ADDED
@@ -0,0 +1,447 @@
1
+ // src/types.ts
2
+ var ExportResult = /* @__PURE__ */ ((ExportResult2) => {
3
+ ExportResult2[ExportResult2["SUCCESS"] = 0] = "SUCCESS";
4
+ ExportResult2[ExportResult2["FAILURE"] = 1] = "FAILURE";
5
+ return ExportResult2;
6
+ })(ExportResult || {});
7
+
8
+ // src/context.ts
9
+ import { AsyncLocalStorage } from "async_hooks";
10
+ var contextStorage = new AsyncLocalStorage();
11
+ function runWithContext(ctx, fn) {
12
+ return contextStorage.run(ctx, fn);
13
+ }
14
+ function getCurrentContext() {
15
+ return contextStorage.getStore();
16
+ }
17
+
18
+ // src/tracer.ts
19
+ import { randomUUID } from "crypto";
20
+
21
+ // src/sampler.ts
22
+ var Sampler = class {
23
+ rate;
24
+ constructor(rate = 1) {
25
+ if (rate < 0 || rate > 1) {
26
+ throw new Error(`Sample rate must be between 0.0 and 1.0, got ${rate}`);
27
+ }
28
+ this.rate = rate;
29
+ }
30
+ shouldSample() {
31
+ if (this.rate === 1) return true;
32
+ if (this.rate === 0) return false;
33
+ return Math.random() < this.rate;
34
+ }
35
+ getRate() {
36
+ return this.rate;
37
+ }
38
+ };
39
+
40
+ // src/tracer.ts
41
+ var MutableSpan = class {
42
+ traceId;
43
+ spanId;
44
+ operation;
45
+ parentSpanId;
46
+ status = "ok";
47
+ startTime;
48
+ endTime = 0;
49
+ agentId;
50
+ sessionId;
51
+ userId;
52
+ inputContent = null;
53
+ outputContent = null;
54
+ attributes;
55
+ constructor(options) {
56
+ this.traceId = randomUUID().replace(/-/g, "");
57
+ this.spanId = randomUUID().replace(/-/g, "").substring(0, 16);
58
+ this.operation = options.operation;
59
+ this.parentSpanId = options.parentSpanId ?? null;
60
+ const ctx = getCurrentContext();
61
+ this.agentId = options.agentId !== void 0 ? options.agentId : ctx?.agentId ?? null;
62
+ this.sessionId = options.sessionId !== void 0 ? options.sessionId : ctx?.sessionId ?? null;
63
+ this.userId = options.userId !== void 0 ? options.userId : ctx?.userId ?? null;
64
+ this.attributes = { ...options.attributes };
65
+ this.startTime = Date.now();
66
+ }
67
+ setAttribute(key, value) {
68
+ this.attributes[key] = value;
69
+ }
70
+ setContent(input, output) {
71
+ if (input !== void 0) this.inputContent = input;
72
+ if (output !== void 0) this.outputContent = output;
73
+ }
74
+ setStatus(status) {
75
+ this.status = status;
76
+ }
77
+ setError(error) {
78
+ this.status = "error";
79
+ if (error instanceof Error) {
80
+ this.attributes["error.type"] = error.constructor.name;
81
+ this.attributes["error.message"] = error.message;
82
+ } else {
83
+ this.attributes["error.type"] = "Error";
84
+ this.attributes["error.message"] = String(error);
85
+ }
86
+ }
87
+ end() {
88
+ this.endTime = Date.now();
89
+ return {
90
+ spanId: this.spanId,
91
+ traceId: this.traceId,
92
+ parentSpanId: this.parentSpanId,
93
+ operation: this.operation,
94
+ status: this.status,
95
+ startTime: this.startTime,
96
+ endTime: this.endTime,
97
+ durationMs: this.endTime - this.startTime,
98
+ agentId: this.agentId,
99
+ sessionId: this.sessionId,
100
+ userId: this.userId,
101
+ inputContent: this.inputContent,
102
+ outputContent: this.outputContent,
103
+ attributes: { ...this.attributes }
104
+ };
105
+ }
106
+ };
107
+ var Tracer = class {
108
+ name;
109
+ provider;
110
+ constructor(name, provider) {
111
+ this.name = name;
112
+ this.provider = provider;
113
+ }
114
+ getName() {
115
+ return this.name;
116
+ }
117
+ startSpan(operation, attributes) {
118
+ const ctx = getCurrentContext();
119
+ return new MutableSpan({
120
+ operation,
121
+ agentId: ctx?.agentId ?? null,
122
+ sessionId: ctx?.sessionId ?? null,
123
+ userId: ctx?.userId ?? null,
124
+ attributes
125
+ });
126
+ }
127
+ endSpan(span) {
128
+ const finished = span.end();
129
+ for (const processor of this.provider.processors) {
130
+ processor.onEnd(finished);
131
+ }
132
+ }
133
+ };
134
+ var TracerProvider = class _TracerProvider {
135
+ static instance = null;
136
+ processors = [];
137
+ sampler = new Sampler(1);
138
+ serviceName = "memorylens";
139
+ static get() {
140
+ if (!_TracerProvider.instance) {
141
+ _TracerProvider.instance = new _TracerProvider();
142
+ }
143
+ return _TracerProvider.instance;
144
+ }
145
+ static reset() {
146
+ if (_TracerProvider.instance) {
147
+ for (const p of _TracerProvider.instance.processors) {
148
+ p.shutdown().catch(() => {
149
+ });
150
+ }
151
+ }
152
+ _TracerProvider.instance = null;
153
+ }
154
+ addProcessor(processor) {
155
+ this.processors.push(processor);
156
+ }
157
+ getTracer(name) {
158
+ return new Tracer(name, this);
159
+ }
160
+ async shutdown() {
161
+ for (const p of this.processors) {
162
+ await p.shutdown();
163
+ }
164
+ }
165
+ };
166
+
167
+ // src/processor.ts
168
+ var SimpleSpanProcessor = class {
169
+ exporter;
170
+ constructor(exporter) {
171
+ this.exporter = exporter;
172
+ }
173
+ onStart(_span) {
174
+ }
175
+ onEnd(span) {
176
+ this.exporter.export([span]);
177
+ }
178
+ async shutdown() {
179
+ await this.exporter.shutdown();
180
+ }
181
+ async forceFlush(_timeoutMs) {
182
+ return true;
183
+ }
184
+ };
185
+ var BatchSpanProcessor = class {
186
+ exporter;
187
+ queue = [];
188
+ maxBatchSize;
189
+ scheduleDelayMs;
190
+ maxQueueSize;
191
+ timer = null;
192
+ isShutdown = false;
193
+ constructor(exporter, options) {
194
+ this.exporter = exporter;
195
+ this.maxBatchSize = options?.maxBatchSize ?? 512;
196
+ this.scheduleDelayMs = options?.scheduleDelayMs ?? 5e3;
197
+ this.maxQueueSize = options?.maxQueueSize ?? 2048;
198
+ this.scheduleFlush();
199
+ }
200
+ onStart(_span) {
201
+ }
202
+ onEnd(span) {
203
+ if (this.isShutdown) return;
204
+ if (this.queue.length < this.maxQueueSize) {
205
+ this.queue.push(span);
206
+ }
207
+ if (this.queue.length >= this.maxBatchSize) {
208
+ this.flush();
209
+ }
210
+ }
211
+ async shutdown() {
212
+ this.isShutdown = true;
213
+ if (this.timer) clearTimeout(this.timer);
214
+ await this.flush();
215
+ await this.exporter.shutdown();
216
+ }
217
+ async forceFlush(_timeoutMs) {
218
+ await this.flush();
219
+ return true;
220
+ }
221
+ async flush() {
222
+ if (this.queue.length === 0) return;
223
+ const batch = this.queue.splice(0, this.maxBatchSize);
224
+ await this.exporter.export(batch);
225
+ }
226
+ scheduleFlush() {
227
+ this.timer = setTimeout(async () => {
228
+ await this.flush();
229
+ if (!this.isShutdown) this.scheduleFlush();
230
+ }, this.scheduleDelayMs);
231
+ if (this.timer && typeof this.timer === "object" && "unref" in this.timer) {
232
+ this.timer.unref();
233
+ }
234
+ }
235
+ };
236
+
237
+ // src/exporters/console.ts
238
+ var ConsoleExporter = class {
239
+ async export(spans) {
240
+ for (const span of spans) {
241
+ console.log(
242
+ JSON.stringify(
243
+ {
244
+ spanId: span.spanId,
245
+ traceId: span.traceId,
246
+ parentSpanId: span.parentSpanId,
247
+ operation: span.operation,
248
+ status: span.status,
249
+ startTime: span.startTime,
250
+ endTime: span.endTime,
251
+ durationMs: span.durationMs,
252
+ agentId: span.agentId,
253
+ sessionId: span.sessionId,
254
+ userId: span.userId,
255
+ inputContent: span.inputContent,
256
+ outputContent: span.outputContent,
257
+ attributes: span.attributes
258
+ },
259
+ null,
260
+ 2
261
+ )
262
+ );
263
+ }
264
+ return 0 /* SUCCESS */;
265
+ }
266
+ async shutdown() {
267
+ }
268
+ };
269
+
270
+ // src/exporters/otlp.ts
271
+ var OTLPExporter = class {
272
+ endpoint;
273
+ constructor(options) {
274
+ this.endpoint = options?.endpoint ?? process.env["OTEL_EXPORTER_OTLP_ENDPOINT"] ?? "http://localhost:8000/v1/traces";
275
+ }
276
+ async export(spans) {
277
+ if (spans.length === 0) return 0 /* SUCCESS */;
278
+ const body = this.buildOTLPPayload(spans);
279
+ try {
280
+ const response = await fetch(this.endpoint, {
281
+ method: "POST",
282
+ headers: { "Content-Type": "application/json" },
283
+ body: JSON.stringify(body)
284
+ });
285
+ if (!response.ok) {
286
+ return 1 /* FAILURE */;
287
+ }
288
+ return 0 /* SUCCESS */;
289
+ } catch {
290
+ return 1 /* FAILURE */;
291
+ }
292
+ }
293
+ async shutdown() {
294
+ }
295
+ buildOTLPPayload(spans) {
296
+ return {
297
+ resourceSpans: [
298
+ {
299
+ resource: {
300
+ attributes: [
301
+ {
302
+ key: "service.name",
303
+ value: {
304
+ stringValue: process.env["OTEL_SERVICE_NAME"] ?? "memorylens"
305
+ }
306
+ }
307
+ ]
308
+ },
309
+ scopeSpans: [
310
+ {
311
+ scope: { name: "memorylens", version: "0.1.0" },
312
+ spans: spans.map((span) => this.spanToOTLP(span))
313
+ }
314
+ ]
315
+ }
316
+ ]
317
+ };
318
+ }
319
+ spanToOTLP(span) {
320
+ const startTimeUnixNano = String(span.startTime * 1e6);
321
+ const endTimeUnixNano = String(span.endTime * 1e6);
322
+ const attributes = [{ key: "memory.operation", value: { stringValue: span.operation } }];
323
+ if (span.agentId) attributes.push({ key: "agent.id", value: { stringValue: span.agentId } });
324
+ if (span.sessionId)
325
+ attributes.push({ key: "session.id", value: { stringValue: span.sessionId } });
326
+ if (span.userId) attributes.push({ key: "user.id", value: { stringValue: span.userId } });
327
+ if (span.inputContent)
328
+ attributes.push({ key: "memory.input", value: { stringValue: span.inputContent } });
329
+ if (span.outputContent)
330
+ attributes.push({ key: "memory.output", value: { stringValue: span.outputContent } });
331
+ for (const [key, val] of Object.entries(span.attributes)) {
332
+ attributes.push({ key, value: { stringValue: String(val) } });
333
+ }
334
+ return {
335
+ traceId: span.traceId,
336
+ spanId: span.spanId,
337
+ parentSpanId: span.parentSpanId ?? void 0,
338
+ name: span.operation,
339
+ kind: 1,
340
+ // SPAN_KIND_INTERNAL
341
+ startTimeUnixNano,
342
+ endTimeUnixNano,
343
+ attributes,
344
+ status: {
345
+ code: span.status === "ok" ? 1 : span.status === "error" ? 2 : 0
346
+ }
347
+ };
348
+ }
349
+ };
350
+
351
+ // src/wrappers.ts
352
+ function createWrapper(operation, fn, options = {}) {
353
+ const { captureContent = true, ...extraAttrs } = options;
354
+ const attributes = { ...extraAttrs };
355
+ return async (...args) => {
356
+ const provider = TracerProvider.get();
357
+ if (!provider.sampler.shouldSample()) {
358
+ return fn(...args);
359
+ }
360
+ const tracer = provider.getTracer("memorylens.wrappers");
361
+ const span = tracer.startSpan(operation, attributes);
362
+ if (captureContent && args.length > 0) {
363
+ const firstArg = args[0];
364
+ if (typeof firstArg === "string") {
365
+ span.setContent(firstArg, void 0);
366
+ }
367
+ }
368
+ try {
369
+ const result = await fn(...args);
370
+ span.setStatus("ok");
371
+ if (captureContent && result !== void 0) {
372
+ if (typeof result === "string") {
373
+ span.setContent(void 0, result);
374
+ } else if (result !== null && typeof result === "object") {
375
+ span.setContent(void 0, JSON.stringify(result));
376
+ }
377
+ }
378
+ tracer.endSpan(span);
379
+ return result;
380
+ } catch (error) {
381
+ span.setError(error);
382
+ tracer.endSpan(span);
383
+ throw error;
384
+ }
385
+ };
386
+ }
387
+ function instrumentWrite(fn, options) {
388
+ return createWrapper("memory.write", fn, options);
389
+ }
390
+ function instrumentRead(fn, options) {
391
+ return createWrapper("memory.read", fn, options);
392
+ }
393
+ function instrumentCompress(fn, options) {
394
+ return createWrapper("memory.compress", fn, options);
395
+ }
396
+ function instrumentUpdate(fn, options) {
397
+ return createWrapper("memory.update", fn, options);
398
+ }
399
+
400
+ // src/index.ts
401
+ function init(options = {}) {
402
+ const {
403
+ serviceName = process.env["OTEL_SERVICE_NAME"] ?? "memorylens",
404
+ exporter: exporterType = process.env["MEMORYLENS_EXPORTER"] ?? "otlp",
405
+ endpoint,
406
+ sampleRate = parseFloat(process.env["MEMORYLENS_SAMPLE_RATE"] ?? "1.0"),
407
+ batch = true
408
+ } = options;
409
+ const provider = TracerProvider.get();
410
+ provider.serviceName = serviceName;
411
+ provider.sampler = new Sampler(sampleRate);
412
+ const exp = exporterType === "console" ? new ConsoleExporter() : new OTLPExporter({ endpoint });
413
+ const processor = batch ? new BatchSpanProcessor(exp) : new SimpleSpanProcessor(exp);
414
+ provider.addProcessor(processor);
415
+ }
416
+ async function shutdown() {
417
+ const provider = TracerProvider.get();
418
+ await provider.shutdown();
419
+ TracerProvider.reset();
420
+ }
421
+ async function context(ctx, fn) {
422
+ return runWithContext(ctx, fn);
423
+ }
424
+ function getTracer(name) {
425
+ return TracerProvider.get().getTracer(name);
426
+ }
427
+ export {
428
+ BatchSpanProcessor,
429
+ ConsoleExporter,
430
+ ExportResult,
431
+ MutableSpan,
432
+ OTLPExporter,
433
+ Sampler,
434
+ SimpleSpanProcessor,
435
+ Tracer,
436
+ TracerProvider,
437
+ context,
438
+ getCurrentContext,
439
+ getTracer,
440
+ init,
441
+ instrumentCompress,
442
+ instrumentRead,
443
+ instrumentUpdate,
444
+ instrumentWrite,
445
+ runWithContext,
446
+ shutdown
447
+ };
@@ -0,0 +1,9 @@
1
+ import { I as Instrumentor } from '../../index-BZqWj0_R.mjs';
2
+
3
+ declare class LangChainInstrumentor implements Instrumentor {
4
+ private patched;
5
+ instrument(_options?: Record<string, unknown>): void;
6
+ uninstrument(): void;
7
+ }
8
+
9
+ export { LangChainInstrumentor };
@@ -0,0 +1,9 @@
1
+ import { I as Instrumentor } from '../../index-BZqWj0_R.js';
2
+
3
+ declare class LangChainInstrumentor implements Instrumentor {
4
+ private patched;
5
+ instrument(_options?: Record<string, unknown>): void;
6
+ uninstrument(): void;
7
+ }
8
+
9
+ export { LangChainInstrumentor };
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/integrations/langchain/index.ts
21
+ var langchain_exports = {};
22
+ __export(langchain_exports, {
23
+ LangChainInstrumentor: () => LangChainInstrumentor
24
+ });
25
+ module.exports = __toCommonJS(langchain_exports);
26
+
27
+ // src/tracer.ts
28
+ var import_node_crypto = require("crypto");
29
+
30
+ // src/context.ts
31
+ var import_node_async_hooks = require("async_hooks");
32
+ var contextStorage = new import_node_async_hooks.AsyncLocalStorage();
33
+ function getCurrentContext() {
34
+ return contextStorage.getStore();
35
+ }
36
+
37
+ // src/sampler.ts
38
+ var Sampler = class {
39
+ rate;
40
+ constructor(rate = 1) {
41
+ if (rate < 0 || rate > 1) {
42
+ throw new Error(`Sample rate must be between 0.0 and 1.0, got ${rate}`);
43
+ }
44
+ this.rate = rate;
45
+ }
46
+ shouldSample() {
47
+ if (this.rate === 1) return true;
48
+ if (this.rate === 0) return false;
49
+ return Math.random() < this.rate;
50
+ }
51
+ getRate() {
52
+ return this.rate;
53
+ }
54
+ };
55
+
56
+ // src/tracer.ts
57
+ var MutableSpan = class {
58
+ traceId;
59
+ spanId;
60
+ operation;
61
+ parentSpanId;
62
+ status = "ok";
63
+ startTime;
64
+ endTime = 0;
65
+ agentId;
66
+ sessionId;
67
+ userId;
68
+ inputContent = null;
69
+ outputContent = null;
70
+ attributes;
71
+ constructor(options) {
72
+ this.traceId = (0, import_node_crypto.randomUUID)().replace(/-/g, "");
73
+ this.spanId = (0, import_node_crypto.randomUUID)().replace(/-/g, "").substring(0, 16);
74
+ this.operation = options.operation;
75
+ this.parentSpanId = options.parentSpanId ?? null;
76
+ const ctx = getCurrentContext();
77
+ this.agentId = options.agentId !== void 0 ? options.agentId : ctx?.agentId ?? null;
78
+ this.sessionId = options.sessionId !== void 0 ? options.sessionId : ctx?.sessionId ?? null;
79
+ this.userId = options.userId !== void 0 ? options.userId : ctx?.userId ?? null;
80
+ this.attributes = { ...options.attributes };
81
+ this.startTime = Date.now();
82
+ }
83
+ setAttribute(key, value) {
84
+ this.attributes[key] = value;
85
+ }
86
+ setContent(input, output) {
87
+ if (input !== void 0) this.inputContent = input;
88
+ if (output !== void 0) this.outputContent = output;
89
+ }
90
+ setStatus(status) {
91
+ this.status = status;
92
+ }
93
+ setError(error) {
94
+ this.status = "error";
95
+ if (error instanceof Error) {
96
+ this.attributes["error.type"] = error.constructor.name;
97
+ this.attributes["error.message"] = error.message;
98
+ } else {
99
+ this.attributes["error.type"] = "Error";
100
+ this.attributes["error.message"] = String(error);
101
+ }
102
+ }
103
+ end() {
104
+ this.endTime = Date.now();
105
+ return {
106
+ spanId: this.spanId,
107
+ traceId: this.traceId,
108
+ parentSpanId: this.parentSpanId,
109
+ operation: this.operation,
110
+ status: this.status,
111
+ startTime: this.startTime,
112
+ endTime: this.endTime,
113
+ durationMs: this.endTime - this.startTime,
114
+ agentId: this.agentId,
115
+ sessionId: this.sessionId,
116
+ userId: this.userId,
117
+ inputContent: this.inputContent,
118
+ outputContent: this.outputContent,
119
+ attributes: { ...this.attributes }
120
+ };
121
+ }
122
+ };
123
+ var Tracer = class {
124
+ name;
125
+ provider;
126
+ constructor(name, provider) {
127
+ this.name = name;
128
+ this.provider = provider;
129
+ }
130
+ getName() {
131
+ return this.name;
132
+ }
133
+ startSpan(operation, attributes) {
134
+ const ctx = getCurrentContext();
135
+ return new MutableSpan({
136
+ operation,
137
+ agentId: ctx?.agentId ?? null,
138
+ sessionId: ctx?.sessionId ?? null,
139
+ userId: ctx?.userId ?? null,
140
+ attributes
141
+ });
142
+ }
143
+ endSpan(span) {
144
+ const finished = span.end();
145
+ for (const processor of this.provider.processors) {
146
+ processor.onEnd(finished);
147
+ }
148
+ }
149
+ };
150
+ var TracerProvider = class _TracerProvider {
151
+ static instance = null;
152
+ processors = [];
153
+ sampler = new Sampler(1);
154
+ serviceName = "memorylens";
155
+ static get() {
156
+ if (!_TracerProvider.instance) {
157
+ _TracerProvider.instance = new _TracerProvider();
158
+ }
159
+ return _TracerProvider.instance;
160
+ }
161
+ static reset() {
162
+ if (_TracerProvider.instance) {
163
+ for (const p of _TracerProvider.instance.processors) {
164
+ p.shutdown().catch(() => {
165
+ });
166
+ }
167
+ }
168
+ _TracerProvider.instance = null;
169
+ }
170
+ addProcessor(processor) {
171
+ this.processors.push(processor);
172
+ }
173
+ getTracer(name) {
174
+ return new Tracer(name, this);
175
+ }
176
+ async shutdown() {
177
+ for (const p of this.processors) {
178
+ await p.shutdown();
179
+ }
180
+ }
181
+ };
182
+
183
+ // src/integrations/langchain/instrumentor.ts
184
+ var originals = /* @__PURE__ */ new WeakMap();
185
+ var LangChainInstrumentor = class {
186
+ patched = false;
187
+ instrument(_options) {
188
+ if (this.patched) return;
189
+ let BaseChatMemory;
190
+ try {
191
+ const mod = require("langchain/memory");
192
+ BaseChatMemory = mod.BaseChatMemory;
193
+ } catch {
194
+ console.warn("[memorylens] langchain/memory not found \u2014 LangChain instrumentation skipped");
195
+ return;
196
+ }
197
+ if (!BaseChatMemory?.prototype) return;
198
+ const proto = BaseChatMemory.prototype;
199
+ const origSaveContext = proto.saveContext;
200
+ const origLoadMemoryVariables = proto.loadMemoryVariables;
201
+ proto.saveContext = async function(...args) {
202
+ const provider = TracerProvider.get();
203
+ const tracer = provider.getTracer("memorylens.langchain");
204
+ const span = tracer.startSpan("memory.write", { "langchain.method": "saveContext" });
205
+ try {
206
+ const result = await origSaveContext.apply(this, args);
207
+ tracer.endSpan(span);
208
+ return result;
209
+ } catch (error) {
210
+ span.setError(error);
211
+ tracer.endSpan(span);
212
+ throw error;
213
+ }
214
+ };
215
+ proto.loadMemoryVariables = async function(...args) {
216
+ const provider = TracerProvider.get();
217
+ const tracer = provider.getTracer("memorylens.langchain");
218
+ const span = tracer.startSpan("memory.read", {
219
+ "langchain.method": "loadMemoryVariables"
220
+ });
221
+ try {
222
+ const result = await origLoadMemoryVariables.apply(this, args);
223
+ tracer.endSpan(span);
224
+ return result;
225
+ } catch (error) {
226
+ span.setError(error);
227
+ tracer.endSpan(span);
228
+ throw error;
229
+ }
230
+ };
231
+ originals.set(proto, { saveContext: origSaveContext, loadMemoryVariables: origLoadMemoryVariables });
232
+ this.patched = true;
233
+ }
234
+ uninstrument() {
235
+ if (!this.patched) return;
236
+ let BaseChatMemory;
237
+ try {
238
+ const mod = require("langchain/memory");
239
+ BaseChatMemory = mod.BaseChatMemory;
240
+ } catch {
241
+ return;
242
+ }
243
+ if (!BaseChatMemory?.prototype) return;
244
+ const proto = BaseChatMemory.prototype;
245
+ const orig = originals.get(proto);
246
+ if (orig) {
247
+ proto.saveContext = orig.saveContext;
248
+ proto.loadMemoryVariables = orig.loadMemoryVariables;
249
+ originals.delete(proto);
250
+ }
251
+ this.patched = false;
252
+ }
253
+ };
254
+ // Annotate the CommonJS export names for ESM import in node:
255
+ 0 && (module.exports = {
256
+ LangChainInstrumentor
257
+ });