@brizz/sdk 0.1.26 → 0.1.27
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.cjs +140 -21
- package/dist/index.js +126 -7
- package/dist/preload.cjs +47 -8
- package/dist/preload.js +42 -3
- package/package.json +5 -1
package/dist/index.cjs
CHANGED
|
@@ -305,7 +305,7 @@ var init_schemas = __esm({
|
|
|
305
305
|
});
|
|
306
306
|
|
|
307
307
|
// src/internal/semantic-conventions.ts
|
|
308
|
-
var import_api3, BRIZZ, PROPERTIES, SESSION_ID, PROPERTIES_CONTEXT_KEY, SESSION_OBJECT_CONTEXT_KEY, SESSION_INPUT, SESSION_OUTPUT, SESSION_INPUT_CONTEXT, SESSION_OUTPUT_CONTEXT, SESSION_SPAN_NAME, SESSION_TITLE_SPAN_NAME, SESSION_TITLE_GENERATION, SESSION_TITLE;
|
|
308
|
+
var import_api3, BRIZZ, PROPERTIES, SESSION_ID, PROPERTIES_CONTEXT_KEY, SESSION_OBJECT_CONTEXT_KEY, SESSION_INPUT, SESSION_OUTPUT, SESSION_INPUT_CONTEXT, SESSION_OUTPUT_CONTEXT, SESSION_SPAN_NAME, SESSION_TITLE_SPAN_NAME, SESSION_TITLE_GENERATION, SESSION_TITLE, INTERRUPT_TOOLS;
|
|
309
309
|
var init_semantic_conventions2 = __esm({
|
|
310
310
|
"src/internal/semantic-conventions.ts"() {
|
|
311
311
|
"use strict";
|
|
@@ -323,6 +323,7 @@ var init_semantic_conventions2 = __esm({
|
|
|
323
323
|
SESSION_TITLE_SPAN_NAME = "brizz.session_title";
|
|
324
324
|
SESSION_TITLE_GENERATION = "session.title_generation";
|
|
325
325
|
SESSION_TITLE = "brizz.session.title";
|
|
326
|
+
INTERRUPT_TOOLS = "brizz.internal.interrupt";
|
|
326
327
|
}
|
|
327
328
|
});
|
|
328
329
|
|
|
@@ -790,7 +791,7 @@ var init_protocol = __esm({
|
|
|
790
791
|
|
|
791
792
|
// src/internal/version.ts
|
|
792
793
|
function getSDKVersion() {
|
|
793
|
-
return "0.1.
|
|
794
|
+
return "0.1.27";
|
|
794
795
|
}
|
|
795
796
|
var init_version = __esm({
|
|
796
797
|
"src/internal/version.ts"() {
|
|
@@ -972,6 +973,100 @@ var init_mcp = __esm({
|
|
|
972
973
|
}
|
|
973
974
|
});
|
|
974
975
|
|
|
976
|
+
// src/internal/instrumentation/vercel-ai/interrupt.ts
|
|
977
|
+
var interrupt_exports = {};
|
|
978
|
+
__export(interrupt_exports, {
|
|
979
|
+
InterruptPropagator: () => InterruptPropagator,
|
|
980
|
+
_resetInterruptState: () => _resetInterruptState,
|
|
981
|
+
createInterruptIntegration: () => createInterruptIntegration
|
|
982
|
+
});
|
|
983
|
+
function isInnerLLMSpan(span) {
|
|
984
|
+
if (INNER_OPERATION_IDS.has(span.name)) {
|
|
985
|
+
return true;
|
|
986
|
+
}
|
|
987
|
+
const opId = span.attributes["ai.operationId"];
|
|
988
|
+
return typeof opId === "string" && INNER_OPERATION_IDS.has(opId);
|
|
989
|
+
}
|
|
990
|
+
function setPending(parentSpanId, value) {
|
|
991
|
+
pendingByParentSpanId.set(parentSpanId, value);
|
|
992
|
+
while (pendingByParentSpanId.size > MAX_PENDING_ENTRIES) {
|
|
993
|
+
const oldest = pendingByParentSpanId.keys().next().value;
|
|
994
|
+
if (oldest === void 0) {
|
|
995
|
+
break;
|
|
996
|
+
}
|
|
997
|
+
pendingByParentSpanId.delete(oldest);
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
function extractInterruptTools(tools) {
|
|
1001
|
+
if (!tools || typeof tools !== "object") {
|
|
1002
|
+
return [];
|
|
1003
|
+
}
|
|
1004
|
+
return Object.entries(tools).filter(
|
|
1005
|
+
([, t]) => !!t && typeof t === "object" && t.needsApproval
|
|
1006
|
+
).map(([name]) => name);
|
|
1007
|
+
}
|
|
1008
|
+
function createInterruptIntegration() {
|
|
1009
|
+
const onStepStart = (event) => {
|
|
1010
|
+
const names = extractInterruptTools(event.tools);
|
|
1011
|
+
if (names.length === 0) {
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
const value = JSON.stringify(names);
|
|
1015
|
+
const span = import_api8.trace.getActiveSpan();
|
|
1016
|
+
if (!span) {
|
|
1017
|
+
return;
|
|
1018
|
+
}
|
|
1019
|
+
span.setAttribute(INTERRUPT_TOOLS, value);
|
|
1020
|
+
setPending(span.spanContext().spanId, value);
|
|
1021
|
+
};
|
|
1022
|
+
return {
|
|
1023
|
+
onStepStart
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
1026
|
+
function _resetInterruptState() {
|
|
1027
|
+
if (process.env["NODE_ENV"] !== "test") {
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
pendingByParentSpanId.clear();
|
|
1031
|
+
}
|
|
1032
|
+
var import_api8, INNER_OPERATION_IDS, MAX_PENDING_ENTRIES, pendingByParentSpanId, InterruptPropagator;
|
|
1033
|
+
var init_interrupt = __esm({
|
|
1034
|
+
"src/internal/instrumentation/vercel-ai/interrupt.ts"() {
|
|
1035
|
+
"use strict";
|
|
1036
|
+
import_api8 = require("@opentelemetry/api");
|
|
1037
|
+
init_semantic_conventions2();
|
|
1038
|
+
INNER_OPERATION_IDS = /* @__PURE__ */ new Set([
|
|
1039
|
+
"ai.generateText.doGenerate",
|
|
1040
|
+
"ai.streamText.doStream"
|
|
1041
|
+
]);
|
|
1042
|
+
MAX_PENDING_ENTRIES = 1024;
|
|
1043
|
+
pendingByParentSpanId = /* @__PURE__ */ new Map();
|
|
1044
|
+
InterruptPropagator = class {
|
|
1045
|
+
onStart(span, _parentContext) {
|
|
1046
|
+
if (!isInnerLLMSpan(span)) {
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
const parentSpanId = span.parentSpanContext?.spanId;
|
|
1050
|
+
if (!parentSpanId) {
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
const value = pendingByParentSpanId.get(parentSpanId);
|
|
1054
|
+
if (!value) {
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
span.setAttribute(INTERRUPT_TOOLS, value);
|
|
1058
|
+
pendingByParentSpanId.delete(parentSpanId);
|
|
1059
|
+
}
|
|
1060
|
+
onEnd() {
|
|
1061
|
+
}
|
|
1062
|
+
async shutdown() {
|
|
1063
|
+
}
|
|
1064
|
+
async forceFlush() {
|
|
1065
|
+
}
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
});
|
|
1069
|
+
|
|
975
1070
|
// src/index.ts
|
|
976
1071
|
var src_exports = {};
|
|
977
1072
|
__export(src_exports, {
|
|
@@ -1084,6 +1179,26 @@ function loadMCPInstrumentation() {
|
|
|
1084
1179
|
}
|
|
1085
1180
|
})();
|
|
1086
1181
|
}
|
|
1182
|
+
function loadVercelAIInterruptIntegration() {
|
|
1183
|
+
void (async () => {
|
|
1184
|
+
try {
|
|
1185
|
+
const ai = await import("ai");
|
|
1186
|
+
if (typeof ai.registerTelemetryIntegration !== "function") {
|
|
1187
|
+
logger.debug(
|
|
1188
|
+
"AI SDK present but lacks registerTelemetryIntegration (needs ai@>=6); skipping interrupt bridge"
|
|
1189
|
+
);
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
const { createInterruptIntegration: createInterruptIntegration2 } = await Promise.resolve().then(() => (init_interrupt(), interrupt_exports));
|
|
1193
|
+
ai.registerTelemetryIntegration(createInterruptIntegration2());
|
|
1194
|
+
logger.debug("Auto-loaded Vercel AI interrupt bridge");
|
|
1195
|
+
} catch (error) {
|
|
1196
|
+
logger.debug(
|
|
1197
|
+
`Vercel AI interrupt bridge not loaded (install ai@>=6 if you want HITL attribution): ${String(error)}`
|
|
1198
|
+
);
|
|
1199
|
+
}
|
|
1200
|
+
})();
|
|
1201
|
+
}
|
|
1087
1202
|
function autoInitializeInstrumentations() {
|
|
1088
1203
|
if (autoInstrumentationsLoaded) {
|
|
1089
1204
|
return;
|
|
@@ -1092,6 +1207,7 @@ function autoInitializeInstrumentations() {
|
|
|
1092
1207
|
const nodeInstrumentations = loadNodeAutoInstrumentations();
|
|
1093
1208
|
const genAIInstrumentations = loadGenAIInstrumentations();
|
|
1094
1209
|
loadMCPInstrumentation();
|
|
1210
|
+
loadVercelAIInterruptIntegration();
|
|
1095
1211
|
autoInstrumentationsLoaded = true;
|
|
1096
1212
|
logger.info(
|
|
1097
1213
|
`Auto-initialization complete: ${nodeInstrumentations.length} node + ${genAIInstrumentations.length} GenAI instrumentations`
|
|
@@ -1406,6 +1522,9 @@ var InstrumentationRegistry = class _InstrumentationRegistry {
|
|
|
1406
1522
|
}
|
|
1407
1523
|
};
|
|
1408
1524
|
|
|
1525
|
+
// src/internal/sdk.ts
|
|
1526
|
+
init_interrupt();
|
|
1527
|
+
|
|
1409
1528
|
// src/internal/log/logging.ts
|
|
1410
1529
|
var import_api_logs = require("@opentelemetry/api-logs");
|
|
1411
1530
|
var import_exporter_logs_otlp_http = require("@opentelemetry/exporter-logs-otlp-http");
|
|
@@ -1415,7 +1534,7 @@ init_logger();
|
|
|
1415
1534
|
init_version();
|
|
1416
1535
|
|
|
1417
1536
|
// src/internal/log/processors/log-processor.ts
|
|
1418
|
-
var
|
|
1537
|
+
var import_api9 = require("@opentelemetry/api");
|
|
1419
1538
|
var import_sdk_logs = require("@opentelemetry/sdk-logs");
|
|
1420
1539
|
init_logger();
|
|
1421
1540
|
|
|
@@ -1847,7 +1966,7 @@ var BrizzSimpleLogRecordProcessor = class extends import_sdk_logs.SimpleLogRecor
|
|
|
1847
1966
|
if (maskingConfig) {
|
|
1848
1967
|
maskLog(logRecord, maskingConfig);
|
|
1849
1968
|
}
|
|
1850
|
-
const associationProperties =
|
|
1969
|
+
const associationProperties = import_api9.context.active().getValue(PROPERTIES_CONTEXT_KEY);
|
|
1851
1970
|
if (associationProperties) {
|
|
1852
1971
|
for (const [key, value] of Object.entries(associationProperties)) {
|
|
1853
1972
|
logRecord.setAttribute(`${BRIZZ}.${key}`, value);
|
|
@@ -1867,7 +1986,7 @@ var BrizzBatchLogRecordProcessor = class extends import_sdk_logs.BatchLogRecordP
|
|
|
1867
1986
|
if (maskingConfig) {
|
|
1868
1987
|
maskLog(logRecord, maskingConfig);
|
|
1869
1988
|
}
|
|
1870
|
-
const associationProperties =
|
|
1989
|
+
const associationProperties = import_api9.context.active().getValue(PROPERTIES_CONTEXT_KEY);
|
|
1871
1990
|
if (associationProperties) {
|
|
1872
1991
|
for (const [key, value] of Object.entries(associationProperties)) {
|
|
1873
1992
|
logRecord.setAttribute(`${BRIZZ}.${key}`, value);
|
|
@@ -2267,12 +2386,12 @@ var BrizzSpanExporter = class {
|
|
|
2267
2386
|
};
|
|
2268
2387
|
|
|
2269
2388
|
// src/internal/trace/processors/span-processor.ts
|
|
2270
|
-
var
|
|
2389
|
+
var import_api10 = require("@opentelemetry/api");
|
|
2271
2390
|
var import_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
|
|
2272
2391
|
init_logger();
|
|
2273
2392
|
init_semantic_conventions2();
|
|
2274
2393
|
function applyContextAttributes(span) {
|
|
2275
|
-
const sessionProperties =
|
|
2394
|
+
const sessionProperties = import_api10.context.active().getValue(PROPERTIES_CONTEXT_KEY);
|
|
2276
2395
|
if (sessionProperties) {
|
|
2277
2396
|
for (const [key, value] of Object.entries(sessionProperties)) {
|
|
2278
2397
|
span.setAttribute(`${BRIZZ}.${key}`, value);
|
|
@@ -2458,10 +2577,10 @@ function getSpanProcessor() {
|
|
|
2458
2577
|
}
|
|
2459
2578
|
|
|
2460
2579
|
// src/internal/trace/session.ts
|
|
2461
|
-
var
|
|
2580
|
+
var import_api11 = require("@opentelemetry/api");
|
|
2462
2581
|
init_semantic_conventions2();
|
|
2463
2582
|
function setCurrentSpanCustomProperties(properties) {
|
|
2464
|
-
const current =
|
|
2583
|
+
const current = import_api11.trace.getActiveSpan();
|
|
2465
2584
|
if (!current || !current.isRecording()) {
|
|
2466
2585
|
return;
|
|
2467
2586
|
}
|
|
@@ -2473,11 +2592,11 @@ function setCurrentSpanCustomProperties(properties) {
|
|
|
2473
2592
|
}
|
|
2474
2593
|
}
|
|
2475
2594
|
function callWithProperties(properties, fn, thisArg, ...args) {
|
|
2476
|
-
const base =
|
|
2595
|
+
const base = import_api11.context.active();
|
|
2477
2596
|
const prev = base.getValue(PROPERTIES_CONTEXT_KEY);
|
|
2478
2597
|
const merged = prev ? { ...prev, ...properties } : properties;
|
|
2479
2598
|
const next = base.setValue(PROPERTIES_CONTEXT_KEY, merged);
|
|
2480
|
-
return
|
|
2599
|
+
return import_api11.context.with(next, fn, thisArg, ...args);
|
|
2481
2600
|
}
|
|
2482
2601
|
function withProperties(properties, fn, thisArg) {
|
|
2483
2602
|
return function wrapped(...args) {
|
|
@@ -2576,12 +2695,12 @@ var SessionTitle = class {
|
|
|
2576
2695
|
}
|
|
2577
2696
|
};
|
|
2578
2697
|
function getActiveSession() {
|
|
2579
|
-
return
|
|
2698
|
+
return import_api11.context.active().getValue(SESSION_OBJECT_CONTEXT_KEY);
|
|
2580
2699
|
}
|
|
2581
2700
|
function startSession(sessionId, callback, extraProperties, options) {
|
|
2582
2701
|
const isTitle = options?.mode === "title";
|
|
2583
2702
|
const spanName = isTitle ? SESSION_TITLE_SPAN_NAME : SESSION_SPAN_NAME;
|
|
2584
|
-
const tracer =
|
|
2703
|
+
const tracer = import_api11.trace.getTracer("@brizz/sdk");
|
|
2585
2704
|
return tracer.startActiveSpan(spanName, (span) => {
|
|
2586
2705
|
span.setAttribute(`${BRIZZ}.${SESSION_ID}`, sessionId);
|
|
2587
2706
|
if (extraProperties) {
|
|
@@ -2600,8 +2719,8 @@ function startSession(sessionId, callback, extraProperties, options) {
|
|
|
2600
2719
|
}
|
|
2601
2720
|
}
|
|
2602
2721
|
return callWithProperties(contextProperties, () => {
|
|
2603
|
-
const sessionCtx =
|
|
2604
|
-
return
|
|
2722
|
+
const sessionCtx = import_api11.context.active().setValue(SESSION_OBJECT_CONTEXT_KEY, session);
|
|
2723
|
+
return import_api11.context.with(sessionCtx, () => {
|
|
2605
2724
|
try {
|
|
2606
2725
|
const result = callback(session);
|
|
2607
2726
|
if (result && typeof result.then === "function") {
|
|
@@ -2610,7 +2729,7 @@ function startSession(sessionId, callback, extraProperties, options) {
|
|
|
2610
2729
|
return value;
|
|
2611
2730
|
}).catch((error) => {
|
|
2612
2731
|
span.recordException(error);
|
|
2613
|
-
span.setStatus({ code:
|
|
2732
|
+
span.setStatus({ code: import_api11.SpanStatusCode.ERROR });
|
|
2614
2733
|
span.end();
|
|
2615
2734
|
throw error;
|
|
2616
2735
|
});
|
|
@@ -2619,7 +2738,7 @@ function startSession(sessionId, callback, extraProperties, options) {
|
|
|
2619
2738
|
return result;
|
|
2620
2739
|
} catch (error) {
|
|
2621
2740
|
span.recordException(error);
|
|
2622
|
-
span.setStatus({ code:
|
|
2741
|
+
span.setStatus({ code: import_api11.SpanStatusCode.ERROR });
|
|
2623
2742
|
span.end();
|
|
2624
2743
|
throw error;
|
|
2625
2744
|
}
|
|
@@ -2629,7 +2748,7 @@ function startSession(sessionId, callback, extraProperties, options) {
|
|
|
2629
2748
|
}
|
|
2630
2749
|
function startSessionTitle(callback, options) {
|
|
2631
2750
|
const resolvedSessionId = options?.sessionId ?? getActiveSession()?.sessionId;
|
|
2632
|
-
const tracer =
|
|
2751
|
+
const tracer = import_api11.trace.getTracer("@brizz/sdk");
|
|
2633
2752
|
return tracer.startActiveSpan(SESSION_TITLE_SPAN_NAME, (span) => {
|
|
2634
2753
|
if (resolvedSessionId) {
|
|
2635
2754
|
span.setAttribute(`${BRIZZ}.${SESSION_ID}`, resolvedSessionId);
|
|
@@ -2648,7 +2767,7 @@ function startSessionTitle(callback, options) {
|
|
|
2648
2767
|
return value;
|
|
2649
2768
|
}).catch((error) => {
|
|
2650
2769
|
span.recordException(error);
|
|
2651
|
-
span.setStatus({ code:
|
|
2770
|
+
span.setStatus({ code: import_api11.SpanStatusCode.ERROR });
|
|
2652
2771
|
span.end();
|
|
2653
2772
|
throw error;
|
|
2654
2773
|
});
|
|
@@ -2657,7 +2776,7 @@ function startSessionTitle(callback, options) {
|
|
|
2657
2776
|
return result;
|
|
2658
2777
|
} catch (error) {
|
|
2659
2778
|
span.recordException(error);
|
|
2660
|
-
span.setStatus({ code:
|
|
2779
|
+
span.setStatus({ code: import_api11.SpanStatusCode.ERROR });
|
|
2661
2780
|
span.end();
|
|
2662
2781
|
throw error;
|
|
2663
2782
|
}
|
|
@@ -2749,7 +2868,7 @@ var _Brizz = class __Brizz {
|
|
|
2749
2868
|
resourceAttributes["service.version"] = resolvedConfig.appVersion;
|
|
2750
2869
|
}
|
|
2751
2870
|
this._sdk = new import_sdk_node.NodeSDK({
|
|
2752
|
-
spanProcessors: resolvedConfig.disableSpanExporter ? [] : [getSpanProcessor()],
|
|
2871
|
+
spanProcessors: resolvedConfig.disableSpanExporter ? [] : [new InterruptPropagator(), getSpanProcessor()],
|
|
2753
2872
|
metricReader: getMetricsReader(),
|
|
2754
2873
|
resource: (0, import_resources3.resourceFromAttributes)(resourceAttributes),
|
|
2755
2874
|
instrumentations: manualInstrumentations
|
package/dist/index.js
CHANGED
|
@@ -290,7 +290,7 @@ var init_schemas = __esm({
|
|
|
290
290
|
|
|
291
291
|
// src/internal/semantic-conventions.ts
|
|
292
292
|
import { createContextKey } from "@opentelemetry/api";
|
|
293
|
-
var BRIZZ, PROPERTIES, SESSION_ID, PROPERTIES_CONTEXT_KEY, SESSION_OBJECT_CONTEXT_KEY, SESSION_INPUT, SESSION_OUTPUT, SESSION_INPUT_CONTEXT, SESSION_OUTPUT_CONTEXT, SESSION_SPAN_NAME, SESSION_TITLE_SPAN_NAME, SESSION_TITLE_GENERATION, SESSION_TITLE;
|
|
293
|
+
var BRIZZ, PROPERTIES, SESSION_ID, PROPERTIES_CONTEXT_KEY, SESSION_OBJECT_CONTEXT_KEY, SESSION_INPUT, SESSION_OUTPUT, SESSION_INPUT_CONTEXT, SESSION_OUTPUT_CONTEXT, SESSION_SPAN_NAME, SESSION_TITLE_SPAN_NAME, SESSION_TITLE_GENERATION, SESSION_TITLE, INTERRUPT_TOOLS;
|
|
294
294
|
var init_semantic_conventions2 = __esm({
|
|
295
295
|
"src/internal/semantic-conventions.ts"() {
|
|
296
296
|
"use strict";
|
|
@@ -307,6 +307,7 @@ var init_semantic_conventions2 = __esm({
|
|
|
307
307
|
SESSION_TITLE_SPAN_NAME = "brizz.session_title";
|
|
308
308
|
SESSION_TITLE_GENERATION = "session.title_generation";
|
|
309
309
|
SESSION_TITLE = "brizz.session.title";
|
|
310
|
+
INTERRUPT_TOOLS = "brizz.internal.interrupt";
|
|
310
311
|
}
|
|
311
312
|
});
|
|
312
313
|
|
|
@@ -772,7 +773,7 @@ var init_protocol = __esm({
|
|
|
772
773
|
|
|
773
774
|
// src/internal/version.ts
|
|
774
775
|
function getSDKVersion() {
|
|
775
|
-
return "0.1.
|
|
776
|
+
return "0.1.27";
|
|
776
777
|
}
|
|
777
778
|
var init_version = __esm({
|
|
778
779
|
"src/internal/version.ts"() {
|
|
@@ -954,6 +955,100 @@ var init_mcp = __esm({
|
|
|
954
955
|
}
|
|
955
956
|
});
|
|
956
957
|
|
|
958
|
+
// src/internal/instrumentation/vercel-ai/interrupt.ts
|
|
959
|
+
var interrupt_exports = {};
|
|
960
|
+
__export(interrupt_exports, {
|
|
961
|
+
InterruptPropagator: () => InterruptPropagator,
|
|
962
|
+
_resetInterruptState: () => _resetInterruptState,
|
|
963
|
+
createInterruptIntegration: () => createInterruptIntegration
|
|
964
|
+
});
|
|
965
|
+
import { trace as trace3 } from "@opentelemetry/api";
|
|
966
|
+
function isInnerLLMSpan(span) {
|
|
967
|
+
if (INNER_OPERATION_IDS.has(span.name)) {
|
|
968
|
+
return true;
|
|
969
|
+
}
|
|
970
|
+
const opId = span.attributes["ai.operationId"];
|
|
971
|
+
return typeof opId === "string" && INNER_OPERATION_IDS.has(opId);
|
|
972
|
+
}
|
|
973
|
+
function setPending(parentSpanId, value) {
|
|
974
|
+
pendingByParentSpanId.set(parentSpanId, value);
|
|
975
|
+
while (pendingByParentSpanId.size > MAX_PENDING_ENTRIES) {
|
|
976
|
+
const oldest = pendingByParentSpanId.keys().next().value;
|
|
977
|
+
if (oldest === void 0) {
|
|
978
|
+
break;
|
|
979
|
+
}
|
|
980
|
+
pendingByParentSpanId.delete(oldest);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
function extractInterruptTools(tools) {
|
|
984
|
+
if (!tools || typeof tools !== "object") {
|
|
985
|
+
return [];
|
|
986
|
+
}
|
|
987
|
+
return Object.entries(tools).filter(
|
|
988
|
+
([, t]) => !!t && typeof t === "object" && t.needsApproval
|
|
989
|
+
).map(([name]) => name);
|
|
990
|
+
}
|
|
991
|
+
function createInterruptIntegration() {
|
|
992
|
+
const onStepStart = (event) => {
|
|
993
|
+
const names = extractInterruptTools(event.tools);
|
|
994
|
+
if (names.length === 0) {
|
|
995
|
+
return;
|
|
996
|
+
}
|
|
997
|
+
const value = JSON.stringify(names);
|
|
998
|
+
const span = trace3.getActiveSpan();
|
|
999
|
+
if (!span) {
|
|
1000
|
+
return;
|
|
1001
|
+
}
|
|
1002
|
+
span.setAttribute(INTERRUPT_TOOLS, value);
|
|
1003
|
+
setPending(span.spanContext().spanId, value);
|
|
1004
|
+
};
|
|
1005
|
+
return {
|
|
1006
|
+
onStepStart
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
function _resetInterruptState() {
|
|
1010
|
+
if (process.env["NODE_ENV"] !== "test") {
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
pendingByParentSpanId.clear();
|
|
1014
|
+
}
|
|
1015
|
+
var INNER_OPERATION_IDS, MAX_PENDING_ENTRIES, pendingByParentSpanId, InterruptPropagator;
|
|
1016
|
+
var init_interrupt = __esm({
|
|
1017
|
+
"src/internal/instrumentation/vercel-ai/interrupt.ts"() {
|
|
1018
|
+
"use strict";
|
|
1019
|
+
init_semantic_conventions2();
|
|
1020
|
+
INNER_OPERATION_IDS = /* @__PURE__ */ new Set([
|
|
1021
|
+
"ai.generateText.doGenerate",
|
|
1022
|
+
"ai.streamText.doStream"
|
|
1023
|
+
]);
|
|
1024
|
+
MAX_PENDING_ENTRIES = 1024;
|
|
1025
|
+
pendingByParentSpanId = /* @__PURE__ */ new Map();
|
|
1026
|
+
InterruptPropagator = class {
|
|
1027
|
+
onStart(span, _parentContext) {
|
|
1028
|
+
if (!isInnerLLMSpan(span)) {
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
const parentSpanId = span.parentSpanContext?.spanId;
|
|
1032
|
+
if (!parentSpanId) {
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
const value = pendingByParentSpanId.get(parentSpanId);
|
|
1036
|
+
if (!value) {
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
span.setAttribute(INTERRUPT_TOOLS, value);
|
|
1040
|
+
pendingByParentSpanId.delete(parentSpanId);
|
|
1041
|
+
}
|
|
1042
|
+
onEnd() {
|
|
1043
|
+
}
|
|
1044
|
+
async shutdown() {
|
|
1045
|
+
}
|
|
1046
|
+
async forceFlush() {
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
});
|
|
1051
|
+
|
|
957
1052
|
// src/internal/instrumentation/auto-init.ts
|
|
958
1053
|
init_logger();
|
|
959
1054
|
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
|
|
@@ -1034,6 +1129,26 @@ function loadMCPInstrumentation() {
|
|
|
1034
1129
|
}
|
|
1035
1130
|
})();
|
|
1036
1131
|
}
|
|
1132
|
+
function loadVercelAIInterruptIntegration() {
|
|
1133
|
+
void (async () => {
|
|
1134
|
+
try {
|
|
1135
|
+
const ai = await import("ai");
|
|
1136
|
+
if (typeof ai.registerTelemetryIntegration !== "function") {
|
|
1137
|
+
logger.debug(
|
|
1138
|
+
"AI SDK present but lacks registerTelemetryIntegration (needs ai@>=6); skipping interrupt bridge"
|
|
1139
|
+
);
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
const { createInterruptIntegration: createInterruptIntegration2 } = await Promise.resolve().then(() => (init_interrupt(), interrupt_exports));
|
|
1143
|
+
ai.registerTelemetryIntegration(createInterruptIntegration2());
|
|
1144
|
+
logger.debug("Auto-loaded Vercel AI interrupt bridge");
|
|
1145
|
+
} catch (error) {
|
|
1146
|
+
logger.debug(
|
|
1147
|
+
`Vercel AI interrupt bridge not loaded (install ai@>=6 if you want HITL attribution): ${String(error)}`
|
|
1148
|
+
);
|
|
1149
|
+
}
|
|
1150
|
+
})();
|
|
1151
|
+
}
|
|
1037
1152
|
function autoInitializeInstrumentations() {
|
|
1038
1153
|
if (autoInstrumentationsLoaded) {
|
|
1039
1154
|
return;
|
|
@@ -1042,6 +1157,7 @@ function autoInitializeInstrumentations() {
|
|
|
1042
1157
|
const nodeInstrumentations = loadNodeAutoInstrumentations();
|
|
1043
1158
|
const genAIInstrumentations = loadGenAIInstrumentations();
|
|
1044
1159
|
loadMCPInstrumentation();
|
|
1160
|
+
loadVercelAIInterruptIntegration();
|
|
1045
1161
|
autoInstrumentationsLoaded = true;
|
|
1046
1162
|
logger.info(
|
|
1047
1163
|
`Auto-initialization complete: ${nodeInstrumentations.length} node + ${genAIInstrumentations.length} GenAI instrumentations`
|
|
@@ -1356,6 +1472,9 @@ var InstrumentationRegistry = class _InstrumentationRegistry {
|
|
|
1356
1472
|
}
|
|
1357
1473
|
};
|
|
1358
1474
|
|
|
1475
|
+
// src/internal/sdk.ts
|
|
1476
|
+
init_interrupt();
|
|
1477
|
+
|
|
1359
1478
|
// src/internal/log/logging.ts
|
|
1360
1479
|
import { SeverityNumber } from "@opentelemetry/api-logs";
|
|
1361
1480
|
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
|
|
@@ -2414,9 +2533,9 @@ function getSpanProcessor() {
|
|
|
2414
2533
|
|
|
2415
2534
|
// src/internal/trace/session.ts
|
|
2416
2535
|
init_semantic_conventions2();
|
|
2417
|
-
import { context as context5, trace as
|
|
2536
|
+
import { context as context5, trace as trace4, SpanStatusCode as SpanStatusCode3 } from "@opentelemetry/api";
|
|
2418
2537
|
function setCurrentSpanCustomProperties(properties) {
|
|
2419
|
-
const current =
|
|
2538
|
+
const current = trace4.getActiveSpan();
|
|
2420
2539
|
if (!current || !current.isRecording()) {
|
|
2421
2540
|
return;
|
|
2422
2541
|
}
|
|
@@ -2536,7 +2655,7 @@ function getActiveSession() {
|
|
|
2536
2655
|
function startSession(sessionId, callback, extraProperties, options) {
|
|
2537
2656
|
const isTitle = options?.mode === "title";
|
|
2538
2657
|
const spanName = isTitle ? SESSION_TITLE_SPAN_NAME : SESSION_SPAN_NAME;
|
|
2539
|
-
const tracer =
|
|
2658
|
+
const tracer = trace4.getTracer("@brizz/sdk");
|
|
2540
2659
|
return tracer.startActiveSpan(spanName, (span) => {
|
|
2541
2660
|
span.setAttribute(`${BRIZZ}.${SESSION_ID}`, sessionId);
|
|
2542
2661
|
if (extraProperties) {
|
|
@@ -2584,7 +2703,7 @@ function startSession(sessionId, callback, extraProperties, options) {
|
|
|
2584
2703
|
}
|
|
2585
2704
|
function startSessionTitle(callback, options) {
|
|
2586
2705
|
const resolvedSessionId = options?.sessionId ?? getActiveSession()?.sessionId;
|
|
2587
|
-
const tracer =
|
|
2706
|
+
const tracer = trace4.getTracer("@brizz/sdk");
|
|
2588
2707
|
return tracer.startActiveSpan(SESSION_TITLE_SPAN_NAME, (span) => {
|
|
2589
2708
|
if (resolvedSessionId) {
|
|
2590
2709
|
span.setAttribute(`${BRIZZ}.${SESSION_ID}`, resolvedSessionId);
|
|
@@ -2704,7 +2823,7 @@ var _Brizz = class __Brizz {
|
|
|
2704
2823
|
resourceAttributes["service.version"] = resolvedConfig.appVersion;
|
|
2705
2824
|
}
|
|
2706
2825
|
this._sdk = new NodeSDK({
|
|
2707
|
-
spanProcessors: resolvedConfig.disableSpanExporter ? [] : [getSpanProcessor()],
|
|
2826
|
+
spanProcessors: resolvedConfig.disableSpanExporter ? [] : [new InterruptPropagator(), getSpanProcessor()],
|
|
2708
2827
|
metricReader: getMetricsReader(),
|
|
2709
2828
|
resource: resourceFromAttributes3(resourceAttributes),
|
|
2710
2829
|
instrumentations: manualInstrumentations
|
package/dist/preload.cjs
CHANGED
|
@@ -471,6 +471,7 @@ var PROPERTIES = "properties";
|
|
|
471
471
|
var SESSION_ID = "session.id";
|
|
472
472
|
var PROPERTIES_CONTEXT_KEY = (0, import_api3.createContextKey)(PROPERTIES);
|
|
473
473
|
var SESSION_OBJECT_CONTEXT_KEY = (0, import_api3.createContextKey)("brizz.session.object");
|
|
474
|
+
var INTERRUPT_TOOLS = "brizz.internal.interrupt";
|
|
474
475
|
|
|
475
476
|
// src/internal/instrumentation/mcp/session.ts
|
|
476
477
|
function stampAndPropagateSession(span, sessionId, baseContext = import_api4.context.active()) {
|
|
@@ -908,7 +909,7 @@ function safeEnd(span) {
|
|
|
908
909
|
|
|
909
910
|
// src/internal/version.ts
|
|
910
911
|
function getSDKVersion() {
|
|
911
|
-
return "0.1.
|
|
912
|
+
return "0.1.27";
|
|
912
913
|
}
|
|
913
914
|
|
|
914
915
|
// src/internal/instrumentation/mcp/version.ts
|
|
@@ -1166,6 +1167,44 @@ var InstrumentationRegistry = class _InstrumentationRegistry {
|
|
|
1166
1167
|
}
|
|
1167
1168
|
};
|
|
1168
1169
|
|
|
1170
|
+
// src/internal/instrumentation/vercel-ai/interrupt.ts
|
|
1171
|
+
var import_api8 = require("@opentelemetry/api");
|
|
1172
|
+
var INNER_OPERATION_IDS = /* @__PURE__ */ new Set([
|
|
1173
|
+
"ai.generateText.doGenerate",
|
|
1174
|
+
"ai.streamText.doStream"
|
|
1175
|
+
]);
|
|
1176
|
+
function isInnerLLMSpan(span) {
|
|
1177
|
+
if (INNER_OPERATION_IDS.has(span.name)) {
|
|
1178
|
+
return true;
|
|
1179
|
+
}
|
|
1180
|
+
const opId = span.attributes["ai.operationId"];
|
|
1181
|
+
return typeof opId === "string" && INNER_OPERATION_IDS.has(opId);
|
|
1182
|
+
}
|
|
1183
|
+
var pendingByParentSpanId = /* @__PURE__ */ new Map();
|
|
1184
|
+
var InterruptPropagator = class {
|
|
1185
|
+
onStart(span, _parentContext) {
|
|
1186
|
+
if (!isInnerLLMSpan(span)) {
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
const parentSpanId = span.parentSpanContext?.spanId;
|
|
1190
|
+
if (!parentSpanId) {
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
const value = pendingByParentSpanId.get(parentSpanId);
|
|
1194
|
+
if (!value) {
|
|
1195
|
+
return;
|
|
1196
|
+
}
|
|
1197
|
+
span.setAttribute(INTERRUPT_TOOLS, value);
|
|
1198
|
+
pendingByParentSpanId.delete(parentSpanId);
|
|
1199
|
+
}
|
|
1200
|
+
onEnd() {
|
|
1201
|
+
}
|
|
1202
|
+
async shutdown() {
|
|
1203
|
+
}
|
|
1204
|
+
async forceFlush() {
|
|
1205
|
+
}
|
|
1206
|
+
};
|
|
1207
|
+
|
|
1169
1208
|
// src/internal/log/logging.ts
|
|
1170
1209
|
var import_api_logs = require("@opentelemetry/api-logs");
|
|
1171
1210
|
var import_exporter_logs_otlp_http = require("@opentelemetry/exporter-logs-otlp-http");
|
|
@@ -1173,7 +1212,7 @@ var import_resources = require("@opentelemetry/resources");
|
|
|
1173
1212
|
var import_sdk_logs2 = require("@opentelemetry/sdk-logs");
|
|
1174
1213
|
|
|
1175
1214
|
// src/internal/log/processors/log-processor.ts
|
|
1176
|
-
var
|
|
1215
|
+
var import_api9 = require("@opentelemetry/api");
|
|
1177
1216
|
var import_sdk_logs = require("@opentelemetry/sdk-logs");
|
|
1178
1217
|
|
|
1179
1218
|
// src/internal/masking/patterns.ts
|
|
@@ -1602,7 +1641,7 @@ var BrizzSimpleLogRecordProcessor = class extends import_sdk_logs.SimpleLogRecor
|
|
|
1602
1641
|
if (maskingConfig) {
|
|
1603
1642
|
maskLog(logRecord, maskingConfig);
|
|
1604
1643
|
}
|
|
1605
|
-
const associationProperties =
|
|
1644
|
+
const associationProperties = import_api9.context.active().getValue(PROPERTIES_CONTEXT_KEY);
|
|
1606
1645
|
if (associationProperties) {
|
|
1607
1646
|
for (const [key, value] of Object.entries(associationProperties)) {
|
|
1608
1647
|
logRecord.setAttribute(`${BRIZZ}.${key}`, value);
|
|
@@ -1622,7 +1661,7 @@ var BrizzBatchLogRecordProcessor = class extends import_sdk_logs.BatchLogRecordP
|
|
|
1622
1661
|
if (maskingConfig) {
|
|
1623
1662
|
maskLog(logRecord, maskingConfig);
|
|
1624
1663
|
}
|
|
1625
|
-
const associationProperties =
|
|
1664
|
+
const associationProperties = import_api9.context.active().getValue(PROPERTIES_CONTEXT_KEY);
|
|
1626
1665
|
if (associationProperties) {
|
|
1627
1666
|
for (const [key, value] of Object.entries(associationProperties)) {
|
|
1628
1667
|
logRecord.setAttribute(`${BRIZZ}.${key}`, value);
|
|
@@ -2009,10 +2048,10 @@ var BrizzSpanExporter = class {
|
|
|
2009
2048
|
};
|
|
2010
2049
|
|
|
2011
2050
|
// src/internal/trace/processors/span-processor.ts
|
|
2012
|
-
var
|
|
2051
|
+
var import_api10 = require("@opentelemetry/api");
|
|
2013
2052
|
var import_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
|
|
2014
2053
|
function applyContextAttributes(span) {
|
|
2015
|
-
const sessionProperties =
|
|
2054
|
+
const sessionProperties = import_api10.context.active().getValue(PROPERTIES_CONTEXT_KEY);
|
|
2016
2055
|
if (sessionProperties) {
|
|
2017
2056
|
for (const [key, value] of Object.entries(sessionProperties)) {
|
|
2018
2057
|
span.setAttribute(`${BRIZZ}.${key}`, value);
|
|
@@ -2195,7 +2234,7 @@ function getSpanProcessor() {
|
|
|
2195
2234
|
}
|
|
2196
2235
|
|
|
2197
2236
|
// src/internal/trace/session.ts
|
|
2198
|
-
var
|
|
2237
|
+
var import_api11 = require("@opentelemetry/api");
|
|
2199
2238
|
|
|
2200
2239
|
// src/internal/sdk.ts
|
|
2201
2240
|
var _Brizz = class __Brizz {
|
|
@@ -2280,7 +2319,7 @@ var _Brizz = class __Brizz {
|
|
|
2280
2319
|
resourceAttributes["service.version"] = resolvedConfig.appVersion;
|
|
2281
2320
|
}
|
|
2282
2321
|
this._sdk = new import_sdk_node.NodeSDK({
|
|
2283
|
-
spanProcessors: resolvedConfig.disableSpanExporter ? [] : [getSpanProcessor()],
|
|
2322
|
+
spanProcessors: resolvedConfig.disableSpanExporter ? [] : [new InterruptPropagator(), getSpanProcessor()],
|
|
2284
2323
|
metricReader: getMetricsReader(),
|
|
2285
2324
|
resource: (0, import_resources3.resourceFromAttributes)(resourceAttributes),
|
|
2286
2325
|
instrumentations: manualInstrumentations
|
package/dist/preload.js
CHANGED
|
@@ -454,6 +454,7 @@ var PROPERTIES = "properties";
|
|
|
454
454
|
var SESSION_ID = "session.id";
|
|
455
455
|
var PROPERTIES_CONTEXT_KEY = createContextKey(PROPERTIES);
|
|
456
456
|
var SESSION_OBJECT_CONTEXT_KEY = createContextKey("brizz.session.object");
|
|
457
|
+
var INTERRUPT_TOOLS = "brizz.internal.interrupt";
|
|
457
458
|
|
|
458
459
|
// src/internal/instrumentation/mcp/session.ts
|
|
459
460
|
function stampAndPropagateSession(span, sessionId, baseContext = context.active()) {
|
|
@@ -891,7 +892,7 @@ function safeEnd(span) {
|
|
|
891
892
|
|
|
892
893
|
// src/internal/version.ts
|
|
893
894
|
function getSDKVersion() {
|
|
894
|
-
return "0.1.
|
|
895
|
+
return "0.1.27";
|
|
895
896
|
}
|
|
896
897
|
|
|
897
898
|
// src/internal/instrumentation/mcp/version.ts
|
|
@@ -1149,6 +1150,44 @@ var InstrumentationRegistry = class _InstrumentationRegistry {
|
|
|
1149
1150
|
}
|
|
1150
1151
|
};
|
|
1151
1152
|
|
|
1153
|
+
// src/internal/instrumentation/vercel-ai/interrupt.ts
|
|
1154
|
+
import { trace as trace3 } from "@opentelemetry/api";
|
|
1155
|
+
var INNER_OPERATION_IDS = /* @__PURE__ */ new Set([
|
|
1156
|
+
"ai.generateText.doGenerate",
|
|
1157
|
+
"ai.streamText.doStream"
|
|
1158
|
+
]);
|
|
1159
|
+
function isInnerLLMSpan(span) {
|
|
1160
|
+
if (INNER_OPERATION_IDS.has(span.name)) {
|
|
1161
|
+
return true;
|
|
1162
|
+
}
|
|
1163
|
+
const opId = span.attributes["ai.operationId"];
|
|
1164
|
+
return typeof opId === "string" && INNER_OPERATION_IDS.has(opId);
|
|
1165
|
+
}
|
|
1166
|
+
var pendingByParentSpanId = /* @__PURE__ */ new Map();
|
|
1167
|
+
var InterruptPropagator = class {
|
|
1168
|
+
onStart(span, _parentContext) {
|
|
1169
|
+
if (!isInnerLLMSpan(span)) {
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
const parentSpanId = span.parentSpanContext?.spanId;
|
|
1173
|
+
if (!parentSpanId) {
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
const value = pendingByParentSpanId.get(parentSpanId);
|
|
1177
|
+
if (!value) {
|
|
1178
|
+
return;
|
|
1179
|
+
}
|
|
1180
|
+
span.setAttribute(INTERRUPT_TOOLS, value);
|
|
1181
|
+
pendingByParentSpanId.delete(parentSpanId);
|
|
1182
|
+
}
|
|
1183
|
+
onEnd() {
|
|
1184
|
+
}
|
|
1185
|
+
async shutdown() {
|
|
1186
|
+
}
|
|
1187
|
+
async forceFlush() {
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
|
|
1152
1191
|
// src/internal/log/logging.ts
|
|
1153
1192
|
import { SeverityNumber } from "@opentelemetry/api-logs";
|
|
1154
1193
|
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
|
|
@@ -2183,7 +2222,7 @@ function getSpanProcessor() {
|
|
|
2183
2222
|
}
|
|
2184
2223
|
|
|
2185
2224
|
// src/internal/trace/session.ts
|
|
2186
|
-
import { context as context5, trace as
|
|
2225
|
+
import { context as context5, trace as trace4, SpanStatusCode as SpanStatusCode3 } from "@opentelemetry/api";
|
|
2187
2226
|
|
|
2188
2227
|
// src/internal/sdk.ts
|
|
2189
2228
|
var _Brizz = class __Brizz {
|
|
@@ -2268,7 +2307,7 @@ var _Brizz = class __Brizz {
|
|
|
2268
2307
|
resourceAttributes["service.version"] = resolvedConfig.appVersion;
|
|
2269
2308
|
}
|
|
2270
2309
|
this._sdk = new NodeSDK({
|
|
2271
|
-
spanProcessors: resolvedConfig.disableSpanExporter ? [] : [getSpanProcessor()],
|
|
2310
|
+
spanProcessors: resolvedConfig.disableSpanExporter ? [] : [new InterruptPropagator(), getSpanProcessor()],
|
|
2272
2311
|
metricReader: getMetricsReader(),
|
|
2273
2312
|
resource: resourceFromAttributes3(resourceAttributes),
|
|
2274
2313
|
instrumentations: manualInstrumentations
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brizz/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenTelemetry-based observability SDK for AI applications",
|
|
6
6
|
"keywords": [
|
|
@@ -114,12 +114,16 @@
|
|
|
114
114
|
},
|
|
115
115
|
"peerDependencies": {
|
|
116
116
|
"@langchain/core": "^0.3.0 || ^1.0.0",
|
|
117
|
+
"ai": "*",
|
|
117
118
|
"typescript": ">=5.0.0"
|
|
118
119
|
},
|
|
119
120
|
"peerDependenciesMeta": {
|
|
120
121
|
"@langchain/core": {
|
|
121
122
|
"optional": true
|
|
122
123
|
},
|
|
124
|
+
"ai": {
|
|
125
|
+
"optional": true
|
|
126
|
+
},
|
|
123
127
|
"typescript": {
|
|
124
128
|
"optional": true
|
|
125
129
|
}
|