@copilotkit/web-inspector 1.61.1 → 1.62.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.
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.62.0";
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
  }
@@ -294,6 +356,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
294
356
  //#endregion
295
357
  //#region src/index.ts
296
358
  const WEB_INSPECTOR_TAG = "cpk-web-inspector";
359
+ const THREAD_INSPECTOR_TAG = "cpk-thread-inspector";
297
360
  const EDGE_MARGIN = 16;
298
361
  const DRAG_THRESHOLD = 6;
299
362
  const MIN_WINDOW_WIDTH = 600;
@@ -313,6 +376,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
313
376
  const DOCKED_LEFT_WIDTH = 500;
314
377
  const MAX_AGENT_EVENTS = 200;
315
378
  const MAX_TOTAL_EVENTS = 500;
379
+ const INTELLIGENCE_SIGNUP_URL = "https://go.copilotkit.ai/intelligence-signup";
380
+ const TALK_TO_ENGINEER_URL = "https://www.copilotkit.ai/talk-to-an-engineer";
316
381
  const AGENT_EVENT_TYPES = [
317
382
  "RUN_STARTED",
318
383
  "RUN_FINISHED",
@@ -388,14 +453,14 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
388
453
  bg: "rgba(190,194,255,0.102)",
389
454
  fg: "#5558B2"
390
455
  };
456
+ if (type === "RUN_ERROR" || type === "ERROR") return {
457
+ bg: "rgba(250,95,103,0.13)",
458
+ fg: "#c0333a"
459
+ };
391
460
  if (type.startsWith("RUN_") || type.startsWith("STEP_")) return {
392
461
  bg: "rgba(255,172,77,0.2)",
393
462
  fg: "#996300"
394
463
  };
395
- if (type === "ERROR") return {
396
- bg: "rgba(250,95,103,0.13)",
397
- fg: "#c0333a"
398
- };
399
464
  return {
400
465
  bg: "#F7F7F9",
401
466
  fg: "#838389"
@@ -491,28 +556,30 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
491
556
  ${filtered.length === 0 ? lit.html`
492
557
  <div class="cpk-tl__empty">
493
558
  ${this.errorMessage ? lit.html`
494
- <svg
495
- width="24"
496
- height="24"
497
- viewBox="0 0 24 24"
498
- fill="none"
499
- stroke="currentColor"
500
- stroke-width="1.5"
501
- stroke-linecap="round"
502
- stroke-linejoin="round"
503
- class="cpk-tl__empty-icon"
559
+ <svg
560
+ width="24"
561
+ height="24"
562
+ viewBox="0 0 24 24"
563
+ fill="none"
564
+ stroke="currentColor"
565
+ stroke-width="1.5"
566
+ stroke-linecap="round"
567
+ stroke-linejoin="round"
568
+ class="cpk-tl__empty-icon"
569
+ >
570
+ <circle cx="12" cy="12" r="10" />
571
+ <line x1="12" y1="8" x2="12" y2="12" />
572
+ <line x1="12" y1="16" x2="12.01" y2="16" />
573
+ </svg>
574
+ <div>
575
+ Failed to load threads
576
+ <div
577
+ style="font-size:11px;margin-top:4px;color:#c0333a;"
504
578
  >
505
- <circle cx="12" cy="12" r="10" />
506
- <line x1="12" y1="8" x2="12" y2="12" />
507
- <line x1="12" y1="16" x2="12.01" y2="16" />
508
- </svg>
509
- <div>
510
- Failed to load threads
511
- <div style="font-size:11px;margin-top:4px;color:#c0333a;">
512
- ${this.errorMessage}
513
- </div>
579
+ ${this.errorMessage}
514
580
  </div>
515
- ` : this.threads.length === 0 ? lit.html`
581
+ </div>
582
+ ` : this.threads.length === 0 ? lit.html`
516
583
  <svg
517
584
  width="24"
518
585
  height="24"
@@ -680,10 +747,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
680
747
  color: #c0c0c8;
681
748
  }
682
749
  `;
683
- var ɵCpkThreadDetails = class ɵCpkThreadDetails extends lit.LitElement {
750
+ var CpkThreadInspector = class CpkThreadInspector extends lit.LitElement {
684
751
  constructor(..._args2) {
685
752
  super(..._args2);
686
753
  this.threadId = null;
754
+ this.provider = null;
687
755
  this.thread = null;
688
756
  this.runtimeUrl = "";
689
757
  this.headers = {};
@@ -691,7 +759,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
691
759
  this.agentStateInput = null;
692
760
  this.agentEventsInput = [];
693
761
  this.liveMessageVersion = 0;
694
- this._tab = "conversation";
762
+ this._tab = "timeline";
763
+ this._fetchedMetadata = null;
695
764
  this._conversation = [];
696
765
  this._fetchedEvents = null;
697
766
  this._fetchedState = null;
@@ -708,12 +777,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
708
777
  this._eventsNotAvailable = false;
709
778
  this._stateNotAvailable = false;
710
779
  this._panelInitializing = false;
711
- this._activatedTabs = new Set(["conversation"]);
780
+ this._activatedTabs = new Set(["timeline"]);
712
781
  this._panelTplCache = /* @__PURE__ */ new Map();
782
+ this._timelineItemsCache = null;
783
+ this._liveEventsWithSourceIndexCache = null;
713
784
  this._eventsFetched = false;
714
785
  this._stateFetched = false;
715
- this._lastFetchedThreadId = null;
786
+ this._lastLoadKey = null;
716
787
  this._lastSeenLiveMessageVersion = 0;
788
+ this._metadataAbort = null;
717
789
  this._messagesAbort = null;
718
790
  this._eventsAbort = null;
719
791
  this._stateAbort = null;
@@ -741,9 +813,33 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
741
813
  this._dividerResizing = false;
742
814
  };
743
815
  }
816
+ static providerLoadKey(provider) {
817
+ if (!provider) return "provider:none";
818
+ let id = CpkThreadInspector.providerIds.get(provider);
819
+ if (!id) {
820
+ id = CpkThreadInspector.nextProviderId;
821
+ CpkThreadInspector.nextProviderId += 1;
822
+ CpkThreadInspector.providerIds.set(provider, id);
823
+ }
824
+ return [
825
+ `provider:${id}`,
826
+ provider.getThreadMetadata ? "metadata:1" : "metadata:0",
827
+ provider.getMessages ? "messages:1" : "messages:0",
828
+ provider.getEvents ? "events:1" : "events:0",
829
+ provider.getState ? "state:1" : "state:0"
830
+ ].join("|");
831
+ }
832
+ /**
833
+ * Build a deterministic signature for runtime fetch headers so auth/CSRF
834
+ * changes invalidate cached thread data even when the selected thread is
835
+ * otherwise unchanged.
836
+ */
837
+ static headersLoadKey(headers) {
838
+ return JSON.stringify(Object.entries(headers).sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey)));
839
+ }
744
840
  renderTabContent(id) {
745
- if (id === "conversation") return this.renderConversation();
746
- if (id === "agent-state") return this.renderState();
841
+ if (id === "timeline") return this.renderTimeline();
842
+ if (id === "state") return this.renderState();
747
843
  return this.renderEvents();
748
844
  }
749
845
  activateTab(id) {
@@ -761,44 +857,108 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
761
857
  }
762
858
  maybeFetchTabData(id) {
763
859
  if (!this.threadId) return;
764
- if (id === "ag-ui-events" && !this._eventsFetched) {
860
+ if ((id === "timeline" || id === "raw-events") && !this._eventsFetched) {
765
861
  this._eventsFetched = true;
766
862
  this.fetchEvents(this.threadId);
767
- } else if (id === "agent-state" && !this._stateFetched) {
863
+ } else if (id === "state" && !this._stateFetched) {
768
864
  this._stateFetched = true;
769
865
  this.fetchState(this.threadId);
770
866
  }
771
867
  }
772
868
  updated(_changed) {
773
- if (this.threadId !== this._lastFetchedThreadId) {
774
- var _this$_messagesAbort, _this$_eventsAbort, _this$_stateAbort;
775
- this._lastFetchedThreadId = this.threadId;
869
+ const loadKey = this.currentLoadKey();
870
+ if (loadKey !== this._lastLoadKey) {
871
+ this._lastLoadKey = loadKey;
776
872
  this._lastSeenLiveMessageVersion = this.liveMessageVersion;
777
- this._tab = "conversation";
778
- this._activatedTabs = new Set(["conversation"]);
779
- this._panelTplCache = /* @__PURE__ */ new Map();
780
- this._expandedTools = /* @__PURE__ */ new Set();
781
- this._expandedMessages = /* @__PURE__ */ new Set();
782
- (_this$_messagesAbort = this._messagesAbort) === null || _this$_messagesAbort === void 0 || _this$_messagesAbort.abort();
783
- this._messagesAbort = null;
784
- (_this$_eventsAbort = this._eventsAbort) === null || _this$_eventsAbort === void 0 || _this$_eventsAbort.abort();
785
- this._eventsAbort = null;
786
- (_this$_stateAbort = this._stateAbort) === null || _this$_stateAbort === void 0 || _this$_stateAbort.abort();
787
- this._stateAbort = null;
788
- this._eventsFetched = false;
789
- this._stateFetched = false;
790
- this._fetchedEvents = null;
791
- this._fetchedState = null;
792
- if (this.threadId) this.fetchMessages(this.threadId);
793
- else this._conversation = [];
873
+ this.resetLoadedThreadData();
874
+ if (this.threadId) {
875
+ this.fetchMetadata(this.threadId);
876
+ if (this.canFetchEvents()) {
877
+ this._eventsFetched = true;
878
+ this.fetchEvents(this.threadId);
879
+ } else this.fetchMessages(this.threadId);
880
+ } else {
881
+ this._fetchedMetadata = null;
882
+ this._conversation = [];
883
+ }
794
884
  } else if (this.threadId && this.liveMessageVersion !== this._lastSeenLiveMessageVersion) {
795
- var _this$_messagesAbort2;
885
+ var _this$_messagesAbort;
796
886
  this._lastSeenLiveMessageVersion = this.liveMessageVersion;
797
- (_this$_messagesAbort2 = this._messagesAbort) === null || _this$_messagesAbort2 === void 0 || _this$_messagesAbort2.abort();
887
+ (_this$_messagesAbort = this._messagesAbort) === null || _this$_messagesAbort === void 0 || _this$_messagesAbort.abort();
798
888
  this._messagesAbort = null;
799
889
  this.fetchMessages(this.threadId, true);
800
890
  }
801
891
  }
892
+ canFetchMessages() {
893
+ var _this$provider;
894
+ return !!((_this$provider = this.provider) === null || _this$provider === void 0 ? void 0 : _this$provider.getMessages) || !!this.runtimeUrl && this.threadInspectionAvailable;
895
+ }
896
+ canFetchEvents() {
897
+ var _this$provider2;
898
+ return !!((_this$provider2 = this.provider) === null || _this$provider2 === void 0 ? void 0 : _this$provider2.getEvents) || !!this.runtimeUrl && this.threadInspectionAvailable;
899
+ }
900
+ canFetchState() {
901
+ var _this$provider3;
902
+ return !!((_this$provider3 = this.provider) === null || _this$provider3 === void 0 ? void 0 : _this$provider3.getState) || !!this.runtimeUrl && this.threadInspectionAvailable;
903
+ }
904
+ currentLoadKey() {
905
+ var _this$threadId;
906
+ return [
907
+ (_this$threadId = this.threadId) !== null && _this$threadId !== void 0 ? _this$threadId : "thread:none",
908
+ CpkThreadInspector.providerLoadKey(this.provider),
909
+ `runtime:${this.runtimeUrl}`,
910
+ `headers:${CpkThreadInspector.headersLoadKey(this.headers)}`,
911
+ `inspect:${this.threadInspectionAvailable ? "1" : "0"}`
912
+ ].join("||");
913
+ }
914
+ resetLoadedThreadData() {
915
+ var _this$_metadataAbort, _this$_messagesAbort2, _this$_eventsAbort, _this$_stateAbort;
916
+ this._tab = "timeline";
917
+ this._activatedTabs = new Set(["timeline"]);
918
+ this._panelTplCache = /* @__PURE__ */ new Map();
919
+ this._timelineItemsCache = null;
920
+ this._liveEventsWithSourceIndexCache = null;
921
+ this._expandedTools = /* @__PURE__ */ new Set();
922
+ this._expandedMessages = /* @__PURE__ */ new Set();
923
+ (_this$_metadataAbort = this._metadataAbort) === null || _this$_metadataAbort === void 0 || _this$_metadataAbort.abort();
924
+ this._metadataAbort = null;
925
+ (_this$_messagesAbort2 = this._messagesAbort) === null || _this$_messagesAbort2 === void 0 || _this$_messagesAbort2.abort();
926
+ this._messagesAbort = null;
927
+ (_this$_eventsAbort = this._eventsAbort) === null || _this$_eventsAbort === void 0 || _this$_eventsAbort.abort();
928
+ this._eventsAbort = null;
929
+ (_this$_stateAbort = this._stateAbort) === null || _this$_stateAbort === void 0 || _this$_stateAbort.abort();
930
+ this._stateAbort = null;
931
+ this._eventsFetched = false;
932
+ this._stateFetched = false;
933
+ this._eventsNotAvailable = false;
934
+ this._stateNotAvailable = false;
935
+ this._loadingMessages = false;
936
+ this._loadingEvents = false;
937
+ this._loadingState = false;
938
+ this._messagesError = null;
939
+ this._eventsError = null;
940
+ this._stateError = null;
941
+ this._fetchedMetadata = null;
942
+ this._conversation = [];
943
+ this._fetchedEvents = null;
944
+ this._fetchedState = null;
945
+ }
946
+ async fetchMetadata(threadId) {
947
+ var _this$provider4, _this$_metadataAbort2;
948
+ if (!((_this$provider4 = this.provider) === null || _this$provider4 === void 0 ? void 0 : _this$provider4.getThreadMetadata)) return;
949
+ (_this$_metadataAbort2 = this._metadataAbort) === null || _this$_metadataAbort2 === void 0 || _this$_metadataAbort2.abort();
950
+ const controller = new AbortController();
951
+ this._metadataAbort = controller;
952
+ try {
953
+ const metadata = await this.provider.getThreadMetadata(threadId, { signal: controller.signal });
954
+ if (controller.signal.aborted || this.threadId !== threadId) return;
955
+ this._fetchedMetadata = metadata;
956
+ } catch (err) {
957
+ if (err instanceof Error && err.name === "AbortError") return;
958
+ if (this.threadId !== threadId) return;
959
+ this._fetchedMetadata = null;
960
+ }
961
+ }
802
962
  /**
803
963
  * Fetch the canonical conversation for `threadId` from the runtime.
804
964
  *
@@ -810,10 +970,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
810
970
  * so users see an explicit loading indicator on first load.
811
971
  */
812
972
  async fetchMessages(threadId, silent = false) {
813
- if (!this.runtimeUrl || !this.threadInspectionAvailable) {
973
+ var _this$_messagesAbort3;
974
+ if (!this.canFetchMessages()) {
814
975
  if (!silent) this._conversation = [];
815
976
  return;
816
977
  }
978
+ (_this$_messagesAbort3 = this._messagesAbort) === null || _this$_messagesAbort3 === void 0 || _this$_messagesAbort3.abort();
817
979
  const controller = new AbortController();
818
980
  this._messagesAbort = controller;
819
981
  if (!silent) {
@@ -821,15 +983,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
821
983
  this._messagesError = null;
822
984
  }
823
985
  try {
824
- const res = await fetch(`${this.runtimeUrl}/threads/${encodeURIComponent(threadId)}/messages`, {
825
- headers: { ...this.headers },
826
- signal: controller.signal
827
- });
828
- if (controller.signal.aborted || this.threadId !== threadId) return;
829
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
830
- const data = await res.json();
986
+ var _this$provider5;
987
+ const messages = ((_this$provider5 = this.provider) === null || _this$provider5 === void 0 ? void 0 : _this$provider5.getMessages) ? await this.provider.getMessages(threadId, { signal: controller.signal }) : await this.fetchRuntimeMessages(threadId, controller.signal);
831
988
  if (controller.signal.aborted || this.threadId !== threadId) return;
832
- this._conversation = this.mapMessages(data.messages);
989
+ this._conversation = this.mapMessages(messages);
833
990
  } catch (err) {
834
991
  if (err instanceof Error && err.name === "AbortError") return;
835
992
  if (!silent) {
@@ -841,65 +998,66 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
841
998
  }
842
999
  }
843
1000
  async fetchEvents(threadId) {
844
- this._eventsNotAvailable = false;
845
- if (!this.runtimeUrl || !this.threadInspectionAvailable) {
1001
+ var _this$_eventsAbort2;
1002
+ if (!this.canFetchEvents()) {
846
1003
  this._fetchedEvents = null;
847
1004
  return;
848
1005
  }
1006
+ (_this$_eventsAbort2 = this._eventsAbort) === null || _this$_eventsAbort2 === void 0 || _this$_eventsAbort2.abort();
849
1007
  const controller = new AbortController();
850
1008
  this._eventsAbort = controller;
851
1009
  this._loadingEvents = true;
852
1010
  this._eventsError = null;
853
1011
  try {
854
- const res = await fetch(`${this.runtimeUrl}/threads/${encodeURIComponent(threadId)}/events`, {
855
- headers: { ...this.headers },
856
- signal: controller.signal
857
- });
1012
+ var _this$provider6;
1013
+ const result = ((_this$provider6 = this.provider) === null || _this$provider6 === void 0 ? void 0 : _this$provider6.getEvents) ? {
1014
+ status: "available",
1015
+ events: await this.provider.getEvents(threadId, { signal: controller.signal })
1016
+ } : await this.fetchRuntimeEvents(threadId, controller.signal);
858
1017
  if (controller.signal.aborted || this.threadId !== threadId) return;
859
- if (res.status === 501) {
1018
+ if (result.status === "not-available") {
860
1019
  this._eventsNotAvailable = true;
861
- this._fetchedEvents = null;
1020
+ this._fetchedEvents = [];
1021
+ if (this.canFetchMessages()) this.fetchMessages(threadId);
862
1022
  return;
863
1023
  }
864
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
865
- const data = await res.json();
866
- if (controller.signal.aborted || this.threadId !== threadId) return;
867
- this._fetchedEvents = this.mapApiEvents(data.events);
1024
+ const mappedEvents = this.mapApiEvents(result.events);
1025
+ this._fetchedEvents = mappedEvents;
1026
+ if (mappedEvents.length === 0 && this.canFetchMessages()) this.fetchMessages(threadId);
868
1027
  } catch (err) {
869
1028
  if (err instanceof Error && err.name === "AbortError") return;
870
1029
  if (this.threadId !== threadId) return;
871
1030
  this._eventsError = err instanceof Error ? err.message : "Failed to load events";
872
1031
  this._fetchedEvents = [];
1032
+ if (this.canFetchMessages()) this.fetchMessages(threadId);
873
1033
  } finally {
874
1034
  if (!controller.signal.aborted && this.threadId === threadId) this._loadingEvents = false;
875
1035
  }
876
1036
  }
877
1037
  async fetchState(threadId) {
878
- this._stateNotAvailable = false;
879
- if (!this.runtimeUrl || !this.threadInspectionAvailable) {
1038
+ var _this$_stateAbort2;
1039
+ if (!this.canFetchState()) {
880
1040
  this._fetchedState = null;
881
1041
  return;
882
1042
  }
1043
+ (_this$_stateAbort2 = this._stateAbort) === null || _this$_stateAbort2 === void 0 || _this$_stateAbort2.abort();
883
1044
  const controller = new AbortController();
884
1045
  this._stateAbort = controller;
885
1046
  this._loadingState = true;
886
1047
  this._stateError = null;
887
1048
  try {
888
- var _data$state;
889
- const res = await fetch(`${this.runtimeUrl}/threads/${encodeURIComponent(threadId)}/state`, {
890
- headers: { ...this.headers },
891
- signal: controller.signal
892
- });
1049
+ var _this$provider7, _result$state;
1050
+ const result = ((_this$provider7 = this.provider) === null || _this$provider7 === void 0 ? void 0 : _this$provider7.getState) ? {
1051
+ status: "available",
1052
+ state: await this.provider.getState(threadId, { signal: controller.signal })
1053
+ } : await this.fetchRuntimeState(threadId, controller.signal);
893
1054
  if (controller.signal.aborted || this.threadId !== threadId) return;
894
- if (res.status === 501) {
1055
+ if (result.status === "not-available") {
895
1056
  this._stateNotAvailable = true;
896
1057
  this._fetchedState = null;
897
1058
  return;
898
1059
  }
899
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
900
- const data = await res.json();
901
- if (controller.signal.aborted || this.threadId !== threadId) return;
902
- this._fetchedState = (_data$state = data.state) !== null && _data$state !== void 0 ? _data$state : null;
1060
+ this._fetchedState = (_result$state = result.state) !== null && _result$state !== void 0 ? _result$state : null;
903
1061
  } catch (err) {
904
1062
  if (err instanceof Error && err.name === "AbortError") return;
905
1063
  if (this.threadId !== threadId) return;
@@ -909,6 +1067,42 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
909
1067
  if (!controller.signal.aborted && this.threadId === threadId) this._loadingState = false;
910
1068
  }
911
1069
  }
1070
+ async fetchRuntimeMessages(threadId, signal) {
1071
+ const res = await fetch(this.getThreadInspectionUrl(threadId, "messages"), {
1072
+ headers: { ...this.headers },
1073
+ signal
1074
+ });
1075
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
1076
+ return (await res.json()).messages;
1077
+ }
1078
+ async fetchRuntimeEvents(threadId, signal) {
1079
+ const res = await fetch(this.getThreadInspectionUrl(threadId, "events"), {
1080
+ headers: { ...this.headers },
1081
+ signal
1082
+ });
1083
+ if (res.status === 501) return { status: "not-available" };
1084
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
1085
+ return {
1086
+ status: "available",
1087
+ events: (await res.json()).events
1088
+ };
1089
+ }
1090
+ async fetchRuntimeState(threadId, signal) {
1091
+ var _data$state;
1092
+ const res = await fetch(this.getThreadInspectionUrl(threadId, "state"), {
1093
+ headers: { ...this.headers },
1094
+ signal
1095
+ });
1096
+ if (res.status === 501) return { status: "not-available" };
1097
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
1098
+ return {
1099
+ status: "available",
1100
+ state: (_data$state = (await res.json()).state) !== null && _data$state !== void 0 ? _data$state : null
1101
+ };
1102
+ }
1103
+ getThreadInspectionUrl(threadId, resource) {
1104
+ return `${this.runtimeUrl.replace(/\/+$/, "")}/threads/${encodeURIComponent(threadId)}/${resource}`;
1105
+ }
912
1106
  mapMessages(messages) {
913
1107
  const items = [];
914
1108
  const toolCallMap = /* @__PURE__ */ new Map();
@@ -922,7 +1116,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
922
1116
  var _msg$toolCalls;
923
1117
  if ((_msg$toolCalls = msg.toolCalls) === null || _msg$toolCalls === void 0 ? void 0 : _msg$toolCalls.length) for (const tc of msg.toolCalls) {
924
1118
  let args = {};
925
- try {
1119
+ if (typeof tc.args === "string") try {
926
1120
  args = JSON.parse(tc.args);
927
1121
  } catch (err) {
928
1122
  console.error("[CopilotKit Inspector] Failed to parse tool-call arguments", {
@@ -935,6 +1129,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
935
1129
  __raw: tc.args
936
1130
  };
937
1131
  }
1132
+ else args = tc.args;
938
1133
  const item = {
939
1134
  id: tc.id,
940
1135
  type: "tool_call",
@@ -982,15 +1177,245 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
982
1177
  return items;
983
1178
  }
984
1179
  mapApiEvents(events) {
985
- return events.map((event) => {
986
- const { type, timestamp, ...rest } = event;
1180
+ return events.map((event, index) => {
1181
+ const { type, timestamp, payload, ...rest } = event;
987
1182
  return {
988
1183
  type: typeof type === "string" ? type : "UNKNOWN",
989
1184
  timestamp: typeof timestamp === "string" || typeof timestamp === "number" ? timestamp : Date.now(),
990
- payload: rest
1185
+ payload: payload !== null && payload !== void 0 ? payload : rest,
1186
+ sourceIndex: index + 1,
1187
+ rawEvent: event
991
1188
  };
992
1189
  });
993
1190
  }
1191
+ get activeTimelineItems() {
1192
+ return this.timelineItemsForEvents(this.activeEvents);
1193
+ }
1194
+ timelineItemsForEvents(events) {
1195
+ var _this$_timelineItemsC;
1196
+ if (((_this$_timelineItemsC = this._timelineItemsCache) === null || _this$_timelineItemsC === void 0 ? void 0 : _this$_timelineItemsC.events) === events) return this._timelineItemsCache.items;
1197
+ const items = this.timelineItemsFromEvents(events);
1198
+ this._timelineItemsCache = {
1199
+ events,
1200
+ items
1201
+ };
1202
+ return items;
1203
+ }
1204
+ timelineItemsFromEvents(events) {
1205
+ if (events.length === 0) return [];
1206
+ const items = [];
1207
+ const messageItems = /* @__PURE__ */ new Map();
1208
+ const toolItems = /* @__PURE__ */ new Map();
1209
+ const readString = (payload, keys) => {
1210
+ for (const key of keys) {
1211
+ const value = payload[key];
1212
+ if (typeof value === "string") return value;
1213
+ }
1214
+ return null;
1215
+ };
1216
+ const sourceIndexFor = (event) => {
1217
+ var _event$sourceIndex;
1218
+ return (_event$sourceIndex = event.sourceIndex) !== null && _event$sourceIndex !== void 0 ? _event$sourceIndex : 0;
1219
+ };
1220
+ const appendWarning = (event, title, body, severity = "warning") => {
1221
+ const sourceIndex = sourceIndexFor(event);
1222
+ items.push({
1223
+ id: `warning-${sourceIndex}-${items.length}`,
1224
+ kind: "warning",
1225
+ title,
1226
+ body,
1227
+ timestamp: event.timestamp,
1228
+ sourceIndex,
1229
+ severity
1230
+ });
1231
+ };
1232
+ const ensureMessage = (event, role) => {
1233
+ var _readString;
1234
+ const sourceIndex = sourceIndexFor(event);
1235
+ const key = (_readString = readString(event.payload, [
1236
+ "messageId",
1237
+ "message_id",
1238
+ "id"
1239
+ ])) !== null && _readString !== void 0 ? _readString : `message-${sourceIndex}`;
1240
+ let item = messageItems.get(key);
1241
+ if (!item) {
1242
+ item = {
1243
+ id: `message-${key}`,
1244
+ kind: "message",
1245
+ title: `${role || "message"} message`,
1246
+ body: "",
1247
+ timestamp: event.timestamp,
1248
+ sourceIndex
1249
+ };
1250
+ messageItems.set(key, item);
1251
+ items.push(item);
1252
+ }
1253
+ return item;
1254
+ };
1255
+ const ensureTool = (event) => {
1256
+ var _readString2;
1257
+ const sourceIndex = sourceIndexFor(event);
1258
+ const key = (_readString2 = readString(event.payload, [
1259
+ "toolCallId",
1260
+ "tool_call_id",
1261
+ "id",
1262
+ "callId"
1263
+ ])) !== null && _readString2 !== void 0 ? _readString2 : `tool-${sourceIndex}`;
1264
+ let item = toolItems.get(key);
1265
+ if (!item) {
1266
+ var _readString3;
1267
+ item = {
1268
+ id: `tool-${key}`,
1269
+ kind: "tool",
1270
+ title: (_readString3 = readString(event.payload, [
1271
+ "toolCallName",
1272
+ "toolName",
1273
+ "name",
1274
+ "functionName"
1275
+ ])) !== null && _readString3 !== void 0 ? _readString3 : "Tool call",
1276
+ body: "",
1277
+ timestamp: event.timestamp,
1278
+ sourceIndex
1279
+ };
1280
+ toolItems.set(key, item);
1281
+ items.push(item);
1282
+ }
1283
+ return item;
1284
+ };
1285
+ for (const event of events) {
1286
+ const { type, payload } = event;
1287
+ const sourceIndex = sourceIndexFor(event);
1288
+ if (type === "UNKNOWN") {
1289
+ appendWarning(event, "Unknown AG-UI event", "The event is missing a string type and could not be normalized.");
1290
+ continue;
1291
+ }
1292
+ if (type === "RUN_STARTED" || type === "STEP_STARTED") {
1293
+ items.push({
1294
+ id: `${type}-${sourceIndex}`,
1295
+ kind: "run",
1296
+ title: type === "RUN_STARTED" ? "Run started" : "Step started",
1297
+ timestamp: event.timestamp,
1298
+ sourceIndex,
1299
+ details: payload
1300
+ });
1301
+ continue;
1302
+ }
1303
+ if (type === "RUN_FINISHED" || type === "STEP_FINISHED") {
1304
+ items.push({
1305
+ id: `${type}-${sourceIndex}`,
1306
+ kind: "run",
1307
+ title: type === "RUN_FINISHED" ? "Run finished" : "Step finished",
1308
+ timestamp: event.timestamp,
1309
+ sourceIndex,
1310
+ details: payload
1311
+ });
1312
+ continue;
1313
+ }
1314
+ if (type === "RUN_ERROR" || type === "ERROR") {
1315
+ var _readString4;
1316
+ items.push({
1317
+ id: `${type}-${sourceIndex}`,
1318
+ kind: "warning",
1319
+ title: "Run error",
1320
+ body: (_readString4 = readString(payload, [
1321
+ "message",
1322
+ "error",
1323
+ "description"
1324
+ ])) !== null && _readString4 !== void 0 ? _readString4 : "",
1325
+ timestamp: event.timestamp,
1326
+ sourceIndex,
1327
+ severity: "error",
1328
+ details: payload
1329
+ });
1330
+ continue;
1331
+ }
1332
+ if (type === "TEXT_MESSAGE_START") {
1333
+ var _readString5;
1334
+ ensureMessage(event, (_readString5 = readString(payload, ["role"])) !== null && _readString5 !== void 0 ? _readString5 : "assistant");
1335
+ continue;
1336
+ }
1337
+ if (type === "TEXT_MESSAGE_CONTENT") {
1338
+ var _readString6, _item$body, _readString7;
1339
+ const item = ensureMessage(event, (_readString6 = readString(payload, ["role"])) !== null && _readString6 !== void 0 ? _readString6 : "assistant");
1340
+ item.body = `${(_item$body = item.body) !== null && _item$body !== void 0 ? _item$body : ""}${(_readString7 = readString(payload, [
1341
+ "delta",
1342
+ "content",
1343
+ "text"
1344
+ ])) !== null && _readString7 !== void 0 ? _readString7 : ""}`;
1345
+ continue;
1346
+ }
1347
+ if (type === "TEXT_MESSAGE_END") {
1348
+ var _readString8;
1349
+ ensureMessage(event, (_readString8 = readString(payload, ["role"])) !== null && _readString8 !== void 0 ? _readString8 : "assistant");
1350
+ continue;
1351
+ }
1352
+ if (type === "TOOL_CALL_START") {
1353
+ ensureTool(event);
1354
+ continue;
1355
+ }
1356
+ if (type === "TOOL_CALL_ARGS") {
1357
+ var _readString9;
1358
+ const item = ensureTool(event);
1359
+ const chunk = (_readString9 = readString(payload, [
1360
+ "args",
1361
+ "arguments",
1362
+ "delta"
1363
+ ])) !== null && _readString9 !== void 0 ? _readString9 : typeof payload.args === "object" ? JSON.stringify(payload.args) : null;
1364
+ if (chunk) {
1365
+ var _item$rawArgs;
1366
+ item.rawArgs = `${(_item$rawArgs = item.rawArgs) !== null && _item$rawArgs !== void 0 ? _item$rawArgs : ""}${chunk}`;
1367
+ item.body = item.rawArgs;
1368
+ }
1369
+ continue;
1370
+ }
1371
+ if (type === "TOOL_CALL_END") {
1372
+ const item = ensureTool(event);
1373
+ if (item.rawArgs) try {
1374
+ JSON.parse(item.rawArgs);
1375
+ } catch (_unused) {
1376
+ appendWarning(event, "Could not decode tool call arguments", item.rawArgs);
1377
+ }
1378
+ continue;
1379
+ }
1380
+ if (type === "TOOL_CALL_RESULT") {
1381
+ const item = ensureTool(event);
1382
+ const result = readString(payload, [
1383
+ "result",
1384
+ "content",
1385
+ "delta"
1386
+ ]);
1387
+ if (result) {
1388
+ item.body = item.body ? `${item.body}\nResult: ${result}` : `Result: ${result}`;
1389
+ try {
1390
+ JSON.parse(result);
1391
+ } catch (_unused2) {
1392
+ appendWarning(event, "Could not decode tool result", result);
1393
+ }
1394
+ }
1395
+ continue;
1396
+ }
1397
+ if (type.startsWith("STATE_")) {
1398
+ items.push({
1399
+ id: `${type}-${sourceIndex}`,
1400
+ kind: "state",
1401
+ title: type === "STATE_SNAPSHOT" ? "State snapshot captured" : "State delta captured",
1402
+ timestamp: event.timestamp,
1403
+ sourceIndex,
1404
+ details: payload
1405
+ });
1406
+ continue;
1407
+ }
1408
+ items.push({
1409
+ id: `event-${sourceIndex}`,
1410
+ kind: "event",
1411
+ title: type,
1412
+ timestamp: event.timestamp,
1413
+ sourceIndex,
1414
+ details: payload
1415
+ });
1416
+ }
1417
+ return items;
1418
+ }
994
1419
  get renderItems() {
995
1420
  const items = this._conversation;
996
1421
  const result = [];
@@ -1028,7 +1453,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1028
1453
  };
1029
1454
  }
1030
1455
  get duration() {
1031
- const t = this.thread;
1456
+ const t = this.metadata;
1032
1457
  if (!(t === null || t === void 0 ? void 0 : t.createdAt) || !(t === null || t === void 0 ? void 0 : t.updatedAt)) return "—";
1033
1458
  const ms = new Date(t.updatedAt).getTime() - new Date(t.createdAt).getTime();
1034
1459
  if (ms < 0) return "—";
@@ -1050,9 +1475,20 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1050
1475
  this._expandedMessages = next;
1051
1476
  }
1052
1477
  get activeEvents() {
1053
- var _ref, _this$_fetchedEvents;
1478
+ var _ref, _this$_fetchedEvents, _this$_liveEventsWith;
1054
1479
  if (this._eventsNotAvailable) return [];
1055
- return (_ref = (_this$_fetchedEvents = this._fetchedEvents) !== null && _this$_fetchedEvents !== void 0 ? _this$_fetchedEvents : this.agentEventsInput) !== null && _ref !== void 0 ? _ref : [];
1480
+ const events = (_ref = (_this$_fetchedEvents = this._fetchedEvents) !== null && _this$_fetchedEvents !== void 0 ? _this$_fetchedEvents : this.agentEventsInput) !== null && _ref !== void 0 ? _ref : [];
1481
+ if (events.every((event) => event.sourceIndex != null)) return events;
1482
+ if (((_this$_liveEventsWith = this._liveEventsWithSourceIndexCache) === null || _this$_liveEventsWith === void 0 ? void 0 : _this$_liveEventsWith.events) === events) return this._liveEventsWithSourceIndexCache.indexedEvents;
1483
+ const indexedEvents = events.map((event, index) => event.sourceIndex == null ? {
1484
+ ...event,
1485
+ sourceIndex: index + 1
1486
+ } : event);
1487
+ this._liveEventsWithSourceIndexCache = {
1488
+ events,
1489
+ indexedEvents
1490
+ };
1491
+ return indexedEvents;
1056
1492
  }
1057
1493
  get activeState() {
1058
1494
  var _ref2, _this$_fetchedState;
@@ -1067,6 +1503,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1067
1503
  if (!id) return "—";
1068
1504
  return id.length > 20 ? id.slice(0, 8) + "…" : id;
1069
1505
  }
1506
+ get metadata() {
1507
+ var _ref3, _this$_fetchedMetadat;
1508
+ return (_ref3 = (_this$_fetchedMetadat = this._fetchedMetadata) !== null && _this$_fetchedMetadat !== void 0 ? _this$_fetchedMetadat : this.thread) !== null && _ref3 !== void 0 ? _ref3 : null;
1509
+ }
1070
1510
  fmtTime(dateStr) {
1071
1511
  if (!dateStr) return "—";
1072
1512
  const d = new Date(dateStr);
@@ -1086,7 +1526,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1086
1526
  <!-- Tab bar -->
1087
1527
  <div class="cpk-td__tabs-header">
1088
1528
  <div class="cpk-td__tab-group" role="tablist">
1089
- ${ɵCpkThreadDetails.TAB_LIST.map((tab) => lit.html`
1529
+ ${CpkThreadInspector.TAB_LIST.map((tab) => lit.html`
1090
1530
  <button
1091
1531
  role="tab"
1092
1532
  class="cpk-td__tab ${this._tab === tab.id ? "cpk-td__tab--active" : ""}"
@@ -1098,18 +1538,19 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1098
1538
  </div>
1099
1539
  ${this.renderPanelToggle()}
1100
1540
  </div>
1541
+ ${this.renderMetadataStrip()}
1101
1542
 
1102
1543
  <!-- Scrollable content -->
1103
1544
  <div class="cpk-td__content">
1104
1545
  ${this._panelInitializing ? lit.html`
1105
1546
  <div class="cpk-td__status">Loading…</div>
1106
1547
  ` : lit.nothing}
1107
- ${ɵCpkThreadDetails.TAB_LIST.map((tab) => this._activatedTabs.has(tab.id) ? lit.html`<div
1108
- class="cpk-td__panel"
1109
- style=${this._tab === tab.id && !this._panelInitializing ? "" : "display:none"}
1110
- >
1111
- ${this.renderTabContent(tab.id)}
1112
- </div>` : lit.nothing)}
1548
+ ${CpkThreadInspector.TAB_LIST.map((tab) => this._activatedTabs.has(tab.id) ? lit.html`<div
1549
+ class="cpk-td__panel"
1550
+ style=${this._tab === tab.id && !this._panelInitializing ? "" : "display:none"}
1551
+ >
1552
+ ${this.renderTabContent(tab.id)}
1553
+ </div>` : lit.nothing)}
1113
1554
  </div>
1114
1555
  </div>
1115
1556
 
@@ -1137,6 +1578,122 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1137
1578
  ${this.renderDetailPanel()}
1138
1579
  </div>
1139
1580
  </div>
1581
+ `;
1582
+ }
1583
+ renderMetadataStrip() {
1584
+ var _metadata$id, _metadata$endUserId;
1585
+ const metadata = this.metadata;
1586
+ const pills = [
1587
+ {
1588
+ label: "Thread",
1589
+ value: (_metadata$id = metadata === null || metadata === void 0 ? void 0 : metadata.id) !== null && _metadata$id !== void 0 ? _metadata$id : this.threadId
1590
+ },
1591
+ {
1592
+ label: "Agent",
1593
+ value: metadata === null || metadata === void 0 ? void 0 : metadata.agentId
1594
+ },
1595
+ {
1596
+ label: "End user",
1597
+ value: (_metadata$endUserId = metadata === null || metadata === void 0 ? void 0 : metadata.endUserId) !== null && _metadata$endUserId !== void 0 ? _metadata$endUserId : metadata === null || metadata === void 0 ? void 0 : metadata.createdById
1598
+ },
1599
+ {
1600
+ label: "Status",
1601
+ value: metadata === null || metadata === void 0 ? void 0 : metadata.status
1602
+ }
1603
+ ].filter((pill) => pill.value != null && pill.value !== "");
1604
+ if (pills.length === 0) return lit.nothing;
1605
+ return lit.html`
1606
+ <div class="cpk-td__metadata-strip" aria-label="Thread metadata">
1607
+ ${pills.map((pill) => {
1608
+ var _pill$value;
1609
+ return lit.html`
1610
+ <span class="cpk-td__metadata-pill" title=${(_pill$value = pill.value) !== null && _pill$value !== void 0 ? _pill$value : ""}>
1611
+ <span class="cpk-td__metadata-label">${pill.label}</span>
1612
+ <span class="cpk-td__metadata-value"
1613
+ >${this.shortId(pill.value)}</span
1614
+ >
1615
+ </span>
1616
+ `;
1617
+ })}
1618
+ </div>
1619
+ `;
1620
+ }
1621
+ revealSourceEvent(sourceIndex) {
1622
+ this._activatedTabs = new Set([...this._activatedTabs, "raw-events"]);
1623
+ this._tab = "raw-events";
1624
+ this.requestUpdate();
1625
+ requestAnimationFrame(() => {
1626
+ var _this$shadowRoot, _source$scrollIntoVie;
1627
+ const source = (_this$shadowRoot = this.shadowRoot) === null || _this$shadowRoot === void 0 ? void 0 : _this$shadowRoot.querySelector(`[data-source-index="${sourceIndex}"]`);
1628
+ source === null || source === void 0 || (_source$scrollIntoVie = source.scrollIntoView) === null || _source$scrollIntoVie === void 0 || _source$scrollIntoVie.call(source, { block: "center" });
1629
+ });
1630
+ }
1631
+ renderTimeline() {
1632
+ if (this._loadingEvents) return lit.html`
1633
+ <div class="cpk-td__status">Loading timeline…</div>
1634
+ `;
1635
+ if (this._eventsError) return lit.html`<div class="cpk-td__status cpk-td__status--error">
1636
+ ${this._eventsError}
1637
+ </div>`;
1638
+ if (this._eventsNotAvailable) {
1639
+ if (this._conversation.length > 0) return this.renderConversation();
1640
+ if (this._loadingMessages) return this.renderConversation();
1641
+ return lit.html`
1642
+ <div class="cpk-td__empty-state">
1643
+ <span>Timeline event history not available</span>
1644
+ <span class="cpk-td__empty-hint"
1645
+ >This runtime doesn't yet expose per-thread AG-UI events. Check State for
1646
+ the latest snapshot when available.</span
1647
+ >
1648
+ </div>
1649
+ `;
1650
+ }
1651
+ const events = this.activeEvents;
1652
+ const cachedTimeline = this.getCachedPanelTpl("timeline", [events]);
1653
+ if (cachedTimeline) return cachedTimeline;
1654
+ const timelineItems = this.timelineItemsForEvents(events);
1655
+ if (timelineItems.length === 0) {
1656
+ if (this._conversation.length > 0) return this.renderConversation();
1657
+ if (this._loadingMessages) return this.renderConversation();
1658
+ return lit.html`
1659
+ <div class="cpk-td__empty-state">
1660
+ <span>No timeline events captured</span>
1661
+ <span class="cpk-td__empty-hint"
1662
+ >Timeline rows are normalized from AG-UI events. Open Raw AG-UI Events or
1663
+ State to inspect the available thread data.</span
1664
+ >
1665
+ </div>
1666
+ `;
1667
+ }
1668
+ return this.cachedPanelTpl("timeline", [events], () => {
1669
+ return lit.html`${timelineItems.map((item) => this.renderTimelineItem(item))}`;
1670
+ });
1671
+ }
1672
+ renderTimelineItem(item) {
1673
+ return lit.html`
1674
+ <div
1675
+ class="cpk-td__timeline-item ${item.kind === "warning" ? "cpk-td__timeline-item--warning" : ""}"
1676
+ >
1677
+ <div class="cpk-td__timeline-header">
1678
+ <span class="cpk-td__timeline-kind"
1679
+ >${item.severity === "error" ? "error" : item.kind}</span
1680
+ >
1681
+ <span class="cpk-td__timeline-title">${item.title}</span>
1682
+ <button
1683
+ type="button"
1684
+ class="cpk-td__source-link"
1685
+ @click=${() => this.revealSourceEvent(item.sourceIndex)}
1686
+ >
1687
+ Source event #${item.sourceIndex}
1688
+ </button>
1689
+ <span class="cpk-td__timeline-time"
1690
+ >${formatTimestamp(item.timestamp)}</span
1691
+ >
1692
+ </div>
1693
+ ${item.body ? lit.html`<div class="cpk-td__timeline-body">${item.body}</div>` : item.details ? lit.html`<pre class="cpk-td__timeline-body">
1694
+ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(item.details))}</pre
1695
+ >` : lit.nothing}
1696
+ </div>
1140
1697
  `;
1141
1698
  }
1142
1699
  renderConversation() {
@@ -1163,7 +1720,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1163
1720
  <span>No messages yet</span>
1164
1721
  </div>
1165
1722
  `;
1166
- return this.cachedPanelTpl("conversation", [
1723
+ return this.cachedPanelTpl("timeline-fallback", [
1167
1724
  this._conversation,
1168
1725
  this._expandedTools,
1169
1726
  this._expandedMessages
@@ -1181,8 +1738,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1181
1738
  * change without the listed key flipping.
1182
1739
  */
1183
1740
  cachedPanelTpl(slot, key, build) {
1184
- const cached = this._panelTplCache.get(slot);
1185
- if (cached && cached.key.length === key.length && cached.key.every((v, i) => v === key[i])) return cached.tpl;
1741
+ const cached = this.getCachedPanelTpl(slot, key);
1742
+ if (cached) return cached;
1186
1743
  const tpl = build();
1187
1744
  this._panelTplCache.set(slot, {
1188
1745
  key,
@@ -1190,6 +1747,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1190
1747
  });
1191
1748
  return tpl;
1192
1749
  }
1750
+ getCachedPanelTpl(slot, key) {
1751
+ const cached = this._panelTplCache.get(slot);
1752
+ if (cached && cached.key.length === key.length && cached.key.every((v, i) => v === key[i])) return cached.tpl;
1753
+ return null;
1754
+ }
1193
1755
  renderRenderItem(item) {
1194
1756
  switch (item.type) {
1195
1757
  case "user":
@@ -1210,7 +1772,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1210
1772
  }
1211
1773
  renderBubble(item) {
1212
1774
  const isUser = item.type === "user";
1213
- const threshold = ɵCpkThreadDetails.COLLAPSE_THRESHOLD;
1775
+ const threshold = CpkThreadInspector.COLLAPSE_THRESHOLD;
1214
1776
  const expanded = this._expandedMessages.has(item.id);
1215
1777
  const tooLong = item.content.length > threshold;
1216
1778
  const shown = tooLong && !expanded ? item.content.slice(0, threshold) + "…" : item.content;
@@ -1356,7 +1918,7 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(item.result))}</
1356
1918
  </div>
1357
1919
  `;
1358
1920
  const stateValue = this.activeState;
1359
- return this.cachedPanelTpl("agent-state", [stateValue], () => {
1921
+ return this.cachedPanelTpl("state", [stateValue], () => {
1360
1922
  return lit.html`<pre class="cpk-td__json-block">
1361
1923
  ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(stateValue))}</pre
1362
1924
  >`;
@@ -1387,11 +1949,12 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(stateValue))}</p
1387
1949
  >
1388
1950
  </div>
1389
1951
  `;
1390
- return this.cachedPanelTpl("ag-ui-events", [events], () => {
1952
+ return this.cachedPanelTpl("raw-events", [events], () => {
1391
1953
  return lit.html`${events.map((event) => {
1954
+ var _event$rawEvent;
1392
1955
  const { bg, fg } = eventColors(event.type);
1393
1956
  return lit.html`
1394
- <div class="cpk-td__event">
1957
+ <div class="cpk-td__event" data-source-index=${event.sourceIndex}>
1395
1958
  <div class="cpk-td__event-header" style="background:${bg}">
1396
1959
  <span class="cpk-td__event-type" style="color:${fg}"
1397
1960
  >${event.type}</span
@@ -1401,7 +1964,7 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(stateValue))}</p
1401
1964
  >
1402
1965
  </div>
1403
1966
  <pre class="cpk-td__event-payload">
1404
- ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}</pre
1967
+ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson((_event$rawEvent = event.rawEvent) !== null && _event$rawEvent !== void 0 ? _event$rawEvent : event))}</pre
1405
1968
  >
1406
1969
  </div>
1407
1970
  `;
@@ -1435,31 +1998,44 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
1435
1998
  `;
1436
1999
  }
1437
2000
  renderDetailPanel() {
1438
- var _this$thread, _this$thread$name, _this$thread2, _this$thread$agentId, _this$thread3, _this$thread$createdB, _this$thread4, _this$thread5, _this$thread6;
2001
+ var _metadata$name, _metadata$agentId, _metadata$endUserId2, _metadata$createdById, _metadata$status;
1439
2002
  const counts = this.activityCounts;
2003
+ const metadata = this.metadata;
1440
2004
  return lit.html`
1441
2005
  <!-- Thread -->
1442
2006
  <div class="cpk-tdp__section-title">Thread</div>
1443
2007
  <div class="cpk-tdp__row">
1444
2008
  <span class="cpk-tdp__label">ID</span>
1445
2009
  <span class="cpk-tdp__value cpk-tdp__value--wrap"
1446
- >${this.shortId((_this$thread = this.thread) === null || _this$thread === void 0 ? void 0 : _this$thread.id)}</span
2010
+ >${this.shortId(metadata === null || metadata === void 0 ? void 0 : metadata.id)}</span
1447
2011
  >
1448
2012
  </div>
1449
2013
  <div class="cpk-tdp__row">
1450
2014
  <span class="cpk-tdp__label">Name</span>
1451
- <span class="cpk-tdp__value">${(_this$thread$name = (_this$thread2 = this.thread) === null || _this$thread2 === void 0 ? void 0 : _this$thread2.name) !== null && _this$thread$name !== void 0 ? _this$thread$name : "—"}</span>
2015
+ <span class="cpk-tdp__value">${(_metadata$name = metadata === null || metadata === void 0 ? void 0 : metadata.name) !== null && _metadata$name !== void 0 ? _metadata$name : "—"}</span>
1452
2016
  </div>
1453
2017
  <div class="cpk-tdp__row">
1454
2018
  <span class="cpk-tdp__label">Agent</span>
1455
2019
  <span class="cpk-tdp__value cpk-tdp__value--truncate"
1456
- >${(_this$thread$agentId = (_this$thread3 = this.thread) === null || _this$thread3 === void 0 ? void 0 : _this$thread3.agentId) !== null && _this$thread$agentId !== void 0 ? _this$thread$agentId : "—"}</span
2020
+ >${(_metadata$agentId = metadata === null || metadata === void 0 ? void 0 : metadata.agentId) !== null && _metadata$agentId !== void 0 ? _metadata$agentId : "—"}</span
2021
+ >
2022
+ </div>
2023
+ <div class="cpk-tdp__row">
2024
+ <span class="cpk-tdp__label">End user</span>
2025
+ <span class="cpk-tdp__value cpk-tdp__value--truncate"
2026
+ >${(_metadata$endUserId2 = metadata === null || metadata === void 0 ? void 0 : metadata.endUserId) !== null && _metadata$endUserId2 !== void 0 ? _metadata$endUserId2 : "—"}</span
1457
2027
  >
1458
2028
  </div>
1459
2029
  <div class="cpk-tdp__row">
1460
2030
  <span class="cpk-tdp__label">Created by</span>
1461
2031
  <span class="cpk-tdp__value cpk-tdp__value--truncate"
1462
- >${(_this$thread$createdB = (_this$thread4 = this.thread) === null || _this$thread4 === void 0 ? void 0 : _this$thread4.createdById) !== null && _this$thread$createdB !== void 0 ? _this$thread$createdB : "—"}</span
2032
+ >${(_metadata$createdById = metadata === null || metadata === void 0 ? void 0 : metadata.createdById) !== null && _metadata$createdById !== void 0 ? _metadata$createdById : "—"}</span
2033
+ >
2034
+ </div>
2035
+ <div class="cpk-tdp__row">
2036
+ <span class="cpk-tdp__label">Status</span>
2037
+ <span class="cpk-tdp__value cpk-tdp__value--truncate"
2038
+ >${(_metadata$status = metadata === null || metadata === void 0 ? void 0 : metadata.status) !== null && _metadata$status !== void 0 ? _metadata$status : "—"}</span
1463
2039
  >
1464
2040
  </div>
1465
2041
 
@@ -1469,11 +2045,11 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
1469
2045
  <div class="cpk-tdp__section-title">Timestamps</div>
1470
2046
  <div class="cpk-tdp__row">
1471
2047
  <span class="cpk-tdp__label">Created</span>
1472
- <span class="cpk-tdp__value">${this.fmtTime((_this$thread5 = this.thread) === null || _this$thread5 === void 0 ? void 0 : _this$thread5.createdAt)}</span>
2048
+ <span class="cpk-tdp__value">${this.fmtTime(metadata === null || metadata === void 0 ? void 0 : metadata.createdAt)}</span>
1473
2049
  </div>
1474
2050
  <div class="cpk-tdp__row">
1475
2051
  <span class="cpk-tdp__label">Updated</span>
1476
- <span class="cpk-tdp__value">${this.fmtTime((_this$thread6 = this.thread) === null || _this$thread6 === void 0 ? void 0 : _this$thread6.updatedAt)}</span>
2052
+ <span class="cpk-tdp__value">${this.fmtTime(metadata === null || metadata === void 0 ? void 0 : metadata.updatedAt)}</span>
1477
2053
  </div>
1478
2054
  <div class="cpk-tdp__row">
1479
2055
  <span class="cpk-tdp__label">Duration</span>
@@ -1499,8 +2075,9 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
1499
2075
  `;
1500
2076
  }
1501
2077
  };
1502
- ɵCpkThreadDetails.properties = {
2078
+ CpkThreadInspector.properties = {
1503
2079
  threadId: { attribute: false },
2080
+ provider: { attribute: false },
1504
2081
  thread: { attribute: false },
1505
2082
  runtimeUrl: { attribute: false },
1506
2083
  headers: { attribute: false },
@@ -1509,6 +2086,7 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
1509
2086
  agentEventsInput: { attribute: false },
1510
2087
  liveMessageVersion: { attribute: false },
1511
2088
  _tab: { state: true },
2089
+ _fetchedMetadata: { state: true },
1512
2090
  _conversation: { state: true },
1513
2091
  _fetchedEvents: { state: true },
1514
2092
  _fetchedState: { state: true },
@@ -1527,22 +2105,24 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
1527
2105
  _panelInitializing: { state: true },
1528
2106
  _activatedTabs: { state: true }
1529
2107
  };
1530
- ɵCpkThreadDetails.COLLAPSE_THRESHOLD = 800;
1531
- ɵCpkThreadDetails.TAB_LIST = [
2108
+ CpkThreadInspector.COLLAPSE_THRESHOLD = 800;
2109
+ CpkThreadInspector.TAB_LIST = [
1532
2110
  {
1533
- id: "conversation",
1534
- label: "Conversation"
2111
+ id: "timeline",
2112
+ label: "Timeline"
1535
2113
  },
1536
2114
  {
1537
- id: "agent-state",
1538
- label: "Agent State"
2115
+ id: "raw-events",
2116
+ label: "Raw AG-UI Events"
1539
2117
  },
1540
2118
  {
1541
- id: "ag-ui-events",
1542
- label: "AG-UI Events"
2119
+ id: "state",
2120
+ label: "State"
1543
2121
  }
1544
2122
  ];
1545
- ɵCpkThreadDetails.styles = lit.css`
2123
+ CpkThreadInspector.providerIds = /* @__PURE__ */ new WeakMap();
2124
+ CpkThreadInspector.nextProviderId = 1;
2125
+ CpkThreadInspector.styles = lit.css`
1546
2126
  @import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600&family=Spline+Sans+Mono:wght@400;500&display=swap");
1547
2127
 
1548
2128
  /* ── Root ────────────────────────────────────────────────────────── */
@@ -1668,6 +2248,42 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
1668
2248
  flex-shrink: 0;
1669
2249
  }
1670
2250
 
2251
+ .cpk-td__metadata-strip {
2252
+ display: flex;
2253
+ gap: 6px;
2254
+ flex-wrap: wrap;
2255
+ padding: 10px 16px;
2256
+ border-bottom: 1px solid #e9e9ef;
2257
+ background: #fbfbfd;
2258
+ flex-shrink: 0;
2259
+ }
2260
+
2261
+ .cpk-td__metadata-pill {
2262
+ display: inline-flex;
2263
+ align-items: center;
2264
+ gap: 5px;
2265
+ max-width: 220px;
2266
+ padding: 3px 7px;
2267
+ border: 1px solid #e9e9ef;
2268
+ border-radius: 5px;
2269
+ background: #ffffff;
2270
+ color: #57575b;
2271
+ font-family: "Spline Sans Mono", monospace;
2272
+ font-size: 10px;
2273
+ white-space: nowrap;
2274
+ }
2275
+
2276
+ .cpk-td__metadata-label {
2277
+ color: #838389;
2278
+ text-transform: uppercase;
2279
+ font-size: 9px;
2280
+ }
2281
+
2282
+ .cpk-td__metadata-value {
2283
+ overflow: hidden;
2284
+ text-overflow: ellipsis;
2285
+ }
2286
+
1671
2287
  /*
1672
2288
  * Each tab's content is wrapped in this panel so the keep-mounted
1673
2289
  * inactive panels can be hidden via display:none without disturbing
@@ -1888,6 +2504,81 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
1888
2504
  background: #e9e9ef;
1889
2505
  }
1890
2506
 
2507
+ /* ── Interaction timeline ───────────────────────────────────────── */
2508
+ .cpk-td__timeline-item {
2509
+ border: 1px solid #e9e9ef;
2510
+ border-radius: 6px;
2511
+ background: #ffffff;
2512
+ overflow: hidden;
2513
+ }
2514
+
2515
+ .cpk-td__timeline-item--warning {
2516
+ border-color: rgba(250, 95, 103, 0.35);
2517
+ background: rgba(250, 95, 103, 0.04);
2518
+ }
2519
+
2520
+ .cpk-td__timeline-header {
2521
+ display: flex;
2522
+ align-items: center;
2523
+ gap: 8px;
2524
+ padding: 7px 10px;
2525
+ background: #f7f7f9;
2526
+ }
2527
+
2528
+ .cpk-td__timeline-kind {
2529
+ font-family: "Spline Sans Mono", monospace;
2530
+ font-size: 9px;
2531
+ font-weight: 600;
2532
+ text-transform: uppercase;
2533
+ color: #5558b2;
2534
+ }
2535
+
2536
+ .cpk-td__timeline-title {
2537
+ flex: 1;
2538
+ min-width: 0;
2539
+ font-size: 12px;
2540
+ font-weight: 500;
2541
+ color: #010507;
2542
+ overflow: hidden;
2543
+ text-overflow: ellipsis;
2544
+ white-space: nowrap;
2545
+ }
2546
+
2547
+ .cpk-td__timeline-time {
2548
+ font-family: "Spline Sans Mono", monospace;
2549
+ font-size: 9px;
2550
+ color: #838389;
2551
+ flex-shrink: 0;
2552
+ }
2553
+
2554
+ .cpk-td__timeline-body {
2555
+ padding: 9px 10px;
2556
+ font-size: 12px;
2557
+ line-height: 1.55;
2558
+ color: #57575b;
2559
+ white-space: pre-wrap;
2560
+ word-break: break-word;
2561
+ border-top: 1px solid #e9e9ef;
2562
+ }
2563
+
2564
+ .cpk-td__source-link {
2565
+ margin: 0;
2566
+ padding: 0;
2567
+ border: none;
2568
+ background: transparent;
2569
+ color: #5558b2;
2570
+ cursor: pointer;
2571
+ font-family: "Spline Sans Mono", monospace;
2572
+ font-size: 9px;
2573
+ text-decoration: underline;
2574
+ text-underline-offset: 2px;
2575
+ flex-shrink: 0;
2576
+ }
2577
+
2578
+ .cpk-td__source-link:hover {
2579
+ color: #010507;
2580
+ }
2581
+
1891
2582
  /* ── Generative UI ──────────────────────────────────────────────── */
1892
2583
  @keyframes cpk-genui-enter {
1893
2584
  from {
@@ -2095,7 +2786,9 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2095
2786
  text-align: right;
2096
2787
  }
2097
2788
  `;
2789
+ var ɵCpkThreadDetails = class extends CpkThreadInspector {};
2098
2790
  if (!customElements.get("cpk-thread-list")) customElements.define("cpk-thread-list", CpkThreadList);
2791
+ if (!customElements.get(THREAD_INSPECTOR_TAG)) customElements.define(THREAD_INSPECTOR_TAG, CpkThreadInspector);
2099
2792
  if (!customElements.get("cpk-thread-details")) customElements.define("cpk-thread-details", ɵCpkThreadDetails);
2100
2793
  var WebInspectorElement = class extends lit.LitElement {
2101
2794
  constructor(..._args3) {
@@ -2167,6 +2860,7 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2167
2860
  this.viewedBannerTimestamps = /* @__PURE__ */ new Set();
2168
2861
  this.pendingBannerViewed = null;
2169
2862
  this.clickedBannerIds = /* @__PURE__ */ new Set();
2863
+ this.viewedThreadsTelemetryStates = /* @__PURE__ */ new Set();
2170
2864
  this.contextState = {
2171
2865
  button: {
2172
2866
  position: {
@@ -2376,6 +3070,30 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2376
3070
  this.expandedTools = /* @__PURE__ */ new Set();
2377
3071
  this.expandedContextItems = /* @__PURE__ */ new Set();
2378
3072
  this.copiedContextItems = /* @__PURE__ */ new Set();
3073
+ this.handleTalkToEngineerClick = () => {
3074
+ var _this$core;
3075
+ if ((_this$core = this.core) === null || _this$core === void 0 ? void 0 : _this$core.telemetryDisabled) return;
3076
+ trackTalkToEngineerClicked(this.getThreadsTelemetryProps({
3077
+ cta: "talk_to_engineer",
3078
+ cta_surface: "threads_header"
3079
+ }, { includeUrlAttribution: true }));
3080
+ };
3081
+ this.handleThreadsIntelligenceSignupClick = () => {
3082
+ var _this$core2;
3083
+ if ((_this$core2 = this.core) === null || _this$core2 === void 0 ? void 0 : _this$core2.telemetryDisabled) return;
3084
+ trackThreadsIntelligenceSignupClicked(this.getThreadsTelemetryProps({
3085
+ cta: "signup",
3086
+ cta_surface: "threads_locked"
3087
+ }, { includeUrlAttribution: true }));
3088
+ };
3089
+ this.handleThreadsTalkToEngineerClick = () => {
3090
+ var _this$core3;
3091
+ if ((_this$core3 = this.core) === null || _this$core3 === void 0 ? void 0 : _this$core3.telemetryDisabled) return;
3092
+ trackThreadsTalkToEngineerClicked(this.getThreadsTelemetryProps({
3093
+ cta: "talk_to_engineer",
3094
+ cta_surface: "threads_locked"
3095
+ }, { includeUrlAttribution: true }));
3096
+ };
2379
3097
  this.handleThreadDividerPointerDown = (event) => {
2380
3098
  this.threadDividerResizing = true;
2381
3099
  this.threadDividerPointerId = event.pointerId;
@@ -2498,7 +3216,38 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2498
3216
  }
2499
3217
  ];
2500
3218
  }
3219
+ getThreadServiceStatus() {
3220
+ var _this$_core$threadEnd;
3221
+ if (!this._core) return "unknown";
3222
+ if (!this._core.threadEndpoints) return "unknown";
3223
+ return ((_this$_core$threadEnd = this._core.threadEndpoints) === null || _this$_core$threadEnd === void 0 ? void 0 : _this$_core$threadEnd.list) === false ? "unavailable" : "available";
3224
+ }
3225
+ areThreadEndpointsAvailable() {
3226
+ return this.getThreadServiceStatus() !== "unavailable";
3227
+ }
3228
+ getThreadsTelemetryProps(extra = {}, options = {}) {
3229
+ var _this$core4, _this$core$licenseSta, _this$core5, _this$core$runtimeMod, _this$core6, _this$core7, _this$core$telemetryD, _this$core8;
3230
+ const distinctId = options.includeUrlAttribution && !((_this$core4 = this.core) === null || _this$core4 === void 0 ? void 0 : _this$core4.telemetryDisabled) ? getTelemetryDistinctIdForUrl() : null;
3231
+ const threadServiceStatus = this.getThreadServiceStatus();
3232
+ return {
3233
+ posthog_distinct_id: distinctId !== null && distinctId !== void 0 ? distinctId : void 0,
3234
+ intelligence_status: threadServiceStatus === "available" ? "intelligence_enabled" : threadServiceStatus === "unavailable" ? "intelligence_not_enabled" : "unknown",
3235
+ thread_service_status: threadServiceStatus,
3236
+ 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,
3237
+ 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,
3238
+ runtime_url_type: getRuntimeUrlType((_this$core7 = this.core) === null || _this$core7 === void 0 ? void 0 : _this$core7.runtimeUrl),
3239
+ 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,
3240
+ ...extra
3241
+ };
3242
+ }
3243
+ getIntelligenceSignupUrl() {
3244
+ return this.appendRefParam(INTELLIGENCE_SIGNUP_URL, "cpk-inspector");
3245
+ }
3246
+ getTalkToEngineerUrl() {
3247
+ return this.appendRefParam(TALK_TO_ENGINEER_URL, "cpk-inspector-threads");
3248
+ }
2501
3249
  subscribeToThreadStore(agentId, store) {
3250
+ if (!this.areThreadEndpointsAvailable()) return;
2502
3251
  if (this._threadStoreSubscriptions.has(agentId)) return;
2503
3252
  const threadsSub = store.select(_copilotkit_core.ɵselectThreads).subscribe((threads) => {
2504
3253
  this._threadsByAgent.set(agentId, threads);
@@ -2535,12 +3284,12 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2535
3284
  this._threads = [];
2536
3285
  }
2537
3286
  ensureOwnedThreadStore(agentId) {
2538
- var _this$core, _core$threadEndpoints, _core$intelligence;
3287
+ var _this$core9, _core$intelligence;
2539
3288
  if (this._ownedThreadStores.has(agentId)) return;
2540
- if ((_this$core = this.core) === null || _this$core === void 0 ? void 0 : _this$core.getThreadStore(agentId)) return;
3289
+ if ((_this$core9 = this.core) === null || _this$core9 === void 0 ? void 0 : _this$core9.getThreadStore(agentId)) return;
2541
3290
  const core = this.core;
2542
3291
  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;
3292
+ if (!this.areThreadEndpointsAvailable()) return;
2544
3293
  const store = (0, _copilotkit_core.ɵcreateThreadStore)({ fetch: globalThis.fetch });
2545
3294
  store.start();
2546
3295
  store.setContext({
@@ -2561,25 +3310,29 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2561
3310
  updateOwnedThreadStoreHeaders(headers) {
2562
3311
  const core = this.core;
2563
3312
  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
- });
3313
+ for (const [agentId, store] of this._ownedThreadStores) {
3314
+ var _core$intelligence2;
3315
+ store.setContext({
3316
+ runtimeUrl: core.runtimeUrl,
3317
+ headers: { ...headers },
3318
+ wsUrl: (_core$intelligence2 = core.intelligence) === null || _core$intelligence2 === void 0 ? void 0 : _core$intelligence2.wsUrl,
3319
+ agentId
3320
+ });
3321
+ }
2569
3322
  }
2570
3323
  removeOwnedThreadStore(agentId) {
2571
- var _this$core2;
3324
+ var _this$core10;
2572
3325
  const store = this._ownedThreadStores.get(agentId);
2573
3326
  if (!store) return;
2574
3327
  store.stop();
2575
- (_this$core2 = this.core) === null || _this$core2 === void 0 || _this$core2.unregisterThreadStore(agentId);
3328
+ (_this$core10 = this.core) === null || _this$core10 === void 0 || _this$core10.unregisterThreadStore(agentId);
2576
3329
  this._ownedThreadStores.delete(agentId);
2577
3330
  }
2578
3331
  teardownOwnedThreadStores() {
2579
3332
  for (const [agentId, store] of this._ownedThreadStores) {
2580
- var _this$core3;
3333
+ var _this$core11;
2581
3334
  store.stop();
2582
- (_this$core3 = this.core) === null || _this$core3 === void 0 || _this$core3.unregisterThreadStore(agentId);
3335
+ (_this$core11 = this.core) === null || _this$core11 === void 0 || _this$core11.unregisterThreadStore(agentId);
2583
3336
  }
2584
3337
  this._ownedThreadStores.clear();
2585
3338
  }
@@ -2591,13 +3344,12 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2591
3344
  onRuntimeConnectionStatusChanged: ({ status }) => {
2592
3345
  this.runtimeStatus = status;
2593
3346
  if (status === "connected") {
2594
- var _core$threadEndpoints2;
2595
3347
  if (!core.telemetryDisabled) {
2596
3348
  ensureTelemetryDistinctId();
2597
3349
  maybeShowDisclosure();
2598
3350
  }
2599
3351
  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);
3352
+ if (this.areThreadEndpointsAvailable()) for (const agentId of this._ownedThreadStores.keys()) this.refreshOwnedThreadStore(agentId);
2601
3353
  else this.teardownOwnedThreadStores();
2602
3354
  } else {
2603
3355
  this._threadsByAgent.clear();
@@ -2611,6 +3363,7 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2611
3363
  },
2612
3364
  onHeadersChanged: ({ headers }) => {
2613
3365
  this.updateOwnedThreadStoreHeaders(headers);
3366
+ this.requestUpdate();
2614
3367
  },
2615
3368
  onError: ({ code, error }) => {
2616
3369
  this.lastCoreError = {
@@ -2622,6 +3375,9 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2622
3375
  onAgentsChanged: ({ agents }) => {
2623
3376
  this.processAgentsChanged(agents);
2624
3377
  },
3378
+ onAgentRunStarted: ({ agent }) => {
3379
+ if (agent === null || agent === void 0 ? void 0 : agent.agentId) this.subscribeToAgent(agent);
3380
+ },
2625
3381
  onContextChanged: ({ context }) => {
2626
3382
  this.contextStore = this.normalizeContextStore(context);
2627
3383
  this.requestUpdate();
@@ -2644,6 +3400,13 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2644
3400
  };
2645
3401
  this.coreUnsubscribe = core.subscribe(this.coreSubscriber).unsubscribe;
2646
3402
  this.processAgentsChanged(core.agents);
3403
+ if (core.runtimeConnectionStatus === "connected") {
3404
+ if (!core.telemetryDisabled) {
3405
+ ensureTelemetryDistinctId();
3406
+ maybeShowDisclosure();
3407
+ }
3408
+ this.flushPendingBannerViewed();
3409
+ }
2647
3410
  const threadStores = typeof core.getThreadStores === "function" ? core.getThreadStores() : {};
2648
3411
  for (const [agentId, store] of Object.entries(threadStores)) this.subscribeToThreadStore(agentId, store);
2649
3412
  if (core.context) this.contextStore = this.normalizeContextStore(core.context);
@@ -2733,10 +3496,10 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
2733
3496
  onRunStartedEvent: ({ event }) => {
2734
3497
  this.recordAgentEvent(agentId, "RUN_STARTED", event);
2735
3498
  },
2736
- onRunFinishedEvent: ({ event, result }) => {
3499
+ onRunFinishedEvent: (params) => {
2737
3500
  this.recordAgentEvent(agentId, "RUN_FINISHED", {
2738
- event,
2739
- result
3501
+ event: params.event,
3502
+ result: "result" in params ? params.result : void 0
2740
3503
  });
2741
3504
  this.refreshOwnedThreadStore(agentId);
2742
3505
  },
@@ -3002,8 +3765,8 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}
3002
3765
  return lit.html`
3003
3766
  <div class="mt-2 space-y-2">
3004
3767
  ${toolCalls.map((call, index) => {
3005
- var _ref3, _call$function$name, _call$function, _call$function2;
3006
- const functionName = (_ref3 = (_call$function$name = (_call$function = call.function) === null || _call$function === void 0 ? void 0 : _call$function.name) !== null && _call$function$name !== void 0 ? _call$function$name : call.toolName) !== null && _ref3 !== void 0 ? _ref3 : "Unknown function";
3768
+ var _ref4, _call$function$name, _call$function, _call$function2;
3769
+ const functionName = (_ref4 = (_call$function$name = (_call$function = call.function) === null || _call$function === void 0 ? void 0 : _call$function.name) !== null && _call$function$name !== void 0 ? _call$function$name : call.toolName) !== null && _ref4 !== void 0 ? _ref4 : "Unknown function";
3007
3770
  const callId = typeof (call === null || call === void 0 ? void 0 : call.id) === "string" ? call.id : `tool-call-${index + 1}`;
3008
3771
  const argsString = this.formatToolCallArguments((_call$function2 = call.function) === null || _call$function2 === void 0 ? void 0 : _call$function2.arguments);
3009
3772
  return lit.html`
@@ -3032,12 +3795,12 @@ ${argsString}</pre
3032
3795
  if (typeof args === "string") try {
3033
3796
  const parsed = JSON.parse(args);
3034
3797
  return JSON.stringify(parsed, null, 2);
3035
- } catch (_unused) {
3798
+ } catch (_unused3) {
3036
3799
  return args;
3037
3800
  }
3038
3801
  if (typeof args === "object") try {
3039
3802
  return JSON.stringify(args, null, 2);
3040
- } catch (_unused2) {
3803
+ } catch (_unused4) {
3041
3804
  return String(args);
3042
3805
  }
3043
3806
  return String(args);
@@ -3060,26 +3823,26 @@ ${argsString}</pre
3060
3823
  try {
3061
3824
  const parsed = JSON.parse(trimmed);
3062
3825
  return JSON.stringify(parsed, null, 2);
3063
- } catch (_unused3) {
3826
+ } catch (_unused5) {
3064
3827
  return state;
3065
3828
  }
3066
3829
  }
3067
3830
  if (typeof state === "object") try {
3068
3831
  return JSON.stringify(state, null, 2);
3069
- } catch (_unused4) {
3832
+ } catch (_unused6) {
3070
3833
  return String(state);
3071
3834
  }
3072
3835
  return String(state);
3073
3836
  }
3074
3837
  getEventBadgeClasses(type) {
3075
3838
  const base = "font-mono text-[10px] font-medium inline-flex items-center rounded-sm px-1.5 py-0.5 border";
3839
+ if (type === "RUN_ERROR") return `${base} bg-rose-50 text-rose-700 border-rose-200`;
3076
3840
  if (type.startsWith("RUN_")) return `${base} bg-blue-50 text-blue-700 border-blue-200`;
3077
3841
  if (type.startsWith("TEXT_MESSAGE")) return `${base} bg-emerald-50 text-emerald-700 border-emerald-200`;
3078
3842
  if (type.startsWith("TOOL_CALL")) return `${base} bg-amber-50 text-amber-700 border-amber-200`;
3079
3843
  if (type.startsWith("REASONING")) return `${base} bg-fuchsia-50 text-fuchsia-700 border-fuchsia-200`;
3080
3844
  if (type.startsWith("STATE")) return `${base} bg-violet-50 text-violet-700 border-violet-200`;
3081
3845
  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
3846
  return `${base} bg-gray-100 text-gray-600 border-gray-200`;
3084
3847
  }
3085
3848
  stringifyPayload(payload, pretty) {
@@ -3751,7 +4514,7 @@ ${argsString}</pre
3751
4514
  if (content === null || content === void 0) return "";
3752
4515
  if (typeof content === "object") try {
3753
4516
  return JSON.stringify(this.sanitizeForLogging(content));
3754
- } catch (_unused5) {
4517
+ } catch (_unused7) {
3755
4518
  return "";
3756
4519
  }
3757
4520
  return String(content);
@@ -3869,8 +4632,8 @@ ${argsString}</pre
3869
4632
  return lit.nothing;
3870
4633
  }
3871
4634
  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;
4635
+ var _this$core$telemetryD2, _this$core12;
4636
+ 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
4637
  return lit.html`
3875
4638
  <div class="flex h-full flex-col overflow-hidden">
3876
4639
  <div class="overflow-auto p-4">
@@ -3879,7 +4642,9 @@ ${argsString}</pre
3879
4642
 
3880
4643
  <div class="space-y-2">
3881
4644
  <h3 class="text-sm text-slate-500">Privacy</h3>
3882
- <div class="rounded-lg border border-slate-200 bg-white p-4 space-y-3">
4645
+ <div
4646
+ class="rounded-lg border border-slate-200 bg-white p-4 space-y-3"
4647
+ >
3883
4648
  <p class="text-sm text-gray-600 flex items-start gap-2">
3884
4649
  <span>${optedOut ? "❌" : "✅"}</span>
3885
4650
  <span>
@@ -3891,7 +4656,8 @@ ${argsString}</pre
3891
4656
  href=${TELEMETRY_DOCS_URL}
3892
4657
  target="_blank"
3893
4658
  rel="noopener"
3894
- >Learn more →</a>
4659
+ >Learn more →</a
4660
+ >
3895
4661
  </div>
3896
4662
  </div>
3897
4663
  </div>
@@ -3900,8 +4666,8 @@ ${argsString}</pre
3900
4666
  `;
3901
4667
  }
3902
4668
  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;
4669
+ var _this$core13, _this$announcementCta;
4670
+ if ((_this$core13 = this.core) === null || _this$core13 === void 0 ? void 0 : _this$core13.telemetryDisabled) return;
3905
4671
  const id = this.announcementTimestamp;
3906
4672
  if (!id) return;
3907
4673
  const key = `${id}:${opts.cta}`;
@@ -3913,8 +4679,314 @@ ${argsString}</pre
3913
4679
  cta_label: (_this$announcementCta = this.announcementCtaLabel) !== null && _this$announcementCta !== void 0 ? _this$announcementCta : void 0
3914
4680
  });
3915
4681
  }
4682
+ trackThreadsViewStateOnce(state, threadCount) {
4683
+ var _this$core14;
4684
+ if ((_this$core14 = this.core) === null || _this$core14 === void 0 ? void 0 : _this$core14.telemetryDisabled) return;
4685
+ const key = `${state}:${this.getThreadServiceStatus()}`;
4686
+ if (this.viewedThreadsTelemetryStates.has(key)) return;
4687
+ this.viewedThreadsTelemetryStates.add(key);
4688
+ const props = this.getThreadsTelemetryProps({ thread_count: threadCount });
4689
+ if (state === "locked") trackThreadsLockedViewed(props);
4690
+ else if (state === "empty_enabled") trackThreadsEmptyEnabledViewed(props);
4691
+ else trackThreadsEnabledViewed(props);
4692
+ }
4693
+ renderThreadsLockedBackgroundMockup() {
4694
+ return lit.html`
4695
+ <div
4696
+ aria-hidden="true"
4697
+ style="
4698
+ position: absolute;
4699
+ inset: 0;
4700
+ display: grid;
4701
+ grid-template-columns: minmax(180px, 28%) 1fr;
4702
+ overflow: hidden;
4703
+ opacity: 0.58;
4704
+ pointer-events: none;
4705
+ "
4706
+ >
4707
+ <div
4708
+ style="
4709
+ display: flex;
4710
+ flex-direction: column;
4711
+ gap: 12px;
4712
+ padding: 28px 24px;
4713
+ border-right: 1px solid #dbdbe5;
4714
+ background: #fafafa;
4715
+ "
4716
+ >
4717
+ ${[
4718
+ {
4719
+ width: 74,
4720
+ accent: true
4721
+ },
4722
+ { width: 92 },
4723
+ { width: 68 },
4724
+ { width: 84 },
4725
+ { width: 58 },
4726
+ { width: 76 }
4727
+ ].map((row) => lit.html`
4728
+ <div
4729
+ style="
4730
+ padding: 12px;
4731
+ border-radius: 8px;
4732
+ background: ${row.accent ? "#eee6fe" : "#ffffff"};
4733
+ box-shadow: inset 0 0 0 1px #eeeef4;
4734
+ "
4735
+ >
4736
+ <div
4737
+ style="
4738
+ height: 8px;
4739
+ width: ${row.width}%;
4740
+ border-radius: 99px;
4741
+ background: ${row.accent ? "#a984f5" : "#d7d7df"};
4742
+ "
4743
+ ></div>
4744
+ <div
4745
+ style="
4746
+ height: 6px;
4747
+ width: 88%;
4748
+ margin-top: 10px;
4749
+ border-radius: 99px;
4750
+ background: #e3e3eb;
4751
+ "
4752
+ ></div>
4753
+ <div
4754
+ style="
4755
+ height: 6px;
4756
+ width: 62%;
4757
+ margin-top: 7px;
4758
+ border-radius: 99px;
4759
+ background: #e8e8ef;
4760
+ "
4761
+ ></div>
4762
+ </div>
4763
+ `)}
4764
+ </div>
4765
+ <div
4766
+ style="
4767
+ min-width: 0;
4768
+ padding: 42px 48px;
4769
+ background: #ffffff;
4770
+ "
4771
+ >
4772
+ <div
4773
+ style="
4774
+ height: 10px;
4775
+ width: 180px;
4776
+ border-radius: 99px;
4777
+ background: #d7d7df;
4778
+ "
4779
+ ></div>
4780
+ <div
4781
+ style="
4782
+ height: 8px;
4783
+ width: min(520px, 58%);
4784
+ margin-top: 28px;
4785
+ border-radius: 99px;
4786
+ background: #e3e3eb;
4787
+ "
4788
+ ></div>
4789
+ <div
4790
+ style="
4791
+ height: 8px;
4792
+ width: min(430px, 48%);
4793
+ margin-top: 12px;
4794
+ border-radius: 99px;
4795
+ background: #e8e8ef;
4796
+ "
4797
+ ></div>
4798
+ <div
4799
+ style="
4800
+ display: grid;
4801
+ grid-template-columns: repeat(2, minmax(0, 1fr));
4802
+ gap: 16px;
4803
+ max-width: 620px;
4804
+ margin-top: 30px;
4805
+ "
4806
+ >
4807
+ <div
4808
+ style="
4809
+ height: 116px;
4810
+ border-radius: 8px;
4811
+ background: #f5f5f8;
4812
+ box-shadow: inset 0 0 0 1px #eeeef4;
4813
+ "
4814
+ ></div>
4815
+ <div
4816
+ style="
4817
+ height: 116px;
4818
+ border-radius: 8px;
4819
+ background: #f5f5f8;
4820
+ box-shadow: inset 0 0 0 1px #eeeef4;
4821
+ "
4822
+ ></div>
4823
+ </div>
4824
+ <div
4825
+ style="
4826
+ height: 10px;
4827
+ width: min(680px, 74%);
4828
+ margin-top: 34px;
4829
+ border-radius: 99px;
4830
+ background: #e3e3eb;
4831
+ "
4832
+ ></div>
4833
+ <div
4834
+ style="
4835
+ height: 10px;
4836
+ width: min(560px, 60%);
4837
+ margin-top: 14px;
4838
+ border-radius: 99px;
4839
+ background: #e8e8ef;
4840
+ "
4841
+ ></div>
4842
+ </div>
4843
+ </div>
4844
+ `;
4845
+ }
4846
+ renderThreadsLockedView() {
4847
+ this.trackThreadsViewStateOnce("locked", 0);
4848
+ return lit.html`
4849
+ <div
4850
+ style="
4851
+ position: relative;
4852
+ height: 100%;
4853
+ display: flex;
4854
+ align-items: center;
4855
+ justify-content: center;
4856
+ padding: 32px;
4857
+ overflow: hidden;
4858
+ background: #ffffff;
4859
+ "
4860
+ >
4861
+ ${this.renderThreadsLockedBackgroundMockup()}
4862
+ <div
4863
+ aria-hidden="true"
4864
+ style="
4865
+ position: absolute;
4866
+ inset: 0;
4867
+ pointer-events: none;
4868
+ background:
4869
+ 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%);
4870
+ "
4871
+ ></div>
4872
+ <div
4873
+ style="
4874
+ position: relative;
4875
+ z-index: 1;
4876
+ max-width: 440px;
4877
+ text-align: center;
4878
+ color: #57575b;
4879
+ "
4880
+ >
4881
+ <div
4882
+ aria-hidden="true"
4883
+ style="
4884
+ margin: 0 auto 18px;
4885
+ display: flex;
4886
+ justify-content: center;
4887
+ "
4888
+ >
4889
+ <div
4890
+ style="
4891
+ display: flex;
4892
+ height: 44px;
4893
+ width: 44px;
4894
+ align-items: center;
4895
+ justify-content: center;
4896
+ border: 1px solid #dfd6fb;
4897
+ border-radius: 8px;
4898
+ background: #eee6fe;
4899
+ color: #57575b;
4900
+ box-shadow: 0 8px 18px rgba(87, 87, 91, 0.14);
4901
+ "
4902
+ >
4903
+ ${this.renderIcon("Lock")}
4904
+ </div>
4905
+ </div>
4906
+ <h2
4907
+ style="
4908
+ margin: 0 0 8px;
4909
+ font-size: 16px;
4910
+ line-height: 1.35;
4911
+ font-weight: 600;
4912
+ color: #010507;
4913
+ "
4914
+ >
4915
+ Enable Intelligence to inspect Threads.
4916
+ </h2>
4917
+ <p
4918
+ style="
4919
+ margin: 0 auto 18px;
4920
+ max-width: 380px;
4921
+ font-size: 13px;
4922
+ line-height: 1.55;
4923
+ color: #57575b;
4924
+ "
4925
+ >
4926
+ Persist conversations and inspect saved thread history from the
4927
+ Inspector.
4928
+ </p>
4929
+ <div
4930
+ style="
4931
+ display: flex;
4932
+ flex-wrap: wrap;
4933
+ justify-content: center;
4934
+ gap: 8px;
4935
+ "
4936
+ >
4937
+ <a
4938
+ href=${this.getTalkToEngineerUrl()}
4939
+ target="_blank"
4940
+ rel="noopener"
4941
+ style="
4942
+ display: inline-flex;
4943
+ min-height: 34px;
4944
+ align-items: center;
4945
+ justify-content: center;
4946
+ gap: 6px;
4947
+ border-radius: 6px;
4948
+ background: #010507;
4949
+ padding: 8px 12px;
4950
+ font-size: 12px;
4951
+ font-weight: 600;
4952
+ color: #ffffff;
4953
+ text-decoration: none;
4954
+ "
4955
+ @click=${this.handleThreadsTalkToEngineerClick}
4956
+ >
4957
+ Talk to an Engineer
4958
+ </a>
4959
+ <a
4960
+ href=${this.getIntelligenceSignupUrl()}
4961
+ target="_blank"
4962
+ rel="noopener"
4963
+ style="
4964
+ display: inline-flex;
4965
+ min-height: 34px;
4966
+ align-items: center;
4967
+ justify-content: center;
4968
+ gap: 6px;
4969
+ border-radius: 6px;
4970
+ border: 1px solid #dbdbe5;
4971
+ background: #ffffff;
4972
+ padding: 8px 12px;
4973
+ font-size: 12px;
4974
+ font-weight: 600;
4975
+ color: #57575b;
4976
+ text-decoration: none;
4977
+ "
4978
+ @click=${this.handleThreadsIntelligenceSignupClick}
4979
+ >
4980
+ Sign up for Intelligence
4981
+ </a>
4982
+ </div>
4983
+ </div>
4984
+ </div>
4985
+ `;
4986
+ }
3916
4987
  renderThreadsView() {
3917
4988
  var _this$_threadsByAgent, _displayThreads$find, _this$_core$runtimeUr, _this$_core2, _this$_core$headers, _this$_core3, _this$_core4, _this$liveMessageVers2, _this$agentEvents$get6;
4989
+ if (!this.areThreadEndpointsAvailable()) return this.renderThreadsLockedView();
3918
4990
  const displayThreads = this.selectedContext === "all-agents" ? this._threads : (_this$_threadsByAgent = this._threadsByAgent.get(this.selectedContext)) !== null && _this$_threadsByAgent !== void 0 ? _this$_threadsByAgent : [];
3919
4991
  let threadsErrorMessage = null;
3920
4992
  if (this.selectedContext === "all-agents") {
@@ -3926,72 +4998,88 @@ ${argsString}</pre
3926
4998
  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
4999
  }
3928
5000
  const selectedThread = this.selectedThreadId != null ? (_displayThreads$find = displayThreads.find((t) => t.id === this.selectedThreadId)) !== null && _displayThreads$find !== void 0 ? _displayThreads$find : null : null;
5001
+ if (!threadsErrorMessage) this.trackThreadsViewStateOnce(displayThreads.length === 0 ? "empty_enabled" : "enabled", displayThreads.length);
3929
5002
  return lit.html`
3930
- <div style="display:flex;height:100%;overflow:hidden;">
3931
- <!-- Left sidebar: thread list -->
5003
+ <div style="display:flex;height:100%;overflow:hidden;flex-direction:column;">
3932
5004
  <div
3933
- style="width:${this.threadListWidth}px;flex-shrink:0;overflow:hidden;display:flex;flex-direction:column;border-right:1px solid #DBDBE5;"
5005
+ style="display:flex;align-items:center;justify-content:flex-end;border-bottom:1px solid #DBDBE5;background:#ffffff;padding:8px 12px;flex-shrink:0;"
3934
5006
  >
3935
- <cpk-thread-list
3936
- style="height:100%;"
3937
- .threads=${displayThreads}
3938
- .selectedThreadId=${this.selectedThreadId}
3939
- .errorMessage=${threadsErrorMessage}
3940
- @threadSelected=${(e) => {
5007
+ <a
5008
+ href=${this.getTalkToEngineerUrl()}
5009
+ target="_blank"
5010
+ rel="noopener"
5011
+ 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;"
5012
+ @click=${this.handleTalkToEngineerClick}
5013
+ >
5014
+ Talk to an Engineer
5015
+ </a>
5016
+ </div>
5017
+ <div style="display:flex;min-height:0;flex:1;overflow:hidden;">
5018
+ <!-- Left sidebar: thread list -->
5019
+ <div
5020
+ style="width:${this.threadListWidth}px;flex-shrink:0;overflow:hidden;display:flex;flex-direction:column;border-right:1px solid #DBDBE5;"
5021
+ >
5022
+ <cpk-thread-list
5023
+ style="height:100%;"
5024
+ .threads=${displayThreads}
5025
+ .selectedThreadId=${this.selectedThreadId}
5026
+ .errorMessage=${threadsErrorMessage}
5027
+ @threadSelected=${(e) => {
3941
5028
  this.selectedThreadId = e.detail;
3942
5029
  this.requestUpdate();
3943
5030
  }}
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>
5031
+ ></cpk-thread-list>
5032
+ </div>
3955
5033
 
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"
5034
+ <!-- Resize divider -->
5035
+ <div
5036
+ style="width:4px;flex-shrink:0;cursor:col-resize;background:transparent;position:relative;z-index:1;"
5037
+ @pointerdown=${this.handleThreadDividerPointerDown}
5038
+ @pointermove=${this.handleThreadDividerPointerMove}
5039
+ @pointerup=${this.handleThreadDividerPointerUp}
5040
+ @pointercancel=${this.handleThreadDividerPointerUp}
5041
+ ></div>
5042
+
5043
+ <!-- Center + right: thread details or empty state -->
5044
+ <div style="flex:1;min-width:0;overflow:hidden;display:flex;">
5045
+ ${selectedThread ? lit.html`<cpk-thread-details
5046
+ style="flex:1;min-width:0;"
5047
+ .threadId=${selectedThread.id}
5048
+ .thread=${selectedThread}
5049
+ .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 : ""}
5050
+ .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 : {}}
5051
+ .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}
5052
+ .liveMessageVersion=${(_this$liveMessageVers2 = this.liveMessageVersion.get(selectedThread.id)) !== null && _this$liveMessageVers2 !== void 0 ? _this$liveMessageVers2 : 0}
5053
+ .agentStateInput=${this.getLatestStateForAgent(selectedThread.agentId)}
5054
+ .agentEventsInput=${(_this$agentEvents$get6 = this.agentEvents.get(selectedThread.agentId)) !== null && _this$agentEvents$get6 !== void 0 ? _this$agentEvents$get6 : []}
5055
+ ></cpk-thread-details>` : lit.html`
5056
+ <div
5057
+ style="
5058
+ flex: 1;
5059
+ display: flex;
5060
+ flex-direction: column;
5061
+ align-items: center;
5062
+ justify-content: center;
5063
+ gap: 8px;
5064
+ color: #838389;
5065
+ "
3989
5066
  >
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
- `}
5067
+ <svg
5068
+ width="32"
5069
+ height="32"
5070
+ viewBox="0 0 24 24"
5071
+ fill="none"
5072
+ stroke="#c0c0c8"
5073
+ stroke-width="1.5"
5074
+ stroke-linecap="round"
5075
+ stroke-linejoin="round"
5076
+ >
5077
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
5078
+ </svg>
5079
+ <span style="font-size: 13px">${displayThreads.length === 0 ? "No threads yet" : "Select a thread to inspect"}</span>
5080
+ </div>
5081
+ `}
5082
+ </div>
3995
5083
  </div>
3996
5084
  </div>
3997
5085
  `;
@@ -4108,10 +5196,10 @@ ${argsString}</pre
4108
5196
  <div class="relative h-full w-full overflow-y-auto overflow-x-hidden">
4109
5197
  <table class="w-full table-fixed border-collapse text-xs box-border">
4110
5198
  <colgroup>
4111
- <col style="width:${this.evtColWidths[0]}px">
4112
- <col style="width:${this.evtColWidths[1]}px">
4113
- <col style="width:${this.evtColWidths[2]}px">
4114
- <col>
5199
+ <col style="width:${this.evtColWidths[0]}px" />
5200
+ <col style="width:${this.evtColWidths[1]}px" />
5201
+ <col style="width:${this.evtColWidths[2]}px" />
5202
+ <col />
4115
5203
  </colgroup>
4116
5204
  <thead class="sticky top-0 z-10">
4117
5205
  <tr class="bg-white">
@@ -4119,20 +5207,19 @@ ${argsString}</pre
4119
5207
  "Agent",
4120
5208
  "Time",
4121
5209
  "Event Type"
4122
- ].map((label, col) => lit.html`
4123
- <th
4124
- class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900"
4125
- style="position:relative;overflow:hidden;"
4126
- >
4127
- ${label}
4128
- <div
4129
- style="position:absolute;top:0;right:0;width:5px;height:100%;cursor:col-resize;user-select:none;background:transparent;"
4130
- @pointerdown=${(e) => this._onEvtColResizeStart(e, col)}
4131
- @pointermove=${(e) => this._onEvtColResizeMove(e)}
4132
- @pointerup=${() => this._onEvtColResizeEnd()}
4133
- @pointercancel=${() => this._onEvtColResizeEnd()}
4134
- ></div>
4135
- </th>`)}
5210
+ ].map((label, col) => lit.html` <th
5211
+ class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900"
5212
+ style="position:relative;overflow:hidden;"
5213
+ >
5214
+ ${label}
5215
+ <div
5216
+ style="position:absolute;top:0;right:0;width:5px;height:100%;cursor:col-resize;user-select:none;background:transparent;"
5217
+ @pointerdown=${(e) => this._onEvtColResizeStart(e, col)}
5218
+ @pointermove=${(e) => this._onEvtColResizeMove(e)}
5219
+ @pointerup=${() => this._onEvtColResizeEnd()}
5220
+ @pointercancel=${() => this._onEvtColResizeEnd()}
5221
+ ></div>
5222
+ </th>`)}
4136
5223
  <th
4137
5224
  class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900"
4138
5225
  >
@@ -4393,8 +5480,14 @@ ${prettyEvent}</pre
4393
5480
  ${messages && messages.length > 0 ? lit.html`
4394
5481
  <div class="w-full text-xs">
4395
5482
  <div class="flex bg-gray-50">
4396
- <div class="w-40 shrink-0 px-4 py-2 font-medium text-gray-700">Role</div>
4397
- <div class="flex-1 px-4 py-2 font-medium text-gray-700">Content</div>
5483
+ <div
5484
+ class="w-40 shrink-0 px-4 py-2 font-medium text-gray-700"
5485
+ >
5486
+ Role
5487
+ </div>
5488
+ <div class="flex-1 px-4 py-2 font-medium text-gray-700">
5489
+ Content
5490
+ </div>
4398
5491
  </div>
4399
5492
  <div class="divide-y divide-gray-200">
4400
5493
  ${messages.map((msg) => {
@@ -4519,13 +5612,13 @@ ${prettyEvent}</pre
4519
5612
  if (this.contextOptions.filter((opt) => opt.key !== "all-agents").length > 1) this.selectedContext = "all-agents";
4520
5613
  }
4521
5614
  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();
5615
+ var _this$core15;
5616
+ if (previousMenu !== "threads" && !((_this$core15 = this.core) === null || _this$core15 === void 0 ? void 0 : _this$core15.telemetryDisabled)) trackThreadsTabClicked(this.getThreadsTelemetryProps());
4524
5617
  this.autoSelectLatestThread();
4525
5618
  }
4526
5619
  if (key === "ag-ui-events" || key === "agents") requestAnimationFrame(() => {
4527
- var _this$shadowRoot;
4528
- const scroller = (_this$shadowRoot = this.shadowRoot) === null || _this$shadowRoot === void 0 ? void 0 : _this$shadowRoot.getElementById("cpk-main-scroll");
5620
+ var _this$shadowRoot2;
5621
+ const scroller = (_this$shadowRoot2 = this.shadowRoot) === null || _this$shadowRoot2 === void 0 ? void 0 : _this$shadowRoot2.getElementById("cpk-main-scroll");
4529
5622
  if (scroller) scroller.scrollTop = 0;
4530
5623
  });
4531
5624
  this.contextMenuOpen = false;
@@ -4825,9 +5918,9 @@ ${prettyEvent}</pre
4825
5918
  let currentSchema = schema;
4826
5919
  let def = currentSchema._def;
4827
5920
  while (def.typeName === "ZodOptional" || def.typeName === "ZodNullable" || def.typeName === "ZodDefault") {
4828
- var _ref4;
5921
+ var _ref5;
4829
5922
  if (def.typeName === "ZodDefault" && def.defaultValue !== void 0) info.defaultValue = typeof def.defaultValue === "function" ? def.defaultValue() : def.defaultValue;
4830
- currentSchema = (_ref4 = def.innerType) !== null && _ref4 !== void 0 ? _ref4 : currentSchema;
5923
+ currentSchema = (_ref5 = def.innerType) !== null && _ref5 !== void 0 ? _ref5 : currentSchema;
4831
5924
  if (!(currentSchema === null || currentSchema === void 0 ? void 0 : currentSchema._def)) break;
4832
5925
  def = currentSchema._def;
4833
5926
  }
@@ -4953,6 +6046,22 @@ ${prettyEvent}</pre
4953
6046
  ${this.copiedContextItems.has(id) ? "Copied" : "Copy JSON"}
4954
6047
  </button>
4955
6048
  </div>
6049
+ <pre
6050
+ style="
6051
+ margin: 0;
6052
+ max-height: 180px;
6053
+ overflow: auto;
6054
+ white-space: pre-wrap;
6055
+ word-break: break-word;
6056
+ border-radius: 6px;
6057
+ border: 1px solid #eeeef4;
6058
+ background: #f7f7f9;
6059
+ padding: 10px;
6060
+ font-size: 11px;
6061
+ line-height: 1.5;
6062
+ color: #2d2d30;
6063
+ "
6064
+ >${this.formatContextValue(context.value)}</pre>
4956
6065
  ` : lit.html`
4957
6066
  <div class="flex items-center justify-center py-4 text-xs text-gray-500">
4958
6067
  <span>No value available</span>
@@ -4981,7 +6090,7 @@ ${prettyEvent}</pre
4981
6090
  if (typeof value === "function") return value.toString();
4982
6091
  try {
4983
6092
  return JSON.stringify(value, null, 2);
4984
- } catch (_unused6) {
6093
+ } catch (_unused8) {
4985
6094
  return String(value);
4986
6095
  }
4987
6096
  }
@@ -5029,7 +6138,9 @@ ${prettyEvent}</pre
5029
6138
  <span>Loading latest announcement…</span>
5030
6139
  </div>`;
5031
6140
  if (!this.announcementHtml) return lit.nothing;
5032
- return lit.html`<div class="mx-4 mt-3 mb-3 rounded-xl border border-slate-200 bg-white px-4 py-3">
6141
+ return lit.html`<div
6142
+ class="mx-4 mt-3 mb-3 rounded-xl border border-slate-200 bg-white px-4 py-3"
6143
+ >
5033
6144
  <div
5034
6145
  class="mb-2 flex items-center gap-2 text-xs font-semibold text-slate-900"
5035
6146
  >
@@ -5048,7 +6159,9 @@ ${prettyEvent}</pre
5048
6159
  ${this.renderIcon("X")}
5049
6160
  </button>
5050
6161
  </div>
5051
- <div class="announcement-body ${this.announcementExpanded ? "announcement-body--expanded" : "announcement-body--collapsed"}">
6162
+ <div
6163
+ class="announcement-body ${this.announcementExpanded ? "announcement-body--expanded" : "announcement-body--collapsed"}"
6164
+ >
5052
6165
  <div
5053
6166
  class="announcement-content"
5054
6167
  @click=${this.handleAnnouncementContentClick}
@@ -5072,8 +6185,8 @@ ${prettyEvent}</pre
5072
6185
  </div>`;
5073
6186
  }
5074
6187
  flushPendingBannerViewed() {
5075
- var _this$core7;
5076
- if (!this.pendingBannerViewed || ((_this$core7 = this.core) === null || _this$core7 === void 0 ? void 0 : _this$core7.telemetryDisabled)) {
6188
+ var _this$core16;
6189
+ if (!this.pendingBannerViewed || ((_this$core16 = this.core) === null || _this$core16 === void 0 ? void 0 : _this$core16.telemetryDisabled)) {
5077
6190
  this.pendingBannerViewed = null;
5078
6191
  return;
5079
6192
  }
@@ -5145,8 +6258,9 @@ ${prettyEvent}</pre
5145
6258
  async convertMarkdownToHtml(markdown) {
5146
6259
  const renderer = new marked.marked.Renderer();
5147
6260
  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>`;
6261
+ 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
6262
  };
6263
+ renderer.html = (html) => escapeHtml(html);
5150
6264
  renderer.code = (code, lang) => {
5151
6265
  const safeLang = (lang !== null && lang !== void 0 ? lang : "").replace(/[^a-z0-9-]/gi, "");
5152
6266
  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 +6270,14 @@ ${prettyEvent}</pre
5156
6270
  async: false
5157
6271
  });
5158
6272
  }
6273
+ isSafeAnnouncementHref(href) {
6274
+ try {
6275
+ const url = new URL(href, typeof window !== "undefined" ? window.location.href : "https://copilotkit.ai");
6276
+ return url.protocol === "http:" || url.protocol === "https:" || url.protocol === "mailto:";
6277
+ } catch (_unused9) {
6278
+ return false;
6279
+ }
6280
+ }
5159
6281
  encodeBase64(value) {
5160
6282
  if (typeof window === "undefined" || typeof window.btoa !== "function") return "";
5161
6283
  const bytes = new TextEncoder().encode(value);
@@ -5170,20 +6292,26 @@ ${prettyEvent}</pre
5170
6292
  for (let i = 0; i < decoded.length; i++) bytes[i] = decoded.charCodeAt(i);
5171
6293
  return new TextDecoder().decode(bytes);
5172
6294
  }
5173
- appendRefParam(href) {
6295
+ appendRefParam(href, ref = "cpk-inspector") {
5174
6296
  try {
5175
- var _this$core8;
6297
+ var _this$core17;
6298
+ const isRootRelative = href.startsWith("/") && !href.startsWith("//");
5176
6299
  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)) {
6300
+ if (!url.searchParams.has("ref")) url.searchParams.append("ref", ref);
6301
+ 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
6302
  const distinctId = getTelemetryDistinctIdForUrl();
5180
6303
  if (distinctId) url.searchParams.append("posthog_distinct_id", distinctId);
5181
6304
  }
6305
+ if (isRootRelative) return `${url.pathname}${url.search}${url.hash}`;
5182
6306
  return url.toString();
5183
- } catch (_unused7) {
6307
+ } catch (_unused10) {
5184
6308
  return href;
5185
6309
  }
5186
6310
  }
6311
+ isCopilotKitDestination(url) {
6312
+ const hostname = url.hostname.toLowerCase();
6313
+ return hostname === "copilotkit.ai" || hostname.endsWith(".copilotkit.ai");
6314
+ }
5187
6315
  escapeHtmlAttr(value) {
5188
6316
  return escapeHtml(value).replace(/"/g, "&quot;").replace(/'/g, "&#39;");
5189
6317
  }
@@ -5195,7 +6323,7 @@ ${prettyEvent}</pre
5195
6323
  const parsed = JSON.parse(raw);
5196
6324
  if (parsed && typeof parsed.timestamp === "string") return parsed.timestamp;
5197
6325
  return null;
5198
- } catch (_unused8) {}
6326
+ } catch (_unused11) {}
5199
6327
  return null;
5200
6328
  }
5201
6329
  persistAnnouncementTimestamp(timestamp) {
@@ -5203,7 +6331,7 @@ ${prettyEvent}</pre
5203
6331
  try {
5204
6332
  const payload = JSON.stringify({ timestamp });
5205
6333
  window.localStorage.setItem(ANNOUNCEMENT_STORAGE_KEY, payload);
5206
- } catch (_unused9) {}
6334
+ } catch (_unused12) {}
5207
6335
  }
5208
6336
  markAnnouncementSeen() {
5209
6337
  this.hasUnseenAnnouncement = false;
@@ -5957,6 +7085,8 @@ ${prettyEvent}</pre
5957
7085
  defineWebInspector();
5958
7086
 
5959
7087
  //#endregion
7088
+ exports.CpkThreadInspector = CpkThreadInspector;
7089
+ exports.THREAD_INSPECTOR_TAG = THREAD_INSPECTOR_TAG;
5960
7090
  exports.WEB_INSPECTOR_TAG = WEB_INSPECTOR_TAG;
5961
7091
  exports.WebInspectorElement = WebInspectorElement;
5962
7092
  exports.defineWebInspector = defineWebInspector;