@copilotkit/web-inspector 1.61.1 → 1.61.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.
package/dist/index.umd.js CHANGED
@@ -189,17 +189,45 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
189
189
  });
190
190
  }
191
191
 
192
+ //#endregion
193
+ //#region package.json
194
+ var version = "1.61.2";
195
+
192
196
  //#endregion
193
197
  //#region src/lib/telemetry.ts
194
198
  const TELEMETRY_EVENTS = {
195
199
  bannerViewed: "oss.inspector.banner_viewed",
196
200
  bannerClicked: "oss.inspector.banner_clicked",
197
- threadsTabClicked: "oss.inspector.threads_tab_clicked"
201
+ threadsTabClicked: "oss.inspector.threads_tab_clicked",
202
+ threadsLockedViewed: "oss.inspector.threads_locked_viewed",
203
+ threadsIntelligenceSignupClicked: "oss.inspector.threads_intelligence_signup_clicked",
204
+ threadsTalkToEngineerClicked: "oss.inspector.threads_talk_to_engineer_clicked",
205
+ talkToEngineerClicked: "oss.inspector.talk_to_engineer_clicked",
206
+ threadsEmptyEnabledViewed: "oss.inspector.threads_empty_enabled_viewed",
207
+ threadsEnabledViewed: "oss.inspector.threads_enabled_viewed"
198
208
  };
199
209
  const TELEMETRY_INGEST_URL = "https://telemetry.copilotkit.ai/ingest";
200
210
  const TELEMETRY_DOCS_URL = "https://docs.copilotkit.ai/telemetry";
201
211
  const PACKAGE_NAME = "@copilotkit/web-inspector";
212
+ const PACKAGE_VERSION = version;
202
213
  const FETCH_TIMEOUT_MS = 3e3;
214
+ function isThreadsTelemetryEvent(event) {
215
+ return event === TELEMETRY_EVENTS.threadsTabClicked || event === TELEMETRY_EVENTS.threadsLockedViewed || event === TELEMETRY_EVENTS.threadsIntelligenceSignupClicked || event === TELEMETRY_EVENTS.threadsTalkToEngineerClicked || event === TELEMETRY_EVENTS.talkToEngineerClicked || event === TELEMETRY_EVENTS.threadsEmptyEnabledViewed || event === TELEMETRY_EVENTS.threadsEnabledViewed;
216
+ }
217
+ function getRuntimeUrlType(runtimeUrl) {
218
+ if (!runtimeUrl) return "missing";
219
+ if (runtimeUrl.startsWith("/") && !runtimeUrl.startsWith("//")) return "relative";
220
+ try {
221
+ const baseHref = typeof window !== "undefined" ? window.location.href : "https://copilotkit.ai";
222
+ const url = new URL(runtimeUrl, baseHref);
223
+ const baseUrl = new URL(baseHref);
224
+ const hostname = url.hostname.toLowerCase();
225
+ if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]") return "localhost";
226
+ return url.origin === baseUrl.origin ? "same_origin" : "remote";
227
+ } catch (_unused) {
228
+ return "invalid";
229
+ }
230
+ }
203
231
  /**
204
232
  * Fire-and-forget telemetry send. Returns synchronously; the network
205
233
  * call is dispatched in the background and any failure is swallowed.
@@ -209,16 +237,32 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
209
237
  * inspector's mount lifecycle instead.
210
238
  */
211
239
  function track(event, properties = {}) {
240
+ if (isTelemetryOptedOut()) return;
212
241
  const distinctId = getOrCreateTelemetryDistinctId();
213
- postBestEffort(TELEMETRY_INGEST_URL, JSON.stringify({
214
- event,
215
- properties: {
216
- ...properties,
217
- distinct_id: distinctId
218
- },
219
- package: { name: PACKAGE_NAME },
220
- ts: Math.floor(Date.now() / 1e3)
221
- }), distinctId);
242
+ const threadsProperties = isThreadsTelemetryEvent(event) ? {
243
+ package_name: PACKAGE_NAME,
244
+ package_version: PACKAGE_VERSION,
245
+ inspector_distinct_id: distinctId
246
+ } : {};
247
+ let body;
248
+ try {
249
+ body = JSON.stringify({
250
+ event,
251
+ properties: {
252
+ ...properties,
253
+ ...threadsProperties,
254
+ distinct_id: distinctId
255
+ },
256
+ package: {
257
+ name: PACKAGE_NAME,
258
+ ...isThreadsTelemetryEvent(event) ? { version: PACKAGE_VERSION } : {}
259
+ },
260
+ ts: Math.floor(Date.now() / 1e3)
261
+ });
262
+ } catch (_unused2) {
263
+ return;
264
+ }
265
+ postBestEffort(TELEMETRY_INGEST_URL, body, distinctId);
222
266
  }
223
267
  function trackBannerViewed(props) {
224
268
  track(TELEMETRY_EVENTS.bannerViewed, props);
@@ -226,8 +270,26 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
226
270
  function trackBannerClicked(props) {
227
271
  track(TELEMETRY_EVENTS.bannerClicked, props);
228
272
  }
229
- function trackThreadsTabClicked() {
230
- track(TELEMETRY_EVENTS.threadsTabClicked);
273
+ function trackThreadsTabClicked(props = {}) {
274
+ track(TELEMETRY_EVENTS.threadsTabClicked, props);
275
+ }
276
+ function trackThreadsLockedViewed(props) {
277
+ track(TELEMETRY_EVENTS.threadsLockedViewed, props);
278
+ }
279
+ function trackThreadsIntelligenceSignupClicked(props) {
280
+ track(TELEMETRY_EVENTS.threadsIntelligenceSignupClicked, props);
281
+ }
282
+ function trackThreadsTalkToEngineerClicked(props) {
283
+ track(TELEMETRY_EVENTS.threadsTalkToEngineerClicked, props);
284
+ }
285
+ function trackTalkToEngineerClicked(props) {
286
+ track(TELEMETRY_EVENTS.talkToEngineerClicked, props);
287
+ }
288
+ function trackThreadsEmptyEnabledViewed(props) {
289
+ track(TELEMETRY_EVENTS.threadsEmptyEnabledViewed, props);
290
+ }
291
+ function trackThreadsEnabledViewed(props) {
292
+ track(TELEMETRY_EVENTS.threadsEnabledViewed, props);
231
293
  }
232
294
  /**
233
295
  * Returns the inspector's anonymous distinct-ID for cross-domain
@@ -286,7 +348,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
286
348
  body,
287
349
  signal: controller.signal
288
350
  });
289
- } catch (_unused) {} finally {
351
+ } catch (_unused3) {} finally {
290
352
  clearTimeout(timeoutId);
291
353
  }
292
354
  }
@@ -313,6 +375,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
313
375
  const DOCKED_LEFT_WIDTH = 500;
314
376
  const MAX_AGENT_EVENTS = 200;
315
377
  const MAX_TOTAL_EVENTS = 500;
378
+ const INTELLIGENCE_SIGNUP_URL = "https://go.copilotkit.ai/intelligence-signup";
379
+ const TALK_TO_ENGINEER_URL = "https://www.copilotkit.ai/talk-to-an-engineer";
316
380
  const AGENT_EVENT_TYPES = [
317
381
  "RUN_STARTED",
318
382
  "RUN_FINISHED",
@@ -388,14 +452,14 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
388
452
  bg: "rgba(190,194,255,0.102)",
389
453
  fg: "#5558B2"
390
454
  };
455
+ if (type === "RUN_ERROR" || type === "ERROR") return {
456
+ bg: "rgba(250,95,103,0.13)",
457
+ fg: "#c0333a"
458
+ };
391
459
  if (type.startsWith("RUN_") || type.startsWith("STEP_")) return {
392
460
  bg: "rgba(255,172,77,0.2)",
393
461
  fg: "#996300"
394
462
  };
395
- if (type === "ERROR") return {
396
- bg: "rgba(250,95,103,0.13)",
397
- fg: "#c0333a"
398
- };
399
463
  return {
400
464
  bg: "#F7F7F9",
401
465
  fg: "#838389"
@@ -821,7 +885,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
821
885
  this._messagesError = null;
822
886
  }
823
887
  try {
824
- const res = await fetch(`${this.runtimeUrl}/threads/${encodeURIComponent(threadId)}/messages`, {
888
+ const res = await fetch(this.getThreadInspectionUrl(threadId, "messages"), {
825
889
  headers: { ...this.headers },
826
890
  signal: controller.signal
827
891
  });
@@ -851,7 +915,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
851
915
  this._loadingEvents = true;
852
916
  this._eventsError = null;
853
917
  try {
854
- const res = await fetch(`${this.runtimeUrl}/threads/${encodeURIComponent(threadId)}/events`, {
918
+ const res = await fetch(this.getThreadInspectionUrl(threadId, "events"), {
855
919
  headers: { ...this.headers },
856
920
  signal: controller.signal
857
921
  });
@@ -886,7 +950,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
886
950
  this._stateError = null;
887
951
  try {
888
952
  var _data$state;
889
- const res = await fetch(`${this.runtimeUrl}/threads/${encodeURIComponent(threadId)}/state`, {
953
+ const res = await fetch(this.getThreadInspectionUrl(threadId, "state"), {
890
954
  headers: { ...this.headers },
891
955
  signal: controller.signal
892
956
  });
@@ -909,6 +973,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
909
973
  if (!controller.signal.aborted && this.threadId === threadId) this._loadingState = false;
910
974
  }
911
975
  }
976
+ getThreadInspectionUrl(threadId, resource) {
977
+ return `${this.runtimeUrl.replace(/\/+$/, "")}/threads/${encodeURIComponent(threadId)}/${resource}`;
978
+ }
912
979
  mapMessages(messages) {
913
980
  const items = [];
914
981
  const toolCallMap = /* @__PURE__ */ new Map();
@@ -2167,6 +2234,7 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2167
2234
  this.viewedBannerTimestamps = /* @__PURE__ */ new Set();
2168
2235
  this.pendingBannerViewed = null;
2169
2236
  this.clickedBannerIds = /* @__PURE__ */ new Set();
2237
+ this.viewedThreadsTelemetryStates = /* @__PURE__ */ new Set();
2170
2238
  this.contextState = {
2171
2239
  button: {
2172
2240
  position: {
@@ -2376,6 +2444,30 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2376
2444
  this.expandedTools = /* @__PURE__ */ new Set();
2377
2445
  this.expandedContextItems = /* @__PURE__ */ new Set();
2378
2446
  this.copiedContextItems = /* @__PURE__ */ new Set();
2447
+ this.handleTalkToEngineerClick = () => {
2448
+ var _this$core;
2449
+ if ((_this$core = this.core) === null || _this$core === void 0 ? void 0 : _this$core.telemetryDisabled) return;
2450
+ trackTalkToEngineerClicked(this.getThreadsTelemetryProps({
2451
+ cta: "talk_to_engineer",
2452
+ cta_surface: "threads_header"
2453
+ }, { includeUrlAttribution: true }));
2454
+ };
2455
+ this.handleThreadsIntelligenceSignupClick = () => {
2456
+ var _this$core2;
2457
+ if ((_this$core2 = this.core) === null || _this$core2 === void 0 ? void 0 : _this$core2.telemetryDisabled) return;
2458
+ trackThreadsIntelligenceSignupClicked(this.getThreadsTelemetryProps({
2459
+ cta: "signup",
2460
+ cta_surface: "threads_locked"
2461
+ }, { includeUrlAttribution: true }));
2462
+ };
2463
+ this.handleThreadsTalkToEngineerClick = () => {
2464
+ var _this$core3;
2465
+ if ((_this$core3 = this.core) === null || _this$core3 === void 0 ? void 0 : _this$core3.telemetryDisabled) return;
2466
+ trackThreadsTalkToEngineerClicked(this.getThreadsTelemetryProps({
2467
+ cta: "talk_to_engineer",
2468
+ cta_surface: "threads_locked"
2469
+ }, { includeUrlAttribution: true }));
2470
+ };
2379
2471
  this.handleThreadDividerPointerDown = (event) => {
2380
2472
  this.threadDividerResizing = true;
2381
2473
  this.threadDividerPointerId = event.pointerId;
@@ -2498,7 +2590,38 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2498
2590
  }
2499
2591
  ];
2500
2592
  }
2593
+ getThreadServiceStatus() {
2594
+ var _this$_core$threadEnd;
2595
+ if (!this._core) return "unknown";
2596
+ if (!this._core.threadEndpoints) return "unknown";
2597
+ return ((_this$_core$threadEnd = this._core.threadEndpoints) === null || _this$_core$threadEnd === void 0 ? void 0 : _this$_core$threadEnd.list) === false ? "unavailable" : "available";
2598
+ }
2599
+ areThreadEndpointsAvailable() {
2600
+ return this.getThreadServiceStatus() !== "unavailable";
2601
+ }
2602
+ getThreadsTelemetryProps(extra = {}, options = {}) {
2603
+ var _this$core4, _this$core$licenseSta, _this$core5, _this$core$runtimeMod, _this$core6, _this$core7, _this$core$telemetryD, _this$core8;
2604
+ const distinctId = options.includeUrlAttribution && !((_this$core4 = this.core) === null || _this$core4 === void 0 ? void 0 : _this$core4.telemetryDisabled) ? getTelemetryDistinctIdForUrl() : null;
2605
+ const threadServiceStatus = this.getThreadServiceStatus();
2606
+ return {
2607
+ posthog_distinct_id: distinctId !== null && distinctId !== void 0 ? distinctId : void 0,
2608
+ intelligence_status: threadServiceStatus === "available" ? "intelligence_enabled" : threadServiceStatus === "unavailable" ? "intelligence_not_enabled" : "unknown",
2609
+ thread_service_status: threadServiceStatus,
2610
+ license_status: (_this$core$licenseSta = (_this$core5 = this.core) === null || _this$core5 === void 0 ? void 0 : _this$core5.licenseStatus) !== null && _this$core$licenseSta !== void 0 ? _this$core$licenseSta : void 0,
2611
+ runtime_mode: (_this$core$runtimeMod = (_this$core6 = this.core) === null || _this$core6 === void 0 ? void 0 : _this$core6.runtimeMode) !== null && _this$core$runtimeMod !== void 0 ? _this$core$runtimeMod : void 0,
2612
+ runtime_url_type: getRuntimeUrlType((_this$core7 = this.core) === null || _this$core7 === void 0 ? void 0 : _this$core7.runtimeUrl),
2613
+ telemetry_disabled: (_this$core$telemetryD = (_this$core8 = this.core) === null || _this$core8 === void 0 ? void 0 : _this$core8.telemetryDisabled) !== null && _this$core$telemetryD !== void 0 ? _this$core$telemetryD : false,
2614
+ ...extra
2615
+ };
2616
+ }
2617
+ getIntelligenceSignupUrl() {
2618
+ return this.appendRefParam(INTELLIGENCE_SIGNUP_URL, "cpk-inspector");
2619
+ }
2620
+ getTalkToEngineerUrl() {
2621
+ return this.appendRefParam(TALK_TO_ENGINEER_URL, "cpk-inspector-threads");
2622
+ }
2501
2623
  subscribeToThreadStore(agentId, store) {
2624
+ if (!this.areThreadEndpointsAvailable()) return;
2502
2625
  if (this._threadStoreSubscriptions.has(agentId)) return;
2503
2626
  const threadsSub = store.select(_copilotkit_core.ɵselectThreads).subscribe((threads) => {
2504
2627
  this._threadsByAgent.set(agentId, threads);
@@ -2535,12 +2658,12 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2535
2658
  this._threads = [];
2536
2659
  }
2537
2660
  ensureOwnedThreadStore(agentId) {
2538
- var _this$core, _core$threadEndpoints, _core$intelligence;
2661
+ var _this$core9, _core$intelligence;
2539
2662
  if (this._ownedThreadStores.has(agentId)) return;
2540
- if ((_this$core = this.core) === null || _this$core === void 0 ? void 0 : _this$core.getThreadStore(agentId)) return;
2663
+ if ((_this$core9 = this.core) === null || _this$core9 === void 0 ? void 0 : _this$core9.getThreadStore(agentId)) return;
2541
2664
  const core = this.core;
2542
2665
  if (!(core === null || core === void 0 ? void 0 : core.runtimeUrl)) return;
2543
- if (((_core$threadEndpoints = core.threadEndpoints) === null || _core$threadEndpoints === void 0 ? void 0 : _core$threadEndpoints.list) === false) return;
2666
+ if (!this.areThreadEndpointsAvailable()) return;
2544
2667
  const store = (0, _copilotkit_core.ɵcreateThreadStore)({ fetch: globalThis.fetch });
2545
2668
  store.start();
2546
2669
  store.setContext({
@@ -2561,25 +2684,29 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2561
2684
  updateOwnedThreadStoreHeaders(headers) {
2562
2685
  const core = this.core;
2563
2686
  if (!(core === null || core === void 0 ? void 0 : core.runtimeUrl)) return;
2564
- for (const [agentId, store] of this._ownedThreadStores) store.setContext({
2565
- runtimeUrl: core.runtimeUrl,
2566
- headers: { ...headers },
2567
- agentId
2568
- });
2687
+ for (const [agentId, store] of this._ownedThreadStores) {
2688
+ var _core$intelligence2;
2689
+ store.setContext({
2690
+ runtimeUrl: core.runtimeUrl,
2691
+ headers: { ...headers },
2692
+ wsUrl: (_core$intelligence2 = core.intelligence) === null || _core$intelligence2 === void 0 ? void 0 : _core$intelligence2.wsUrl,
2693
+ agentId
2694
+ });
2695
+ }
2569
2696
  }
2570
2697
  removeOwnedThreadStore(agentId) {
2571
- var _this$core2;
2698
+ var _this$core10;
2572
2699
  const store = this._ownedThreadStores.get(agentId);
2573
2700
  if (!store) return;
2574
2701
  store.stop();
2575
- (_this$core2 = this.core) === null || _this$core2 === void 0 || _this$core2.unregisterThreadStore(agentId);
2702
+ (_this$core10 = this.core) === null || _this$core10 === void 0 || _this$core10.unregisterThreadStore(agentId);
2576
2703
  this._ownedThreadStores.delete(agentId);
2577
2704
  }
2578
2705
  teardownOwnedThreadStores() {
2579
2706
  for (const [agentId, store] of this._ownedThreadStores) {
2580
- var _this$core3;
2707
+ var _this$core11;
2581
2708
  store.stop();
2582
- (_this$core3 = this.core) === null || _this$core3 === void 0 || _this$core3.unregisterThreadStore(agentId);
2709
+ (_this$core11 = this.core) === null || _this$core11 === void 0 || _this$core11.unregisterThreadStore(agentId);
2583
2710
  }
2584
2711
  this._ownedThreadStores.clear();
2585
2712
  }
@@ -2591,13 +2718,12 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2591
2718
  onRuntimeConnectionStatusChanged: ({ status }) => {
2592
2719
  this.runtimeStatus = status;
2593
2720
  if (status === "connected") {
2594
- var _core$threadEndpoints2;
2595
2721
  if (!core.telemetryDisabled) {
2596
2722
  ensureTelemetryDistinctId();
2597
2723
  maybeShowDisclosure();
2598
2724
  }
2599
2725
  this.flushPendingBannerViewed();
2600
- if (((_core$threadEndpoints2 = core.threadEndpoints) === null || _core$threadEndpoints2 === void 0 ? void 0 : _core$threadEndpoints2.list) !== false) for (const agentId of this._ownedThreadStores.keys()) this.refreshOwnedThreadStore(agentId);
2726
+ if (this.areThreadEndpointsAvailable()) for (const agentId of this._ownedThreadStores.keys()) this.refreshOwnedThreadStore(agentId);
2601
2727
  else this.teardownOwnedThreadStores();
2602
2728
  } else {
2603
2729
  this._threadsByAgent.clear();
@@ -2644,6 +2770,13 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2644
2770
  };
2645
2771
  this.coreUnsubscribe = core.subscribe(this.coreSubscriber).unsubscribe;
2646
2772
  this.processAgentsChanged(core.agents);
2773
+ if (core.runtimeConnectionStatus === "connected") {
2774
+ if (!core.telemetryDisabled) {
2775
+ ensureTelemetryDistinctId();
2776
+ maybeShowDisclosure();
2777
+ }
2778
+ this.flushPendingBannerViewed();
2779
+ }
2647
2780
  const threadStores = typeof core.getThreadStores === "function" ? core.getThreadStores() : {};
2648
2781
  for (const [agentId, store] of Object.entries(threadStores)) this.subscribeToThreadStore(agentId, store);
2649
2782
  if (core.context) this.contextStore = this.normalizeContextStore(core.context);
@@ -2733,10 +2866,10 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2733
2866
  onRunStartedEvent: ({ event }) => {
2734
2867
  this.recordAgentEvent(agentId, "RUN_STARTED", event);
2735
2868
  },
2736
- onRunFinishedEvent: ({ event, result }) => {
2869
+ onRunFinishedEvent: (params) => {
2737
2870
  this.recordAgentEvent(agentId, "RUN_FINISHED", {
2738
- event,
2739
- result
2871
+ event: params.event,
2872
+ result: "result" in params ? params.result : void 0
2740
2873
  });
2741
2874
  this.refreshOwnedThreadStore(agentId);
2742
2875
  },
@@ -3073,13 +3206,13 @@ ${argsString}</pre
3073
3206
  }
3074
3207
  getEventBadgeClasses(type) {
3075
3208
  const base = "font-mono text-[10px] font-medium inline-flex items-center rounded-sm px-1.5 py-0.5 border";
3209
+ if (type === "RUN_ERROR") return `${base} bg-rose-50 text-rose-700 border-rose-200`;
3076
3210
  if (type.startsWith("RUN_")) return `${base} bg-blue-50 text-blue-700 border-blue-200`;
3077
3211
  if (type.startsWith("TEXT_MESSAGE")) return `${base} bg-emerald-50 text-emerald-700 border-emerald-200`;
3078
3212
  if (type.startsWith("TOOL_CALL")) return `${base} bg-amber-50 text-amber-700 border-amber-200`;
3079
3213
  if (type.startsWith("REASONING")) return `${base} bg-fuchsia-50 text-fuchsia-700 border-fuchsia-200`;
3080
3214
  if (type.startsWith("STATE")) return `${base} bg-violet-50 text-violet-700 border-violet-200`;
3081
3215
  if (type.startsWith("MESSAGES")) return `${base} bg-sky-50 text-sky-700 border-sky-200`;
3082
- if (type === "RUN_ERROR") return `${base} bg-rose-50 text-rose-700 border-rose-200`;
3083
3216
  return `${base} bg-gray-100 text-gray-600 border-gray-200`;
3084
3217
  }
3085
3218
  stringifyPayload(payload, pretty) {
@@ -3869,8 +4002,8 @@ ${argsString}</pre
3869
4002
  return lit.nothing;
3870
4003
  }
3871
4004
  renderSettingsPanel() {
3872
- var _this$core$telemetryD, _this$core4;
3873
- const optedOut = (_this$core$telemetryD = (_this$core4 = this.core) === null || _this$core4 === void 0 ? void 0 : _this$core4.telemetryDisabled) !== null && _this$core$telemetryD !== void 0 ? _this$core$telemetryD : false;
4005
+ var _this$core$telemetryD2, _this$core12;
4006
+ const optedOut = (_this$core$telemetryD2 = (_this$core12 = this.core) === null || _this$core12 === void 0 ? void 0 : _this$core12.telemetryDisabled) !== null && _this$core$telemetryD2 !== void 0 ? _this$core$telemetryD2 : false;
3874
4007
  return lit.html`
3875
4008
  <div class="flex h-full flex-col overflow-hidden">
3876
4009
  <div class="overflow-auto p-4">
@@ -3900,8 +4033,8 @@ ${argsString}</pre
3900
4033
  `;
3901
4034
  }
3902
4035
  trackBannerClickedOnce(opts) {
3903
- var _this$core5, _this$announcementCta;
3904
- if ((_this$core5 = this.core) === null || _this$core5 === void 0 ? void 0 : _this$core5.telemetryDisabled) return;
4036
+ var _this$core13, _this$announcementCta;
4037
+ if ((_this$core13 = this.core) === null || _this$core13 === void 0 ? void 0 : _this$core13.telemetryDisabled) return;
3905
4038
  const id = this.announcementTimestamp;
3906
4039
  if (!id) return;
3907
4040
  const key = `${id}:${opts.cta}`;
@@ -3913,8 +4046,314 @@ ${argsString}</pre
3913
4046
  cta_label: (_this$announcementCta = this.announcementCtaLabel) !== null && _this$announcementCta !== void 0 ? _this$announcementCta : void 0
3914
4047
  });
3915
4048
  }
4049
+ trackThreadsViewStateOnce(state, threadCount) {
4050
+ var _this$core14;
4051
+ if ((_this$core14 = this.core) === null || _this$core14 === void 0 ? void 0 : _this$core14.telemetryDisabled) return;
4052
+ const key = `${state}:${this.getThreadServiceStatus()}`;
4053
+ if (this.viewedThreadsTelemetryStates.has(key)) return;
4054
+ this.viewedThreadsTelemetryStates.add(key);
4055
+ const props = this.getThreadsTelemetryProps({ thread_count: threadCount });
4056
+ if (state === "locked") trackThreadsLockedViewed(props);
4057
+ else if (state === "empty_enabled") trackThreadsEmptyEnabledViewed(props);
4058
+ else trackThreadsEnabledViewed(props);
4059
+ }
4060
+ renderThreadsLockedBackgroundMockup() {
4061
+ return lit.html`
4062
+ <div
4063
+ aria-hidden="true"
4064
+ style="
4065
+ position: absolute;
4066
+ inset: 0;
4067
+ display: grid;
4068
+ grid-template-columns: minmax(180px, 28%) 1fr;
4069
+ overflow: hidden;
4070
+ opacity: 0.58;
4071
+ pointer-events: none;
4072
+ "
4073
+ >
4074
+ <div
4075
+ style="
4076
+ display: flex;
4077
+ flex-direction: column;
4078
+ gap: 12px;
4079
+ padding: 28px 24px;
4080
+ border-right: 1px solid #dbdbe5;
4081
+ background: #fafafa;
4082
+ "
4083
+ >
4084
+ ${[
4085
+ {
4086
+ width: 74,
4087
+ accent: true
4088
+ },
4089
+ { width: 92 },
4090
+ { width: 68 },
4091
+ { width: 84 },
4092
+ { width: 58 },
4093
+ { width: 76 }
4094
+ ].map((row) => lit.html`
4095
+ <div
4096
+ style="
4097
+ padding: 12px;
4098
+ border-radius: 8px;
4099
+ background: ${row.accent ? "#eee6fe" : "#ffffff"};
4100
+ box-shadow: inset 0 0 0 1px #eeeef4;
4101
+ "
4102
+ >
4103
+ <div
4104
+ style="
4105
+ height: 8px;
4106
+ width: ${row.width}%;
4107
+ border-radius: 99px;
4108
+ background: ${row.accent ? "#a984f5" : "#d7d7df"};
4109
+ "
4110
+ ></div>
4111
+ <div
4112
+ style="
4113
+ height: 6px;
4114
+ width: 88%;
4115
+ margin-top: 10px;
4116
+ border-radius: 99px;
4117
+ background: #e3e3eb;
4118
+ "
4119
+ ></div>
4120
+ <div
4121
+ style="
4122
+ height: 6px;
4123
+ width: 62%;
4124
+ margin-top: 7px;
4125
+ border-radius: 99px;
4126
+ background: #e8e8ef;
4127
+ "
4128
+ ></div>
4129
+ </div>
4130
+ `)}
4131
+ </div>
4132
+ <div
4133
+ style="
4134
+ min-width: 0;
4135
+ padding: 42px 48px;
4136
+ background: #ffffff;
4137
+ "
4138
+ >
4139
+ <div
4140
+ style="
4141
+ height: 10px;
4142
+ width: 180px;
4143
+ border-radius: 99px;
4144
+ background: #d7d7df;
4145
+ "
4146
+ ></div>
4147
+ <div
4148
+ style="
4149
+ height: 8px;
4150
+ width: min(520px, 58%);
4151
+ margin-top: 28px;
4152
+ border-radius: 99px;
4153
+ background: #e3e3eb;
4154
+ "
4155
+ ></div>
4156
+ <div
4157
+ style="
4158
+ height: 8px;
4159
+ width: min(430px, 48%);
4160
+ margin-top: 12px;
4161
+ border-radius: 99px;
4162
+ background: #e8e8ef;
4163
+ "
4164
+ ></div>
4165
+ <div
4166
+ style="
4167
+ display: grid;
4168
+ grid-template-columns: repeat(2, minmax(0, 1fr));
4169
+ gap: 16px;
4170
+ max-width: 620px;
4171
+ margin-top: 30px;
4172
+ "
4173
+ >
4174
+ <div
4175
+ style="
4176
+ height: 116px;
4177
+ border-radius: 8px;
4178
+ background: #f5f5f8;
4179
+ box-shadow: inset 0 0 0 1px #eeeef4;
4180
+ "
4181
+ ></div>
4182
+ <div
4183
+ style="
4184
+ height: 116px;
4185
+ border-radius: 8px;
4186
+ background: #f5f5f8;
4187
+ box-shadow: inset 0 0 0 1px #eeeef4;
4188
+ "
4189
+ ></div>
4190
+ </div>
4191
+ <div
4192
+ style="
4193
+ height: 10px;
4194
+ width: min(680px, 74%);
4195
+ margin-top: 34px;
4196
+ border-radius: 99px;
4197
+ background: #e3e3eb;
4198
+ "
4199
+ ></div>
4200
+ <div
4201
+ style="
4202
+ height: 10px;
4203
+ width: min(560px, 60%);
4204
+ margin-top: 14px;
4205
+ border-radius: 99px;
4206
+ background: #e8e8ef;
4207
+ "
4208
+ ></div>
4209
+ </div>
4210
+ </div>
4211
+ `;
4212
+ }
4213
+ renderThreadsLockedView() {
4214
+ this.trackThreadsViewStateOnce("locked", 0);
4215
+ return lit.html`
4216
+ <div
4217
+ style="
4218
+ position: relative;
4219
+ height: 100%;
4220
+ display: flex;
4221
+ align-items: center;
4222
+ justify-content: center;
4223
+ padding: 32px;
4224
+ overflow: hidden;
4225
+ background: #ffffff;
4226
+ "
4227
+ >
4228
+ ${this.renderThreadsLockedBackgroundMockup()}
4229
+ <div
4230
+ aria-hidden="true"
4231
+ style="
4232
+ position: absolute;
4233
+ inset: 0;
4234
+ pointer-events: none;
4235
+ background:
4236
+ radial-gradient(circle at center, rgba(255,255,255,0.9) 0, rgba(255,255,255,0.78) 24%, rgba(255,255,255,0.34) 48%, rgba(255,255,255,0.56) 100%);
4237
+ "
4238
+ ></div>
4239
+ <div
4240
+ style="
4241
+ position: relative;
4242
+ z-index: 1;
4243
+ max-width: 440px;
4244
+ text-align: center;
4245
+ color: #57575b;
4246
+ "
4247
+ >
4248
+ <div
4249
+ aria-hidden="true"
4250
+ style="
4251
+ margin: 0 auto 18px;
4252
+ display: flex;
4253
+ justify-content: center;
4254
+ "
4255
+ >
4256
+ <div
4257
+ style="
4258
+ display: flex;
4259
+ height: 44px;
4260
+ width: 44px;
4261
+ align-items: center;
4262
+ justify-content: center;
4263
+ border: 1px solid #dfd6fb;
4264
+ border-radius: 8px;
4265
+ background: #eee6fe;
4266
+ color: #57575b;
4267
+ box-shadow: 0 8px 18px rgba(87, 87, 91, 0.14);
4268
+ "
4269
+ >
4270
+ ${this.renderIcon("Lock")}
4271
+ </div>
4272
+ </div>
4273
+ <h2
4274
+ style="
4275
+ margin: 0 0 8px;
4276
+ font-size: 16px;
4277
+ line-height: 1.35;
4278
+ font-weight: 600;
4279
+ color: #010507;
4280
+ "
4281
+ >
4282
+ Enable Intelligence to inspect Threads.
4283
+ </h2>
4284
+ <p
4285
+ style="
4286
+ margin: 0 auto 18px;
4287
+ max-width: 380px;
4288
+ font-size: 13px;
4289
+ line-height: 1.55;
4290
+ color: #57575b;
4291
+ "
4292
+ >
4293
+ Persist conversations and inspect saved thread history from the
4294
+ Inspector.
4295
+ </p>
4296
+ <div
4297
+ style="
4298
+ display: flex;
4299
+ flex-wrap: wrap;
4300
+ justify-content: center;
4301
+ gap: 8px;
4302
+ "
4303
+ >
4304
+ <a
4305
+ href=${this.getTalkToEngineerUrl()}
4306
+ target="_blank"
4307
+ rel="noopener"
4308
+ style="
4309
+ display: inline-flex;
4310
+ min-height: 34px;
4311
+ align-items: center;
4312
+ justify-content: center;
4313
+ gap: 6px;
4314
+ border-radius: 6px;
4315
+ background: #010507;
4316
+ padding: 8px 12px;
4317
+ font-size: 12px;
4318
+ font-weight: 600;
4319
+ color: #ffffff;
4320
+ text-decoration: none;
4321
+ "
4322
+ @click=${this.handleThreadsTalkToEngineerClick}
4323
+ >
4324
+ Talk to an Engineer
4325
+ </a>
4326
+ <a
4327
+ href=${this.getIntelligenceSignupUrl()}
4328
+ target="_blank"
4329
+ rel="noopener"
4330
+ style="
4331
+ display: inline-flex;
4332
+ min-height: 34px;
4333
+ align-items: center;
4334
+ justify-content: center;
4335
+ gap: 6px;
4336
+ border-radius: 6px;
4337
+ border: 1px solid #dbdbe5;
4338
+ background: #ffffff;
4339
+ padding: 8px 12px;
4340
+ font-size: 12px;
4341
+ font-weight: 600;
4342
+ color: #57575b;
4343
+ text-decoration: none;
4344
+ "
4345
+ @click=${this.handleThreadsIntelligenceSignupClick}
4346
+ >
4347
+ Sign up for Intelligence
4348
+ </a>
4349
+ </div>
4350
+ </div>
4351
+ </div>
4352
+ `;
4353
+ }
3916
4354
  renderThreadsView() {
3917
4355
  var _this$_threadsByAgent, _displayThreads$find, _this$_core$runtimeUr, _this$_core2, _this$_core$headers, _this$_core3, _this$_core4, _this$liveMessageVers2, _this$agentEvents$get6;
4356
+ if (!this.areThreadEndpointsAvailable()) return this.renderThreadsLockedView();
3918
4357
  const displayThreads = this.selectedContext === "all-agents" ? this._threads : (_this$_threadsByAgent = this._threadsByAgent.get(this.selectedContext)) !== null && _this$_threadsByAgent !== void 0 ? _this$_threadsByAgent : [];
3919
4358
  let threadsErrorMessage = null;
3920
4359
  if (this.selectedContext === "all-agents") {
@@ -3926,72 +4365,88 @@ ${argsString}</pre
3926
4365
  threadsErrorMessage = (_this$_threadsErrorBy = (_this$_threadsErrorBy2 = this._threadsErrorByAgent.get(this.selectedContext)) === null || _this$_threadsErrorBy2 === void 0 ? void 0 : _this$_threadsErrorBy2.message) !== null && _this$_threadsErrorBy !== void 0 ? _this$_threadsErrorBy : null;
3927
4366
  }
3928
4367
  const selectedThread = this.selectedThreadId != null ? (_displayThreads$find = displayThreads.find((t) => t.id === this.selectedThreadId)) !== null && _displayThreads$find !== void 0 ? _displayThreads$find : null : null;
4368
+ if (!threadsErrorMessage) this.trackThreadsViewStateOnce(displayThreads.length === 0 ? "empty_enabled" : "enabled", displayThreads.length);
3929
4369
  return lit.html`
3930
- <div style="display:flex;height:100%;overflow:hidden;">
3931
- <!-- Left sidebar: thread list -->
4370
+ <div style="display:flex;height:100%;overflow:hidden;flex-direction:column;">
3932
4371
  <div
3933
- style="width:${this.threadListWidth}px;flex-shrink:0;overflow:hidden;display:flex;flex-direction:column;border-right:1px solid #DBDBE5;"
4372
+ style="display:flex;align-items:center;justify-content:flex-end;border-bottom:1px solid #DBDBE5;background:#ffffff;padding:8px 12px;flex-shrink:0;"
3934
4373
  >
3935
- <cpk-thread-list
3936
- style="height:100%;"
3937
- .threads=${displayThreads}
3938
- .selectedThreadId=${this.selectedThreadId}
3939
- .errorMessage=${threadsErrorMessage}
3940
- @threadSelected=${(e) => {
4374
+ <a
4375
+ href=${this.getTalkToEngineerUrl()}
4376
+ target="_blank"
4377
+ rel="noopener"
4378
+ style="display:inline-flex;align-items:center;gap:6px;border-radius:6px;border:1px solid #dbdbe5;background:#ffffff;padding:7px 10px;font-size:12px;font-weight:600;color:#57575b;text-decoration:none;"
4379
+ @click=${this.handleTalkToEngineerClick}
4380
+ >
4381
+ Talk to an Engineer
4382
+ </a>
4383
+ </div>
4384
+ <div style="display:flex;min-height:0;flex:1;overflow:hidden;">
4385
+ <!-- Left sidebar: thread list -->
4386
+ <div
4387
+ style="width:${this.threadListWidth}px;flex-shrink:0;overflow:hidden;display:flex;flex-direction:column;border-right:1px solid #DBDBE5;"
4388
+ >
4389
+ <cpk-thread-list
4390
+ style="height:100%;"
4391
+ .threads=${displayThreads}
4392
+ .selectedThreadId=${this.selectedThreadId}
4393
+ .errorMessage=${threadsErrorMessage}
4394
+ @threadSelected=${(e) => {
3941
4395
  this.selectedThreadId = e.detail;
3942
4396
  this.requestUpdate();
3943
4397
  }}
3944
- ></cpk-thread-list>
3945
- </div>
3946
-
3947
- <!-- Resize divider -->
3948
- <div
3949
- style="width:4px;flex-shrink:0;cursor:col-resize;background:transparent;position:relative;z-index:1;"
3950
- @pointerdown=${this.handleThreadDividerPointerDown}
3951
- @pointermove=${this.handleThreadDividerPointerMove}
3952
- @pointerup=${this.handleThreadDividerPointerUp}
3953
- @pointercancel=${this.handleThreadDividerPointerUp}
3954
- ></div>
4398
+ ></cpk-thread-list>
4399
+ </div>
3955
4400
 
3956
- <!-- Center + right: thread details or empty state -->
3957
- <div style="flex:1;min-width:0;overflow:hidden;display:flex;">
3958
- ${this.selectedThreadId ? lit.html`<cpk-thread-details
3959
- style="flex:1;min-width:0;"
3960
- .threadId=${this.selectedThreadId}
3961
- .thread=${selectedThread}
3962
- .runtimeUrl=${(_this$_core$runtimeUr = (_this$_core2 = this._core) === null || _this$_core2 === void 0 ? void 0 : _this$_core2.runtimeUrl) !== null && _this$_core$runtimeUr !== void 0 ? _this$_core$runtimeUr : ""}
3963
- .headers=${(_this$_core$headers = (_this$_core3 = this._core) === null || _this$_core3 === void 0 ? void 0 : _this$_core3.headers) !== null && _this$_core$headers !== void 0 ? _this$_core$headers : {}}
3964
- .threadInspectionAvailable=${((_this$_core4 = this._core) === null || _this$_core4 === void 0 || (_this$_core4 = _this$_core4.threadEndpoints) === null || _this$_core4 === void 0 ? void 0 : _this$_core4.inspect) !== false}
3965
- .liveMessageVersion=${this.selectedThreadId ? (_this$liveMessageVers2 = this.liveMessageVersion.get(this.selectedThreadId)) !== null && _this$liveMessageVers2 !== void 0 ? _this$liveMessageVers2 : 0 : 0}
3966
- .agentStateInput=${selectedThread ? this.getLatestStateForAgent(selectedThread.agentId) : null}
3967
- .agentEventsInput=${selectedThread ? (_this$agentEvents$get6 = this.agentEvents.get(selectedThread.agentId)) !== null && _this$agentEvents$get6 !== void 0 ? _this$agentEvents$get6 : [] : []}
3968
- ></cpk-thread-details>` : lit.html`
3969
- <div
3970
- style="
3971
- flex: 1;
3972
- display: flex;
3973
- flex-direction: column;
3974
- align-items: center;
3975
- justify-content: center;
3976
- gap: 8px;
3977
- color: #838389;
3978
- "
3979
- >
3980
- <svg
3981
- width="32"
3982
- height="32"
3983
- viewBox="0 0 24 24"
3984
- fill="none"
3985
- stroke="#c0c0c8"
3986
- stroke-width="1.5"
3987
- stroke-linecap="round"
3988
- stroke-linejoin="round"
4401
+ <!-- Resize divider -->
4402
+ <div
4403
+ style="width:4px;flex-shrink:0;cursor:col-resize;background:transparent;position:relative;z-index:1;"
4404
+ @pointerdown=${this.handleThreadDividerPointerDown}
4405
+ @pointermove=${this.handleThreadDividerPointerMove}
4406
+ @pointerup=${this.handleThreadDividerPointerUp}
4407
+ @pointercancel=${this.handleThreadDividerPointerUp}
4408
+ ></div>
4409
+
4410
+ <!-- Center + right: thread details or empty state -->
4411
+ <div style="flex:1;min-width:0;overflow:hidden;display:flex;">
4412
+ ${selectedThread ? lit.html`<cpk-thread-details
4413
+ style="flex:1;min-width:0;"
4414
+ .threadId=${selectedThread.id}
4415
+ .thread=${selectedThread}
4416
+ .runtimeUrl=${(_this$_core$runtimeUr = (_this$_core2 = this._core) === null || _this$_core2 === void 0 ? void 0 : _this$_core2.runtimeUrl) !== null && _this$_core$runtimeUr !== void 0 ? _this$_core$runtimeUr : ""}
4417
+ .headers=${(_this$_core$headers = (_this$_core3 = this._core) === null || _this$_core3 === void 0 ? void 0 : _this$_core3.headers) !== null && _this$_core$headers !== void 0 ? _this$_core$headers : {}}
4418
+ .threadInspectionAvailable=${((_this$_core4 = this._core) === null || _this$_core4 === void 0 || (_this$_core4 = _this$_core4.threadEndpoints) === null || _this$_core4 === void 0 ? void 0 : _this$_core4.inspect) !== false}
4419
+ .liveMessageVersion=${(_this$liveMessageVers2 = this.liveMessageVersion.get(selectedThread.id)) !== null && _this$liveMessageVers2 !== void 0 ? _this$liveMessageVers2 : 0}
4420
+ .agentStateInput=${this.getLatestStateForAgent(selectedThread.agentId)}
4421
+ .agentEventsInput=${(_this$agentEvents$get6 = this.agentEvents.get(selectedThread.agentId)) !== null && _this$agentEvents$get6 !== void 0 ? _this$agentEvents$get6 : []}
4422
+ ></cpk-thread-details>` : lit.html`
4423
+ <div
4424
+ style="
4425
+ flex: 1;
4426
+ display: flex;
4427
+ flex-direction: column;
4428
+ align-items: center;
4429
+ justify-content: center;
4430
+ gap: 8px;
4431
+ color: #838389;
4432
+ "
3989
4433
  >
3990
- <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
3991
- </svg>
3992
- <span style="font-size: 13px">${displayThreads.length === 0 ? "No threads yet" : "Select a thread to inspect"}</span>
3993
- </div>
3994
- `}
4434
+ <svg
4435
+ width="32"
4436
+ height="32"
4437
+ viewBox="0 0 24 24"
4438
+ fill="none"
4439
+ stroke="#c0c0c8"
4440
+ stroke-width="1.5"
4441
+ stroke-linecap="round"
4442
+ stroke-linejoin="round"
4443
+ >
4444
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
4445
+ </svg>
4446
+ <span style="font-size: 13px">${displayThreads.length === 0 ? "No threads yet" : "Select a thread to inspect"}</span>
4447
+ </div>
4448
+ `}
4449
+ </div>
3995
4450
  </div>
3996
4451
  </div>
3997
4452
  `;
@@ -4519,8 +4974,8 @@ ${prettyEvent}</pre
4519
4974
  if (this.contextOptions.filter((opt) => opt.key !== "all-agents").length > 1) this.selectedContext = "all-agents";
4520
4975
  }
4521
4976
  if (key === "threads") {
4522
- var _this$core6;
4523
- if (this.selectedMenu !== "threads" && !((_this$core6 = this.core) === null || _this$core6 === void 0 ? void 0 : _this$core6.telemetryDisabled)) trackThreadsTabClicked();
4977
+ var _this$core15;
4978
+ if (previousMenu !== "threads" && !((_this$core15 = this.core) === null || _this$core15 === void 0 ? void 0 : _this$core15.telemetryDisabled)) trackThreadsTabClicked(this.getThreadsTelemetryProps());
4524
4979
  this.autoSelectLatestThread();
4525
4980
  }
4526
4981
  if (key === "ag-ui-events" || key === "agents") requestAnimationFrame(() => {
@@ -4953,6 +5408,22 @@ ${prettyEvent}</pre
4953
5408
  ${this.copiedContextItems.has(id) ? "Copied" : "Copy JSON"}
4954
5409
  </button>
4955
5410
  </div>
5411
+ <pre
5412
+ style="
5413
+ margin: 0;
5414
+ max-height: 180px;
5415
+ overflow: auto;
5416
+ white-space: pre-wrap;
5417
+ word-break: break-word;
5418
+ border-radius: 6px;
5419
+ border: 1px solid #eeeef4;
5420
+ background: #f7f7f9;
5421
+ padding: 10px;
5422
+ font-size: 11px;
5423
+ line-height: 1.5;
5424
+ color: #2d2d30;
5425
+ "
5426
+ >${this.formatContextValue(context.value)}</pre>
4956
5427
  ` : lit.html`
4957
5428
  <div class="flex items-center justify-center py-4 text-xs text-gray-500">
4958
5429
  <span>No value available</span>
@@ -5072,8 +5543,8 @@ ${prettyEvent}</pre
5072
5543
  </div>`;
5073
5544
  }
5074
5545
  flushPendingBannerViewed() {
5075
- var _this$core7;
5076
- if (!this.pendingBannerViewed || ((_this$core7 = this.core) === null || _this$core7 === void 0 ? void 0 : _this$core7.telemetryDisabled)) {
5546
+ var _this$core16;
5547
+ if (!this.pendingBannerViewed || ((_this$core16 = this.core) === null || _this$core16 === void 0 ? void 0 : _this$core16.telemetryDisabled)) {
5077
5548
  this.pendingBannerViewed = null;
5078
5549
  return;
5079
5550
  }
@@ -5145,8 +5616,9 @@ ${prettyEvent}</pre
5145
5616
  async convertMarkdownToHtml(markdown) {
5146
5617
  const renderer = new marked.marked.Renderer();
5147
5618
  renderer.link = (href, title, text) => {
5148
- return `<a href="${this.escapeHtmlAttr(this.appendRefParam(href !== null && href !== void 0 ? href : ""))}" target="_blank" rel="noopener"${title ? ` title="${this.escapeHtmlAttr(title)}"` : ""}>${text}</a>`;
5619
+ return `<a href="${this.escapeHtmlAttr(this.isSafeAnnouncementHref(href !== null && href !== void 0 ? href : "") ? this.appendRefParam(href !== null && href !== void 0 ? href : "") : "#")}" target="_blank" rel="noopener"${title ? ` title="${this.escapeHtmlAttr(title)}"` : ""}>${text}</a>`;
5149
5620
  };
5621
+ renderer.html = (html) => escapeHtml(html);
5150
5622
  renderer.code = (code, lang) => {
5151
5623
  const safeLang = (lang !== null && lang !== void 0 ? lang : "").replace(/[^a-z0-9-]/gi, "");
5152
5624
  return `<div class="announcement-code"><pre><code${safeLang ? ` class="language-${safeLang}"` : ""}>${escapeHtml(code)}</code></pre><div class="announcement-code__copy-shield"><button type="button" class="announcement-code__copy" data-copy="${this.encodeBase64(code)}" aria-label="Copy code">Copy</button></div></div>`;
@@ -5156,6 +5628,14 @@ ${prettyEvent}</pre
5156
5628
  async: false
5157
5629
  });
5158
5630
  }
5631
+ isSafeAnnouncementHref(href) {
5632
+ try {
5633
+ const url = new URL(href, typeof window !== "undefined" ? window.location.href : "https://copilotkit.ai");
5634
+ return url.protocol === "http:" || url.protocol === "https:" || url.protocol === "mailto:";
5635
+ } catch (_unused7) {
5636
+ return false;
5637
+ }
5638
+ }
5159
5639
  encodeBase64(value) {
5160
5640
  if (typeof window === "undefined" || typeof window.btoa !== "function") return "";
5161
5641
  const bytes = new TextEncoder().encode(value);
@@ -5170,20 +5650,26 @@ ${prettyEvent}</pre
5170
5650
  for (let i = 0; i < decoded.length; i++) bytes[i] = decoded.charCodeAt(i);
5171
5651
  return new TextDecoder().decode(bytes);
5172
5652
  }
5173
- appendRefParam(href) {
5653
+ appendRefParam(href, ref = "cpk-inspector") {
5174
5654
  try {
5175
- var _this$core8;
5655
+ var _this$core17;
5656
+ const isRootRelative = href.startsWith("/") && !href.startsWith("//");
5176
5657
  const url = new URL(href, typeof window !== "undefined" ? window.location.href : "https://copilotkit.ai");
5177
- if (!url.searchParams.has("ref")) url.searchParams.append("ref", "cpk-inspector");
5178
- if (!url.searchParams.has("posthog_distinct_id") && !((_this$core8 = this.core) === null || _this$core8 === void 0 ? void 0 : _this$core8.telemetryDisabled)) {
5658
+ if (!url.searchParams.has("ref")) url.searchParams.append("ref", ref);
5659
+ if (!url.searchParams.has("posthog_distinct_id") && !((_this$core17 = this.core) === null || _this$core17 === void 0 ? void 0 : _this$core17.telemetryDisabled) && this.isCopilotKitDestination(url)) {
5179
5660
  const distinctId = getTelemetryDistinctIdForUrl();
5180
5661
  if (distinctId) url.searchParams.append("posthog_distinct_id", distinctId);
5181
5662
  }
5663
+ if (isRootRelative) return `${url.pathname}${url.search}${url.hash}`;
5182
5664
  return url.toString();
5183
- } catch (_unused7) {
5665
+ } catch (_unused8) {
5184
5666
  return href;
5185
5667
  }
5186
5668
  }
5669
+ isCopilotKitDestination(url) {
5670
+ const hostname = url.hostname.toLowerCase();
5671
+ return hostname === "copilotkit.ai" || hostname.endsWith(".copilotkit.ai");
5672
+ }
5187
5673
  escapeHtmlAttr(value) {
5188
5674
  return escapeHtml(value).replace(/"/g, "&quot;").replace(/'/g, "&#39;");
5189
5675
  }
@@ -5195,7 +5681,7 @@ ${prettyEvent}</pre
5195
5681
  const parsed = JSON.parse(raw);
5196
5682
  if (parsed && typeof parsed.timestamp === "string") return parsed.timestamp;
5197
5683
  return null;
5198
- } catch (_unused8) {}
5684
+ } catch (_unused9) {}
5199
5685
  return null;
5200
5686
  }
5201
5687
  persistAnnouncementTimestamp(timestamp) {
@@ -5203,7 +5689,7 @@ ${prettyEvent}</pre
5203
5689
  try {
5204
5690
  const payload = JSON.stringify({ timestamp });
5205
5691
  window.localStorage.setItem(ANNOUNCEMENT_STORAGE_KEY, payload);
5206
- } catch (_unused9) {}
5692
+ } catch (_unused10) {}
5207
5693
  }
5208
5694
  markAnnouncementSeen() {
5209
5695
  this.hasUnseenAnnouncement = false;