autotel-devtools 23.0.0 → 24.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/cli.cjs +2 -2
  2. package/dist/cli.js +2 -2
  3. package/dist/{error-aggregator-DSwUvgFF.d.cts → error-aggregator-C0at0wzF.d.cts} +1 -1
  4. package/dist/{error-aggregator-B52JI8jL.d.ts → error-aggregator-C25_JiVI.d.ts} +1 -1
  5. package/dist/{exporter-C4uKgo7l.d.cts → exporter-AkgWRDpc.d.cts} +55 -2
  6. package/dist/{exporter-BrEcnzoT.d.ts → exporter-yo7lLDIs.d.ts} +55 -2
  7. package/dist/fullpage.global.js +37 -30
  8. package/dist/genai/index.d.cts +1 -1
  9. package/dist/genai/index.d.ts +1 -1
  10. package/dist/{grpc-CSWjMRiB.cjs → grpc-CSW1Evnt.cjs} +1 -1
  11. package/dist/{grpc-CZEDUYCM.js → grpc-D1tt8UPi.js} +1 -1
  12. package/dist/{http-Cqm_MAtc.cjs → http-CahjEnpE.cjs} +291 -5
  13. package/dist/{http-Dbd9TIYU.js → http-z8UbJsqk.js} +292 -6
  14. package/dist/index.cjs +1 -1
  15. package/dist/index.d.cts +4 -4
  16. package/dist/index.d.ts +4 -4
  17. package/dist/index.js +1 -1
  18. package/dist/server/exporter.d.cts +1 -1
  19. package/dist/server/exporter.d.ts +1 -1
  20. package/dist/server/index.cjs +2 -2
  21. package/dist/server/index.d.cts +4 -4
  22. package/dist/server/index.d.ts +4 -4
  23. package/dist/server/index.js +2 -2
  24. package/dist/types-B86Qkqg5.d.cts +120 -0
  25. package/dist/types-B86Qkqg5.d.ts +120 -0
  26. package/dist/{types-DM8y4A9Z.d.ts → types-BhbHVeiy.d.ts} +1 -1
  27. package/dist/{types-B0tjwFqj.d.cts → types-C-ORUrT2.d.cts} +1 -1
  28. package/dist/widget.global.js +14 -14
  29. package/dist/wire/index.d.cts +1 -1
  30. package/dist/wire/index.d.ts +1 -1
  31. package/package.json +2 -2
  32. package/dist/types-DHDvZnnn.d.cts +0 -47
  33. package/dist/types-DHDvZnnn.d.ts +0 -47
@@ -1,5 +1,5 @@
1
1
  import { i as encodeTraces } from "./wire-2Rmfg6IT.js";
2
- import { i as asString, o as stringAttr, t as asObject } from "./json-fields-CPjKZ2WH.js";
2
+ import { i as asString, n as asBoolean, o as stringAttr, r as asNumber, t as asObject } from "./json-fields-CPjKZ2WH.js";
3
3
  import { t as pickRoot } from "./trace-root-EHnvuA7f.js";
4
4
  import { a as compileWhere, t as parse } from "./parse-D_RmPPQs.js";
5
5
  import { t as getResourceName } from "./resource-utils-B4UVvfnH.js";
@@ -287,6 +287,181 @@ var ErrorAggregator = class {
287
287
  }
288
288
  };
289
289
 
290
+ //#endregion
291
+ //#region src/server/webmcp-aggregator.ts
292
+ /** Span names this fold consumes. Everything else in the trace is ignored. */
293
+ const INSTALL = "webmcp.install";
294
+ const REGISTER = "webmcp.tool.register";
295
+ const EXECUTE = "webmcp.tool.execute";
296
+ const WITHDRAW = "webmcp.tool.withdraw";
297
+ /** How many recent executions a tool carries. Enough to see a pattern, not a log. */
298
+ const RECENT_CALLS = 5;
299
+ /**
300
+ * `{"content":[{"type":"text","text":` + `}]}` and the quoting around it.
301
+ *
302
+ * Chrome does not unwrap the MCP envelope, so an enveloped result spends these
303
+ * bytes of the agent's context on structure carrying no information. Measured
304
+ * rather than derived: 45 bytes wrapped versus 13 plain for the same text.
305
+ */
306
+ const ENVELOPE_OVERHEAD_BYTES = 32;
307
+ const median = (values) => {
308
+ if (values.length === 0) return 0;
309
+ const sorted = [...values].sort((a, b) => a - b);
310
+ const mid = Math.floor(sorted.length / 2);
311
+ return sorted.length % 2 === 0 ? Math.round((sorted[mid - 1] + sorted[mid]) / 2) : sorted[mid];
312
+ };
313
+ const csv = (value) => {
314
+ const raw = asString(value);
315
+ if (!raw) return [];
316
+ return raw.split(",").map((part) => part.trim()).filter(Boolean);
317
+ };
318
+ /**
319
+ * Spans with no installation id — emitted by an `autotel-webmcp` older than the
320
+ * lifecycle release. Grouping them under one key per service keeps them
321
+ * readable as a single legacy installation rather than scattering one
322
+ * installation per tool.
323
+ */
324
+ const UNKNOWN_INSTALLATION = "unknown";
325
+ const isWebMcpSpan = (span) => span.name === INSTALL || span.name === REGISTER || span.name === EXECUTE || span.name === WITHDRAW;
326
+ function foldWebMcpTools(traces, activityWindow) {
327
+ const tools = /* @__PURE__ */ new Map();
328
+ /** Installations seen, and whether each one ever registered anything. */
329
+ const installations = /* @__PURE__ */ new Map();
330
+ const latestInstallation = /* @__PURE__ */ new Map();
331
+ const spans = traces.flatMap((trace) => trace.spans.map((span) => ({
332
+ span,
333
+ service: trace.service
334
+ }))).sort((a, b) => a.span.startTime - b.span.startTime);
335
+ for (const { span, service } of spans) {
336
+ if (!isWebMcpSpan(span)) continue;
337
+ if (activityWindow && span.startTime > activityWindow.end) continue;
338
+ const attrs = span.attributes ?? {};
339
+ const installationId = asString(attrs["webmcp.installation.id"]) ?? UNKNOWN_INSTALLATION;
340
+ const installationKey = `${service}${installationId}`;
341
+ if (!installations.has(installationKey)) installations.set(installationKey, false);
342
+ if (span.name === INSTALL) {
343
+ latestInstallation.set(service, installationId);
344
+ continue;
345
+ }
346
+ const name = asString(attrs["webmcp.tool.name"]) ?? asString(attrs["gen_ai.tool.name"]);
347
+ if (!name) continue;
348
+ const key = `${service}${installationId}${name}`;
349
+ let tool = tools.get(key);
350
+ if (!tool) {
351
+ tool = {
352
+ name,
353
+ installationId,
354
+ service,
355
+ sessionId: asString(attrs["session.id"]),
356
+ observedAtRegistration: false,
357
+ offered: false,
358
+ firstSeen: span.startTime,
359
+ lastSeen: span.startTime,
360
+ annotationsSent: [],
361
+ annotationsDropped: [],
362
+ calls: 0,
363
+ errors: 0,
364
+ envelopeCalls: 0,
365
+ envelopeBytes: 0,
366
+ substitutedCalls: 0,
367
+ resultBytes: 0,
368
+ medianResultBytes: 0,
369
+ resultSizes: [],
370
+ recentCalls: [],
371
+ traceId: span.traceId,
372
+ spanId: span.spanId
373
+ };
374
+ tools.set(key, tool);
375
+ }
376
+ tool.firstSeen = Math.min(tool.firstSeen, span.startTime);
377
+ tool.lastSeen = Math.max(tool.lastSeen, span.startTime);
378
+ tool.sessionId ??= asString(attrs["session.id"]);
379
+ switch (span.name) {
380
+ case REGISTER:
381
+ installations.set(installationKey, true);
382
+ tool.observedAtRegistration = true;
383
+ tool.offered = true;
384
+ tool.descriptionLength = asNumber(attrs["webmcp.tool.description.length"]);
385
+ tool.hasInputSchema = asBoolean(attrs["webmcp.tool.has_input_schema"]);
386
+ tool.annotationsSent = csv(attrs["webmcp.annotations.sent"]);
387
+ tool.annotationsDropped = csv(attrs["webmcp.annotations.dropped"]);
388
+ tool.traceId = span.traceId;
389
+ tool.spanId = span.spanId;
390
+ break;
391
+ case WITHDRAW:
392
+ tool.offered = false;
393
+ break;
394
+ case EXECUTE: {
395
+ if (activityWindow && span.startTime < activityWindow.start) break;
396
+ tool.calls += 1;
397
+ const bytes = asNumber(attrs["webmcp.result.bytes"]) ?? 0;
398
+ tool.resultBytes += bytes;
399
+ tool.resultSizes.push(bytes);
400
+ if (asBoolean(attrs["webmcp.result.envelope"])) {
401
+ tool.envelopeCalls += 1;
402
+ tool.envelopeBytes += ENVELOPE_OVERHEAD_BYTES;
403
+ }
404
+ if (asBoolean(attrs["webmcp.result.substituted"])) tool.substitutedCalls += 1;
405
+ const failed = span.status.code === "ERROR" || (asBoolean(attrs["webmcp.result.error"]) ?? false) || asString(attrs["error.type"]) !== void 0;
406
+ if (failed) tool.errors += 1;
407
+ tool.recentCalls.push({
408
+ timestamp: span.startTime,
409
+ durationMs: span.duration,
410
+ resultBytes: bytes,
411
+ resultType: asString(attrs["webmcp.result.type"]),
412
+ envelope: asBoolean(attrs["webmcp.result.envelope"]) ?? false,
413
+ substituted: asBoolean(attrs["webmcp.result.substituted"]) ?? false,
414
+ error: failed,
415
+ input: asString(attrs["webmcp.input"]) ?? asString(attrs["gen_ai.tool.call.arguments"]),
416
+ result: asString(attrs["webmcp.result"]) ?? asString(attrs["gen_ai.tool.call.result"]),
417
+ traceId: span.traceId,
418
+ spanId: span.spanId
419
+ });
420
+ break;
421
+ }
422
+ }
423
+ }
424
+ const list = [...tools.values()].map((tool) => {
425
+ const { resultSizes, ...rest } = tool;
426
+ return {
427
+ ...rest,
428
+ offered: rest.offered && (latestInstallation.get(rest.service) ?? rest.installationId) === rest.installationId,
429
+ medianResultBytes: median(resultSizes),
430
+ recentCalls: [...tool.recentCalls].sort((a, b) => b.timestamp - a.timestamp).slice(0, RECENT_CALLS)
431
+ };
432
+ });
433
+ list.sort((a, b) => Number(b.offered) - Number(a.offered) || b.calls - a.calls || a.name.localeCompare(b.name));
434
+ return {
435
+ tools: list,
436
+ summary: summarize(list, installations)
437
+ };
438
+ }
439
+ function summarize(tools, installations) {
440
+ const summary = {
441
+ installations: installations.size,
442
+ emptyInstallations: [...installations.values()].filter((saw) => !saw).length,
443
+ toolsOffered: 0,
444
+ toolsWithdrawn: 0,
445
+ calls: 0,
446
+ errors: 0,
447
+ resultBytes: 0,
448
+ envelopeBytes: 0,
449
+ toolsWithDroppedAnnotations: 0,
450
+ toolsWithoutInputSchema: 0
451
+ };
452
+ for (const tool of tools) {
453
+ if (tool.offered) summary.toolsOffered += 1;
454
+ else summary.toolsWithdrawn += 1;
455
+ summary.calls += tool.calls;
456
+ summary.errors += tool.errors;
457
+ summary.resultBytes += tool.resultBytes;
458
+ summary.envelopeBytes += tool.envelopeBytes;
459
+ if (tool.annotationsDropped.length > 0) summary.toolsWithDroppedAnnotations += 1;
460
+ if (tool.observedAtRegistration && tool.hasInputSchema === false) summary.toolsWithoutInputSchema += 1;
461
+ }
462
+ return summary;
463
+ }
464
+
290
465
  //#endregion
291
466
  //#region src/server/telemetry-limits.ts
292
467
  const defaultLimit = 100;
@@ -1499,6 +1674,42 @@ var DevtoolsStore = class {
1499
1674
  LIMIT ?`).all(Math.max(1, Math.min(limit, 500)));
1500
1675
  return [.../* @__PURE__ */ new Set([...Object.keys(schema.columns), ...rows.map((row) => row.key)])];
1501
1676
  }
1677
+ /**
1678
+ * Values of one attribute paired with another on the same entity.
1679
+ *
1680
+ * `searchAttributes` matches on value text, which cannot answer "what arms
1681
+ * does this experiment have". Pairing two keys across the same span can, and
1682
+ * that is what turns a pair of cohorts into something the viewer offers
1683
+ * rather than something the reader has to type.
1684
+ *
1685
+ * Rows arrive grouped by `key`, each group's values commonest first, so a
1686
+ * caller can build the groups in one pass and take the two commonest as a
1687
+ * default pair.
1688
+ *
1689
+ * The join runs over `attribute_occurrences`, not the `attribute_values`
1690
+ * dictionary: occurrences are deleted with their span, so retention prunes
1691
+ * them, and they carry the entity a value was seen on, so an arm is only
1692
+ * offered for the experiment it actually ran under. The dictionary can do
1693
+ * neither — it counts values for the lifetime of the database and forgets
1694
+ * which span each came from, which would offer arms belonging to a different
1695
+ * experiment and experiments whose spans are long gone.
1696
+ */
1697
+ pairedAttributeValues(signal, key, pairedKey, limit = 200) {
1698
+ return this.db.prepare(`
1699
+ SELECT a.value_json AS value_json, b.value_json AS paired_json, count(*) AS count
1700
+ FROM attribute_occurrences a
1701
+ JOIN attribute_occurrences b
1702
+ ON b.signal = a.signal AND b.entity_id = a.entity_id AND b.key = ?
1703
+ WHERE a.signal = ? AND a.key = ?
1704
+ GROUP BY a.value_json, b.value_json
1705
+ ORDER BY value_json ASC, count DESC, paired_json ASC
1706
+ LIMIT ?
1707
+ `).all(pairedKey, signal, key, Math.max(1, Math.min(limit, 500))).map((row) => ({
1708
+ value: JSON.parse(row.value_json),
1709
+ paired: JSON.parse(row.paired_json),
1710
+ count: Number(row.count)
1711
+ }));
1712
+ }
1502
1713
  searchAttributes(signal, value, limit = 50) {
1503
1714
  return this.db.prepare(`
1504
1715
  SELECT key, value_json, seen_count
@@ -2474,11 +2685,15 @@ var DevtoolsServer = class {
2474
2685
  this.log(`Client disconnected (${this.clients.size} total)`);
2475
2686
  });
2476
2687
  });
2477
- if (!options.server) this.httpServer.listen(this._port, () => {
2478
- const addr = this.httpServer.address();
2479
- if (addr && typeof addr === "object") this._port = addr.port;
2480
- this.log(`WebSocket server listening on port ${this._port}`);
2481
- });
2688
+ if (!options.server) {
2689
+ const listening = () => {
2690
+ const addr = this.httpServer.address();
2691
+ if (addr && typeof addr === "object") this._port = addr.port;
2692
+ this.log(`WebSocket server listening on port ${this._port}`);
2693
+ };
2694
+ if (options.host == null) this.httpServer.listen(this._port, listening);
2695
+ else this.httpServer.listen(this._port, options.host, listening);
2696
+ }
2482
2697
  }
2483
2698
  get port() {
2484
2699
  const addr = this.httpServer.address();
@@ -2685,6 +2900,44 @@ var DevtoolsServer = class {
2685
2900
  } while (cursor);
2686
2901
  return { errors: aggregator.getErrorGroups() };
2687
2902
  }
2903
+ /**
2904
+ * Fold WebMCP lifecycle history through the window end into the tool surface
2905
+ * an agent is offered, while counting executions only inside the window.
2906
+ *
2907
+ * Drains every page rather than folding the first one: an inventory built
2908
+ * from a page of results does not fail, it *under-reports* — "2 tools dropped
2909
+ * annotations" when the answer is 6 — and gets more wrong the more traffic
2910
+ * there is, which is backwards for an observability answer.
2911
+ *
2912
+ * The span-name filter is composed here rather than accepted from the client:
2913
+ * this endpoint answers one question, and a caller-supplied predicate could
2914
+ * only narrow it into a wrong answer.
2915
+ */
2916
+ queryWebMcp(args) {
2917
+ const traces = [];
2918
+ const seenCursors = /* @__PURE__ */ new Set();
2919
+ let cursor;
2920
+ do {
2921
+ const result = this.store.queryTraces({
2922
+ query: "name ^ \"webmcp.\"",
2923
+ window: args.window ? {
2924
+ start: 0,
2925
+ end: args.window.end
2926
+ } : void 0,
2927
+ limit: args.limit,
2928
+ cursor
2929
+ });
2930
+ if (result.errors) return {
2931
+ webmcp: foldWebMcpTools([]),
2932
+ errors_parse: result.errors
2933
+ };
2934
+ traces.push(...result.traces);
2935
+ cursor = result.nextCursor ?? void 0;
2936
+ if (cursor && seenCursors.has(cursor)) break;
2937
+ if (cursor) seenCursors.add(cursor);
2938
+ } while (cursor);
2939
+ return { webmcp: foldWebMcpTools(traces, args.window) };
2940
+ }
2688
2941
  /** Run a log query against the durable store. */
2689
2942
  queryLogs(args) {
2690
2943
  return this.store.queryLogs(args);
@@ -2692,6 +2945,9 @@ var DevtoolsServer = class {
2692
2945
  listQueryFields(signal) {
2693
2946
  return this.store.listQueryFields(signal);
2694
2947
  }
2948
+ pairedAttributeValues(signal, key, pairedKey, limit) {
2949
+ return this.store.pairedAttributeValues(signal, key, pairedKey, limit);
2950
+ }
2695
2951
  searchAttributes(signal, value, limit) {
2696
2952
  return this.store.searchAttributes(signal, value, limit);
2697
2953
  }
@@ -3406,6 +3662,12 @@ function attachDevtoolsRoutes(httpServer, devtools, options = {}) {
3406
3662
  }
3407
3663
  const params = new URL(url, "http://localhost").searchParams;
3408
3664
  const signal = params.get("signal") === "logs" ? "logs" : "traces";
3665
+ const key = params.get("key");
3666
+ const pair = params.get("pair");
3667
+ if (key !== null && pair !== null) {
3668
+ sendJson(res, 200, { pairs: devtools.pairedAttributeValues(signal, key, pair) });
3669
+ return;
3670
+ }
3409
3671
  sendJson(res, 200, { attributes: devtools.searchAttributes(signal, params.get("value") ?? "") });
3410
3672
  return;
3411
3673
  }
@@ -3679,6 +3941,30 @@ function attachDevtoolsRoutes(httpServer, devtools, options = {}) {
3679
3941
  }
3680
3942
  return;
3681
3943
  }
3944
+ if (req.method === "POST" && url === "/api/query/webmcp") {
3945
+ if (!allowSensitiveRequest(req.headers, loopbackOnly)) {
3946
+ sendJson(res, 403, { error: "Forbidden" });
3947
+ return;
3948
+ }
3949
+ try {
3950
+ const body = await readJsonBody(req);
3951
+ const result = devtools.queryWebMcp({
3952
+ window: body.window,
3953
+ limit: body.limit
3954
+ });
3955
+ if (result.errors_parse) {
3956
+ sendJson(res, 400, { errors: result.errors_parse });
3957
+ return;
3958
+ }
3959
+ sendJson(res, 200, { webmcp: result.webmcp });
3960
+ } catch (e) {
3961
+ sendJson(res, 400, {
3962
+ error: "Invalid query request",
3963
+ message: e instanceof Error ? e.message : String(e)
3964
+ });
3965
+ }
3966
+ return;
3967
+ }
3682
3968
  if (req.method === "GET" && url === "/api/metrics") {
3683
3969
  if (!allowSensitiveRequest(req.headers, loopbackOnly)) {
3684
3970
  sendJson(res, 403, { error: "Forbidden" });
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_http = require('./http-Cqm_MAtc.cjs');
2
+ const require_http = require('./http-CahjEnpE.cjs');
3
3
  const require_listen = require('./listen-l09RRHht.cjs');
4
4
  const require_server_exporter = require('./server/exporter.cjs');
5
5
  const require_server_log_exporter = require('./server/log-exporter.cjs');
package/dist/index.d.cts CHANGED
@@ -1,9 +1,9 @@
1
- import { n as SpanAttributes, t as AttributeValue } from "./types-DHDvZnnn.cjs";
2
- import { a as SpanData, i as LogData, n as ErrorGroup, o as TraceData, t as DevtoolsData } from "./types-B0tjwFqj.cjs";
3
- import { n as DevtoolsServer, t as DevtoolsSpanExporter } from "./exporter-C4uKgo7l.cjs";
1
+ import { n as SpanAttributes, t as AttributeValue } from "./types-B86Qkqg5.cjs";
2
+ import { a as SpanData, i as LogData, n as ErrorGroup, o as TraceData, t as DevtoolsData } from "./types-C-ORUrT2.cjs";
3
+ import { n as DevtoolsServer, t as DevtoolsSpanExporter } from "./exporter-AkgWRDpc.cjs";
4
4
  import { DevtoolsLogExporter } from "./server/log-exporter.cjs";
5
5
  import { DevtoolsRemoteExporter } from "./server/remote-exporter.cjs";
6
- import { t as ErrorAggregator } from "./error-aggregator-DSwUvgFF.cjs";
6
+ import { t as ErrorAggregator } from "./error-aggregator-C0at0wzF.cjs";
7
7
  import { Server } from "node:http";
8
8
  //#region src/index.d.ts
9
9
  interface CreateDevtoolsOptions {
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { n as SpanAttributes, t as AttributeValue } from "./types-DHDvZnnn.js";
2
- import { a as SpanData, i as LogData, n as ErrorGroup, o as TraceData, t as DevtoolsData } from "./types-DM8y4A9Z.js";
3
- import { n as DevtoolsServer, t as DevtoolsSpanExporter } from "./exporter-BrEcnzoT.js";
1
+ import { n as SpanAttributes, t as AttributeValue } from "./types-B86Qkqg5.js";
2
+ import { a as SpanData, i as LogData, n as ErrorGroup, o as TraceData, t as DevtoolsData } from "./types-BhbHVeiy.js";
3
+ import { n as DevtoolsServer, t as DevtoolsSpanExporter } from "./exporter-yo7lLDIs.js";
4
4
  import { DevtoolsLogExporter } from "./server/log-exporter.js";
5
5
  import { DevtoolsRemoteExporter } from "./server/remote-exporter.js";
6
- import { t as ErrorAggregator } from "./error-aggregator-B52JI8jL.js";
6
+ import { t as ErrorAggregator } from "./error-aggregator-C25_JiVI.js";
7
7
  import { Server } from "node:http";
8
8
  //#region src/index.d.ts
9
9
  interface CreateDevtoolsOptions {
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as ErrorAggregator, g as hostHeaderIsLoopback, l as DevtoolsServer, r as resolveSourceRoot, t as attachDevtoolsRoutes } from "./http-Dbd9TIYU.js";
1
+ import { C as ErrorAggregator, g as hostHeaderIsLoopback, l as DevtoolsServer, r as resolveSourceRoot, t as attachDevtoolsRoutes } from "./http-z8UbJsqk.js";
2
2
  import { t as listenLoopbackDualStack } from "./listen-D-lLgfro.js";
3
3
  import { DevtoolsSpanExporter } from "./server/exporter.js";
4
4
  import { DevtoolsLogExporter } from "./server/log-exporter.js";
@@ -1,2 +1,2 @@
1
- import { t as DevtoolsSpanExporter } from "../exporter-C4uKgo7l.cjs";
1
+ import { t as DevtoolsSpanExporter } from "../exporter-AkgWRDpc.cjs";
2
2
  export { DevtoolsSpanExporter };
@@ -1,2 +1,2 @@
1
- import { t as DevtoolsSpanExporter } from "../exporter-BrEcnzoT.js";
1
+ import { t as DevtoolsSpanExporter } from "../exporter-yo7lLDIs.js";
2
2
  export { DevtoolsSpanExporter };
@@ -1,9 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_http = require('../http-Cqm_MAtc.cjs');
2
+ const require_http = require('../http-CahjEnpE.cjs');
3
3
  const require_server_exporter = require('./exporter.cjs');
4
4
  const require_server_log_exporter = require('./log-exporter.cjs');
5
5
  const require_server_remote_exporter = require('./remote-exporter.cjs');
6
- const require_grpc = require('../grpc-CSWjMRiB.cjs');
6
+ const require_grpc = require('../grpc-CSW1Evnt.cjs');
7
7
 
8
8
  exports.DEVTOOLS_IDENTITY = require_http.DEVTOOLS_IDENTITY;
9
9
  exports.DevtoolsLogExporter = require_server_log_exporter.DevtoolsLogExporter;
@@ -1,9 +1,9 @@
1
- import "../types-DHDvZnnn.cjs";
2
- import { a as SpanData, i as LogData, n as ErrorGroup, o as TraceData, r as ErrorOccurrence, t as DevtoolsData } from "../types-B0tjwFqj.cjs";
3
- import { a as DevtoolsStoreOptions, c as QueryLogsArgs, d as QueryTracesArgs, f as QueryTracesResult, i as DevtoolsStore, l as QueryLogsResult, m as TimeWindow, n as DevtoolsServer, o as MetricCatalogEntry, p as SPAN_SCHEMA, r as DevtoolsServerOptions, s as MetricSeries, t as DevtoolsSpanExporter, u as QueryMetricSeriesArgs } from "../exporter-C4uKgo7l.cjs";
1
+ import "../types-B86Qkqg5.cjs";
2
+ import { a as SpanData, i as LogData, n as ErrorGroup, o as TraceData, r as ErrorOccurrence, t as DevtoolsData } from "../types-C-ORUrT2.cjs";
3
+ import { a as DevtoolsStoreOptions, c as QueryLogsArgs, d as QueryTracesArgs, f as QueryTracesResult, i as DevtoolsStore, l as QueryLogsResult, m as TimeWindow, n as DevtoolsServer, o as MetricCatalogEntry, p as SPAN_SCHEMA, r as DevtoolsServerOptions, s as MetricSeries, t as DevtoolsSpanExporter, u as QueryMetricSeriesArgs } from "../exporter-AkgWRDpc.cjs";
4
4
  import { DevtoolsLogExporter } from "./log-exporter.cjs";
5
5
  import { DevtoolsRemoteExporter, DevtoolsRemoteExporterOptions } from "./remote-exporter.cjs";
6
- import { t as ErrorAggregator } from "../error-aggregator-DSwUvgFF.cjs";
6
+ import { t as ErrorAggregator } from "../error-aggregator-C0at0wzF.cjs";
7
7
  import { AgentRawEvent, OtelMetricRecord } from "autotel-agents";
8
8
  import { Server } from "node:http";
9
9
  //#region src/server/http.d.ts
@@ -1,9 +1,9 @@
1
- import "../types-DHDvZnnn.js";
2
- import { a as SpanData, i as LogData, n as ErrorGroup, o as TraceData, r as ErrorOccurrence, t as DevtoolsData } from "../types-DM8y4A9Z.js";
3
- import { a as DevtoolsStoreOptions, c as QueryLogsArgs, d as QueryTracesArgs, f as QueryTracesResult, i as DevtoolsStore, l as QueryLogsResult, m as TimeWindow, n as DevtoolsServer, o as MetricCatalogEntry, p as SPAN_SCHEMA, r as DevtoolsServerOptions, s as MetricSeries, t as DevtoolsSpanExporter, u as QueryMetricSeriesArgs } from "../exporter-BrEcnzoT.js";
1
+ import "../types-B86Qkqg5.js";
2
+ import { a as SpanData, i as LogData, n as ErrorGroup, o as TraceData, r as ErrorOccurrence, t as DevtoolsData } from "../types-BhbHVeiy.js";
3
+ import { a as DevtoolsStoreOptions, c as QueryLogsArgs, d as QueryTracesArgs, f as QueryTracesResult, i as DevtoolsStore, l as QueryLogsResult, m as TimeWindow, n as DevtoolsServer, o as MetricCatalogEntry, p as SPAN_SCHEMA, r as DevtoolsServerOptions, s as MetricSeries, t as DevtoolsSpanExporter, u as QueryMetricSeriesArgs } from "../exporter-yo7lLDIs.js";
4
4
  import { DevtoolsLogExporter } from "./log-exporter.js";
5
5
  import { DevtoolsRemoteExporter, DevtoolsRemoteExporterOptions } from "./remote-exporter.js";
6
- import { t as ErrorAggregator } from "../error-aggregator-B52JI8jL.js";
6
+ import { t as ErrorAggregator } from "../error-aggregator-C25_JiVI.js";
7
7
  import { Server } from "node:http";
8
8
  import { AgentRawEvent, OtelMetricRecord } from "autotel-agents";
9
9
  //#region src/server/http.d.ts
@@ -1,7 +1,7 @@
1
- import { C as ErrorAggregator, S as resolveTelemetryLimits, _ as isLoopbackHostname, a as probePortHolder, b as appendWithLimit, c as decodeOtlpTraceRequest, d as parseOtlpLogs, f as parseOtlpTraces, g as hostHeaderIsLoopback, h as allowSensitiveRequest, i as DEVTOOLS_IDENTITY, l as DevtoolsServer, m as SPAN_SCHEMA, n as createDevtoolsHttpServer, o as decodeOtlpLogsRequest, p as DevtoolsStore, s as decodeOtlpMetricsRequest, t as attachDevtoolsRoutes, u as isProtobufContentType, v as originIsLoopback, x as applyTelemetryLimits, y as appendManyWithLimit } from "../http-Dbd9TIYU.js";
1
+ import { C as ErrorAggregator, S as resolveTelemetryLimits, _ as isLoopbackHostname, a as probePortHolder, b as appendWithLimit, c as decodeOtlpTraceRequest, d as parseOtlpLogs, f as parseOtlpTraces, g as hostHeaderIsLoopback, h as allowSensitiveRequest, i as DEVTOOLS_IDENTITY, l as DevtoolsServer, m as SPAN_SCHEMA, n as createDevtoolsHttpServer, o as decodeOtlpLogsRequest, p as DevtoolsStore, s as decodeOtlpMetricsRequest, t as attachDevtoolsRoutes, u as isProtobufContentType, v as originIsLoopback, x as applyTelemetryLimits, y as appendManyWithLimit } from "../http-z8UbJsqk.js";
2
2
  import { DevtoolsSpanExporter } from "./exporter.js";
3
3
  import { DevtoolsLogExporter } from "./log-exporter.js";
4
4
  import { DevtoolsRemoteExporter } from "./remote-exporter.js";
5
- import { t as startOtlpGrpcReceiver } from "../grpc-CZEDUYCM.js";
5
+ import { t as startOtlpGrpcReceiver } from "../grpc-D1tt8UPi.js";
6
6
 
7
7
  export { DEVTOOLS_IDENTITY, DevtoolsLogExporter, DevtoolsRemoteExporter, DevtoolsServer, DevtoolsSpanExporter, DevtoolsStore, ErrorAggregator, SPAN_SCHEMA, allowSensitiveRequest, appendManyWithLimit, appendWithLimit, applyTelemetryLimits, attachDevtoolsRoutes, createDevtoolsHttpServer, decodeOtlpLogsRequest, decodeOtlpMetricsRequest, decodeOtlpTraceRequest, hostHeaderIsLoopback, isLoopbackHostname, isProtobufContentType, originIsLoopback, parseOtlpLogs, parseOtlpTraces, probePortHolder, resolveTelemetryLimits, startOtlpGrpcReceiver };
@@ -0,0 +1,120 @@
1
+ import { AgentSession } from "autotel-agents";
2
+ //#region src/widget/types.d.ts
3
+ /**
4
+ * What a span attribute holds once it has crossed OTLP. The widget is
5
+ * browser-safe and does not depend on the OTel API package, so the value type
6
+ * is named here rather than imported.
7
+ */
8
+ type AttributeValue = string | number | boolean | null | undefined | Uint8Array | Array<AttributeValue> | {
9
+ [key: string]: AttributeValue;
10
+ };
11
+ /**
12
+ * A span's attribute bag as the devtools receives it. Wider than OpenTelemetry's
13
+ * own `Attributes` on purpose: OTLP's kvlist and array values decode to nested
14
+ * maps and lists, and the devtools displays whatever actually arrived.
15
+ */
16
+ type SpanAttributes = Record<string, AttributeValue>;
17
+ interface SpanData {
18
+ traceId: string;
19
+ spanId: string;
20
+ parentSpanId?: string;
21
+ name: string;
22
+ kind: 'INTERNAL' | 'SERVER' | 'CLIENT' | 'PRODUCER' | 'CONSUMER';
23
+ startTime: number;
24
+ endTime: number;
25
+ duration: number;
26
+ attributes: SpanAttributes;
27
+ status: {
28
+ code: 'OK' | 'ERROR' | 'UNSET';
29
+ message?: string;
30
+ };
31
+ events?: Array<{
32
+ name: string;
33
+ timestamp: number;
34
+ attributes?: SpanAttributes;
35
+ }>;
36
+ links?: Array<{
37
+ traceId: string;
38
+ spanId: string;
39
+ attributes?: SpanAttributes;
40
+ }>;
41
+ scope?: {
42
+ name?: string;
43
+ version?: string;
44
+ };
45
+ }
46
+ /**
47
+ * The WebMCP tool surface, as folded by `server/webmcp-aggregator`.
48
+ *
49
+ * A tool is not a span: it is a name whose lifecycle spans a registration, any
50
+ * number of executions and possibly a withdrawal, and it is only meaningful
51
+ * within the installation (page load) that registered it.
52
+ */
53
+ interface WebMcpCall {
54
+ timestamp: number;
55
+ durationMs: number;
56
+ resultBytes: number;
57
+ resultType?: string;
58
+ envelope: boolean;
59
+ substituted: boolean;
60
+ error: boolean;
61
+ /** Present only when the app opted into payload capture. Render masked. */
62
+ input?: string;
63
+ /** The exact string the agent received. Present only with payload capture. */
64
+ result?: string;
65
+ traceId: string;
66
+ spanId: string;
67
+ }
68
+ interface WebMcpTool {
69
+ name: string;
70
+ /** Installation (page load) this record belongs to. */
71
+ installationId: string;
72
+ service: string;
73
+ sessionId?: string;
74
+ /** False when the tool was only ever seen executing — see the module note. */
75
+ observedAtRegistration: boolean;
76
+ /** True while the tool is offered: registered, and not since withdrawn. */
77
+ offered: boolean;
78
+ firstSeen: number;
79
+ lastSeen: number;
80
+ descriptionLength?: number;
81
+ hasInputSchema?: boolean;
82
+ annotationsSent: string[];
83
+ /** Annotations the browser discarded. Available nowhere else. */
84
+ annotationsDropped: string[];
85
+ calls: number;
86
+ errors: number;
87
+ /** Executions whose result was an unwrapped MCP `{ content: [...] }` envelope. */
88
+ envelopeCalls: number;
89
+ /** Of `resultBytes`, the part that is envelope wrapper rather than content. */
90
+ envelopeBytes: number;
91
+ /** Executions where the browser replaced an empty result with its own text. */
92
+ substitutedCalls: number;
93
+ /** UTF-8 bytes of result the agent has paid for across every call. */
94
+ resultBytes: number;
95
+ medianResultBytes: number;
96
+ /** The last few executions, newest first. Bounded — this is not a call log. */
97
+ recentCalls: WebMcpCall[];
98
+ traceId?: string;
99
+ spanId?: string;
100
+ }
101
+ interface WebMcpSummary {
102
+ installations: number;
103
+ /** Installations that registered nothing — the "instrumented too late" signature. */
104
+ emptyInstallations: number;
105
+ toolsOffered: number;
106
+ toolsWithdrawn: number;
107
+ calls: number;
108
+ errors: number;
109
+ resultBytes: number;
110
+ /** Bytes that are envelope wrapper rather than content. See `envelopeOverhead`. */
111
+ envelopeBytes: number;
112
+ toolsWithDroppedAnnotations: number;
113
+ toolsWithoutInputSchema: number;
114
+ }
115
+ interface WebMcpInventory {
116
+ tools: WebMcpTool[];
117
+ summary: WebMcpSummary;
118
+ }
119
+ //#endregion
120
+ export { WebMcpInventory as i, SpanAttributes as n, SpanData as r, AttributeValue as t };