@frontmcp/observability 1.9.2 → 1.9.4
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/esm/index.mjs +224 -135
- package/esm/package.json +3 -3
- package/index.js +316 -228
- package/otel/otel.types.d.ts +1 -1
- package/package.json +3 -3
- package/plugin/observability.hooks.d.ts +28 -0
- package/plugin/observability.plugin.d.ts +7 -2
- package/request-log/request-log.collector.d.ts +4 -0
- package/request-log/request-log.hooks.d.ts +9 -2
- package/request-log/request-log.types.d.ts +1 -1
package/index.js
CHANGED
|
@@ -399,8 +399,8 @@ __export(index_exports, {
|
|
|
399
399
|
module.exports = __toCommonJS(index_exports);
|
|
400
400
|
|
|
401
401
|
// libs/observability/src/plugin/observability.plugin.ts
|
|
402
|
-
var
|
|
403
|
-
var
|
|
402
|
+
var import_api17 = require("@opentelemetry/api");
|
|
403
|
+
var import_sdk4 = require("@frontmcp/sdk");
|
|
404
404
|
|
|
405
405
|
// libs/observability/src/logging/sinks/stdout.sink.ts
|
|
406
406
|
function defaultStream() {
|
|
@@ -763,6 +763,13 @@ var RequestLogCollector = class {
|
|
|
763
763
|
this.status = status;
|
|
764
764
|
this.statusCode = statusCode;
|
|
765
765
|
}
|
|
766
|
+
/**
|
|
767
|
+
* Set the HTTP status the request was answered with; one of 400 or more marks it failed.
|
|
768
|
+
*/
|
|
769
|
+
setStatusCode(statusCode) {
|
|
770
|
+
this.statusCode = statusCode;
|
|
771
|
+
if (statusCode >= 400) this.status = "error";
|
|
772
|
+
}
|
|
766
773
|
/**
|
|
767
774
|
* Set error details.
|
|
768
775
|
*/
|
|
@@ -831,8 +838,12 @@ var RequestLogCollector = class {
|
|
|
831
838
|
}
|
|
832
839
|
};
|
|
833
840
|
|
|
841
|
+
// libs/observability/src/request-log/request-log.hooks.ts
|
|
842
|
+
var import_sdk3 = require("@frontmcp/sdk");
|
|
843
|
+
|
|
834
844
|
// libs/observability/src/plugin/observability.hooks.ts
|
|
835
|
-
var
|
|
845
|
+
var import_api13 = require("@opentelemetry/api");
|
|
846
|
+
var import_sdk2 = require("@frontmcp/sdk");
|
|
836
847
|
var import_utils = require("@frontmcp/utils");
|
|
837
848
|
|
|
838
849
|
// libs/observability/src/otel/otel.types.ts
|
|
@@ -1027,8 +1038,35 @@ function setFetchResponseStatus(span, statusCode) {
|
|
|
1027
1038
|
span.setAttribute(HttpAttributes.STATUS_CODE, statusCode);
|
|
1028
1039
|
}
|
|
1029
1040
|
|
|
1030
|
-
// libs/observability/src/otel/spans/
|
|
1041
|
+
// libs/observability/src/otel/spans/hook.span.ts
|
|
1031
1042
|
var import_api4 = require("@opentelemetry/api");
|
|
1043
|
+
function recordHookEvent(parentSpan, stage, owner) {
|
|
1044
|
+
const attributes = {};
|
|
1045
|
+
if (owner) {
|
|
1046
|
+
attributes[FrontMcpAttributes.HOOK_OWNER] = owner;
|
|
1047
|
+
}
|
|
1048
|
+
parentSpan.addEvent(`hook.${stage}`, attributes);
|
|
1049
|
+
}
|
|
1050
|
+
function startHookSpan(tracer, options) {
|
|
1051
|
+
const attributes = {
|
|
1052
|
+
[FrontMcpAttributes.HOOK_STAGE]: options.stage
|
|
1053
|
+
};
|
|
1054
|
+
if (options.owner) {
|
|
1055
|
+
attributes[FrontMcpAttributes.HOOK_OWNER] = options.owner;
|
|
1056
|
+
}
|
|
1057
|
+
if (options.flowName) {
|
|
1058
|
+
attributes[FrontMcpAttributes.FLOW_NAME] = options.flowName;
|
|
1059
|
+
}
|
|
1060
|
+
return startSpan(tracer, {
|
|
1061
|
+
name: `hook ${options.stage}`,
|
|
1062
|
+
kind: import_api4.SpanKind.INTERNAL,
|
|
1063
|
+
attributes,
|
|
1064
|
+
parentContext: options.parentContext
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
// libs/observability/src/otel/spans/http-server.span.ts
|
|
1069
|
+
var import_api5 = require("@opentelemetry/api");
|
|
1032
1070
|
function startHttpServerSpan(tracer, options) {
|
|
1033
1071
|
const attributes = {
|
|
1034
1072
|
[HttpAttributes.METHOD]: options.method.toUpperCase(),
|
|
@@ -1051,7 +1089,7 @@ function startHttpServerSpan(tracer, options) {
|
|
|
1051
1089
|
}
|
|
1052
1090
|
return startSpan(tracer, {
|
|
1053
1091
|
name: `${options.method.toUpperCase()} ${options.path}`,
|
|
1054
|
-
kind:
|
|
1092
|
+
kind: import_api5.SpanKind.SERVER,
|
|
1055
1093
|
attributes,
|
|
1056
1094
|
parentContext: options.parentContext
|
|
1057
1095
|
});
|
|
@@ -1061,11 +1099,11 @@ function setHttpResponseStatus(span, statusCode) {
|
|
|
1061
1099
|
}
|
|
1062
1100
|
|
|
1063
1101
|
// libs/observability/src/otel/spans/prompt.span.ts
|
|
1064
|
-
var
|
|
1102
|
+
var import_api6 = require("@opentelemetry/api");
|
|
1065
1103
|
function startPromptSpan(tracer, options) {
|
|
1066
1104
|
return startSpan(tracer, {
|
|
1067
1105
|
name: `prompt ${options.name}`,
|
|
1068
|
-
kind:
|
|
1106
|
+
kind: import_api6.SpanKind.INTERNAL,
|
|
1069
1107
|
attributes: {
|
|
1070
1108
|
[FrontMcpAttributes.PROMPT_NAME]: options.name,
|
|
1071
1109
|
[McpAttributes.COMPONENT_TYPE]: "prompt",
|
|
@@ -1076,7 +1114,7 @@ function startPromptSpan(tracer, options) {
|
|
|
1076
1114
|
}
|
|
1077
1115
|
|
|
1078
1116
|
// libs/observability/src/otel/spans/resource.span.ts
|
|
1079
|
-
var
|
|
1117
|
+
var import_api7 = require("@opentelemetry/api");
|
|
1080
1118
|
function startResourceSpan(tracer, options) {
|
|
1081
1119
|
const attributes = {
|
|
1082
1120
|
[FrontMcpAttributes.RESOURCE_URI]: options.uri,
|
|
@@ -1089,14 +1127,14 @@ function startResourceSpan(tracer, options) {
|
|
|
1089
1127
|
}
|
|
1090
1128
|
return startSpan(tracer, {
|
|
1091
1129
|
name: `resource ${options.uri}`,
|
|
1092
|
-
kind:
|
|
1130
|
+
kind: import_api7.SpanKind.INTERNAL,
|
|
1093
1131
|
attributes,
|
|
1094
1132
|
parentContext: options.parentContext
|
|
1095
1133
|
});
|
|
1096
1134
|
}
|
|
1097
1135
|
|
|
1098
1136
|
// libs/observability/src/otel/spans/rpc.span.ts
|
|
1099
|
-
var
|
|
1137
|
+
var import_api8 = require("@opentelemetry/api");
|
|
1100
1138
|
function startRpcSpan(tracer, options) {
|
|
1101
1139
|
const attributes = {
|
|
1102
1140
|
[RpcAttributes.SYSTEM]: "mcp",
|
|
@@ -1120,14 +1158,14 @@ function startRpcSpan(tracer, options) {
|
|
|
1120
1158
|
}
|
|
1121
1159
|
return startSpan(tracer, {
|
|
1122
1160
|
name: options.method,
|
|
1123
|
-
kind:
|
|
1161
|
+
kind: import_api8.SpanKind.SERVER,
|
|
1124
1162
|
attributes,
|
|
1125
1163
|
parentContext: options.parentContext
|
|
1126
1164
|
});
|
|
1127
1165
|
}
|
|
1128
1166
|
|
|
1129
1167
|
// libs/observability/src/otel/spans/startup.span.ts
|
|
1130
|
-
var
|
|
1168
|
+
var import_api9 = require("@opentelemetry/api");
|
|
1131
1169
|
function emitStartupReport(tracer, data) {
|
|
1132
1170
|
const attributes = {
|
|
1133
1171
|
[FrontMcpAttributes.STARTUP_TOOLS_COUNT]: data.toolsCount,
|
|
@@ -1141,14 +1179,14 @@ function emitStartupReport(tracer, data) {
|
|
|
1141
1179
|
}
|
|
1142
1180
|
const { span } = startSpan(tracer, {
|
|
1143
1181
|
name: "frontmcp.startup",
|
|
1144
|
-
kind:
|
|
1182
|
+
kind: import_api9.SpanKind.INTERNAL,
|
|
1145
1183
|
attributes
|
|
1146
1184
|
});
|
|
1147
1185
|
endSpanOk(span);
|
|
1148
1186
|
}
|
|
1149
1187
|
|
|
1150
1188
|
// libs/observability/src/otel/spans/tool.span.ts
|
|
1151
|
-
var
|
|
1189
|
+
var import_api10 = require("@opentelemetry/api");
|
|
1152
1190
|
function startToolSpan(tracer, options) {
|
|
1153
1191
|
const attributes = {
|
|
1154
1192
|
[FrontMcpAttributes.TOOL_NAME]: options.name,
|
|
@@ -1166,14 +1204,14 @@ function startToolSpan(tracer, options) {
|
|
|
1166
1204
|
}
|
|
1167
1205
|
return startSpan(tracer, {
|
|
1168
1206
|
name: `tool ${options.name}`,
|
|
1169
|
-
kind:
|
|
1207
|
+
kind: import_api10.SpanKind.INTERNAL,
|
|
1170
1208
|
attributes,
|
|
1171
1209
|
parentContext: options.parentContext
|
|
1172
1210
|
});
|
|
1173
1211
|
}
|
|
1174
1212
|
|
|
1175
1213
|
// libs/observability/src/otel/spans/transport.span.ts
|
|
1176
|
-
var
|
|
1214
|
+
var import_api11 = require("@opentelemetry/api");
|
|
1177
1215
|
function startTransportSpan(tracer, options) {
|
|
1178
1216
|
const attributes = {
|
|
1179
1217
|
[FrontMcpAttributes.TRANSPORT_TYPE]: options.type
|
|
@@ -1186,7 +1224,7 @@ function startTransportSpan(tracer, options) {
|
|
|
1186
1224
|
}
|
|
1187
1225
|
return startSpan(tracer, {
|
|
1188
1226
|
name: `transport ${options.type}`,
|
|
1189
|
-
kind:
|
|
1227
|
+
kind: import_api11.SpanKind.INTERNAL,
|
|
1190
1228
|
attributes,
|
|
1191
1229
|
parentContext: options.parentContext
|
|
1192
1230
|
});
|
|
@@ -1196,12 +1234,12 @@ function setTransportRequestType(span, requestType) {
|
|
|
1196
1234
|
}
|
|
1197
1235
|
|
|
1198
1236
|
// libs/observability/src/otel/trace-context-bridge.ts
|
|
1199
|
-
var
|
|
1237
|
+
var import_api12 = require("@opentelemetry/api");
|
|
1200
1238
|
function frontmcpToOTelSpanContext(tc) {
|
|
1201
1239
|
return {
|
|
1202
1240
|
traceId: tc.traceId,
|
|
1203
1241
|
spanId: tc.parentId,
|
|
1204
|
-
traceFlags: tc.traceFlags &
|
|
1242
|
+
traceFlags: tc.traceFlags & import_api12.TraceFlags.SAMPLED ? import_api12.TraceFlags.SAMPLED : import_api12.TraceFlags.NONE,
|
|
1205
1243
|
isRemote: true
|
|
1206
1244
|
};
|
|
1207
1245
|
}
|
|
@@ -1216,8 +1254,8 @@ function otelToFrontmcpContext(sc) {
|
|
|
1216
1254
|
}
|
|
1217
1255
|
function createOTelContextFromTrace(tc) {
|
|
1218
1256
|
const spanContext = frontmcpToOTelSpanContext(tc);
|
|
1219
|
-
const span =
|
|
1220
|
-
return
|
|
1257
|
+
const span = import_api12.trace.wrapSpanContext(spanContext);
|
|
1258
|
+
return import_api12.trace.setSpan(import_api12.context.active(), span);
|
|
1221
1259
|
}
|
|
1222
1260
|
|
|
1223
1261
|
// libs/observability/src/plugin/observability.hooks.ts
|
|
@@ -1227,11 +1265,13 @@ var EXEC_SPAN_KEY = /* @__PURE__ */ Symbol.for("frontmcp:otel:exec-span");
|
|
|
1227
1265
|
var ACTIVE_SPAN_KEY = /* @__PURE__ */ Symbol.for("frontmcp:otel:active-span");
|
|
1228
1266
|
var ACTIVE_OTEL_CTX_KEY = /* @__PURE__ */ Symbol.for("frontmcp:otel:active-otel-ctx");
|
|
1229
1267
|
var STAGE_TS_KEY = /* @__PURE__ */ Symbol.for("frontmcp:otel:stage-ts");
|
|
1268
|
+
var STAGE_EVENTS_KEY = /* @__PURE__ */ Symbol.for("frontmcp:otel:stage-events");
|
|
1269
|
+
var HTTP_SPAN_CTX_KEY = /* @__PURE__ */ Symbol.for("frontmcp:otel:http-span-ctx");
|
|
1230
1270
|
function sessionTracingId(sessionId) {
|
|
1231
1271
|
return (0, import_utils.sha256Hex)(sessionId).slice(0, 16);
|
|
1232
1272
|
}
|
|
1233
1273
|
function getTracer() {
|
|
1234
|
-
return
|
|
1274
|
+
return import_api13.trace.getTracer("@frontmcp/observability");
|
|
1235
1275
|
}
|
|
1236
1276
|
function extractContext(flowCtx) {
|
|
1237
1277
|
try {
|
|
@@ -1261,7 +1301,44 @@ function clearActiveSpan(flowCtx) {
|
|
|
1261
1301
|
} catch {
|
|
1262
1302
|
}
|
|
1263
1303
|
}
|
|
1304
|
+
function beginFlowSpan(flowCtx, options, span, spanCtx) {
|
|
1305
|
+
flowCtx.state[SPAN_KEY] = span;
|
|
1306
|
+
flowCtx.state[SPAN_CTX_KEY] = spanCtx;
|
|
1307
|
+
flowCtx.state[STAGE_TS_KEY] = Date.now();
|
|
1308
|
+
flowCtx.state[STAGE_EVENTS_KEY] = options.flowStageEvents !== false;
|
|
1309
|
+
}
|
|
1310
|
+
function parentContextOf(ctx) {
|
|
1311
|
+
return ctx.get?.(HTTP_SPAN_CTX_KEY) ?? createOTelContextFromTrace(ctx.traceContext);
|
|
1312
|
+
}
|
|
1313
|
+
function flowFailureOf(flowError) {
|
|
1314
|
+
const failed = flowError?.originalError;
|
|
1315
|
+
const error = flowError instanceof import_sdk2.FlowControl ? failed instanceof Error ? failed : new import_sdk2.InternalMcpError(`Flow ended with: ${flowError.type}`) : flowError instanceof Error ? flowError : new Error(String(flowError));
|
|
1316
|
+
const reported = (0, import_sdk2.toMcpError)(error);
|
|
1317
|
+
return {
|
|
1318
|
+
error,
|
|
1319
|
+
type: reported.name,
|
|
1320
|
+
message: reported.getPublicMessage(),
|
|
1321
|
+
code: reported.code,
|
|
1322
|
+
errorId: reported.errorId
|
|
1323
|
+
};
|
|
1324
|
+
}
|
|
1325
|
+
function endFailedSpan(span, flowError) {
|
|
1326
|
+
const failure = flowFailureOf(flowError);
|
|
1327
|
+
span.setStatus({ code: import_api13.SpanStatusCode.ERROR, message: failure.message });
|
|
1328
|
+
span.recordException({
|
|
1329
|
+
name: failure.type,
|
|
1330
|
+
message: failure.message,
|
|
1331
|
+
code: failure.code,
|
|
1332
|
+
stack: failure.error.stack
|
|
1333
|
+
});
|
|
1334
|
+
span.end();
|
|
1335
|
+
}
|
|
1336
|
+
function traceparentOf(span) {
|
|
1337
|
+
const { traceId, spanId, traceFlags } = span.spanContext();
|
|
1338
|
+
return `00-${traceId}-${spanId}-${traceFlags.toString(16).padStart(2, "0")}`;
|
|
1339
|
+
}
|
|
1264
1340
|
function recordStageEvent(span, stageName, state) {
|
|
1341
|
+
if (state[STAGE_EVENTS_KEY] === false) return;
|
|
1265
1342
|
const now = Date.now();
|
|
1266
1343
|
const prev = state[STAGE_TS_KEY];
|
|
1267
1344
|
const attributes = {};
|
|
@@ -1287,9 +1364,8 @@ function onHttpWillTrace(options, flowCtx) {
|
|
|
1287
1364
|
});
|
|
1288
1365
|
span.setAttribute(McpAttributes.SESSION_ID, sessionHash);
|
|
1289
1366
|
span.setAttribute(FrontMcpAttributes.SESSION_ID_HASH, sessionHash);
|
|
1290
|
-
|
|
1291
|
-
flowCtx
|
|
1292
|
-
flowCtx.state[STAGE_TS_KEY] = Date.now();
|
|
1367
|
+
ctx.set?.(HTTP_SPAN_CTX_KEY, spanCtx);
|
|
1368
|
+
beginFlowSpan(flowCtx, options, span, spanCtx);
|
|
1293
1369
|
recordStageEvent(span, "traceRequest", flowCtx.state);
|
|
1294
1370
|
}
|
|
1295
1371
|
function onHttpWillAcquireQuota(flowCtx) {
|
|
@@ -1333,7 +1409,7 @@ function onToolWillParse(options, flowCtx) {
|
|
|
1333
1409
|
const ctx = extractContext(flowCtx);
|
|
1334
1410
|
if (!ctx) return;
|
|
1335
1411
|
const tracer = getTracer();
|
|
1336
|
-
const parentOTelCtx =
|
|
1412
|
+
const parentOTelCtx = parentContextOf(ctx);
|
|
1337
1413
|
const sessionHash = sessionTracingId(ctx.sessionId);
|
|
1338
1414
|
const { span, context: spanCtx } = startRpcSpan(tracer, {
|
|
1339
1415
|
method: "tools/call",
|
|
@@ -1341,9 +1417,7 @@ function onToolWillParse(options, flowCtx) {
|
|
|
1341
1417
|
sessionIdHash: sessionHash,
|
|
1342
1418
|
parentContext: parentOTelCtx
|
|
1343
1419
|
});
|
|
1344
|
-
flowCtx
|
|
1345
|
-
flowCtx.state[SPAN_CTX_KEY] = spanCtx;
|
|
1346
|
-
flowCtx.state[STAGE_TS_KEY] = Date.now();
|
|
1420
|
+
beginFlowSpan(flowCtx, options, span, spanCtx);
|
|
1347
1421
|
recordStageEvent(span, "parseInput", flowCtx.state);
|
|
1348
1422
|
}
|
|
1349
1423
|
function onToolWillFindTool(flowCtx) {
|
|
@@ -1413,8 +1487,8 @@ function onToolDidFinalize(flowCtx) {
|
|
|
1413
1487
|
const toolSpan = flowCtx.state?.[EXEC_SPAN_KEY];
|
|
1414
1488
|
const error = flowCtx.state?.flowError;
|
|
1415
1489
|
if (error) {
|
|
1416
|
-
if (toolSpan)
|
|
1417
|
-
if (rpcSpan)
|
|
1490
|
+
if (toolSpan) endFailedSpan(toolSpan, error);
|
|
1491
|
+
if (rpcSpan) endFailedSpan(rpcSpan, error);
|
|
1418
1492
|
} else if (rpcSpan) {
|
|
1419
1493
|
recordStageEvent(rpcSpan, "finalize", flowCtx.state);
|
|
1420
1494
|
endSpanOk(rpcSpan);
|
|
@@ -1425,7 +1499,7 @@ function onResourceWillParse(options, flowCtx) {
|
|
|
1425
1499
|
const ctx = extractContext(flowCtx);
|
|
1426
1500
|
if (!ctx) return;
|
|
1427
1501
|
const tracer = getTracer();
|
|
1428
|
-
const parentOTelCtx =
|
|
1502
|
+
const parentOTelCtx = parentContextOf(ctx);
|
|
1429
1503
|
const sessionHash = sessionTracingId(ctx.sessionId);
|
|
1430
1504
|
const { span, context: spanCtx } = startRpcSpan(tracer, {
|
|
1431
1505
|
method: "resources/read",
|
|
@@ -1433,9 +1507,7 @@ function onResourceWillParse(options, flowCtx) {
|
|
|
1433
1507
|
sessionIdHash: sessionHash,
|
|
1434
1508
|
parentContext: parentOTelCtx
|
|
1435
1509
|
});
|
|
1436
|
-
flowCtx
|
|
1437
|
-
flowCtx.state[SPAN_CTX_KEY] = spanCtx;
|
|
1438
|
-
flowCtx.state[STAGE_TS_KEY] = Date.now();
|
|
1510
|
+
beginFlowSpan(flowCtx, options, span, spanCtx);
|
|
1439
1511
|
recordStageEvent(span, "parseInput", flowCtx.state);
|
|
1440
1512
|
}
|
|
1441
1513
|
function onResourceWillFind(flowCtx) {
|
|
@@ -1466,8 +1538,8 @@ function onResourceDidFinalize(flowCtx) {
|
|
|
1466
1538
|
const resSpan = flowCtx.state?.[EXEC_SPAN_KEY];
|
|
1467
1539
|
const error = flowCtx.state?.flowError;
|
|
1468
1540
|
if (error) {
|
|
1469
|
-
if (resSpan)
|
|
1470
|
-
if (rpcSpan)
|
|
1541
|
+
if (resSpan) endFailedSpan(resSpan, error);
|
|
1542
|
+
if (rpcSpan) endFailedSpan(rpcSpan, error);
|
|
1471
1543
|
} else if (rpcSpan) {
|
|
1472
1544
|
recordStageEvent(rpcSpan, "finalize", flowCtx.state);
|
|
1473
1545
|
endSpanOk(rpcSpan);
|
|
@@ -1478,7 +1550,7 @@ function onPromptWillParse(options, flowCtx) {
|
|
|
1478
1550
|
const ctx = extractContext(flowCtx);
|
|
1479
1551
|
if (!ctx) return;
|
|
1480
1552
|
const tracer = getTracer();
|
|
1481
|
-
const parentOTelCtx =
|
|
1553
|
+
const parentOTelCtx = parentContextOf(ctx);
|
|
1482
1554
|
const sessionHash = sessionTracingId(ctx.sessionId);
|
|
1483
1555
|
const { span, context: spanCtx } = startRpcSpan(tracer, {
|
|
1484
1556
|
method: "prompts/get",
|
|
@@ -1486,9 +1558,7 @@ function onPromptWillParse(options, flowCtx) {
|
|
|
1486
1558
|
sessionIdHash: sessionHash,
|
|
1487
1559
|
parentContext: parentOTelCtx
|
|
1488
1560
|
});
|
|
1489
|
-
flowCtx
|
|
1490
|
-
flowCtx.state[SPAN_CTX_KEY] = spanCtx;
|
|
1491
|
-
flowCtx.state[STAGE_TS_KEY] = Date.now();
|
|
1561
|
+
beginFlowSpan(flowCtx, options, span, spanCtx);
|
|
1492
1562
|
recordStageEvent(span, "parseInput", flowCtx.state);
|
|
1493
1563
|
}
|
|
1494
1564
|
function onPromptWillFind(flowCtx) {
|
|
@@ -1522,8 +1592,8 @@ function onPromptDidFinalize(flowCtx) {
|
|
|
1522
1592
|
const promptSpan = flowCtx.state?.[EXEC_SPAN_KEY];
|
|
1523
1593
|
const error = flowCtx.state?.flowError;
|
|
1524
1594
|
if (error) {
|
|
1525
|
-
if (promptSpan)
|
|
1526
|
-
if (rpcSpan)
|
|
1595
|
+
if (promptSpan) endFailedSpan(promptSpan, error);
|
|
1596
|
+
if (rpcSpan) endFailedSpan(rpcSpan, error);
|
|
1527
1597
|
} else if (rpcSpan) {
|
|
1528
1598
|
recordStageEvent(rpcSpan, "finalize", flowCtx.state);
|
|
1529
1599
|
endSpanOk(rpcSpan);
|
|
@@ -1534,7 +1604,7 @@ function onAgentWillParse(options, flowCtx) {
|
|
|
1534
1604
|
const ctx = extractContext(flowCtx);
|
|
1535
1605
|
if (!ctx) return;
|
|
1536
1606
|
const tracer = getTracer();
|
|
1537
|
-
const parentOTelCtx =
|
|
1607
|
+
const parentOTelCtx = parentContextOf(ctx);
|
|
1538
1608
|
const sessionHash = sessionTracingId(ctx.sessionId);
|
|
1539
1609
|
const { span, context: spanCtx } = startRpcSpan(tracer, {
|
|
1540
1610
|
method: "agents/call",
|
|
@@ -1542,9 +1612,7 @@ function onAgentWillParse(options, flowCtx) {
|
|
|
1542
1612
|
sessionIdHash: sessionHash,
|
|
1543
1613
|
parentContext: parentOTelCtx
|
|
1544
1614
|
});
|
|
1545
|
-
flowCtx
|
|
1546
|
-
flowCtx.state[SPAN_CTX_KEY] = spanCtx;
|
|
1547
|
-
flowCtx.state[STAGE_TS_KEY] = Date.now();
|
|
1615
|
+
beginFlowSpan(flowCtx, options, span, spanCtx);
|
|
1548
1616
|
recordStageEvent(span, "parseInput", flowCtx.state);
|
|
1549
1617
|
}
|
|
1550
1618
|
function onAgentWillFind(flowCtx) {
|
|
@@ -1558,7 +1626,7 @@ function onAgentWillExecute(options, flowCtx) {
|
|
|
1558
1626
|
const agentName = flowCtx.state?.input?.name ?? "unknown";
|
|
1559
1627
|
const { span: agentSpan } = startSpan(tracer, {
|
|
1560
1628
|
name: `agent ${agentName}`,
|
|
1561
|
-
kind:
|
|
1629
|
+
kind: import_api13.SpanKind.INTERNAL,
|
|
1562
1630
|
attributes: {
|
|
1563
1631
|
[FrontMcpAttributes.FLOW_NAME]: "agents:call-agent",
|
|
1564
1632
|
[McpAttributes.COMPONENT_TYPE]: "agent",
|
|
@@ -1566,7 +1634,7 @@ function onAgentWillExecute(options, flowCtx) {
|
|
|
1566
1634
|
},
|
|
1567
1635
|
parentContext: rpcCtx
|
|
1568
1636
|
});
|
|
1569
|
-
const agentOTelCtx =
|
|
1637
|
+
const agentOTelCtx = import_api13.trace.setSpan(rpcCtx ?? import_api13.context.active(), agentSpan);
|
|
1570
1638
|
flowCtx.state[EXEC_SPAN_KEY] = agentSpan;
|
|
1571
1639
|
flowCtx.state[STAGE_TS_KEY] = Date.now();
|
|
1572
1640
|
recordStageEvent(agentSpan, "execute.start", flowCtx.state);
|
|
@@ -1585,8 +1653,8 @@ function onAgentDidFinalize(flowCtx) {
|
|
|
1585
1653
|
const agentSpan = flowCtx.state?.[EXEC_SPAN_KEY];
|
|
1586
1654
|
const error = flowCtx.state?.flowError;
|
|
1587
1655
|
if (error) {
|
|
1588
|
-
if (agentSpan)
|
|
1589
|
-
if (rpcSpan)
|
|
1656
|
+
if (agentSpan) endFailedSpan(agentSpan, error);
|
|
1657
|
+
if (rpcSpan) endFailedSpan(rpcSpan, error);
|
|
1590
1658
|
} else if (rpcSpan) {
|
|
1591
1659
|
recordStageEvent(rpcSpan, "finalize", flowCtx.state);
|
|
1592
1660
|
endSpanOk(rpcSpan);
|
|
@@ -1597,11 +1665,11 @@ function onGenericFlowWillStart(flowName, options, flowCtx) {
|
|
|
1597
1665
|
const ctx = extractContext(flowCtx);
|
|
1598
1666
|
if (!ctx) return;
|
|
1599
1667
|
const tracer = getTracer();
|
|
1600
|
-
const parentOTelCtx =
|
|
1668
|
+
const parentOTelCtx = parentContextOf(ctx);
|
|
1601
1669
|
const sessionHash = sessionTracingId(ctx.sessionId);
|
|
1602
1670
|
const { span, context: spanCtx } = startSpan(tracer, {
|
|
1603
1671
|
name: flowName,
|
|
1604
|
-
kind:
|
|
1672
|
+
kind: import_api13.SpanKind.INTERNAL,
|
|
1605
1673
|
attributes: {
|
|
1606
1674
|
[FrontMcpAttributes.FLOW_NAME]: flowName,
|
|
1607
1675
|
[McpAttributes.SESSION_ID]: sessionHash,
|
|
@@ -1611,9 +1679,7 @@ function onGenericFlowWillStart(flowName, options, flowCtx) {
|
|
|
1611
1679
|
},
|
|
1612
1680
|
parentContext: parentOTelCtx
|
|
1613
1681
|
});
|
|
1614
|
-
flowCtx
|
|
1615
|
-
flowCtx.state[SPAN_CTX_KEY] = spanCtx;
|
|
1616
|
-
flowCtx.state[STAGE_TS_KEY] = Date.now();
|
|
1682
|
+
beginFlowSpan(flowCtx, options, span, spanCtx);
|
|
1617
1683
|
}
|
|
1618
1684
|
function onGenericFlowStage(stageName, flowCtx) {
|
|
1619
1685
|
const span = flowCtx.state?.[SPAN_KEY];
|
|
@@ -1624,7 +1690,7 @@ function onGenericFlowDidFinalize(flowCtx) {
|
|
|
1624
1690
|
if (!span) return;
|
|
1625
1691
|
const error = flowCtx.state?.flowError;
|
|
1626
1692
|
if (error) {
|
|
1627
|
-
|
|
1693
|
+
endFailedSpan(span, error);
|
|
1628
1694
|
} else {
|
|
1629
1695
|
endSpanOk(span);
|
|
1630
1696
|
}
|
|
@@ -1634,16 +1700,14 @@ function onTransportWillStart(transportType, options, flowCtx) {
|
|
|
1634
1700
|
const ctx = extractContext(flowCtx);
|
|
1635
1701
|
if (!ctx) return;
|
|
1636
1702
|
const tracer = getTracer();
|
|
1637
|
-
const parentOTelCtx =
|
|
1703
|
+
const parentOTelCtx = parentContextOf(ctx);
|
|
1638
1704
|
const sessionHash = sessionTracingId(ctx.sessionId);
|
|
1639
1705
|
const { span, context: spanCtx } = startTransportSpan(tracer, {
|
|
1640
1706
|
type: transportType,
|
|
1641
1707
|
sessionIdHash: sessionHash,
|
|
1642
1708
|
parentContext: parentOTelCtx
|
|
1643
1709
|
});
|
|
1644
|
-
flowCtx
|
|
1645
|
-
flowCtx.state[SPAN_CTX_KEY] = spanCtx;
|
|
1646
|
-
flowCtx.state[STAGE_TS_KEY] = Date.now();
|
|
1710
|
+
beginFlowSpan(flowCtx, options, span, spanCtx);
|
|
1647
1711
|
recordStageEvent(span, "parseInput", flowCtx.state);
|
|
1648
1712
|
}
|
|
1649
1713
|
function onTransportDidRoute(flowCtx) {
|
|
@@ -1663,7 +1727,7 @@ function onTransportDidFinalize(flowCtx) {
|
|
|
1663
1727
|
recordStageEvent(span, "cleanup", flowCtx.state);
|
|
1664
1728
|
const error = flowCtx.state?.flowError;
|
|
1665
1729
|
if (error) {
|
|
1666
|
-
|
|
1730
|
+
endFailedSpan(span, error);
|
|
1667
1731
|
} else {
|
|
1668
1732
|
endSpanOk(span);
|
|
1669
1733
|
}
|
|
@@ -1673,14 +1737,12 @@ function onAuthWillStart(flowName, options, flowCtx) {
|
|
|
1673
1737
|
const ctx = extractContext(flowCtx);
|
|
1674
1738
|
if (!ctx) return;
|
|
1675
1739
|
const tracer = getTracer();
|
|
1676
|
-
const parentOTelCtx =
|
|
1740
|
+
const parentOTelCtx = parentContextOf(ctx);
|
|
1677
1741
|
const { span, context: spanCtx } = startAuthSpan(tracer, {
|
|
1678
1742
|
flowName,
|
|
1679
1743
|
parentContext: parentOTelCtx
|
|
1680
1744
|
});
|
|
1681
|
-
flowCtx
|
|
1682
|
-
flowCtx.state[SPAN_CTX_KEY] = spanCtx;
|
|
1683
|
-
flowCtx.state[STAGE_TS_KEY] = Date.now();
|
|
1745
|
+
beginFlowSpan(flowCtx, options, span, spanCtx);
|
|
1684
1746
|
recordStageEvent(span, "parseInput", flowCtx.state);
|
|
1685
1747
|
}
|
|
1686
1748
|
function onAuthDidDetermineMode(flowCtx) {
|
|
@@ -1700,30 +1762,35 @@ function onAuthDidFinalize(flowCtx) {
|
|
|
1700
1762
|
const error = flowCtx.state?.flowError;
|
|
1701
1763
|
if (error) {
|
|
1702
1764
|
setAuthResult(span, "unauthorized");
|
|
1703
|
-
|
|
1765
|
+
endFailedSpan(span, error);
|
|
1704
1766
|
} else {
|
|
1705
1767
|
setAuthResult(span, "authorized");
|
|
1706
1768
|
endSpanOk(span);
|
|
1707
1769
|
}
|
|
1708
1770
|
}
|
|
1709
1771
|
function wrapContextFetch(options, flowCtx) {
|
|
1710
|
-
if (options.fetchSpans === false) return;
|
|
1711
1772
|
const toolCtx = flowCtx.state?.toolContext ?? flowCtx.state?.toolCallContext;
|
|
1712
1773
|
if (!toolCtx || typeof toolCtx.fetch !== "function") return;
|
|
1713
1774
|
const originalFetch = toolCtx.fetch.bind(toolCtx);
|
|
1714
1775
|
const parentOTelCtx = flowCtx.state?.[SPAN_CTX_KEY];
|
|
1715
1776
|
toolCtx.fetch = async (input, init) => {
|
|
1716
|
-
const
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1777
|
+
const fetchSpan = options.fetchSpans === false ? void 0 : startFetchSpan(getTracer(), {
|
|
1778
|
+
method: init?.method ?? (input instanceof Request ? input.method : "GET"),
|
|
1779
|
+
url: typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url,
|
|
1780
|
+
parentContext: parentOTelCtx
|
|
1781
|
+
}).span;
|
|
1782
|
+
const callingSpan = fetchSpan ?? flowCtx.state?.[EXEC_SPAN_KEY] ?? flowCtx.state?.[SPAN_KEY];
|
|
1783
|
+
const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : void 0));
|
|
1784
|
+
if (callingSpan && !headers.has("traceparent")) headers.set("traceparent", traceparentOf(callingSpan));
|
|
1720
1785
|
try {
|
|
1721
|
-
const response = await originalFetch(input, init);
|
|
1722
|
-
|
|
1723
|
-
|
|
1786
|
+
const response = await originalFetch(input, { ...init, headers });
|
|
1787
|
+
if (fetchSpan) {
|
|
1788
|
+
setFetchResponseStatus(fetchSpan, response.status);
|
|
1789
|
+
endSpanOk(fetchSpan);
|
|
1790
|
+
}
|
|
1724
1791
|
return response;
|
|
1725
1792
|
} catch (err) {
|
|
1726
|
-
endSpanError(
|
|
1793
|
+
if (fetchSpan) endSpanError(fetchSpan, err instanceof Error ? err : String(err));
|
|
1727
1794
|
throw err;
|
|
1728
1795
|
}
|
|
1729
1796
|
};
|
|
@@ -1741,6 +1808,26 @@ function onAgentDidExecuteEnrich(flowCtx) {
|
|
|
1741
1808
|
}
|
|
1742
1809
|
}
|
|
1743
1810
|
}
|
|
1811
|
+
var HOOK_OBSERVER_KEY = /* @__PURE__ */ Symbol.for("frontmcp:hook-observer");
|
|
1812
|
+
function installHookObserver(flowCtx, observer) {
|
|
1813
|
+
const ctx = extractContext(flowCtx);
|
|
1814
|
+
if (ctx && !ctx.get?.(HOOK_OBSERVER_KEY)) ctx.set?.(HOOK_OBSERVER_KEY, observer);
|
|
1815
|
+
}
|
|
1816
|
+
async function runInHookSpan(flowCtx, hook, run) {
|
|
1817
|
+
const ctx = extractContext(flowCtx);
|
|
1818
|
+
const { span } = startHookSpan(getTracer(), {
|
|
1819
|
+
...hook,
|
|
1820
|
+
parentContext: flowCtx.state?.[SPAN_CTX_KEY] ?? (ctx && parentContextOf(ctx))
|
|
1821
|
+
});
|
|
1822
|
+
try {
|
|
1823
|
+
await run();
|
|
1824
|
+
endSpanOk(span);
|
|
1825
|
+
} catch (error) {
|
|
1826
|
+
if (error instanceof import_sdk2.FlowControl && error.type !== "fail" && error.type !== "abort") endSpanOk(span);
|
|
1827
|
+
else endFailedSpan(span, error);
|
|
1828
|
+
throw error;
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1744
1831
|
function reportStartup(data) {
|
|
1745
1832
|
const tracer = getTracer();
|
|
1746
1833
|
emitStartupReport(tracer, data);
|
|
@@ -1780,28 +1867,35 @@ function startRequestLog(flowCtx, options) {
|
|
|
1780
1867
|
if (typeof rpcMethod === "string") collector.setRpcMethod(rpcMethod);
|
|
1781
1868
|
}
|
|
1782
1869
|
function recordRequestLogFailure(flowCtx) {
|
|
1783
|
-
const
|
|
1784
|
-
if (!
|
|
1785
|
-
const
|
|
1786
|
-
currentRequestLog(flowCtx)?.setError({
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1870
|
+
const flowError = flowCtx.state?.["flowError"];
|
|
1871
|
+
if (!flowError) return;
|
|
1872
|
+
const { type, message, code, errorId } = flowFailureOf(flowError);
|
|
1873
|
+
currentRequestLog(flowCtx)?.setError({ type, message, code, error_id: errorId });
|
|
1874
|
+
}
|
|
1875
|
+
function recordRequestLogAuth(flowCtx) {
|
|
1876
|
+
const verifyResult = flowCtx.state?.["verifyResult"];
|
|
1877
|
+
const authorization = flowCtx.rawInput?.request?.headers?.["authorization"];
|
|
1878
|
+
const scheme = typeof authorization === "string" ? authorization.trim().split(/\s+/)[0].toLowerCase() : "";
|
|
1879
|
+
const sub = verifyResult?.authorization?.user?.sub;
|
|
1880
|
+
const anonymous = typeof sub !== "string" || (0, import_sdk3.isAnonymousSubject)(sub);
|
|
1881
|
+
currentRequestLog(flowCtx)?.setAuthInfo(
|
|
1882
|
+
anonymous || !scheme ? "anonymous" : scheme,
|
|
1883
|
+
verifyResult?.kind === "authorized" && !anonymous
|
|
1884
|
+
);
|
|
1791
1885
|
}
|
|
1792
1886
|
async function completeRequestLog(flowCtx) {
|
|
1793
1887
|
const collector = currentRequestLog(flowCtx);
|
|
1794
1888
|
if (!collector || collector.isFinalized()) return;
|
|
1795
1889
|
const statusCode = flowCtx.state?.["statusCode"] ?? flowCtx.rawInput?.response?.statusCode;
|
|
1796
|
-
if (typeof statusCode === "number"
|
|
1890
|
+
if (typeof statusCode === "number") collector.setStatusCode(statusCode);
|
|
1797
1891
|
await collector.finalize();
|
|
1798
1892
|
}
|
|
1799
1893
|
|
|
1800
1894
|
// libs/observability/src/telemetry/telemetry.accessor.ts
|
|
1801
|
-
var
|
|
1895
|
+
var import_api15 = require("@opentelemetry/api");
|
|
1802
1896
|
|
|
1803
1897
|
// libs/observability/src/telemetry/telemetry.counters.ts
|
|
1804
|
-
var
|
|
1898
|
+
var import_api14 = require("@opentelemetry/api");
|
|
1805
1899
|
function snapshotKey(name, attributes) {
|
|
1806
1900
|
const keys = Object.keys(attributes).sort();
|
|
1807
1901
|
if (keys.length === 0) return name;
|
|
@@ -1836,7 +1930,7 @@ var counterCache = /* @__PURE__ */ new Map();
|
|
|
1836
1930
|
function createCounter(name, description) {
|
|
1837
1931
|
const existing = counterCache.get(name);
|
|
1838
1932
|
if (existing) return existing;
|
|
1839
|
-
const meter =
|
|
1933
|
+
const meter = import_api14.metrics.getMeter(METER_NAME);
|
|
1840
1934
|
const otelCounter = meter.createCounter(name, description ? { description } : void 0);
|
|
1841
1935
|
const counter = new TelemetryCounterImpl(name, otelCounter);
|
|
1842
1936
|
counterCache.set(name, counter);
|
|
@@ -1915,14 +2009,14 @@ var TelemetrySpan = class {
|
|
|
1915
2009
|
/** Record an error on this span */
|
|
1916
2010
|
recordError(error) {
|
|
1917
2011
|
this.span.recordException(error);
|
|
1918
|
-
this.span.setStatus({ code:
|
|
2012
|
+
this.span.setStatus({ code: import_api15.SpanStatusCode.ERROR, message: error.message });
|
|
1919
2013
|
this.hasError = true;
|
|
1920
2014
|
return this;
|
|
1921
2015
|
}
|
|
1922
2016
|
/** End the span (preserves ERROR status if already set) */
|
|
1923
2017
|
end() {
|
|
1924
2018
|
if (!this.hasError) {
|
|
1925
|
-
this.span.setStatus({ code:
|
|
2019
|
+
this.span.setStatus({ code: import_api15.SpanStatusCode.OK });
|
|
1926
2020
|
}
|
|
1927
2021
|
this.span.end();
|
|
1928
2022
|
}
|
|
@@ -1930,7 +2024,7 @@ var TelemetrySpan = class {
|
|
|
1930
2024
|
endWithError(error) {
|
|
1931
2025
|
const msg = typeof error === "string" ? error : error.message;
|
|
1932
2026
|
if (error instanceof Error) this.span.recordException(error);
|
|
1933
|
-
this.span.setStatus({ code:
|
|
2027
|
+
this.span.setStatus({ code: import_api15.SpanStatusCode.ERROR, message: msg });
|
|
1934
2028
|
this.span.end();
|
|
1935
2029
|
}
|
|
1936
2030
|
/** Get the underlying OTel span (escape hatch) */
|
|
@@ -1941,7 +2035,7 @@ var TelemetrySpan = class {
|
|
|
1941
2035
|
var TelemetryAccessor = class {
|
|
1942
2036
|
constructor(ctx) {
|
|
1943
2037
|
this.ctx = ctx;
|
|
1944
|
-
this.tracer =
|
|
2038
|
+
this.tracer = import_api15.trace.getTracer("@frontmcp/observability");
|
|
1945
2039
|
this.fallbackContext = createOTelContextFromTrace(ctx.traceContext);
|
|
1946
2040
|
this.sessionHash = sessionTracingId(ctx.sessionId);
|
|
1947
2041
|
this.baseAttributes = {
|
|
@@ -1977,7 +2071,7 @@ var TelemetryAccessor = class {
|
|
|
1977
2071
|
const span = this.tracer.startSpan(
|
|
1978
2072
|
name,
|
|
1979
2073
|
{
|
|
1980
|
-
kind:
|
|
2074
|
+
kind: import_api15.SpanKind.INTERNAL,
|
|
1981
2075
|
attributes: { ...this.baseAttributes, ...attributes }
|
|
1982
2076
|
},
|
|
1983
2077
|
this.getActiveContext()
|
|
@@ -2026,11 +2120,11 @@ var TelemetryAccessor = class {
|
|
|
2026
2120
|
} else {
|
|
2027
2121
|
const span = this.tracer.startSpan(
|
|
2028
2122
|
name,
|
|
2029
|
-
{ kind:
|
|
2123
|
+
{ kind: import_api15.SpanKind.INTERNAL, attributes: this.baseAttributes },
|
|
2030
2124
|
this.fallbackContext
|
|
2031
2125
|
);
|
|
2032
2126
|
if (attributes) span.addEvent(name, attributes);
|
|
2033
|
-
span.setStatus({ code:
|
|
2127
|
+
span.setStatus({ code: import_api15.SpanStatusCode.OK });
|
|
2034
2128
|
span.end();
|
|
2035
2129
|
}
|
|
2036
2130
|
}
|
|
@@ -2067,7 +2161,7 @@ var TelemetryAccessor = class {
|
|
|
2067
2161
|
* Useful for including in external API calls or logs.
|
|
2068
2162
|
*/
|
|
2069
2163
|
get traceId() {
|
|
2070
|
-
return
|
|
2164
|
+
return import_api15.trace.getSpan(this.fallbackContext)?.spanContext().traceId ?? "";
|
|
2071
2165
|
}
|
|
2072
2166
|
/**
|
|
2073
2167
|
* Get the session tracing ID (privacy-safe hash).
|
|
@@ -2078,10 +2172,10 @@ var TelemetryAccessor = class {
|
|
|
2078
2172
|
};
|
|
2079
2173
|
|
|
2080
2174
|
// libs/observability/src/telemetry/telemetry.factory.ts
|
|
2081
|
-
var
|
|
2175
|
+
var import_api16 = require("@opentelemetry/api");
|
|
2082
2176
|
var TelemetryFactory = class {
|
|
2083
2177
|
constructor(tracerName = "@frontmcp/observability") {
|
|
2084
|
-
this.tracer =
|
|
2178
|
+
this.tracer = import_api16.trace.getTracer(tracerName);
|
|
2085
2179
|
}
|
|
2086
2180
|
/**
|
|
2087
2181
|
* Create (or retrieve cached) a named counter. Increments propagate to
|
|
@@ -2128,32 +2222,32 @@ var TELEMETRY_ACCESSOR = /* @__PURE__ */ Symbol.for("frontmcp:observability:tele
|
|
|
2128
2222
|
var TELEMETRY_FACTORY = /* @__PURE__ */ Symbol.for("frontmcp:observability:telemetry-factory");
|
|
2129
2223
|
|
|
2130
2224
|
// libs/observability/src/plugin/observability.plugin.ts
|
|
2131
|
-
var PromptHook = (0,
|
|
2132
|
-
var ListPromptsHook = (0,
|
|
2133
|
-
var SkillSearchHook = (0,
|
|
2134
|
-
var SkillLoadHook = (0,
|
|
2135
|
-
var CompletionHook = (0,
|
|
2136
|
-
var LegacySseHook = (0,
|
|
2137
|
-
var StreamableHttpHook = (0,
|
|
2138
|
-
var StatelessHttpHook = (0,
|
|
2139
|
-
var AuthVerifyHook = (0,
|
|
2140
|
-
var SessionVerifyHook = (0,
|
|
2141
|
-
var OAuthTokenHook = (0,
|
|
2142
|
-
var OAuthAuthorizeHook = (0,
|
|
2143
|
-
var OAuthCallbackHook = (0,
|
|
2144
|
-
var OAuthProviderCallbackHook = (0,
|
|
2145
|
-
var OAuthRegisterHook = (0,
|
|
2146
|
-
var ElicitRequestHook = (0,
|
|
2147
|
-
var ElicitResultHook = (0,
|
|
2148
|
-
var SubscribeResourceHook = (0,
|
|
2149
|
-
var UnsubscribeResourceHook = (0,
|
|
2150
|
-
var SkillsHttpLlmTxtHook = (0,
|
|
2151
|
-
var SkillsHttpLlmFullTxtHook = (0,
|
|
2152
|
-
var SkillsHttpApiHook = (0,
|
|
2153
|
-
var WellKnownJwksHook = (0,
|
|
2154
|
-
var WellKnownOAuthServerHook = (0,
|
|
2155
|
-
var WellKnownPrmHook = (0,
|
|
2156
|
-
var LoggingSetLevelHook = (0,
|
|
2225
|
+
var PromptHook = (0, import_sdk4.FlowHooksOf)("prompts:get-prompt");
|
|
2226
|
+
var ListPromptsHook = (0, import_sdk4.FlowHooksOf)("prompts:list-prompts");
|
|
2227
|
+
var SkillSearchHook = (0, import_sdk4.FlowHooksOf)("skills:search");
|
|
2228
|
+
var SkillLoadHook = (0, import_sdk4.FlowHooksOf)("skills:load");
|
|
2229
|
+
var CompletionHook = (0, import_sdk4.FlowHooksOf)("completion:complete");
|
|
2230
|
+
var LegacySseHook = (0, import_sdk4.FlowHooksOf)("handle:legacy-sse");
|
|
2231
|
+
var StreamableHttpHook = (0, import_sdk4.FlowHooksOf)("handle:streamable-http");
|
|
2232
|
+
var StatelessHttpHook = (0, import_sdk4.FlowHooksOf)("handle:stateless-http");
|
|
2233
|
+
var AuthVerifyHook = (0, import_sdk4.FlowHooksOf)("auth:verify");
|
|
2234
|
+
var SessionVerifyHook = (0, import_sdk4.FlowHooksOf)("session:verify");
|
|
2235
|
+
var OAuthTokenHook = (0, import_sdk4.FlowHooksOf)("oauth:token");
|
|
2236
|
+
var OAuthAuthorizeHook = (0, import_sdk4.FlowHooksOf)("oauth:authorize");
|
|
2237
|
+
var OAuthCallbackHook = (0, import_sdk4.FlowHooksOf)("oauth:callback");
|
|
2238
|
+
var OAuthProviderCallbackHook = (0, import_sdk4.FlowHooksOf)("oauth:provider-callback");
|
|
2239
|
+
var OAuthRegisterHook = (0, import_sdk4.FlowHooksOf)("oauth:register");
|
|
2240
|
+
var ElicitRequestHook = (0, import_sdk4.FlowHooksOf)("elicitation:request");
|
|
2241
|
+
var ElicitResultHook = (0, import_sdk4.FlowHooksOf)("elicitation:result");
|
|
2242
|
+
var SubscribeResourceHook = (0, import_sdk4.FlowHooksOf)("resources:subscribe");
|
|
2243
|
+
var UnsubscribeResourceHook = (0, import_sdk4.FlowHooksOf)("resources:unsubscribe");
|
|
2244
|
+
var SkillsHttpLlmTxtHook = (0, import_sdk4.FlowHooksOf)("skills-http:llm-txt");
|
|
2245
|
+
var SkillsHttpLlmFullTxtHook = (0, import_sdk4.FlowHooksOf)("skills-http:llm-full-txt");
|
|
2246
|
+
var SkillsHttpApiHook = (0, import_sdk4.FlowHooksOf)("skills-http:api");
|
|
2247
|
+
var WellKnownJwksHook = (0, import_sdk4.FlowHooksOf)("well-known.jwks");
|
|
2248
|
+
var WellKnownOAuthServerHook = (0, import_sdk4.FlowHooksOf)("well-known.oauth-authorization-server");
|
|
2249
|
+
var WellKnownPrmHook = (0, import_sdk4.FlowHooksOf)("well-known.prm");
|
|
2250
|
+
var LoggingSetLevelHook = (0, import_sdk4.FlowHooksOf)("logging:set-level");
|
|
2157
2251
|
var DEFAULT_TRACING = {
|
|
2158
2252
|
httpSpans: true,
|
|
2159
2253
|
executionSpans: true,
|
|
@@ -2166,9 +2260,17 @@ var DEFAULT_TRACING = {
|
|
|
2166
2260
|
elicitationSpans: true,
|
|
2167
2261
|
startupReport: true
|
|
2168
2262
|
};
|
|
2169
|
-
var ObservabilityPlugin = class extends
|
|
2263
|
+
var ObservabilityPlugin = class extends import_sdk4.DynamicPlugin {
|
|
2170
2264
|
constructor(options = {}) {
|
|
2171
2265
|
super();
|
|
2266
|
+
/** Wraps each other hook the request runs: names it on the request's log, and gives it a span with `hookSpans`. */
|
|
2267
|
+
this.observeHook = async ({ flowName, stage, target, flowContext }, run) => {
|
|
2268
|
+
if (target === this) return run();
|
|
2269
|
+
if (this.requestLogsEnabled) currentRequestLog(flowContext)?.addHook(`${flowName}:${stage}`);
|
|
2270
|
+
if (!this.traces("hookSpans")) return run();
|
|
2271
|
+
const owner = target?.constructor?.name;
|
|
2272
|
+
return runInHookSpan(flowContext, { flowName, stage, owner }, run);
|
|
2273
|
+
};
|
|
2172
2274
|
this.options = resolveOptions(options);
|
|
2173
2275
|
this.tracingOpts = this.options.tracing !== false ? this.options.tracing : DEFAULT_TRACING;
|
|
2174
2276
|
}
|
|
@@ -2178,6 +2280,15 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
|
|
|
2178
2280
|
get requestLogsEnabled() {
|
|
2179
2281
|
return this.options.requestLogs !== false;
|
|
2180
2282
|
}
|
|
2283
|
+
/** Whether tracing is on and its `kind` option isn't off. */
|
|
2284
|
+
traces(kind) {
|
|
2285
|
+
return this.tracingEnabled && this.tracingOpts[kind] !== false;
|
|
2286
|
+
}
|
|
2287
|
+
/** Watches the hooks of the request `ctx` serves, from the first flow of it that this plugin sees. */
|
|
2288
|
+
watchHooks(ctx) {
|
|
2289
|
+
if (this.requestLogsEnabled || this.traces("hookSpans"))
|
|
2290
|
+
installHookObserver(ctx, this.observeHook);
|
|
2291
|
+
}
|
|
2181
2292
|
/** Names the entry a request serves on its request log, and records the entry flow's failure. */
|
|
2182
2293
|
annotateRequestLog(ctx, set) {
|
|
2183
2294
|
if (!this.requestLogsEnabled) return;
|
|
@@ -2188,6 +2299,7 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
|
|
|
2188
2299
|
_httpWillTrace(ctx) {
|
|
2189
2300
|
if (this.tracingEnabled) onHttpWillTrace(this.tracingOpts, ctx);
|
|
2190
2301
|
if (this.options.requestLogs !== false) startRequestLog(ctx, this.options.requestLogs);
|
|
2302
|
+
this.watchHooks(ctx);
|
|
2191
2303
|
}
|
|
2192
2304
|
_httpWillQuota(ctx) {
|
|
2193
2305
|
if (this.tracingEnabled) onHttpWillAcquireQuota(ctx);
|
|
@@ -2200,6 +2312,7 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
|
|
|
2200
2312
|
}
|
|
2201
2313
|
_httpDidAuth(ctx) {
|
|
2202
2314
|
if (this.tracingEnabled) onHttpDidCheckAuth(ctx);
|
|
2315
|
+
if (this.requestLogsEnabled) recordRequestLogAuth(ctx);
|
|
2203
2316
|
}
|
|
2204
2317
|
_httpWillRoute(ctx) {
|
|
2205
2318
|
if (this.tracingEnabled) onHttpWillRoute(ctx);
|
|
@@ -2212,6 +2325,7 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
|
|
|
2212
2325
|
if (this.requestLogsEnabled) void completeRequestLog(ctx);
|
|
2213
2326
|
}
|
|
2214
2327
|
_toolWillParse(ctx) {
|
|
2328
|
+
this.watchHooks(ctx);
|
|
2215
2329
|
if (this.tracingEnabled) onToolWillParse(this.tracingOpts, ctx);
|
|
2216
2330
|
}
|
|
2217
2331
|
_toolWillFind(ctx) {
|
|
@@ -2250,6 +2364,7 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
|
|
|
2250
2364
|
if (this.requestLogsEnabled) recordRequestLogFailure(ctx);
|
|
2251
2365
|
}
|
|
2252
2366
|
_resourceWillParse(ctx) {
|
|
2367
|
+
this.watchHooks(ctx);
|
|
2253
2368
|
if (this.tracingEnabled) onResourceWillParse(this.tracingOpts, ctx);
|
|
2254
2369
|
}
|
|
2255
2370
|
_resourceWillFind(ctx) {
|
|
@@ -2273,6 +2388,7 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
|
|
|
2273
2388
|
if (this.requestLogsEnabled) recordRequestLogFailure(ctx);
|
|
2274
2389
|
}
|
|
2275
2390
|
_promptWillParse(ctx) {
|
|
2391
|
+
this.watchHooks(ctx);
|
|
2276
2392
|
if (this.tracingEnabled) onPromptWillParse(this.tracingOpts, ctx);
|
|
2277
2393
|
}
|
|
2278
2394
|
_promptWillFind(ctx) {
|
|
@@ -2296,6 +2412,7 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
|
|
|
2296
2412
|
if (this.requestLogsEnabled) recordRequestLogFailure(ctx);
|
|
2297
2413
|
}
|
|
2298
2414
|
_agentWillParse(ctx) {
|
|
2415
|
+
this.watchHooks(ctx);
|
|
2299
2416
|
if (this.tracingEnabled) onAgentWillParse(this.tracingOpts, ctx);
|
|
2300
2417
|
}
|
|
2301
2418
|
_agentWillFind(ctx) {
|
|
@@ -2449,46 +2566,46 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
|
|
|
2449
2566
|
if (this.tracingEnabled) onAuthDidFinalize(ctx);
|
|
2450
2567
|
}
|
|
2451
2568
|
_oauthTokenWill(ctx) {
|
|
2452
|
-
if (this.
|
|
2569
|
+
if (this.traces("oauthSpans")) onGenericFlowWillStart("oauth/token", this.tracingOpts, ctx);
|
|
2453
2570
|
}
|
|
2454
2571
|
_oauthTokenDone(ctx) {
|
|
2455
|
-
if (this.
|
|
2572
|
+
if (this.traces("oauthSpans")) onGenericFlowDidFinalize(ctx);
|
|
2456
2573
|
}
|
|
2457
2574
|
_oauthAuthzWill(ctx) {
|
|
2458
|
-
if (this.
|
|
2575
|
+
if (this.traces("oauthSpans")) onGenericFlowWillStart("oauth/authorize", this.tracingOpts, ctx);
|
|
2459
2576
|
}
|
|
2460
2577
|
_oauthAuthzDone(ctx) {
|
|
2461
|
-
if (this.
|
|
2578
|
+
if (this.traces("oauthSpans")) onGenericFlowDidFinalize(ctx);
|
|
2462
2579
|
}
|
|
2463
2580
|
_oauthCallbackWill(ctx) {
|
|
2464
|
-
if (this.
|
|
2581
|
+
if (this.traces("oauthSpans")) onGenericFlowWillStart("oauth/callback", this.tracingOpts, ctx);
|
|
2465
2582
|
}
|
|
2466
2583
|
_oauthCallbackDone(ctx) {
|
|
2467
|
-
if (this.
|
|
2584
|
+
if (this.traces("oauthSpans")) onGenericFlowDidFinalize(ctx);
|
|
2468
2585
|
}
|
|
2469
2586
|
_oauthProviderWill(ctx) {
|
|
2470
|
-
if (this.
|
|
2587
|
+
if (this.traces("oauthSpans")) onGenericFlowWillStart("oauth/provider-callback", this.tracingOpts, ctx);
|
|
2471
2588
|
}
|
|
2472
2589
|
_oauthProviderDone(ctx) {
|
|
2473
|
-
if (this.
|
|
2590
|
+
if (this.traces("oauthSpans")) onGenericFlowDidFinalize(ctx);
|
|
2474
2591
|
}
|
|
2475
2592
|
_oauthRegisterWill(ctx) {
|
|
2476
|
-
if (this.
|
|
2593
|
+
if (this.traces("oauthSpans")) onGenericFlowWillStart("oauth/register", this.tracingOpts, ctx);
|
|
2477
2594
|
}
|
|
2478
2595
|
_oauthRegisterDone(ctx) {
|
|
2479
|
-
if (this.
|
|
2596
|
+
if (this.traces("oauthSpans")) onGenericFlowDidFinalize(ctx);
|
|
2480
2597
|
}
|
|
2481
2598
|
_elicitReqWill(ctx) {
|
|
2482
|
-
if (this.
|
|
2599
|
+
if (this.traces("elicitationSpans")) onGenericFlowWillStart("elicitation/request", this.tracingOpts, ctx);
|
|
2483
2600
|
}
|
|
2484
2601
|
_elicitReqDone(ctx) {
|
|
2485
|
-
if (this.
|
|
2602
|
+
if (this.traces("elicitationSpans")) onGenericFlowDidFinalize(ctx);
|
|
2486
2603
|
}
|
|
2487
2604
|
_elicitResWill(ctx) {
|
|
2488
|
-
if (this.
|
|
2605
|
+
if (this.traces("elicitationSpans")) onGenericFlowWillStart("elicitation/result", this.tracingOpts, ctx);
|
|
2489
2606
|
}
|
|
2490
2607
|
_elicitResDone(ctx) {
|
|
2491
|
-
if (this.
|
|
2608
|
+
if (this.traces("elicitationSpans")) onGenericFlowDidFinalize(ctx);
|
|
2492
2609
|
}
|
|
2493
2610
|
_subscribeWill(ctx) {
|
|
2494
2611
|
if (this.tracingEnabled) onGenericFlowWillStart("resources/subscribe", this.tracingOpts, ctx);
|
|
@@ -2554,12 +2671,10 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
|
|
|
2554
2671
|
// Startup Report (public method)
|
|
2555
2672
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
2556
2673
|
/**
|
|
2557
|
-
* Emit startup
|
|
2558
|
-
* Call after scope.initialize() completes with component counts.
|
|
2674
|
+
* Emit the `frontmcp.startup` span (`tracing.startupReport`). The scope calls it once it is ready.
|
|
2559
2675
|
*/
|
|
2560
2676
|
reportStartupTelemetry(data) {
|
|
2561
|
-
if (this.
|
|
2562
|
-
reportStartup(data);
|
|
2677
|
+
if (this.traces("startupReport")) reportStartup(data);
|
|
2563
2678
|
}
|
|
2564
2679
|
};
|
|
2565
2680
|
ObservabilityPlugin.defaultOptions = {
|
|
@@ -2577,7 +2692,7 @@ ObservabilityPlugin.dynamicProviders = (input) => {
|
|
|
2577
2692
|
providers.push({
|
|
2578
2693
|
name: "observability:tracer",
|
|
2579
2694
|
provide: OTEL_TRACER,
|
|
2580
|
-
useValue:
|
|
2695
|
+
useValue: import_api17.trace.getTracer("@frontmcp/observability")
|
|
2581
2696
|
});
|
|
2582
2697
|
providers.push({
|
|
2583
2698
|
name: "observability:config",
|
|
@@ -2587,8 +2702,8 @@ ObservabilityPlugin.dynamicProviders = (input) => {
|
|
|
2587
2702
|
providers.push({
|
|
2588
2703
|
name: "observability:telemetry-accessor",
|
|
2589
2704
|
provide: TELEMETRY_ACCESSOR,
|
|
2590
|
-
scope:
|
|
2591
|
-
inject: () => [
|
|
2705
|
+
scope: import_sdk4.ProviderScope.CONTEXT,
|
|
2706
|
+
inject: () => [import_sdk4.FRONTMCP_CONTEXT],
|
|
2592
2707
|
useFactory: (ctx) => new TelemetryAccessor(ctx)
|
|
2593
2708
|
});
|
|
2594
2709
|
providers.push({
|
|
@@ -2620,8 +2735,8 @@ ObservabilityPlugin.dynamicProviders = (input) => {
|
|
|
2620
2735
|
providers.push({
|
|
2621
2736
|
name: "observability:request-log-collector",
|
|
2622
2737
|
provide: REQUEST_LOG_COLLECTOR,
|
|
2623
|
-
scope:
|
|
2624
|
-
inject: () => [
|
|
2738
|
+
scope: import_sdk4.ProviderScope.CONTEXT,
|
|
2739
|
+
inject: () => [import_sdk4.FRONTMCP_CONTEXT],
|
|
2625
2740
|
useFactory: (ctx) => {
|
|
2626
2741
|
return new RequestLogCollector(
|
|
2627
2742
|
{
|
|
@@ -2638,85 +2753,85 @@ ObservabilityPlugin.dynamicProviders = (input) => {
|
|
|
2638
2753
|
return providers;
|
|
2639
2754
|
};
|
|
2640
2755
|
__decorateClass([
|
|
2641
|
-
|
|
2756
|
+
import_sdk4.HttpHook.Will("traceRequest", { priority: -1e3 })
|
|
2642
2757
|
], ObservabilityPlugin.prototype, "_httpWillTrace", 1);
|
|
2643
2758
|
__decorateClass([
|
|
2644
|
-
|
|
2759
|
+
import_sdk4.HttpHook.Will("acquireQuota", { priority: -1e3 })
|
|
2645
2760
|
], ObservabilityPlugin.prototype, "_httpWillQuota", 1);
|
|
2646
2761
|
__decorateClass([
|
|
2647
|
-
|
|
2762
|
+
import_sdk4.HttpHook.Did("acquireSemaphore", { priority: 1e3 })
|
|
2648
2763
|
], ObservabilityPlugin.prototype, "_httpDidSemaphore", 1);
|
|
2649
2764
|
__decorateClass([
|
|
2650
|
-
|
|
2765
|
+
import_sdk4.HttpHook.Will("checkAuthorization", { priority: -1e3 })
|
|
2651
2766
|
], ObservabilityPlugin.prototype, "_httpWillAuth", 1);
|
|
2652
2767
|
__decorateClass([
|
|
2653
|
-
|
|
2768
|
+
import_sdk4.HttpHook.Did("checkAuthorization", { priority: 1e3 })
|
|
2654
2769
|
], ObservabilityPlugin.prototype, "_httpDidAuth", 1);
|
|
2655
2770
|
__decorateClass([
|
|
2656
|
-
|
|
2771
|
+
import_sdk4.HttpHook.Will("router", { priority: -1e3 })
|
|
2657
2772
|
], ObservabilityPlugin.prototype, "_httpWillRoute", 1);
|
|
2658
2773
|
__decorateClass([
|
|
2659
|
-
|
|
2774
|
+
import_sdk4.HttpHook.Did("router", { priority: 1e3 })
|
|
2660
2775
|
], ObservabilityPlugin.prototype, "_httpDidRoute", 1);
|
|
2661
2776
|
__decorateClass([
|
|
2662
|
-
|
|
2777
|
+
import_sdk4.HttpHook.Did("finalize", { priority: 1e3 })
|
|
2663
2778
|
], ObservabilityPlugin.prototype, "_httpDidFinalize", 1);
|
|
2664
2779
|
__decorateClass([
|
|
2665
|
-
|
|
2780
|
+
import_sdk4.ToolHook.Will("parseInput", { priority: -1e3 })
|
|
2666
2781
|
], ObservabilityPlugin.prototype, "_toolWillParse", 1);
|
|
2667
2782
|
__decorateClass([
|
|
2668
|
-
|
|
2783
|
+
import_sdk4.ToolHook.Will("findTool", { priority: -1e3 })
|
|
2669
2784
|
], ObservabilityPlugin.prototype, "_toolWillFind", 1);
|
|
2670
2785
|
__decorateClass([
|
|
2671
|
-
|
|
2786
|
+
import_sdk4.ToolHook.Will("checkToolAuthorization", { priority: -1e3 })
|
|
2672
2787
|
], ObservabilityPlugin.prototype, "_toolWillCheckAuth", 1);
|
|
2673
2788
|
__decorateClass([
|
|
2674
|
-
|
|
2789
|
+
import_sdk4.ToolHook.Will("checkEntryAuthorities", { priority: -1e3 })
|
|
2675
2790
|
], ObservabilityPlugin.prototype, "_toolWillCheckAuthorities", 1);
|
|
2676
2791
|
__decorateClass([
|
|
2677
|
-
|
|
2792
|
+
import_sdk4.ToolHook.Did("checkEntryAuthorities", { priority: 1e3 })
|
|
2678
2793
|
], ObservabilityPlugin.prototype, "_toolDidCheckAuthorities", 1);
|
|
2679
2794
|
__decorateClass([
|
|
2680
|
-
|
|
2795
|
+
import_sdk4.ToolHook.Will("createToolCallContext", { priority: -1e3 })
|
|
2681
2796
|
], ObservabilityPlugin.prototype, "_toolWillCreateCtx", 1);
|
|
2682
2797
|
__decorateClass([
|
|
2683
|
-
|
|
2798
|
+
import_sdk4.ToolHook.Will("validateInput", { priority: -1e3 })
|
|
2684
2799
|
], ObservabilityPlugin.prototype, "_toolWillValidate", 1);
|
|
2685
2800
|
__decorateClass([
|
|
2686
|
-
|
|
2801
|
+
import_sdk4.ToolHook.Will("execute", { priority: -1e3 })
|
|
2687
2802
|
], ObservabilityPlugin.prototype, "_toolWillExecute", 1);
|
|
2688
2803
|
__decorateClass([
|
|
2689
|
-
|
|
2804
|
+
import_sdk4.ToolHook.Did("execute", { priority: 1e3 })
|
|
2690
2805
|
], ObservabilityPlugin.prototype, "_toolDidExecute", 1);
|
|
2691
2806
|
__decorateClass([
|
|
2692
|
-
|
|
2807
|
+
import_sdk4.ToolHook.Will("validateOutput", { priority: -1e3 })
|
|
2693
2808
|
], ObservabilityPlugin.prototype, "_toolWillValidateOut", 1);
|
|
2694
2809
|
__decorateClass([
|
|
2695
|
-
|
|
2810
|
+
import_sdk4.ToolHook.Will("applyUI", { priority: -1e3 })
|
|
2696
2811
|
], ObservabilityPlugin.prototype, "_toolWillApplyUI", 1);
|
|
2697
2812
|
__decorateClass([
|
|
2698
|
-
|
|
2813
|
+
import_sdk4.ToolHook.Did("finalize", { priority: 1e3 })
|
|
2699
2814
|
], ObservabilityPlugin.prototype, "_toolDidFinalize", 1);
|
|
2700
2815
|
__decorateClass([
|
|
2701
|
-
|
|
2816
|
+
import_sdk4.ResourceHook.Will("parseInput", { priority: -1e3 })
|
|
2702
2817
|
], ObservabilityPlugin.prototype, "_resourceWillParse", 1);
|
|
2703
2818
|
__decorateClass([
|
|
2704
|
-
|
|
2819
|
+
import_sdk4.ResourceHook.Will("findResource", { priority: -1e3 })
|
|
2705
2820
|
], ObservabilityPlugin.prototype, "_resourceWillFind", 1);
|
|
2706
2821
|
__decorateClass([
|
|
2707
|
-
|
|
2822
|
+
import_sdk4.ResourceHook.Will("checkEntryAuthorities", { priority: -1e3 })
|
|
2708
2823
|
], ObservabilityPlugin.prototype, "_resourceWillCheckAuthorities", 1);
|
|
2709
2824
|
__decorateClass([
|
|
2710
|
-
|
|
2825
|
+
import_sdk4.ResourceHook.Did("checkEntryAuthorities", { priority: 1e3 })
|
|
2711
2826
|
], ObservabilityPlugin.prototype, "_resourceDidCheckAuthorities", 1);
|
|
2712
2827
|
__decorateClass([
|
|
2713
|
-
|
|
2828
|
+
import_sdk4.ResourceHook.Will("execute", { priority: -1e3 })
|
|
2714
2829
|
], ObservabilityPlugin.prototype, "_resourceWillExecute", 1);
|
|
2715
2830
|
__decorateClass([
|
|
2716
|
-
|
|
2831
|
+
import_sdk4.ResourceHook.Did("execute", { priority: 1e3 })
|
|
2717
2832
|
], ObservabilityPlugin.prototype, "_resourceDidExecute", 1);
|
|
2718
2833
|
__decorateClass([
|
|
2719
|
-
|
|
2834
|
+
import_sdk4.ResourceHook.Did("finalize", { priority: 1e3 })
|
|
2720
2835
|
], ObservabilityPlugin.prototype, "_resourceDidFinalize", 1);
|
|
2721
2836
|
__decorateClass([
|
|
2722
2837
|
PromptHook.Will("parseInput", { priority: -1e3 })
|
|
@@ -2740,55 +2855,55 @@ __decorateClass([
|
|
|
2740
2855
|
PromptHook.Did("finalize", { priority: 1e3 })
|
|
2741
2856
|
], ObservabilityPlugin.prototype, "_promptDidFinalize", 1);
|
|
2742
2857
|
__decorateClass([
|
|
2743
|
-
|
|
2858
|
+
import_sdk4.AgentCallHook.Will("parseInput", { priority: -1e3 })
|
|
2744
2859
|
], ObservabilityPlugin.prototype, "_agentWillParse", 1);
|
|
2745
2860
|
__decorateClass([
|
|
2746
|
-
|
|
2861
|
+
import_sdk4.AgentCallHook.Will("findAgent", { priority: -1e3 })
|
|
2747
2862
|
], ObservabilityPlugin.prototype, "_agentWillFind", 1);
|
|
2748
2863
|
__decorateClass([
|
|
2749
|
-
|
|
2864
|
+
import_sdk4.AgentCallHook.Will("checkEntryAuthorities", { priority: -1e3 })
|
|
2750
2865
|
], ObservabilityPlugin.prototype, "_agentWillCheckAuthorities", 1);
|
|
2751
2866
|
__decorateClass([
|
|
2752
|
-
|
|
2867
|
+
import_sdk4.AgentCallHook.Did("checkEntryAuthorities", { priority: 1e3 })
|
|
2753
2868
|
], ObservabilityPlugin.prototype, "_agentDidCheckAuthorities", 1);
|
|
2754
2869
|
__decorateClass([
|
|
2755
|
-
|
|
2870
|
+
import_sdk4.AgentCallHook.Will("execute", { priority: -1e3 })
|
|
2756
2871
|
], ObservabilityPlugin.prototype, "_agentWillExecute", 1);
|
|
2757
2872
|
__decorateClass([
|
|
2758
|
-
|
|
2873
|
+
import_sdk4.AgentCallHook.Did("execute", { priority: 1e3 })
|
|
2759
2874
|
], ObservabilityPlugin.prototype, "_agentDidExecute", 1);
|
|
2760
2875
|
__decorateClass([
|
|
2761
|
-
|
|
2876
|
+
import_sdk4.AgentCallHook.Did("finalize", { priority: 1e3 })
|
|
2762
2877
|
], ObservabilityPlugin.prototype, "_agentDidFinalize", 1);
|
|
2763
2878
|
__decorateClass([
|
|
2764
|
-
|
|
2879
|
+
import_sdk4.ListToolsHook.Will("parseInput", { priority: -1e3 })
|
|
2765
2880
|
], ObservabilityPlugin.prototype, "_listToolsWill", 1);
|
|
2766
2881
|
__decorateClass([
|
|
2767
|
-
|
|
2882
|
+
import_sdk4.ListToolsHook.Did("findTools", { priority: 1e3 })
|
|
2768
2883
|
], ObservabilityPlugin.prototype, "_listToolsDidFind", 1);
|
|
2769
2884
|
__decorateClass([
|
|
2770
|
-
|
|
2885
|
+
import_sdk4.ListToolsHook.Did("filterByAuthorities", { priority: 1e3 })
|
|
2771
2886
|
], ObservabilityPlugin.prototype, "_listToolsDidFilter", 1);
|
|
2772
2887
|
__decorateClass([
|
|
2773
|
-
|
|
2888
|
+
import_sdk4.ListToolsHook.Did("parseTools", { priority: 1e3 })
|
|
2774
2889
|
], ObservabilityPlugin.prototype, "_listToolsDone", 1);
|
|
2775
2890
|
__decorateClass([
|
|
2776
|
-
|
|
2891
|
+
import_sdk4.ListResourcesHook.Will("parseInput", { priority: -1e3 })
|
|
2777
2892
|
], ObservabilityPlugin.prototype, "_listResourcesWill", 1);
|
|
2778
2893
|
__decorateClass([
|
|
2779
|
-
|
|
2894
|
+
import_sdk4.ListResourcesHook.Did("filterByAuthorities", { priority: 1e3 })
|
|
2780
2895
|
], ObservabilityPlugin.prototype, "_listResourcesDidFilter", 1);
|
|
2781
2896
|
__decorateClass([
|
|
2782
|
-
|
|
2897
|
+
import_sdk4.ListResourcesHook.Did("parseResources", { priority: 1e3 })
|
|
2783
2898
|
], ObservabilityPlugin.prototype, "_listResourcesDone", 1);
|
|
2784
2899
|
__decorateClass([
|
|
2785
|
-
|
|
2900
|
+
import_sdk4.ListResourceTemplatesHook.Will("parseInput", { priority: -1e3 })
|
|
2786
2901
|
], ObservabilityPlugin.prototype, "_listTemplatesWill", 1);
|
|
2787
2902
|
__decorateClass([
|
|
2788
|
-
|
|
2903
|
+
import_sdk4.ListResourceTemplatesHook.Did("filterByAuthorities", { priority: 1e3 })
|
|
2789
2904
|
], ObservabilityPlugin.prototype, "_listTemplatesDidFilter", 1);
|
|
2790
2905
|
__decorateClass([
|
|
2791
|
-
|
|
2906
|
+
import_sdk4.ListResourceTemplatesHook.Did("parseTemplates", { priority: 1e3 })
|
|
2792
2907
|
], ObservabilityPlugin.prototype, "_listTemplatesDone", 1);
|
|
2793
2908
|
__decorateClass([
|
|
2794
2909
|
ListPromptsHook.Will("parseInput", { priority: -1e3 })
|
|
@@ -2989,13 +3104,13 @@ __decorateClass([
|
|
|
2989
3104
|
LoggingSetLevelHook.Did("finalize", { priority: 1e3 })
|
|
2990
3105
|
], ObservabilityPlugin.prototype, "_setLevelDone", 1);
|
|
2991
3106
|
__decorateClass([
|
|
2992
|
-
|
|
3107
|
+
import_sdk4.ToolHook.Did("createToolCallContext", { priority: 999 })
|
|
2993
3108
|
], ObservabilityPlugin.prototype, "_toolDidCreateCtxFetch", 1);
|
|
2994
3109
|
__decorateClass([
|
|
2995
|
-
|
|
3110
|
+
import_sdk4.AgentCallHook.Did("execute", { priority: 999 })
|
|
2996
3111
|
], ObservabilityPlugin.prototype, "_agentDidExecuteMeta", 1);
|
|
2997
3112
|
ObservabilityPlugin = __decorateClass([
|
|
2998
|
-
(0,
|
|
3113
|
+
(0, import_sdk4.Plugin)({
|
|
2999
3114
|
name: "observability",
|
|
3000
3115
|
description: "Full-system OpenTelemetry instrumentation, structured logging, and request logs",
|
|
3001
3116
|
providers: [],
|
|
@@ -3032,11 +3147,11 @@ function resolveRequestLogOptions(input) {
|
|
|
3032
3147
|
}
|
|
3033
3148
|
|
|
3034
3149
|
// libs/observability/src/otel/context-propagator.ts
|
|
3035
|
-
var
|
|
3150
|
+
var import_api18 = require("@opentelemetry/api");
|
|
3036
3151
|
var TRACEPARENT_HEADER = "traceparent";
|
|
3037
3152
|
var FrontMcpPropagator = class {
|
|
3038
3153
|
inject(context, carrier, setter) {
|
|
3039
|
-
const span =
|
|
3154
|
+
const span = import_api18.trace.getSpan(context);
|
|
3040
3155
|
if (!span) return;
|
|
3041
3156
|
const sc = span.spanContext();
|
|
3042
3157
|
if (!sc || !isValidSpanContext(sc)) return;
|
|
@@ -3056,8 +3171,8 @@ var FrontMcpPropagator = class {
|
|
|
3056
3171
|
traceFlags: parsed.traceFlags,
|
|
3057
3172
|
isRemote: true
|
|
3058
3173
|
};
|
|
3059
|
-
const span =
|
|
3060
|
-
return
|
|
3174
|
+
const span = import_api18.trace.wrapSpanContext(spanContext);
|
|
3175
|
+
return import_api18.trace.setSpan(context, span);
|
|
3061
3176
|
}
|
|
3062
3177
|
fields() {
|
|
3063
3178
|
return [TRACEPARENT_HEADER];
|
|
@@ -3124,33 +3239,6 @@ function setupOTel(options) {
|
|
|
3124
3239
|
}
|
|
3125
3240
|
}
|
|
3126
3241
|
|
|
3127
|
-
// libs/observability/src/otel/spans/hook.span.ts
|
|
3128
|
-
var import_api18 = require("@opentelemetry/api");
|
|
3129
|
-
function recordHookEvent(parentSpan, stage, owner) {
|
|
3130
|
-
const attributes = {};
|
|
3131
|
-
if (owner) {
|
|
3132
|
-
attributes[FrontMcpAttributes.HOOK_OWNER] = owner;
|
|
3133
|
-
}
|
|
3134
|
-
parentSpan.addEvent(`hook.${stage}`, attributes);
|
|
3135
|
-
}
|
|
3136
|
-
function startHookSpan(tracer, options) {
|
|
3137
|
-
const attributes = {
|
|
3138
|
-
[FrontMcpAttributes.HOOK_STAGE]: options.stage
|
|
3139
|
-
};
|
|
3140
|
-
if (options.owner) {
|
|
3141
|
-
attributes[FrontMcpAttributes.HOOK_OWNER] = options.owner;
|
|
3142
|
-
}
|
|
3143
|
-
if (options.flowName) {
|
|
3144
|
-
attributes[FrontMcpAttributes.FLOW_NAME] = options.flowName;
|
|
3145
|
-
}
|
|
3146
|
-
return startSpan(tracer, {
|
|
3147
|
-
name: `hook ${options.stage}`,
|
|
3148
|
-
kind: import_api18.SpanKind.INTERNAL,
|
|
3149
|
-
attributes,
|
|
3150
|
-
parentContext: options.parentContext
|
|
3151
|
-
});
|
|
3152
|
-
}
|
|
3153
|
-
|
|
3154
3242
|
// libs/observability/src/otel/spans/pretty-span-exporter.ts
|
|
3155
3243
|
var import_api19 = require("@opentelemetry/api");
|
|
3156
3244
|
var RESET = "\x1B[0m";
|
|
@@ -3393,7 +3481,7 @@ var ProcessStatsCollector = class {
|
|
|
3393
3481
|
});
|
|
3394
3482
|
}
|
|
3395
3483
|
const mem = probeSafely(() => this.memoryUsage());
|
|
3396
|
-
if (mem) {
|
|
3484
|
+
if (mem && mem.rss > 0) {
|
|
3397
3485
|
entries.push({
|
|
3398
3486
|
name: "frontmcp_process_resident_memory_bytes",
|
|
3399
3487
|
value: mem.rss,
|
|
@@ -3416,7 +3504,7 @@ var ProcessStatsCollector = class {
|
|
|
3416
3504
|
});
|
|
3417
3505
|
}
|
|
3418
3506
|
const uptime = probeSafely(() => this.uptime());
|
|
3419
|
-
if (uptime !== void 0) {
|
|
3507
|
+
if (uptime !== void 0 && uptime > 0) {
|
|
3420
3508
|
entries.push({
|
|
3421
3509
|
name: "frontmcp_process_uptime_seconds",
|
|
3422
3510
|
value: uptime,
|