@cloudbase/agent-observability 1.0.1-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +231 -0
- package/dist/chunk-NFEGQTCC.mjs +27 -0
- package/dist/chunk-NFEGQTCC.mjs.map +1 -0
- package/dist/chunk-ZGEMAYS4.mjs +716 -0
- package/dist/chunk-ZGEMAYS4.mjs.map +1 -0
- package/dist/esm-PGEDANAI.mjs +1030 -0
- package/dist/esm-PGEDANAI.mjs.map +1 -0
- package/dist/index.d.mts +728 -0
- package/dist/index.d.ts +728 -0
- package/dist/index.js +732 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +52 -0
- package/dist/index.mjs.map +1 -0
- package/dist/langchain.d.mts +108 -0
- package/dist/langchain.d.ts +108 -0
- package/dist/langchain.js +1237 -0
- package/dist/langchain.js.map +1 -0
- package/dist/langchain.mjs +535 -0
- package/dist/langchain.mjs.map +1 -0
- package/dist/server.d.mts +163 -0
- package/dist/server.d.ts +163 -0
- package/dist/server.js +1530 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +177 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +91 -0
- package/src/core/attributes.ts +233 -0
- package/src/core/constants.ts +75 -0
- package/src/core/spanWrapper.ts +417 -0
- package/src/core/tracerProvider.ts +136 -0
- package/src/index.ts +775 -0
- package/src/langchain/CallbackHandler.ts +893 -0
- package/src/langchain/index.ts +7 -0
- package/src/server/config.ts +160 -0
- package/src/server/index.ts +21 -0
- package/src/server/setup.ts +349 -0
- package/src/types.ts +254 -0
|
@@ -0,0 +1,1237 @@
|
|
|
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 __esm = (fn, res) => function __init() {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
};
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
|
|
23
|
+
// src/core/constants.ts
|
|
24
|
+
var import_openinference_semantic_conventions, OtelSpanAttributes;
|
|
25
|
+
var init_constants = __esm({
|
|
26
|
+
"src/core/constants.ts"() {
|
|
27
|
+
"use strict";
|
|
28
|
+
import_openinference_semantic_conventions = require("@arizeai/openinference-semantic-conventions");
|
|
29
|
+
OtelSpanAttributes = {
|
|
30
|
+
// OpenInference - re-export all standard conventions
|
|
31
|
+
...import_openinference_semantic_conventions.SemanticConventions,
|
|
32
|
+
// AG-Kit Trace attributes (non-standard)
|
|
33
|
+
TRACE_NAME: "trace.name",
|
|
34
|
+
TRACE_TAGS: "trace.tags",
|
|
35
|
+
TRACE_PUBLIC: "trace.public",
|
|
36
|
+
TRACE_METADATA: "trace.metadata",
|
|
37
|
+
TRACE_INPUT: "trace.input",
|
|
38
|
+
TRACE_OUTPUT: "trace.output",
|
|
39
|
+
// AG-Kit Observation attributes (non-standard)
|
|
40
|
+
OBSERVATION_TYPE: "observation.type",
|
|
41
|
+
OBSERVATION_LEVEL: "observation.level",
|
|
42
|
+
OBSERVATION_STATUS_MESSAGE: "observation.status_message",
|
|
43
|
+
OBSERVATION_INPUT: "observation.input",
|
|
44
|
+
OBSERVATION_OUTPUT: "observation.output",
|
|
45
|
+
OBSERVATION_METADATA: "observation.metadata",
|
|
46
|
+
// AG-Kit LLM-specific (non-standard)
|
|
47
|
+
LLM_COMPLETION_START_TIME: "llm.completion_start_time",
|
|
48
|
+
LLM_MODEL_PARAMETERS: "llm.model_parameters",
|
|
49
|
+
LLM_USAGE_DETAILS: "llm.usage_details",
|
|
50
|
+
LLM_COST_DETAILS: "llm.cost_details",
|
|
51
|
+
// AG-Kit Retriever-specific (non-standard)
|
|
52
|
+
RETRIEVER_NAME: "retriever.name",
|
|
53
|
+
RETRIEVER_QUERY: "retriever.query",
|
|
54
|
+
RETRIEVER_INDEX_ID: "retriever.index_id",
|
|
55
|
+
RETRIEVER_TOP_K: "retriever.top_k",
|
|
56
|
+
// AG-Kit General (non-standard)
|
|
57
|
+
ENVIRONMENT: "environment",
|
|
58
|
+
RELEASE: "release",
|
|
59
|
+
VERSION: "version"
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// src/core/attributes.ts
|
|
65
|
+
function createTraceAttributes({
|
|
66
|
+
name,
|
|
67
|
+
userId,
|
|
68
|
+
sessionId,
|
|
69
|
+
version,
|
|
70
|
+
release,
|
|
71
|
+
input,
|
|
72
|
+
output,
|
|
73
|
+
metadata,
|
|
74
|
+
tags,
|
|
75
|
+
environment,
|
|
76
|
+
public: isPublic
|
|
77
|
+
} = {}) {
|
|
78
|
+
const attributes = {
|
|
79
|
+
[OtelSpanAttributes.TRACE_NAME]: name,
|
|
80
|
+
// Use OpenInference standard attributes for user and session
|
|
81
|
+
[OtelSpanAttributes.USER_ID]: userId,
|
|
82
|
+
[OtelSpanAttributes.SESSION_ID]: sessionId,
|
|
83
|
+
[OtelSpanAttributes.VERSION]: version,
|
|
84
|
+
[OtelSpanAttributes.RELEASE]: release,
|
|
85
|
+
[OtelSpanAttributes.TRACE_INPUT]: _serialize(input),
|
|
86
|
+
[OtelSpanAttributes.TRACE_OUTPUT]: _serialize(output),
|
|
87
|
+
[OtelSpanAttributes.TRACE_TAGS]: tags,
|
|
88
|
+
[OtelSpanAttributes.ENVIRONMENT]: environment,
|
|
89
|
+
[OtelSpanAttributes.TRACE_PUBLIC]: isPublic,
|
|
90
|
+
..._flattenAndSerializeMetadata(metadata, OtelSpanAttributes.TRACE_METADATA)
|
|
91
|
+
};
|
|
92
|
+
return Object.fromEntries(
|
|
93
|
+
Object.entries(attributes).filter(([_, v]) => v != null)
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
function createObservationAttributes(type, attributes) {
|
|
97
|
+
const {
|
|
98
|
+
metadata,
|
|
99
|
+
input,
|
|
100
|
+
output,
|
|
101
|
+
level,
|
|
102
|
+
statusMessage,
|
|
103
|
+
version,
|
|
104
|
+
completionStartTime,
|
|
105
|
+
model,
|
|
106
|
+
modelParameters,
|
|
107
|
+
usageDetails
|
|
108
|
+
} = attributes;
|
|
109
|
+
const otelAttributes = {
|
|
110
|
+
[import_openinference_semantic_conventions2.SemanticConventions.OPENINFERENCE_SPAN_KIND]: type.toUpperCase(),
|
|
111
|
+
[OtelSpanAttributes.OBSERVATION_TYPE]: type,
|
|
112
|
+
[OtelSpanAttributes.OBSERVATION_LEVEL]: level,
|
|
113
|
+
[OtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,
|
|
114
|
+
[OtelSpanAttributes.VERSION]: version,
|
|
115
|
+
// Use OpenInference input.value convention
|
|
116
|
+
[import_openinference_semantic_conventions2.SemanticConventions.INPUT_VALUE]: _serialize(input),
|
|
117
|
+
// Also set legacy agkit.observation.input for compatibility
|
|
118
|
+
[OtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),
|
|
119
|
+
// Use OpenInference output.value convention
|
|
120
|
+
[import_openinference_semantic_conventions2.SemanticConventions.OUTPUT_VALUE]: _serialize(output),
|
|
121
|
+
// Also set legacy agkit.observation.output for compatibility
|
|
122
|
+
[OtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output)
|
|
123
|
+
};
|
|
124
|
+
if (type === "llm") {
|
|
125
|
+
if (model) {
|
|
126
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_MODEL_NAME] = model;
|
|
127
|
+
}
|
|
128
|
+
if (modelParameters) {
|
|
129
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_INVOCATION_PARAMETERS] = _serialize(modelParameters);
|
|
130
|
+
otelAttributes[OtelSpanAttributes.LLM_MODEL_PARAMETERS] = _serialize(modelParameters);
|
|
131
|
+
}
|
|
132
|
+
if (usageDetails) {
|
|
133
|
+
if (typeof usageDetails === "object") {
|
|
134
|
+
const usage = usageDetails;
|
|
135
|
+
if (usage.promptTokens !== void 0) {
|
|
136
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_TOKEN_COUNT_PROMPT] = usage.promptTokens;
|
|
137
|
+
}
|
|
138
|
+
if (usage.completionTokens !== void 0) {
|
|
139
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_TOKEN_COUNT_COMPLETION] = usage.completionTokens;
|
|
140
|
+
}
|
|
141
|
+
if (usage.totalTokens !== void 0) {
|
|
142
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_TOKEN_COUNT_TOTAL] = usage.totalTokens;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
otelAttributes[OtelSpanAttributes.LLM_USAGE_DETAILS] = _serialize(usageDetails);
|
|
146
|
+
}
|
|
147
|
+
if (completionStartTime) {
|
|
148
|
+
otelAttributes[OtelSpanAttributes.LLM_COMPLETION_START_TIME] = _serialize(completionStartTime);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (type === "embedding") {
|
|
152
|
+
if (model) {
|
|
153
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.EMBEDDING_MODEL_NAME] = model;
|
|
154
|
+
}
|
|
155
|
+
if (modelParameters) {
|
|
156
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_INVOCATION_PARAMETERS] = _serialize(modelParameters);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const metadataAttrs = _flattenAndSerializeMetadata(
|
|
160
|
+
metadata,
|
|
161
|
+
import_openinference_semantic_conventions2.SemanticConventions.METADATA
|
|
162
|
+
);
|
|
163
|
+
Object.assign(otelAttributes, metadataAttrs);
|
|
164
|
+
const obsetvabilityMetadataAttrs = _flattenAndSerializeMetadata(
|
|
165
|
+
metadata,
|
|
166
|
+
OtelSpanAttributes.OBSERVATION_METADATA
|
|
167
|
+
);
|
|
168
|
+
Object.assign(otelAttributes, obsetvabilityMetadataAttrs);
|
|
169
|
+
return Object.fromEntries(
|
|
170
|
+
Object.entries(otelAttributes).filter(([_, v]) => v != null)
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
function _serialize(obj) {
|
|
174
|
+
try {
|
|
175
|
+
if (typeof obj === "string") return obj;
|
|
176
|
+
if (obj instanceof Date) return obj.toISOString();
|
|
177
|
+
return obj != null ? JSON.stringify(obj) : void 0;
|
|
178
|
+
} catch {
|
|
179
|
+
return "<failed to serialize>";
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function _flattenAndSerializeMetadata(metadata, prefix) {
|
|
183
|
+
const metadataAttributes = {};
|
|
184
|
+
if (metadata === void 0 || metadata === null) {
|
|
185
|
+
return metadataAttributes;
|
|
186
|
+
}
|
|
187
|
+
if (typeof metadata !== "object" || Array.isArray(metadata)) {
|
|
188
|
+
const serialized = _serialize(metadata);
|
|
189
|
+
if (serialized) {
|
|
190
|
+
metadataAttributes[prefix] = serialized;
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
194
|
+
const serialized = typeof value === "string" ? value : _serialize(value);
|
|
195
|
+
if (serialized) {
|
|
196
|
+
metadataAttributes[`${prefix}.${key}`] = serialized;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return metadataAttributes;
|
|
201
|
+
}
|
|
202
|
+
var import_openinference_semantic_conventions2;
|
|
203
|
+
var init_attributes = __esm({
|
|
204
|
+
"src/core/attributes.ts"() {
|
|
205
|
+
"use strict";
|
|
206
|
+
init_constants();
|
|
207
|
+
import_openinference_semantic_conventions2 = require("@arizeai/openinference-semantic-conventions");
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// src/core/tracerProvider.ts
|
|
212
|
+
function createState() {
|
|
213
|
+
return {
|
|
214
|
+
isolatedTracerProvider: null
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function getObservabilityGlobalState() {
|
|
218
|
+
const initialState = createState();
|
|
219
|
+
try {
|
|
220
|
+
const g = globalThis;
|
|
221
|
+
if (typeof g !== "object" || g === null) {
|
|
222
|
+
console.warn(
|
|
223
|
+
"[Observability] globalThis is not available, using fallback state"
|
|
224
|
+
);
|
|
225
|
+
return initialState;
|
|
226
|
+
}
|
|
227
|
+
if (!g[OBSERVABILITY_GLOBAL_SYMBOL]) {
|
|
228
|
+
Object.defineProperty(g, OBSERVABILITY_GLOBAL_SYMBOL, {
|
|
229
|
+
value: initialState,
|
|
230
|
+
writable: false,
|
|
231
|
+
configurable: false,
|
|
232
|
+
enumerable: false
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
return g[OBSERVABILITY_GLOBAL_SYMBOL];
|
|
236
|
+
} catch (err) {
|
|
237
|
+
console.error(
|
|
238
|
+
`[Observability] Failed to access global state: ${err instanceof Error ? err.message : String(err)}`
|
|
239
|
+
);
|
|
240
|
+
return initialState;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function setTracerProvider(provider) {
|
|
244
|
+
getObservabilityGlobalState().isolatedTracerProvider = provider;
|
|
245
|
+
}
|
|
246
|
+
function getTracerProvider() {
|
|
247
|
+
const { isolatedTracerProvider } = getObservabilityGlobalState();
|
|
248
|
+
if (isolatedTracerProvider) return isolatedTracerProvider;
|
|
249
|
+
return import_api.trace.getTracerProvider();
|
|
250
|
+
}
|
|
251
|
+
function getTracer() {
|
|
252
|
+
return getTracerProvider().getTracer(
|
|
253
|
+
OBSERVABILITY_SDK_NAME,
|
|
254
|
+
OBSERVABILITY_SDK_VERSION
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
var import_api, OBSERVABILITY_GLOBAL_SYMBOL, OBSERVABILITY_SDK_NAME, OBSERVABILITY_SDK_VERSION;
|
|
258
|
+
var init_tracerProvider = __esm({
|
|
259
|
+
"src/core/tracerProvider.ts"() {
|
|
260
|
+
"use strict";
|
|
261
|
+
import_api = require("@opentelemetry/api");
|
|
262
|
+
OBSERVABILITY_GLOBAL_SYMBOL = /* @__PURE__ */ Symbol.for("observability");
|
|
263
|
+
OBSERVABILITY_SDK_NAME = "ag-kit-observability";
|
|
264
|
+
OBSERVABILITY_SDK_VERSION = "0.1.0";
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// src/core/spanWrapper.ts
|
|
269
|
+
var BaseObservation, ObservationSpan, ObservationLLM, ObservationEmbedding, ObservationAgent, ObservationTool, ObservationChain, ObservationRetriever, ObservationReranker, ObservationEvaluator, ObservationGuardrail;
|
|
270
|
+
var init_spanWrapper = __esm({
|
|
271
|
+
"src/core/spanWrapper.ts"() {
|
|
272
|
+
"use strict";
|
|
273
|
+
init_attributes();
|
|
274
|
+
init_tracerProvider();
|
|
275
|
+
BaseObservation = class {
|
|
276
|
+
/** The underlying OpenTelemetry span */
|
|
277
|
+
otelSpan;
|
|
278
|
+
/** The observation type */
|
|
279
|
+
type;
|
|
280
|
+
/** The span ID from the OpenTelemetry span context */
|
|
281
|
+
id;
|
|
282
|
+
/** The trace ID from the OpenTelemetry span context */
|
|
283
|
+
traceId;
|
|
284
|
+
constructor(params) {
|
|
285
|
+
this.otelSpan = params.otelSpan;
|
|
286
|
+
this.id = params.otelSpan.spanContext().spanId;
|
|
287
|
+
this.traceId = params.otelSpan.spanContext().traceId;
|
|
288
|
+
this.type = params.type;
|
|
289
|
+
if (params.attributes) {
|
|
290
|
+
this.otelSpan.setAttributes(
|
|
291
|
+
createObservationAttributes(params.type, params.attributes)
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/** Gets the AG-Kit OpenTelemetry tracer instance */
|
|
296
|
+
get tracer() {
|
|
297
|
+
return getTracer();
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Ends the observation, marking it as complete.
|
|
301
|
+
*
|
|
302
|
+
* @param endTime - Optional end time, defaults to current time
|
|
303
|
+
*/
|
|
304
|
+
end(endTime) {
|
|
305
|
+
this.otelSpan.end(endTime);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Updates the OTEL span attributes.
|
|
309
|
+
*
|
|
310
|
+
* @param attributes - Attributes to update
|
|
311
|
+
* @internal
|
|
312
|
+
*/
|
|
313
|
+
updateOtelSpanAttributes(attributes) {
|
|
314
|
+
this.otelSpan.setAttributes(
|
|
315
|
+
createObservationAttributes(this.type, attributes)
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Updates the parent trace with new attributes.
|
|
320
|
+
*
|
|
321
|
+
* @param attributes - Trace attributes to set
|
|
322
|
+
* @returns This observation for method chaining
|
|
323
|
+
*/
|
|
324
|
+
updateTrace(attributes) {
|
|
325
|
+
this.otelSpan.setAttributes(createTraceAttributes(attributes));
|
|
326
|
+
return this;
|
|
327
|
+
}
|
|
328
|
+
startObservation(name, attributes, options) {
|
|
329
|
+
const { startObservation: startObs } = (init_src(), __toCommonJS(src_exports));
|
|
330
|
+
const { asType = "span" } = options || {};
|
|
331
|
+
return startObs(name, attributes, {
|
|
332
|
+
asType,
|
|
333
|
+
parentSpanContext: this.otelSpan.spanContext()
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
ObservationSpan = class extends BaseObservation {
|
|
338
|
+
constructor(params) {
|
|
339
|
+
super({ ...params, type: "span" });
|
|
340
|
+
}
|
|
341
|
+
update(attributes) {
|
|
342
|
+
super.updateOtelSpanAttributes(attributes);
|
|
343
|
+
return this;
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
ObservationLLM = class extends BaseObservation {
|
|
347
|
+
constructor(params) {
|
|
348
|
+
super({ ...params, type: "llm" });
|
|
349
|
+
}
|
|
350
|
+
update(attributes) {
|
|
351
|
+
super.updateOtelSpanAttributes(attributes);
|
|
352
|
+
return this;
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
ObservationEmbedding = class extends BaseObservation {
|
|
356
|
+
constructor(params) {
|
|
357
|
+
super({ ...params, type: "embedding" });
|
|
358
|
+
}
|
|
359
|
+
update(attributes) {
|
|
360
|
+
super.updateOtelSpanAttributes(attributes);
|
|
361
|
+
return this;
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
ObservationAgent = class extends BaseObservation {
|
|
365
|
+
constructor(params) {
|
|
366
|
+
super({ ...params, type: "agent" });
|
|
367
|
+
}
|
|
368
|
+
update(attributes) {
|
|
369
|
+
super.updateOtelSpanAttributes(attributes);
|
|
370
|
+
return this;
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
ObservationTool = class extends BaseObservation {
|
|
374
|
+
constructor(params) {
|
|
375
|
+
super({ ...params, type: "tool" });
|
|
376
|
+
}
|
|
377
|
+
update(attributes) {
|
|
378
|
+
super.updateOtelSpanAttributes(attributes);
|
|
379
|
+
return this;
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
ObservationChain = class extends BaseObservation {
|
|
383
|
+
constructor(params) {
|
|
384
|
+
super({ ...params, type: "chain" });
|
|
385
|
+
}
|
|
386
|
+
update(attributes) {
|
|
387
|
+
super.updateOtelSpanAttributes(attributes);
|
|
388
|
+
return this;
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
ObservationRetriever = class extends BaseObservation {
|
|
392
|
+
constructor(params) {
|
|
393
|
+
super({ ...params, type: "retriever" });
|
|
394
|
+
}
|
|
395
|
+
update(attributes) {
|
|
396
|
+
super.updateOtelSpanAttributes(attributes);
|
|
397
|
+
return this;
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
ObservationReranker = class extends BaseObservation {
|
|
401
|
+
constructor(params) {
|
|
402
|
+
super({ ...params, type: "reranker" });
|
|
403
|
+
}
|
|
404
|
+
update(attributes) {
|
|
405
|
+
super.updateOtelSpanAttributes(attributes);
|
|
406
|
+
return this;
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
ObservationEvaluator = class extends BaseObservation {
|
|
410
|
+
constructor(params) {
|
|
411
|
+
super({ ...params, type: "evaluator" });
|
|
412
|
+
}
|
|
413
|
+
update(attributes) {
|
|
414
|
+
super.updateOtelSpanAttributes(attributes);
|
|
415
|
+
return this;
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
ObservationGuardrail = class extends BaseObservation {
|
|
419
|
+
constructor(params) {
|
|
420
|
+
super({ ...params, type: "guardrail" });
|
|
421
|
+
}
|
|
422
|
+
update(attributes) {
|
|
423
|
+
super.updateOtelSpanAttributes(attributes);
|
|
424
|
+
return this;
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
// src/index.ts
|
|
431
|
+
var src_exports = {};
|
|
432
|
+
__export(src_exports, {
|
|
433
|
+
ObservationAgent: () => ObservationAgent,
|
|
434
|
+
ObservationChain: () => ObservationChain,
|
|
435
|
+
ObservationEmbedding: () => ObservationEmbedding,
|
|
436
|
+
ObservationEvaluator: () => ObservationEvaluator,
|
|
437
|
+
ObservationGuardrail: () => ObservationGuardrail,
|
|
438
|
+
ObservationLLM: () => ObservationLLM,
|
|
439
|
+
ObservationReranker: () => ObservationReranker,
|
|
440
|
+
ObservationRetriever: () => ObservationRetriever,
|
|
441
|
+
ObservationSpan: () => ObservationSpan,
|
|
442
|
+
ObservationTool: () => ObservationTool,
|
|
443
|
+
createObservationAttributes: () => createObservationAttributes,
|
|
444
|
+
createTraceAttributes: () => createTraceAttributes,
|
|
445
|
+
getActiveSpanId: () => getActiveSpanId,
|
|
446
|
+
getActiveTraceId: () => getActiveTraceId,
|
|
447
|
+
getTracer: () => getTracer,
|
|
448
|
+
getTracerProvider: () => getTracerProvider,
|
|
449
|
+
observe: () => observe,
|
|
450
|
+
setTracerProvider: () => setTracerProvider,
|
|
451
|
+
startActiveObservation: () => startActiveObservation,
|
|
452
|
+
startObservation: () => startObservation,
|
|
453
|
+
updateActiveObservation: () => updateActiveObservation,
|
|
454
|
+
updateActiveTrace: () => updateActiveTrace
|
|
455
|
+
});
|
|
456
|
+
function createOtelSpan(params) {
|
|
457
|
+
return getTracer().startSpan(
|
|
458
|
+
params.name,
|
|
459
|
+
{ startTime: params.startTime },
|
|
460
|
+
createParentContext(params.parentSpanContext)
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
function createParentContext(parentSpanContext) {
|
|
464
|
+
if (!parentSpanContext) return;
|
|
465
|
+
return import_api2.trace.setSpanContext(import_api2.context.active(), parentSpanContext);
|
|
466
|
+
}
|
|
467
|
+
function startObservation(name, attributes, options) {
|
|
468
|
+
const { asType = "span", ...observationOptions } = options || {};
|
|
469
|
+
const otelSpan = createOtelSpan({
|
|
470
|
+
name,
|
|
471
|
+
...observationOptions
|
|
472
|
+
});
|
|
473
|
+
switch (asType) {
|
|
474
|
+
case "llm":
|
|
475
|
+
return new ObservationLLM({
|
|
476
|
+
otelSpan,
|
|
477
|
+
attributes
|
|
478
|
+
});
|
|
479
|
+
case "embedding":
|
|
480
|
+
return new ObservationEmbedding({
|
|
481
|
+
otelSpan,
|
|
482
|
+
attributes
|
|
483
|
+
});
|
|
484
|
+
case "agent":
|
|
485
|
+
return new ObservationAgent({
|
|
486
|
+
otelSpan,
|
|
487
|
+
attributes
|
|
488
|
+
});
|
|
489
|
+
case "tool":
|
|
490
|
+
return new ObservationTool({
|
|
491
|
+
otelSpan,
|
|
492
|
+
attributes
|
|
493
|
+
});
|
|
494
|
+
case "chain":
|
|
495
|
+
return new ObservationChain({
|
|
496
|
+
otelSpan,
|
|
497
|
+
attributes
|
|
498
|
+
});
|
|
499
|
+
case "retriever":
|
|
500
|
+
return new ObservationRetriever({
|
|
501
|
+
otelSpan,
|
|
502
|
+
attributes
|
|
503
|
+
});
|
|
504
|
+
case "reranker":
|
|
505
|
+
return new ObservationReranker({
|
|
506
|
+
otelSpan,
|
|
507
|
+
attributes
|
|
508
|
+
});
|
|
509
|
+
case "evaluator":
|
|
510
|
+
return new ObservationEvaluator({
|
|
511
|
+
otelSpan,
|
|
512
|
+
attributes
|
|
513
|
+
});
|
|
514
|
+
case "guardrail":
|
|
515
|
+
return new ObservationGuardrail({
|
|
516
|
+
otelSpan,
|
|
517
|
+
attributes
|
|
518
|
+
});
|
|
519
|
+
case "span":
|
|
520
|
+
default:
|
|
521
|
+
return new ObservationSpan({
|
|
522
|
+
otelSpan,
|
|
523
|
+
attributes
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
function updateActiveTrace(attributes) {
|
|
528
|
+
const span = import_api2.trace.getActiveSpan();
|
|
529
|
+
if (!span) {
|
|
530
|
+
console.warn(
|
|
531
|
+
"[Observability] No active OTEL span in context. Skipping trace update."
|
|
532
|
+
);
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
span.setAttributes(createTraceAttributes(attributes));
|
|
536
|
+
}
|
|
537
|
+
function getActiveTraceId() {
|
|
538
|
+
return import_api2.trace.getActiveSpan()?.spanContext().traceId;
|
|
539
|
+
}
|
|
540
|
+
function getActiveSpanId() {
|
|
541
|
+
return import_api2.trace.getActiveSpan()?.spanContext().spanId;
|
|
542
|
+
}
|
|
543
|
+
function wrapPromise(promise, span, endOnExit) {
|
|
544
|
+
return promise.then(
|
|
545
|
+
(value) => {
|
|
546
|
+
if (endOnExit !== false) {
|
|
547
|
+
span.end();
|
|
548
|
+
}
|
|
549
|
+
return value;
|
|
550
|
+
},
|
|
551
|
+
(err) => {
|
|
552
|
+
span.setStatus({
|
|
553
|
+
code: import_api2.SpanStatusCode.ERROR,
|
|
554
|
+
message: err instanceof Error ? err.message : "Unknown error"
|
|
555
|
+
});
|
|
556
|
+
if (endOnExit !== false) {
|
|
557
|
+
span.end();
|
|
558
|
+
}
|
|
559
|
+
throw err;
|
|
560
|
+
}
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
function startActiveObservation(name, fn, options) {
|
|
564
|
+
const { asType = "span", endOnExit, ...observationOptions } = options || {};
|
|
565
|
+
return getTracer().startActiveSpan(
|
|
566
|
+
name,
|
|
567
|
+
{ startTime: observationOptions?.startTime },
|
|
568
|
+
createParentContext(observationOptions?.parentSpanContext) ?? import_api2.context.active(),
|
|
569
|
+
(span) => {
|
|
570
|
+
try {
|
|
571
|
+
let observation;
|
|
572
|
+
switch (asType) {
|
|
573
|
+
case "llm":
|
|
574
|
+
observation = new ObservationLLM({ otelSpan: span });
|
|
575
|
+
break;
|
|
576
|
+
case "embedding":
|
|
577
|
+
observation = new ObservationEmbedding({ otelSpan: span });
|
|
578
|
+
break;
|
|
579
|
+
case "agent":
|
|
580
|
+
observation = new ObservationAgent({ otelSpan: span });
|
|
581
|
+
break;
|
|
582
|
+
case "tool":
|
|
583
|
+
observation = new ObservationTool({ otelSpan: span });
|
|
584
|
+
break;
|
|
585
|
+
case "chain":
|
|
586
|
+
observation = new ObservationChain({ otelSpan: span });
|
|
587
|
+
break;
|
|
588
|
+
case "retriever":
|
|
589
|
+
observation = new ObservationRetriever({ otelSpan: span });
|
|
590
|
+
break;
|
|
591
|
+
case "reranker":
|
|
592
|
+
observation = new ObservationReranker({ otelSpan: span });
|
|
593
|
+
break;
|
|
594
|
+
case "evaluator":
|
|
595
|
+
observation = new ObservationEvaluator({ otelSpan: span });
|
|
596
|
+
break;
|
|
597
|
+
case "guardrail":
|
|
598
|
+
observation = new ObservationGuardrail({ otelSpan: span });
|
|
599
|
+
break;
|
|
600
|
+
case "span":
|
|
601
|
+
default:
|
|
602
|
+
observation = new ObservationSpan({ otelSpan: span });
|
|
603
|
+
}
|
|
604
|
+
const result = fn(observation);
|
|
605
|
+
if (result instanceof Promise) {
|
|
606
|
+
return wrapPromise(
|
|
607
|
+
result,
|
|
608
|
+
span,
|
|
609
|
+
endOnExit
|
|
610
|
+
);
|
|
611
|
+
} else {
|
|
612
|
+
if (endOnExit !== false) {
|
|
613
|
+
span.end();
|
|
614
|
+
}
|
|
615
|
+
return result;
|
|
616
|
+
}
|
|
617
|
+
} catch (err) {
|
|
618
|
+
span.setStatus({
|
|
619
|
+
code: import_api2.SpanStatusCode.ERROR,
|
|
620
|
+
message: err instanceof Error ? err.message : "Unknown error"
|
|
621
|
+
});
|
|
622
|
+
if (endOnExit !== false) {
|
|
623
|
+
span.end();
|
|
624
|
+
}
|
|
625
|
+
throw err;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
);
|
|
629
|
+
}
|
|
630
|
+
function updateActiveObservation(attributes) {
|
|
631
|
+
const span = import_api2.trace.getActiveSpan();
|
|
632
|
+
if (!span) {
|
|
633
|
+
console.warn(
|
|
634
|
+
"[Observability] No active OTEL span in context. Skipping observation update."
|
|
635
|
+
);
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
span.setAttributes(createObservationAttributes("span", attributes));
|
|
639
|
+
}
|
|
640
|
+
function _captureArguments(args) {
|
|
641
|
+
if (args.length === 0) return {};
|
|
642
|
+
if (args.length === 1) return { arg: args[0] };
|
|
643
|
+
return { args };
|
|
644
|
+
}
|
|
645
|
+
function observe(fn, options = {}) {
|
|
646
|
+
const {
|
|
647
|
+
asType = "span",
|
|
648
|
+
captureInput = true,
|
|
649
|
+
captureOutput = true,
|
|
650
|
+
...observationOptions
|
|
651
|
+
} = options;
|
|
652
|
+
const wrappedFunction = function(...args) {
|
|
653
|
+
const name = fn.name || "anonymous-function";
|
|
654
|
+
const inputData = captureInput ? _captureArguments(args) : void 0;
|
|
655
|
+
const observation = startObservation(
|
|
656
|
+
name,
|
|
657
|
+
inputData ? { input: inputData } : {},
|
|
658
|
+
{
|
|
659
|
+
...observationOptions,
|
|
660
|
+
asType
|
|
661
|
+
}
|
|
662
|
+
);
|
|
663
|
+
const activeContext = import_api2.trace.setSpan(import_api2.context.active(), observation.otelSpan);
|
|
664
|
+
const result = import_api2.context.with(activeContext, () => fn.apply(this, args));
|
|
665
|
+
if (result instanceof Promise) {
|
|
666
|
+
return result.then(
|
|
667
|
+
(value) => {
|
|
668
|
+
if (captureOutput) {
|
|
669
|
+
observation.update({ output: value });
|
|
670
|
+
}
|
|
671
|
+
observation.end();
|
|
672
|
+
return value;
|
|
673
|
+
},
|
|
674
|
+
(err) => {
|
|
675
|
+
observation.update({
|
|
676
|
+
level: "ERROR",
|
|
677
|
+
statusMessage: err instanceof Error ? err.message : "Unknown error"
|
|
678
|
+
});
|
|
679
|
+
observation.end();
|
|
680
|
+
throw err;
|
|
681
|
+
}
|
|
682
|
+
);
|
|
683
|
+
}
|
|
684
|
+
if (captureOutput) {
|
|
685
|
+
observation.update({ output: result });
|
|
686
|
+
}
|
|
687
|
+
observation.end();
|
|
688
|
+
return result;
|
|
689
|
+
};
|
|
690
|
+
Object.defineProperty(wrappedFunction, "name", { value: fn.name });
|
|
691
|
+
Object.defineProperty(wrappedFunction, "length", { value: fn.length });
|
|
692
|
+
return wrappedFunction;
|
|
693
|
+
}
|
|
694
|
+
var import_api2;
|
|
695
|
+
var init_src = __esm({
|
|
696
|
+
"src/index.ts"() {
|
|
697
|
+
"use strict";
|
|
698
|
+
import_api2 = require("@opentelemetry/api");
|
|
699
|
+
init_attributes();
|
|
700
|
+
init_spanWrapper();
|
|
701
|
+
init_tracerProvider();
|
|
702
|
+
init_attributes();
|
|
703
|
+
init_tracerProvider();
|
|
704
|
+
}
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
// src/langchain/CallbackHandler.ts
|
|
708
|
+
var CallbackHandler_exports = {};
|
|
709
|
+
__export(CallbackHandler_exports, {
|
|
710
|
+
CallbackHandler: () => CallbackHandler
|
|
711
|
+
});
|
|
712
|
+
module.exports = __toCommonJS(CallbackHandler_exports);
|
|
713
|
+
var import_base = require("@langchain/core/callbacks/base");
|
|
714
|
+
var import_messages = require("@langchain/core/messages");
|
|
715
|
+
init_src();
|
|
716
|
+
var CallbackHandler = class extends import_base.BaseCallbackHandler {
|
|
717
|
+
name = "ObservabilityCallbackHandler";
|
|
718
|
+
userId;
|
|
719
|
+
version;
|
|
720
|
+
sessionId;
|
|
721
|
+
tags;
|
|
722
|
+
traceMetadata;
|
|
723
|
+
completionStartTimes = {};
|
|
724
|
+
promptToParentRunMap;
|
|
725
|
+
runMap = /* @__PURE__ */ new Map();
|
|
726
|
+
last_trace_id = null;
|
|
727
|
+
// External parent context from AG-UI.Server span
|
|
728
|
+
externalParentSpanContext;
|
|
729
|
+
// Adapter name for ROOT span prefix
|
|
730
|
+
adapterName;
|
|
731
|
+
constructor(params) {
|
|
732
|
+
super();
|
|
733
|
+
this.sessionId = params?.sessionId;
|
|
734
|
+
this.userId = params?.userId;
|
|
735
|
+
this.tags = params?.tags ?? [];
|
|
736
|
+
this.traceMetadata = params?.traceMetadata;
|
|
737
|
+
this.version = params?.version;
|
|
738
|
+
this.adapterName = params?.adapterName;
|
|
739
|
+
this.promptToParentRunMap = /* @__PURE__ */ new Map();
|
|
740
|
+
}
|
|
741
|
+
get logger() {
|
|
742
|
+
return console;
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Set external parent SpanContext from AG-UI.Server span.
|
|
746
|
+
* This allows the CallbackHandler to link LangChain/LangGraph spans
|
|
747
|
+
* to the server-level span, creating a unified trace hierarchy.
|
|
748
|
+
*
|
|
749
|
+
* @param spanContext - SpanContext from the AG-UI.Server span
|
|
750
|
+
* @public
|
|
751
|
+
*/
|
|
752
|
+
setExternalParentContext(spanContext) {
|
|
753
|
+
this.externalParentSpanContext = spanContext;
|
|
754
|
+
}
|
|
755
|
+
async handleLLMNewToken(token, _idx, runId, _parentRunId, _tags, _fields) {
|
|
756
|
+
if (runId && !(runId in this.completionStartTimes)) {
|
|
757
|
+
this.logger.debug(`LLM first streaming token: ${runId}`);
|
|
758
|
+
this.completionStartTimes[runId] = /* @__PURE__ */ new Date();
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
async handleChainStart(chain, inputs, runId, parentRunId, tags, metadata, runType, name) {
|
|
762
|
+
try {
|
|
763
|
+
this.logger.debug(`Chain start with Id: ${runId}`);
|
|
764
|
+
const runName = name ?? chain.id.at(-1)?.toString() ?? "Langchain Run";
|
|
765
|
+
this.registerPromptInfo(parentRunId, metadata);
|
|
766
|
+
let finalInput = inputs;
|
|
767
|
+
if (typeof inputs === "object" && "input" in inputs && Array.isArray(inputs["input"]) && inputs["input"].every((m) => m instanceof import_messages.BaseMessage)) {
|
|
768
|
+
finalInput = inputs["input"].map(
|
|
769
|
+
(m) => this.extractChatMessageContent(m)
|
|
770
|
+
);
|
|
771
|
+
} else if (typeof inputs === "object" && "messages" in inputs && Array.isArray(inputs["messages"]) && inputs["messages"].every((m) => m instanceof import_messages.BaseMessage)) {
|
|
772
|
+
finalInput = inputs["messages"].map(
|
|
773
|
+
(m) => this.extractChatMessageContent(m)
|
|
774
|
+
);
|
|
775
|
+
} else if (typeof inputs === "object" && "content" in inputs && typeof inputs["content"] === "string") {
|
|
776
|
+
finalInput = inputs["content"];
|
|
777
|
+
}
|
|
778
|
+
const observation = this.startAndRegisterObservation({
|
|
779
|
+
runName,
|
|
780
|
+
parentRunId,
|
|
781
|
+
runId,
|
|
782
|
+
tags,
|
|
783
|
+
metadata,
|
|
784
|
+
attributes: {
|
|
785
|
+
input: finalInput
|
|
786
|
+
},
|
|
787
|
+
asType: "span"
|
|
788
|
+
});
|
|
789
|
+
const traceTags = [.../* @__PURE__ */ new Set([...tags ?? [], ...this.tags])];
|
|
790
|
+
if (!parentRunId) {
|
|
791
|
+
observation.updateTrace({
|
|
792
|
+
tags: traceTags,
|
|
793
|
+
userId: metadata && "userId" in metadata && typeof metadata["userId"] === "string" ? metadata["userId"] : this.userId,
|
|
794
|
+
sessionId: metadata && "sessionId" in metadata && typeof metadata["sessionId"] === "string" ? metadata["sessionId"] : this.sessionId,
|
|
795
|
+
metadata: this.traceMetadata,
|
|
796
|
+
version: this.version
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
} catch (e) {
|
|
800
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
async handleAgentAction(action, runId, parentRunId) {
|
|
804
|
+
try {
|
|
805
|
+
this.logger.debug(`Agent action ${action.tool} with ID: ${runId}`);
|
|
806
|
+
this.startAndRegisterObservation({
|
|
807
|
+
runId,
|
|
808
|
+
parentRunId,
|
|
809
|
+
runName: action.tool,
|
|
810
|
+
attributes: {
|
|
811
|
+
input: action
|
|
812
|
+
},
|
|
813
|
+
asType: "tool"
|
|
814
|
+
});
|
|
815
|
+
} catch (e) {
|
|
816
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
async handleAgentEnd(action, runId, _parentRunId) {
|
|
820
|
+
try {
|
|
821
|
+
this.logger.debug(`Agent finish with ID: ${runId}`);
|
|
822
|
+
this.handleObservationEnd({
|
|
823
|
+
runId,
|
|
824
|
+
attributes: { output: action }
|
|
825
|
+
});
|
|
826
|
+
} catch (e) {
|
|
827
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
async handleChainError(err, runId, _parentRunId) {
|
|
831
|
+
try {
|
|
832
|
+
this.logger.debug(`Chain error: ${err} with ID: ${runId}`);
|
|
833
|
+
this.handleObservationEnd({
|
|
834
|
+
runId,
|
|
835
|
+
attributes: {
|
|
836
|
+
level: "ERROR",
|
|
837
|
+
statusMessage: err.toString()
|
|
838
|
+
}
|
|
839
|
+
});
|
|
840
|
+
} catch (e) {
|
|
841
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
async handleGenerationStart(llm, messages, runId, parentRunId, extraParams, tags, metadata, name) {
|
|
845
|
+
this.logger.debug(
|
|
846
|
+
`Generation start with ID: ${runId} and parentRunId ${parentRunId}`
|
|
847
|
+
);
|
|
848
|
+
const runName = name ?? llm.id.at(-1)?.toString() ?? "Langchain Generation";
|
|
849
|
+
const modelParameters = {};
|
|
850
|
+
const invocationParams = extraParams?.["invocation_params"];
|
|
851
|
+
for (const [key, value] of Object.entries({
|
|
852
|
+
temperature: invocationParams?.temperature,
|
|
853
|
+
max_tokens: invocationParams?.max_tokens,
|
|
854
|
+
top_p: invocationParams?.top_p,
|
|
855
|
+
frequency_penalty: invocationParams?.frequency_penalty,
|
|
856
|
+
presence_penalty: invocationParams?.presence_penalty,
|
|
857
|
+
request_timeout: invocationParams?.request_timeout
|
|
858
|
+
})) {
|
|
859
|
+
if (value !== void 0 && value !== null) {
|
|
860
|
+
modelParameters[key] = value;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
let extractedModelName;
|
|
864
|
+
if (extraParams) {
|
|
865
|
+
const invocationParamsModelName = extraParams.invocation_params.model;
|
|
866
|
+
const metadataModelName = metadata && "ls_model_name" in metadata ? metadata["ls_model_name"] : void 0;
|
|
867
|
+
extractedModelName = invocationParamsModelName ?? metadataModelName;
|
|
868
|
+
}
|
|
869
|
+
const registeredPrompt = this.promptToParentRunMap.get(
|
|
870
|
+
parentRunId ?? "root"
|
|
871
|
+
);
|
|
872
|
+
if (registeredPrompt && parentRunId) {
|
|
873
|
+
this.deregisterPromptInfo(parentRunId);
|
|
874
|
+
}
|
|
875
|
+
this.startAndRegisterObservation({
|
|
876
|
+
runId,
|
|
877
|
+
parentRunId,
|
|
878
|
+
metadata,
|
|
879
|
+
tags,
|
|
880
|
+
runName,
|
|
881
|
+
attributes: {
|
|
882
|
+
input: messages,
|
|
883
|
+
model: extractedModelName,
|
|
884
|
+
modelParameters
|
|
885
|
+
},
|
|
886
|
+
asType: "llm"
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
async handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata, name) {
|
|
890
|
+
try {
|
|
891
|
+
this.logger.debug(`Chat model start with ID: ${runId}`);
|
|
892
|
+
const prompts = messages.flatMap(
|
|
893
|
+
(message) => message.map((m) => this.extractChatMessageContent(m))
|
|
894
|
+
);
|
|
895
|
+
this.handleGenerationStart(
|
|
896
|
+
llm,
|
|
897
|
+
prompts,
|
|
898
|
+
runId,
|
|
899
|
+
parentRunId,
|
|
900
|
+
extraParams,
|
|
901
|
+
tags,
|
|
902
|
+
metadata,
|
|
903
|
+
name
|
|
904
|
+
);
|
|
905
|
+
} catch (e) {
|
|
906
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
async handleChainEnd(outputs, runId, _parentRunId) {
|
|
910
|
+
try {
|
|
911
|
+
this.logger.debug(`Chain end with ID: ${runId}`);
|
|
912
|
+
let finalOutput = outputs;
|
|
913
|
+
if (typeof outputs === "object" && "output" in outputs && typeof outputs["output"] === "string") {
|
|
914
|
+
finalOutput = outputs["output"];
|
|
915
|
+
} else if (typeof outputs === "object" && "messages" in outputs && Array.isArray(outputs["messages"]) && outputs["messages"].every((m) => m instanceof import_messages.BaseMessage)) {
|
|
916
|
+
finalOutput = {
|
|
917
|
+
messages: outputs.messages.map(
|
|
918
|
+
(message) => this.extractChatMessageContent(message)
|
|
919
|
+
)
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
this.handleObservationEnd({
|
|
923
|
+
runId,
|
|
924
|
+
attributes: {
|
|
925
|
+
output: finalOutput
|
|
926
|
+
}
|
|
927
|
+
});
|
|
928
|
+
this.deregisterPromptInfo(runId);
|
|
929
|
+
} catch (e) {
|
|
930
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
async handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata, name) {
|
|
934
|
+
try {
|
|
935
|
+
this.logger.debug(`LLM start with ID: ${runId}`);
|
|
936
|
+
this.handleGenerationStart(
|
|
937
|
+
llm,
|
|
938
|
+
prompts,
|
|
939
|
+
runId,
|
|
940
|
+
parentRunId,
|
|
941
|
+
extraParams,
|
|
942
|
+
tags,
|
|
943
|
+
metadata,
|
|
944
|
+
name
|
|
945
|
+
);
|
|
946
|
+
} catch (e) {
|
|
947
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
async handleToolStart(tool, input, runId, parentRunId, tags, metadata, name) {
|
|
951
|
+
try {
|
|
952
|
+
this.logger.debug(`Tool start with ID: ${runId}`);
|
|
953
|
+
this.startAndRegisterObservation({
|
|
954
|
+
runId,
|
|
955
|
+
parentRunId,
|
|
956
|
+
runName: name ?? tool.id.at(-1)?.toString() ?? "Tool execution",
|
|
957
|
+
attributes: {
|
|
958
|
+
input
|
|
959
|
+
},
|
|
960
|
+
metadata,
|
|
961
|
+
tags,
|
|
962
|
+
asType: "tool"
|
|
963
|
+
});
|
|
964
|
+
} catch (e) {
|
|
965
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
async handleRetrieverStart(retriever, query, runId, parentRunId, tags, metadata, name) {
|
|
969
|
+
try {
|
|
970
|
+
this.logger.debug(`Retriever start with ID: ${runId}`);
|
|
971
|
+
this.startAndRegisterObservation({
|
|
972
|
+
runId,
|
|
973
|
+
parentRunId,
|
|
974
|
+
runName: name ?? retriever.id.at(-1)?.toString() ?? "Retriever",
|
|
975
|
+
attributes: {
|
|
976
|
+
input: query
|
|
977
|
+
},
|
|
978
|
+
tags,
|
|
979
|
+
metadata,
|
|
980
|
+
asType: "span"
|
|
981
|
+
});
|
|
982
|
+
} catch (e) {
|
|
983
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
async handleRetrieverEnd(documents, runId, _parentRunId) {
|
|
987
|
+
try {
|
|
988
|
+
this.logger.debug(`Retriever end with ID: ${runId}`);
|
|
989
|
+
this.handleObservationEnd({
|
|
990
|
+
runId,
|
|
991
|
+
attributes: {
|
|
992
|
+
output: documents
|
|
993
|
+
}
|
|
994
|
+
});
|
|
995
|
+
} catch (e) {
|
|
996
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
async handleRetrieverError(err, runId, _parentRunId) {
|
|
1000
|
+
try {
|
|
1001
|
+
this.logger.debug(`Retriever error: ${err} with ID: ${runId}`);
|
|
1002
|
+
this.handleObservationEnd({
|
|
1003
|
+
runId,
|
|
1004
|
+
attributes: {
|
|
1005
|
+
level: "ERROR",
|
|
1006
|
+
statusMessage: err.toString()
|
|
1007
|
+
}
|
|
1008
|
+
});
|
|
1009
|
+
} catch (e) {
|
|
1010
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
async handleToolEnd(output, runId, _parentRunId) {
|
|
1014
|
+
try {
|
|
1015
|
+
this.logger.debug(`Tool end with ID: ${runId}`);
|
|
1016
|
+
this.handleObservationEnd({
|
|
1017
|
+
runId,
|
|
1018
|
+
attributes: { output }
|
|
1019
|
+
});
|
|
1020
|
+
} catch (e) {
|
|
1021
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
async handleToolError(err, runId, _parentRunId) {
|
|
1025
|
+
try {
|
|
1026
|
+
this.logger.debug(`Tool error ${err} with ID: ${runId}`);
|
|
1027
|
+
this.handleObservationEnd({
|
|
1028
|
+
runId,
|
|
1029
|
+
attributes: {
|
|
1030
|
+
level: "ERROR",
|
|
1031
|
+
statusMessage: err.toString()
|
|
1032
|
+
}
|
|
1033
|
+
});
|
|
1034
|
+
} catch (e) {
|
|
1035
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
async handleLLMEnd(output, runId, _parentRunId) {
|
|
1039
|
+
try {
|
|
1040
|
+
this.logger.debug(`LLM end with ID: ${runId}`);
|
|
1041
|
+
const lastResponse = output.generations[output.generations.length - 1][output.generations[output.generations.length - 1].length - 1];
|
|
1042
|
+
const llmUsage = this.extractUsageMetadata(lastResponse) ?? output.llmOutput?.["tokenUsage"];
|
|
1043
|
+
const modelName = this.extractModelNameFromMetadata(lastResponse);
|
|
1044
|
+
const usageDetails = {
|
|
1045
|
+
input: llmUsage?.input_tokens ?? ("promptTokens" in llmUsage ? llmUsage?.promptTokens : void 0),
|
|
1046
|
+
output: llmUsage?.output_tokens ?? ("completionTokens" in llmUsage ? llmUsage?.completionTokens : void 0),
|
|
1047
|
+
total: llmUsage?.total_tokens ?? ("totalTokens" in llmUsage ? llmUsage?.totalTokens : void 0)
|
|
1048
|
+
};
|
|
1049
|
+
if (llmUsage && "input_token_details" in llmUsage) {
|
|
1050
|
+
for (const [key, val] of Object.entries(
|
|
1051
|
+
llmUsage["input_token_details"] ?? {}
|
|
1052
|
+
)) {
|
|
1053
|
+
usageDetails[`input_${key}`] = val;
|
|
1054
|
+
if ("input" in usageDetails && typeof val === "number") {
|
|
1055
|
+
usageDetails["input"] = Math.max(0, usageDetails["input"] - val);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
if (llmUsage && "output_token_details" in llmUsage) {
|
|
1060
|
+
for (const [key, val] of Object.entries(
|
|
1061
|
+
llmUsage["output_token_details"] ?? {}
|
|
1062
|
+
)) {
|
|
1063
|
+
usageDetails[`output_${key}`] = val;
|
|
1064
|
+
if ("output" in usageDetails && typeof val === "number") {
|
|
1065
|
+
usageDetails["output"] = Math.max(0, usageDetails["output"] - val);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
const extractedOutput = "message" in lastResponse ? this.extractChatMessageContent(
|
|
1070
|
+
lastResponse["message"]
|
|
1071
|
+
) : lastResponse.text;
|
|
1072
|
+
this.handleObservationEnd({
|
|
1073
|
+
runId,
|
|
1074
|
+
attributes: {
|
|
1075
|
+
model: modelName,
|
|
1076
|
+
output: extractedOutput,
|
|
1077
|
+
completionStartTime: runId in this.completionStartTimes ? this.completionStartTimes[runId] : void 0,
|
|
1078
|
+
usageDetails
|
|
1079
|
+
}
|
|
1080
|
+
});
|
|
1081
|
+
if (runId in this.completionStartTimes) {
|
|
1082
|
+
delete this.completionStartTimes[runId];
|
|
1083
|
+
}
|
|
1084
|
+
} catch (e) {
|
|
1085
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
async handleLLMError(err, runId, _parentRunId) {
|
|
1089
|
+
try {
|
|
1090
|
+
this.logger.debug(`LLM error ${err} with ID: ${runId}`);
|
|
1091
|
+
this.handleObservationEnd({
|
|
1092
|
+
runId,
|
|
1093
|
+
attributes: {
|
|
1094
|
+
level: "ERROR",
|
|
1095
|
+
statusMessage: err.toString()
|
|
1096
|
+
}
|
|
1097
|
+
});
|
|
1098
|
+
} catch (e) {
|
|
1099
|
+
this.logger.debug(e instanceof Error ? e.message : String(e));
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
registerPromptInfo(parentRunId, metadata) {
|
|
1103
|
+
if (metadata && "promptInfo" in metadata && parentRunId) {
|
|
1104
|
+
this.promptToParentRunMap.set(
|
|
1105
|
+
parentRunId,
|
|
1106
|
+
metadata.promptInfo
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
deregisterPromptInfo(runId) {
|
|
1111
|
+
this.promptToParentRunMap.delete(runId);
|
|
1112
|
+
}
|
|
1113
|
+
startAndRegisterObservation(params) {
|
|
1114
|
+
const { runName, runId, parentRunId, attributes, metadata, tags, asType } = params;
|
|
1115
|
+
let parentSpanContext;
|
|
1116
|
+
if (parentRunId) {
|
|
1117
|
+
parentSpanContext = this.runMap.get(parentRunId)?.otelSpan.spanContext();
|
|
1118
|
+
} else if (this.externalParentSpanContext) {
|
|
1119
|
+
parentSpanContext = this.externalParentSpanContext;
|
|
1120
|
+
}
|
|
1121
|
+
let finalRunName = runName;
|
|
1122
|
+
if (!parentRunId && this.adapterName) {
|
|
1123
|
+
finalRunName = `Adapter.${this.adapterName}`;
|
|
1124
|
+
}
|
|
1125
|
+
const observation = startObservation(
|
|
1126
|
+
finalRunName,
|
|
1127
|
+
{
|
|
1128
|
+
version: this.version,
|
|
1129
|
+
metadata: this.joinTagsAndMetaData(tags, metadata),
|
|
1130
|
+
...attributes
|
|
1131
|
+
},
|
|
1132
|
+
{
|
|
1133
|
+
asType: asType ?? "span",
|
|
1134
|
+
parentSpanContext
|
|
1135
|
+
}
|
|
1136
|
+
);
|
|
1137
|
+
this.runMap.set(runId, observation);
|
|
1138
|
+
return observation;
|
|
1139
|
+
}
|
|
1140
|
+
handleObservationEnd(params) {
|
|
1141
|
+
const { runId, attributes = {} } = params;
|
|
1142
|
+
const observation = this.runMap.get(runId);
|
|
1143
|
+
if (!observation) {
|
|
1144
|
+
this.logger.warn("Observation not found in runMap. Skipping operation.");
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
observation.update(attributes).end();
|
|
1148
|
+
this.last_trace_id = observation.traceId;
|
|
1149
|
+
this.runMap.delete(runId);
|
|
1150
|
+
}
|
|
1151
|
+
joinTagsAndMetaData(tags, metadata1, metadata2) {
|
|
1152
|
+
const finalDict = {};
|
|
1153
|
+
if (tags && tags.length > 0) {
|
|
1154
|
+
finalDict.tags = tags;
|
|
1155
|
+
}
|
|
1156
|
+
if (metadata1) {
|
|
1157
|
+
Object.assign(finalDict, metadata1);
|
|
1158
|
+
}
|
|
1159
|
+
if (metadata2) {
|
|
1160
|
+
Object.assign(finalDict, metadata2);
|
|
1161
|
+
}
|
|
1162
|
+
return this.stripObservabilityKeysFromMetadata(finalDict);
|
|
1163
|
+
}
|
|
1164
|
+
stripObservabilityKeysFromMetadata(metadata) {
|
|
1165
|
+
if (!metadata) {
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
const reservedKeys = ["promptInfo", "userId", "sessionId"];
|
|
1169
|
+
return Object.fromEntries(
|
|
1170
|
+
Object.entries(metadata).filter(([key, _]) => !reservedKeys.includes(key))
|
|
1171
|
+
);
|
|
1172
|
+
}
|
|
1173
|
+
extractUsageMetadata(generation) {
|
|
1174
|
+
try {
|
|
1175
|
+
const usageMetadata = "message" in generation && (import_messages.AIMessage.isInstance(generation["message"]) || import_messages.AIMessageChunk.isInstance(generation["message"])) ? generation["message"].usage_metadata : void 0;
|
|
1176
|
+
return usageMetadata;
|
|
1177
|
+
} catch (err) {
|
|
1178
|
+
this.logger.debug(`Error extracting usage metadata: ${err}`);
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
extractModelNameFromMetadata(generation) {
|
|
1183
|
+
try {
|
|
1184
|
+
return "message" in generation && (import_messages.AIMessage.isInstance(generation["message"]) || import_messages.AIMessageChunk.isInstance(generation["message"])) ? generation["message"].response_metadata.model_name : void 0;
|
|
1185
|
+
} catch {
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
extractChatMessageContent(message) {
|
|
1189
|
+
let response = void 0;
|
|
1190
|
+
if (message.getType() === "human") {
|
|
1191
|
+
response = { content: message.content, role: "user" };
|
|
1192
|
+
} else if (message.getType() === "generic") {
|
|
1193
|
+
response = {
|
|
1194
|
+
content: message.content,
|
|
1195
|
+
role: "human"
|
|
1196
|
+
};
|
|
1197
|
+
} else if (message.getType() === "ai") {
|
|
1198
|
+
response = { content: message.content, role: "assistant" };
|
|
1199
|
+
if ("tool_calls" in message && Array.isArray(message.tool_calls) && (message.tool_calls?.length ?? 0) > 0) {
|
|
1200
|
+
response["tool_calls"] = message["tool_calls"];
|
|
1201
|
+
}
|
|
1202
|
+
if ("additional_kwargs" in message && "tool_calls" in message["additional_kwargs"]) {
|
|
1203
|
+
response["tool_calls"] = message["additional_kwargs"]["tool_calls"];
|
|
1204
|
+
}
|
|
1205
|
+
} else if (message.getType() === "system") {
|
|
1206
|
+
response = { content: message.content, role: "system" };
|
|
1207
|
+
} else if (message.getType() === "function") {
|
|
1208
|
+
response = {
|
|
1209
|
+
content: message.content,
|
|
1210
|
+
additional_kwargs: message.additional_kwargs,
|
|
1211
|
+
role: message.name
|
|
1212
|
+
};
|
|
1213
|
+
} else if (message.getType() === "tool") {
|
|
1214
|
+
response = {
|
|
1215
|
+
content: message.content,
|
|
1216
|
+
additional_kwargs: message.additional_kwargs,
|
|
1217
|
+
role: message.name
|
|
1218
|
+
};
|
|
1219
|
+
} else if (!message.name) {
|
|
1220
|
+
response = { content: message.content };
|
|
1221
|
+
} else {
|
|
1222
|
+
response = {
|
|
1223
|
+
role: message.name,
|
|
1224
|
+
content: message.content
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
if ((message.additional_kwargs.function_call || message.additional_kwargs.tool_calls) && response["tool_calls"] === void 0) {
|
|
1228
|
+
return { ...response, additional_kwargs: message.additional_kwargs };
|
|
1229
|
+
}
|
|
1230
|
+
return response;
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1234
|
+
0 && (module.exports = {
|
|
1235
|
+
CallbackHandler
|
|
1236
|
+
});
|
|
1237
|
+
//# sourceMappingURL=langchain.js.map
|