@neta-art/cohub 1.10.1 → 1.10.2

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.
@@ -185,6 +185,9 @@ type WebsocketClientEvents = {
185
185
  clientMessageId?: string | null;
186
186
  sessionId?: string | null;
187
187
  spaceId?: string | null;
188
+ turnId?: string | null;
189
+ userMessageId?: string | null;
190
+ traceId?: string | null;
188
191
  };
189
192
  serverError: {
190
193
  code?: string;
@@ -404,7 +404,10 @@ var WebsocketClient = class {
404
404
  requestId: envelope.requestId ?? null,
405
405
  sessionId: envelope.sessionId ?? null,
406
406
  spaceId: envelope.spaceId ?? null,
407
- clientMessageId: typeof payload.clientMessageId === "string" ? payload.clientMessageId : null
407
+ clientMessageId: typeof payload.clientMessageId === "string" ? payload.clientMessageId : null,
408
+ turnId: typeof payload.turnId === "string" ? payload.turnId : null,
409
+ userMessageId: typeof payload.userMessageId === "string" ? payload.userMessageId : null,
410
+ traceId: typeof payload.traceId === "string" ? payload.traceId : null
408
411
  });
409
412
  this.emit("event", envelope);
410
413
  return;
package/dist/debugger.js CHANGED
@@ -91,6 +91,7 @@ function installFetchCollector(state) {
91
91
  const connectionId = nextConnectionId(state, "fetch");
92
92
  const startedAtMs = Date.now();
93
93
  const requestInfo = normalizeFetchRequest(input, init, state.options);
94
+ state.instrumentedRequestUrls.add(requestInfo.url);
94
95
  appendNetwork(state, {
95
96
  connectionId,
96
97
  kind: "fetch",
@@ -105,19 +106,21 @@ function installFetchCollector(state) {
105
106
  try {
106
107
  const response = await originalFetch(input, init);
107
108
  const durationMs = Date.now() - startedAtMs;
109
+ const responseUrl = normalizeHarUrl(response.url || requestInfo.url);
110
+ state.instrumentedRequestUrls.add(responseUrl);
108
111
  const responseHeaders = state.options.captureHeaders ? headersToRecord(response.headers, state.options) : void 0;
109
112
  appendNetwork(state, {
110
113
  connectionId,
111
114
  kind: "fetch",
112
115
  phase: "response",
113
116
  method: requestInfo.method,
114
- url: response.url || requestInfo.url,
117
+ url: responseUrl,
115
118
  status: response.status,
116
119
  statusText: response.statusText,
117
120
  durationMs,
118
121
  responseHeaders
119
122
  });
120
- collectFetchResponseBody(state, connectionId, requestInfo.method, response.url || requestInfo.url, response);
123
+ collectFetchResponseBody(state, connectionId, requestInfo.method, responseUrl, response);
121
124
  return response;
122
125
  } catch (error) {
123
126
  appendNetwork(state, {
@@ -144,15 +147,17 @@ function installXhrCollector(state) {
144
147
  state.originals.xhrSend = originalSend;
145
148
  state.originals.xhrSetRequestHeader = originalSetRequestHeader;
146
149
  XMLHttpRequest.prototype.open = function open(method, url, async, username, password) {
150
+ const normalizedUrl = normalizeHarUrl(String(url));
147
151
  metadata.set(this, {
148
152
  id: nextConnectionId(state, "xhr"),
149
153
  method: method.toUpperCase(),
150
- url: String(url),
154
+ url: normalizedUrl,
151
155
  requestHeaders: {},
152
156
  responseLineCount: 0,
153
157
  lastResponseLength: 0,
154
158
  pendingResponseLine: ""
155
159
  });
160
+ state.instrumentedRequestUrls.add(normalizedUrl);
156
161
  return originalOpen.call(this, method, url, async ?? true, username, password);
157
162
  };
158
163
  XMLHttpRequest.prototype.setRequestHeader = function setRequestHeader(name, value) {
@@ -237,10 +242,11 @@ function installEventSourceCollector(state) {
237
242
  state.originals.EventSource = OriginalEventSource;
238
243
  const InstrumentedEventSource = function EventSource(url, eventSourceInitDict) {
239
244
  const connectionId = nextConnectionId(state, "eventsource");
245
+ const sourceUrl = normalizeHarUrl(String(url));
240
246
  const source = new OriginalEventSource(url, eventSourceInitDict);
241
- const sourceUrl = String(url);
242
247
  let lineNumber = 0;
243
248
  const listenerRecords = [];
249
+ state.instrumentedRequestUrls.add(sourceUrl);
244
250
  const appendEventSourceMessage = (eventName, event) => {
245
251
  appendLines(state, {
246
252
  connectionId,
@@ -322,8 +328,9 @@ function installWebSocketCollector(state) {
322
328
  state.originals.WebSocket = OriginalWebSocket;
323
329
  const InstrumentedWebSocket = function WebSocket(url, protocols) {
324
330
  const connectionId = nextConnectionId(state, "websocket");
331
+ const socketUrl = normalizeHarUrl(String(url), "websocket");
332
+ state.instrumentedRequestUrls.add(socketUrl);
325
333
  const socket = protocols === void 0 ? new OriginalWebSocket(url) : new OriginalWebSocket(url, protocols);
326
- const socketUrl = String(url);
327
334
  let lineNumber = 0;
328
335
  let userOnOpen = null;
329
336
  let userOnMessage = null;
@@ -472,6 +479,8 @@ function collectPerformanceResources(state, entries) {
472
479
  const key = `${entry.name}:${entry.startTime}:${entry.duration}`;
473
480
  if (state.performanceResourceKeys.has(key)) continue;
474
481
  state.performanceResourceKeys.add(key);
482
+ const normalizedEntryUrl = normalizeHarUrl(entry.name);
483
+ if (state.instrumentedRequestUrls.has(normalizedEntryUrl)) continue;
475
484
  const initiatorType = entry.initiatorType || "resource";
476
485
  const kind = resourceKindFromInitiator(initiatorType, entry.name);
477
486
  appendNetwork(state, {
@@ -479,7 +488,7 @@ function collectPerformanceResources(state, entries) {
479
488
  kind,
480
489
  phase: "response",
481
490
  method: "GET",
482
- url: entry.name,
491
+ url: normalizedEntryUrl,
483
492
  status: entry.responseStatus || void 0,
484
493
  durationMs: Math.round(entry.duration),
485
494
  source: "performance",
@@ -592,18 +601,15 @@ function collectXhrResponseLines(state, xhr, meta, flush = false) {
592
601
  meta.lastResponseLength = text.length;
593
602
  const parts = `${meta.pendingResponseLine}${nextChunk}`.split(/\r?\n/);
594
603
  meta.pendingResponseLine = parts.pop() ?? "";
595
- for (const line of parts) {
596
- if (!line) continue;
597
- appendLine(state, {
598
- connectionId: meta.id,
599
- kind: "xhr",
600
- method: meta.method,
601
- url: meta.url,
602
- direction: "incoming",
603
- lineNumber: nextXhrLineNumber(meta),
604
- text: line
605
- });
606
- }
604
+ for (const line of parts) appendLine(state, {
605
+ connectionId: meta.id,
606
+ kind: "xhr",
607
+ method: meta.method,
608
+ url: meta.url,
609
+ direction: "incoming",
610
+ lineNumber: nextXhrLineNumber(meta),
611
+ text: line
612
+ });
607
613
  if (flush && meta.pendingResponseLine) {
608
614
  const line = meta.pendingResponseLine;
609
615
  meta.pendingResponseLine = "";
@@ -674,7 +680,7 @@ function nextXhrLineNumber(meta) {
674
680
  function normalizeFetchRequest(input, init, options) {
675
681
  const request = typeof Request !== "undefined" && input instanceof Request ? input : void 0;
676
682
  const method = (init?.method ?? request?.method ?? "GET").toUpperCase();
677
- const url = typeof Request !== "undefined" && input instanceof Request ? input.url : typeof URL !== "undefined" && input instanceof URL ? input.href : String(input);
683
+ const url = typeof Request !== "undefined" && input instanceof Request ? input.url : typeof URL !== "undefined" && input instanceof URL ? input.href : normalizeHarUrl(String(input));
678
684
  const headers = options.captureHeaders ? mergeHeaders(request?.headers, init?.headers, options) : void 0;
679
685
  const bodyPreview = options.captureRequestBody ? serializeBodyPreview(init?.body, options) : void 0;
680
686
  return {
@@ -898,7 +904,10 @@ function createHarEntry(pageId, entries) {
898
904
  const requestBodyEntry = sortedEntries.find((entry) => entry.phase === "request" && entry.payload !== void 0);
899
905
  const responseBodyEntry = [...messageEntries].reverse().find((entry) => entry.direction === "incoming");
900
906
  const durationMs = Math.max(responseEntry.durationMs ?? responseEntry.elapsedMs - requestEntry.elapsedMs, 0);
901
- const responseText = responseEntry.kind === "websocket" ? void 0 : messageEntries.filter((entry) => entry.direction !== "outgoing").map((entry) => payloadToText(entry.payload)).filter(Boolean).join("\n");
907
+ const responseText = responseEntry.kind === "websocket" ? void 0 : messageEntries.length > 0 ? messageEntries.filter((entry) => entry.direction !== "outgoing").map((entry) => payloadToText(entry.payload)).join("\n") : void 0;
908
+ const contentType = guessMimeType(responseEntry.responseHeaders);
909
+ const normalizedResponseText = responseText !== void 0 && contentType.toLowerCase().includes("text/event-stream") ? normalizeEventStreamText(responseText) : responseText;
910
+ const responseContentSize = normalizedResponseText !== void 0 ? byteLength(normalizedResponseText) : responseBodyEntry?.sizeBytes ?? responseEntry.sizeBytes ?? -1;
902
911
  return {
903
912
  pageref: pageId,
904
913
  startedDateTime: requestEntry.at,
@@ -925,13 +934,13 @@ function createHarEntry(pageId, entries) {
925
934
  cookies: [],
926
935
  headers: headersRecordToHarPairs(responseEntry.responseHeaders),
927
936
  content: {
928
- size: responseBodyEntry?.sizeBytes ?? responseEntry.sizeBytes ?? -1,
929
- mimeType: guessMimeType(responseEntry.responseHeaders),
930
- text: responseText || void 0
937
+ size: responseContentSize,
938
+ mimeType: contentType,
939
+ text: normalizedResponseText === void 0 ? void 0 : normalizedResponseText
931
940
  },
932
941
  redirectURL: "",
933
942
  headersSize: -1,
934
- bodySize: responseBodyEntry?.sizeBytes ?? responseEntry.sizeBytes ?? -1
943
+ bodySize: responseContentSize
935
944
  },
936
945
  cache: {},
937
946
  timings: {
@@ -954,6 +963,11 @@ function createHarEntry(pageId, entries) {
954
963
  _webSocketMessages: firstEntry.kind === "websocket" ? createWebSocketMessages(messageEntries) : void 0
955
964
  };
956
965
  }
966
+ function normalizeEventStreamText(text) {
967
+ if (!text) return text;
968
+ if (text.endsWith("\n\n")) return text;
969
+ return text.endsWith("\n") ? `${text}\n` : text;
970
+ }
957
971
  function headersRecordToHarPairs(headers) {
958
972
  return Object.entries(headers ?? {}).map(([name, value]) => ({
959
973
  name,
@@ -1037,6 +1051,7 @@ function getOrCreateState(options = {}) {
1037
1051
  startedAt: new Date(startedAtMs).toISOString(),
1038
1052
  consoleBuffer: createRingBuffer(normalizedOptions.maxConsoleEntries),
1039
1053
  networkBuffer: createRingBuffer(normalizedOptions.maxNetworkEntries),
1054
+ instrumentedRequestUrls: /* @__PURE__ */ new Set(),
1040
1055
  performanceResourceKeys: /* @__PURE__ */ new Set(),
1041
1056
  nextConsoleId: 1,
1042
1057
  nextNetworkId: 1,
@@ -1062,6 +1077,17 @@ function nextConnectionId(state, kind) {
1062
1077
  state.nextConnectionId += 1;
1063
1078
  return id;
1064
1079
  }
1080
+ function normalizeHarUrl(url, mode = "http") {
1081
+ if (typeof URL === "undefined") return url;
1082
+ const baseUrl = typeof location !== "undefined" && location.href ? location.href : "http://localhost/";
1083
+ try {
1084
+ const normalizedUrl = new URL(url, baseUrl);
1085
+ if (mode === "websocket" && (normalizedUrl.protocol === "http:" || normalizedUrl.protocol === "https:")) normalizedUrl.protocol = normalizedUrl.protocol === "https:" ? "wss:" : "ws:";
1086
+ return normalizedUrl.href;
1087
+ } catch {
1088
+ return url;
1089
+ }
1090
+ }
1065
1091
  function headersToRecord(headers, options) {
1066
1092
  const record = {};
1067
1093
  headers.forEach((value, key) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neta-art/cohub",
3
- "version": "1.10.1",
3
+ "version": "1.10.2",
4
4
  "description": "Cohub SDK for spaces, sessions, checkpoints, and realtime agent collaboration.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,