@copilotkit/web-inspector 1.62.2 → 1.63.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.cjs CHANGED
@@ -35,7 +35,13 @@ const DOCKED_LEFT_WIDTH = 500;
35
35
  const MAX_AGENT_EVENTS = 200;
36
36
  const MAX_TOTAL_EVENTS = 500;
37
37
  const INTELLIGENCE_SIGNUP_URL = "https://go.copilotkit.ai/intelligence-signup";
38
+ const THREADS_INTELLIGENCE_SIGNIN_URL = "https://dashboard.operations.copilotkit.ai/sign-in";
38
39
  const TALK_TO_ENGINEER_URL = "https://www.copilotkit.ai/talk-to-an-engineer";
40
+ const THREADS_DOCS_URL = "https://docs.copilotkit.ai/threads";
41
+ const SELF_HOSTED_INTELLIGENCE_URL = "https://docs.copilotkit.ai/premium/self-hosting";
42
+ const THREADS_EXAMPLE_OVERVIEW_VIDEO_URL = "https://cdn.copilotkit.ai/corp-site/videos/copilotkit-generative-ui-agentic-frontend-demo.webm";
43
+ const THREADS_EXAMPLE_TOUR_STORAGE_KEY = "cpk:inspector:threads-example-tour:v1";
44
+ const THREADS_EXAMPLE_AGENT_ID = "threads-feature";
39
45
  const AGENT_EVENT_TYPES = [
40
46
  "RUN_STARTED",
41
47
  "RUN_FINISHED",
@@ -61,6 +67,201 @@ const AGENT_EVENT_TYPES = [
61
67
  "ACTIVITY_SNAPSHOT",
62
68
  "ACTIVITY_DELTA"
63
69
  ];
70
+ const THREADS_EXAMPLE_THREADS = [
71
+ {
72
+ id: "example-realtime-sync",
73
+ name: "Realtime thread sync",
74
+ agentId: THREADS_EXAMPLE_AGENT_ID,
75
+ organizationId: "example-organization",
76
+ createdById: "example-user",
77
+ archived: false,
78
+ createdAt: "2026-07-08T16:00:00.000Z",
79
+ updatedAt: "2026-07-08T16:30:00.000Z",
80
+ isExample: true
81
+ },
82
+ {
83
+ id: "example-manage-history",
84
+ name: "Manage saved conversations",
85
+ agentId: THREADS_EXAMPLE_AGENT_ID,
86
+ organizationId: "example-organization",
87
+ createdById: "example-user",
88
+ archived: false,
89
+ createdAt: "2026-07-07T17:45:00.000Z",
90
+ updatedAt: "2026-07-07T18:15:00.000Z",
91
+ isExample: true
92
+ },
93
+ {
94
+ id: "example-inspect-runs",
95
+ name: "Inspect durable run history",
96
+ agentId: THREADS_EXAMPLE_AGENT_ID,
97
+ organizationId: "example-organization",
98
+ createdById: "example-user",
99
+ archived: false,
100
+ createdAt: "2026-07-06T20:15:00.000Z",
101
+ updatedAt: "2026-07-06T20:45:00.000Z",
102
+ isExample: true
103
+ }
104
+ ];
105
+ const THREADS_EXAMPLE_DETAILS = {
106
+ "example-realtime-sync": {
107
+ messages: [{
108
+ id: "example-sync-user",
109
+ role: "user",
110
+ content: "Resume the checkout support thread from yesterday."
111
+ }, {
112
+ id: "example-sync-assistant",
113
+ role: "assistant",
114
+ content: "I found the saved thread, restored the cart state, and continued from the latest user message."
115
+ }],
116
+ events: [
117
+ {
118
+ type: "RUN_STARTED",
119
+ timestamp: "2026-07-08T16:30:00.000Z",
120
+ payload: {
121
+ threadId: "example-realtime-sync",
122
+ agentId: THREADS_EXAMPLE_AGENT_ID
123
+ }
124
+ },
125
+ {
126
+ type: "MESSAGES_SNAPSHOT",
127
+ timestamp: "2026-07-08T16:30:01.000Z",
128
+ payload: {
129
+ messageCount: 6,
130
+ source: "thread-history"
131
+ }
132
+ },
133
+ {
134
+ type: "STATE_SNAPSHOT",
135
+ timestamp: "2026-07-08T16:30:02.000Z",
136
+ payload: {
137
+ cartId: "cart_demo_42",
138
+ checkoutStep: "shipping",
139
+ resumed: true
140
+ }
141
+ },
142
+ {
143
+ type: "RUN_FINISHED",
144
+ timestamp: "2026-07-08T16:30:04.000Z",
145
+ payload: { status: "completed" }
146
+ }
147
+ ],
148
+ state: {
149
+ cartId: "cart_demo_42",
150
+ checkoutStep: "shipping",
151
+ userIntent: "resume_previous_checkout",
152
+ persistedThread: true
153
+ }
154
+ },
155
+ "example-manage-history": {
156
+ messages: [{
157
+ id: "example-history-user",
158
+ role: "user",
159
+ content: "Rename this saved support conversation for the handoff."
160
+ }, {
161
+ id: "example-history-assistant",
162
+ role: "assistant",
163
+ content: "Renamed the thread and kept the prior messages available for the next session."
164
+ }],
165
+ events: [
166
+ {
167
+ type: "RUN_STARTED",
168
+ timestamp: "2026-07-07T18:15:00.000Z",
169
+ payload: {
170
+ threadId: "example-manage-history",
171
+ agentId: THREADS_EXAMPLE_AGENT_ID
172
+ }
173
+ },
174
+ {
175
+ type: "CUSTOM_EVENT",
176
+ timestamp: "2026-07-07T18:15:01.000Z",
177
+ payload: {
178
+ action: "thread_renamed",
179
+ previousName: "Untitled",
180
+ name: "Billing escalation handoff"
181
+ }
182
+ },
183
+ {
184
+ type: "RUN_FINISHED",
185
+ timestamp: "2026-07-07T18:15:03.000Z",
186
+ payload: { status: "completed" }
187
+ }
188
+ ],
189
+ state: {
190
+ name: "Billing escalation handoff",
191
+ savedMessages: 14,
192
+ lastHandoff: "support-team"
193
+ }
194
+ },
195
+ "example-inspect-runs": {
196
+ messages: [{
197
+ id: "example-inspect-user",
198
+ role: "user",
199
+ content: "Why did the assistant recommend the enterprise plan?"
200
+ }, {
201
+ id: "example-inspect-assistant",
202
+ role: "assistant",
203
+ content: "The recommendation came from the account size, SSO requirement, and audit-log constraint in state."
204
+ }],
205
+ events: [
206
+ {
207
+ type: "RUN_STARTED",
208
+ timestamp: "2026-07-06T20:45:00.000Z",
209
+ payload: {
210
+ threadId: "example-inspect-runs",
211
+ agentId: THREADS_EXAMPLE_AGENT_ID
212
+ }
213
+ },
214
+ {
215
+ type: "TOOL_CALL_START",
216
+ timestamp: "2026-07-06T20:45:01.000Z",
217
+ payload: {
218
+ toolCallId: "call_account_lookup",
219
+ toolName: "lookupAccount"
220
+ }
221
+ },
222
+ {
223
+ type: "TOOL_CALL_RESULT",
224
+ timestamp: "2026-07-06T20:45:02.000Z",
225
+ payload: {
226
+ toolCallId: "call_account_lookup",
227
+ seats: 220,
228
+ requiresSso: true
229
+ }
230
+ },
231
+ {
232
+ type: "RUN_FINISHED",
233
+ timestamp: "2026-07-06T20:45:04.000Z",
234
+ payload: { status: "completed" }
235
+ }
236
+ ],
237
+ state: {
238
+ accountTier: "growth",
239
+ seats: 220,
240
+ requiresSso: true,
241
+ auditLogsRequired: true
242
+ }
243
+ }
244
+ };
245
+ const THREADS_EXAMPLE_TOUR_STEPS = [
246
+ {
247
+ tab: "timeline",
248
+ label: "Timeline",
249
+ title: "Read the run as a story",
250
+ body: "The timeline turns messages, tool calls, state changes, and run markers into a scannable debugging trail."
251
+ },
252
+ {
253
+ tab: "raw-events",
254
+ label: "Raw AG-UI Events",
255
+ title: "Drop into the protocol payloads",
256
+ body: "Raw events show the exact AG-UI stream behind the timeline when you need to verify ordering or payload shape."
257
+ },
258
+ {
259
+ tab: "state",
260
+ label: "State",
261
+ title: "Check the durable state",
262
+ body: "The state tab shows the saved values that make a thread resumable across sessions."
263
+ }
264
+ ];
64
265
  function escapeHtml(s) {
65
266
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
66
267
  }
@@ -276,6 +477,11 @@ var CpkThreadList = class extends lit.LitElement {
276
477
  color: #57575b;
277
478
  }
278
479
 
480
+ .cpk-tl__pill--example {
481
+ background: rgba(133, 236, 206, 0.22);
482
+ color: #189370;
483
+ }
484
+
279
485
  /* ── Empty state ── */
280
486
  .cpk-tl__empty {
281
487
  padding: 32px 16px;
@@ -349,6 +555,9 @@ var CpkThreadList = class extends lit.LitElement {
349
555
  </div>
350
556
  <div class="cpk-tl__meta">
351
557
  <span class="cpk-tl__pill">${thread.agentId}</span>
558
+ ${thread.isExample ? lit.html`
559
+ <span class="cpk-tl__pill cpk-tl__pill--example">Example</span>
560
+ ` : lit.nothing}
352
561
  </div>
353
562
  </div>
354
563
  `)}
@@ -572,6 +781,9 @@ var CpkThreadInspector = class CpkThreadInspector extends lit.LitElement {
572
781
  }
573
782
  this.maybeFetchTabData(id);
574
783
  }
784
+ selectTab(id) {
785
+ this.activateTab(id);
786
+ }
575
787
  maybeFetchTabData(id) {
576
788
  if (!this.threadId) return;
577
789
  if ((id === "timeline" || id === "raw-events") && !this._eventsFetched) {
@@ -2628,219 +2840,580 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(stateValue))}</p
2628
2840
  `;
2629
2841
  }
2630
2842
  };
2631
- var ɵCpkThreadDetails = class extends CpkThreadInspector {};
2632
- if (!customElements.get("cpk-thread-list")) customElements.define("cpk-thread-list", CpkThreadList);
2633
- if (!customElements.get(THREAD_INSPECTOR_TAG)) customElements.define(THREAD_INSPECTOR_TAG, CpkThreadInspector);
2634
- if (!customElements.get("cpk-thread-details")) customElements.define("cpk-thread-details", ɵCpkThreadDetails);
2635
- var WebInspectorElement = class extends lit.LitElement {
2843
+ var CpkMemoryList = class extends lit.LitElement {
2636
2844
  constructor(..._args3) {
2637
2845
  super(..._args3);
2638
- this._core = null;
2639
- this.coreSubscriber = null;
2640
- this.coreUnsubscribe = null;
2641
- this.runtimeStatus = null;
2642
- this.coreProperties = {};
2643
- this.lastCoreError = null;
2644
- this.agentSubscriptions = /* @__PURE__ */ new Map();
2645
- this.agentEvents = /* @__PURE__ */ new Map();
2646
- this.agentMessages = /* @__PURE__ */ new Map();
2647
- this.liveMessageVersion = /* @__PURE__ */ new Map();
2648
- this.agentStates = /* @__PURE__ */ new Map();
2649
- this.flattenedEvents = [];
2650
- this.eventCounter = 0;
2651
- this.contextStore = {};
2652
- this.pointerId = null;
2653
- this.dragStart = null;
2654
- this.dragOffset = {
2655
- x: 0,
2656
- y: 0
2657
- };
2658
- this.isDragging = false;
2659
- this.pointerContext = null;
2660
- this.isOpen = false;
2661
- this.draggedDuringInteraction = false;
2662
- this.ignoreNextButtonClick = false;
2663
- this.selectedMenu = "ag-ui-events";
2664
- this.selectedThreadId = null;
2665
- this.threadListWidth = 290;
2666
- this.threadDividerResizing = false;
2667
- this.threadDividerPointerId = -1;
2668
- this.threadDividerStartX = 0;
2669
- this.threadDividerStartWidth = 0;
2670
- this._threads = [];
2671
- this._threadStoreSubscriptions = /* @__PURE__ */ new Map();
2672
- this._threadsByAgent = /* @__PURE__ */ new Map();
2673
- this._threadsErrorByAgent = /* @__PURE__ */ new Map();
2674
- this._ownedThreadStores = /* @__PURE__ */ new Map();
2675
- this.contextMenuOpen = false;
2676
- this.dockMode = "floating";
2677
- this.previousBodyMargins = null;
2678
- this.transitionTimeoutId = null;
2679
- this.bodyTransitionTimeoutIds = /* @__PURE__ */ new Set();
2680
- this.pendingSelectedContext = null;
2681
- this.autoAttachCore = true;
2682
- this.attemptedAutoAttach = false;
2683
- this.cachedTools = [];
2684
- this.toolSignature = "";
2685
- this.eventFilterText = "";
2686
- this.eventTypeFilter = "all";
2687
- this.evtColWidths = [
2688
- 100,
2689
- 80,
2690
- 150
2691
- ];
2692
- this._evtColResize = null;
2693
- this.announcementHtml = null;
2694
- this.announcementTimestamp = null;
2695
- this.announcementPreviewText = null;
2696
- this.announcementCtaLabel = null;
2697
- this.hasUnseenAnnouncement = false;
2698
- this.announcementLoaded = false;
2699
- this.announcementPromise = null;
2700
- this.showAnnouncementPreview = true;
2701
- this.announcementExpanded = false;
2702
- this.viewedBannerTimestamps = /* @__PURE__ */ new Set();
2703
- this.pendingBannerViewed = null;
2704
- this.clickedBannerIds = /* @__PURE__ */ new Set();
2705
- this.viewedThreadsTelemetryStates = /* @__PURE__ */ new Set();
2706
- this.contextState = {
2707
- button: {
2708
- position: {
2709
- x: EDGE_MARGIN,
2710
- y: EDGE_MARGIN
2711
- },
2712
- size: { ...DEFAULT_BUTTON_SIZE },
2713
- anchor: {
2714
- horizontal: "right",
2715
- vertical: "top"
2716
- },
2717
- anchorOffset: {
2718
- x: EDGE_MARGIN,
2719
- y: EDGE_MARGIN
2720
- }
2721
- },
2722
- window: {
2723
- position: {
2724
- x: EDGE_MARGIN,
2725
- y: EDGE_MARGIN
2726
- },
2727
- size: { ...DEFAULT_WINDOW_SIZE },
2728
- anchor: {
2729
- horizontal: "right",
2730
- vertical: "top"
2731
- },
2732
- anchorOffset: {
2733
- x: EDGE_MARGIN,
2734
- y: EDGE_MARGIN
2735
- }
2736
- }
2737
- };
2738
- this.hasCustomPosition = {
2739
- button: false,
2740
- window: false
2741
- };
2742
- this.resizePointerId = null;
2743
- this.resizeStart = null;
2744
- this.resizeInitialSize = null;
2745
- this.isResizing = false;
2746
- this.customTabIcons = { threads: `<svg class="h-3.5 w-3.5" width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.04167 15C8.29167 15 7.65972 14.7431 7.14583 14.2292C6.63194 13.7153 6.375 13.0972 6.375 12.375C6.375 11.3194 6.80208 10.3646 7.65625 9.51042C8.51042 8.65625 9.57639 8.125 10.8542 7.91667C10.8125 7.41667 10.6875 7.03819 10.4792 6.78125C10.2708 6.52431 9.98611 6.39583 9.625 6.39583C9.20833 6.39583 8.75694 6.56944 8.27083 6.91667C7.78472 7.26389 7.20833 7.83333 6.54167 8.625C5.45833 9.91667 4.66319 10.7569 4.15625 11.1458C3.64931 11.5347 3.10417 11.7292 2.52083 11.7292C1.8125 11.7292 1.21528 11.4653 0.729167 10.9375C0.243056 10.4097 0 9.77083 0 9.02083C0 8.27083 0.163194 7.50347 0.489583 6.71875C0.815972 5.93403 1.36806 4.99306 2.14583 3.89583C2.40972 3.53472 2.60417 3.22917 2.72917 2.97917C2.85417 2.72917 2.91667 2.52778 2.91667 2.375C2.91667 2.27778 2.89931 2.20486 2.86458 2.15625C2.82986 2.10764 2.77778 2.08333 2.70833 2.08333C2.56944 2.08333 2.39583 2.17014 2.1875 2.34375C1.97917 2.51736 1.73611 2.78472 1.45833 3.14583L0 1.66667C0.444444 1.125 0.895833 0.711806 1.35417 0.427083C1.8125 0.142361 2.26389 0 2.70833 0C3.34722 0 3.88889 0.222222 4.33333 0.666667C4.77778 1.11111 5 1.66667 5 2.33333C5 2.73611 4.89583 3.18056 4.6875 3.66667C4.47917 4.15278 4.13194 4.73611 3.64583 5.41667C3.11806 6.16667 2.72569 6.82639 2.46875 7.39583C2.21181 7.96528 2.08333 8.46528 2.08333 8.89583C2.08333 9.13194 2.12153 9.31597 2.19792 9.44792C2.27431 9.57986 2.38194 9.64583 2.52083 9.64583C2.65972 9.64583 2.78125 9.60764 2.88542 9.53125C2.98958 9.45486 3.18056 9.27083 3.45833 8.97917C3.63889 8.78472 3.85417 8.54514 4.10417 8.26042C4.35417 7.97569 4.65972 7.625 5.02083 7.20833C5.89583 6.16667 6.6875 5.42361 7.39583 4.97917C8.10417 4.53472 8.84722 4.3125 9.625 4.3125C10.5556 4.3125 11.3194 4.625 11.9167 5.25C12.5139 5.875 12.8542 6.72917 12.9375 7.8125H15V9.89583H12.9375C12.8264 11.4514 12.4201 12.691 11.7188 13.6146C11.0174 14.5382 10.125 15 9.04167 15ZM9.08333 12.9167C9.52778 12.9167 9.90278 12.6632 10.2083 12.1562C10.5139 11.6493 10.7222 10.9444 10.8333 10.0417C10.1944 10.1944 9.63889 10.4965 9.16667 10.9479C8.69444 11.3993 8.45833 11.8472 8.45833 12.2917C8.45833 12.4861 8.51389 12.6389 8.625 12.75C8.73611 12.8611 8.88889 12.9167 9.08333 12.9167Z" fill="currentColor"/></svg>` };
2747
- this.handlePointerDown = (event) => {
2748
- if (this.dockMode !== "floating" && this.isOpen) return;
2749
- const target = event.currentTarget;
2750
- const context = target?.dataset.dragContext === "window" ? "window" : "button";
2751
- const eventTarget = event.target;
2752
- if (context === "window" && eventTarget?.closest("button")) return;
2753
- this.pointerContext = context;
2754
- this.measureContext(context);
2755
- event.preventDefault();
2756
- this.pointerId = event.pointerId;
2757
- this.dragStart = {
2758
- x: event.clientX,
2759
- y: event.clientY
2760
- };
2761
- const state = this.contextState[context];
2762
- this.dragOffset = {
2763
- x: event.clientX - state.position.x,
2764
- y: event.clientY - state.position.y
2765
- };
2766
- this.isDragging = false;
2767
- this.draggedDuringInteraction = false;
2768
- this.ignoreNextButtonClick = false;
2769
- target?.setPointerCapture?.(this.pointerId);
2770
- };
2771
- this.handlePointerMove = (event) => {
2772
- if (this.pointerId !== event.pointerId || !this.dragStart || !this.pointerContext) return;
2773
- const distance = Math.hypot(event.clientX - this.dragStart.x, event.clientY - this.dragStart.y);
2774
- if (!this.isDragging && distance < DRAG_THRESHOLD) return;
2775
- event.preventDefault();
2776
- this.setDragging(true);
2777
- this.draggedDuringInteraction = true;
2778
- const desired = {
2779
- x: event.clientX - this.dragOffset.x,
2780
- y: event.clientY - this.dragOffset.y
2781
- };
2782
- const constrained = this.constrainToViewport(desired, this.pointerContext);
2783
- this.contextState[this.pointerContext].position = constrained;
2784
- this.updateHostTransform(this.pointerContext);
2785
- };
2786
- this.handlePointerUp = (event) => {
2787
- if (this.pointerId !== event.pointerId) return;
2788
- const target = event.currentTarget;
2789
- if (target?.hasPointerCapture(this.pointerId)) target.releasePointerCapture(this.pointerId);
2790
- const context = this.pointerContext ?? this.activeContext;
2791
- if (this.isDragging && this.pointerContext) {
2792
- event.preventDefault();
2793
- this.setDragging(false);
2794
- if (this.pointerContext === "window") {
2795
- this.updateAnchorFromPosition(this.pointerContext);
2796
- this.hasCustomPosition.window = true;
2797
- this.applyAnchorPosition(this.pointerContext);
2798
- } else if (this.pointerContext === "button") {
2799
- this.snapButtonToCorner();
2800
- this.hasCustomPosition.button = true;
2801
- if (this.draggedDuringInteraction) this.ignoreNextButtonClick = true;
2802
- }
2803
- } else if (context === "button" && !this.isOpen && !this.draggedDuringInteraction) this.openInspector();
2804
- this.resetPointerTracking();
2805
- };
2806
- this.handlePointerCancel = (event) => {
2807
- if (this.pointerId !== event.pointerId) return;
2808
- const target = event.currentTarget;
2809
- if (target?.hasPointerCapture(this.pointerId)) target.releasePointerCapture(this.pointerId);
2810
- this.resetPointerTracking();
2811
- };
2812
- this.handleButtonClick = (event) => {
2813
- if (this.isDragging) {
2814
- event.preventDefault();
2815
- return;
2816
- }
2817
- if (this.ignoreNextButtonClick) {
2818
- event.preventDefault();
2819
- this.ignoreNextButtonClick = false;
2820
- return;
2821
- }
2822
- if (!this.isOpen) {
2823
- event.preventDefault();
2824
- this.openInspector();
2825
- }
2846
+ this.memories = [];
2847
+ this.search = "";
2848
+ this.kind = "all";
2849
+ this.onSearchInput = (event) => {
2850
+ this.search = event.target.value;
2826
2851
  };
2827
- this.handleClosePointerDown = (event) => {
2828
- event.stopPropagation();
2829
- event.preventDefault();
2852
+ this.onKindClick = (event) => {
2853
+ const seg = event.target.closest("[data-kind]");
2854
+ if (!seg) return;
2855
+ this.kind = seg.dataset["kind"];
2830
2856
  };
2831
- this.handleCloseClick = () => {
2832
- this.closeInspector();
2857
+ }
2858
+ static {
2859
+ this.properties = {
2860
+ memories: { attribute: false },
2861
+ search: { state: true },
2862
+ kind: { state: true }
2833
2863
  };
2834
- this.handleResizePointerDown = (event) => {
2835
- event.stopPropagation();
2836
- event.preventDefault();
2837
- this.hasCustomPosition.window = true;
2838
- this.isResizing = true;
2839
- this.resizePointerId = event.pointerId;
2840
- this.resizeStart = {
2841
- x: event.clientX,
2842
- y: event.clientY
2843
- };
2864
+ }
2865
+ static {
2866
+ this.styles = lit.css`
2867
+ @import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600&family=Spline+Sans+Mono:wght@400;500&display=swap");
2868
+
2869
+ :host {
2870
+ display: flex;
2871
+ flex-direction: column;
2872
+ height: 100%;
2873
+ overflow: hidden;
2874
+ }
2875
+
2876
+ .cpk-ml {
2877
+ font-family: "Plus Jakarta Sans", sans-serif;
2878
+ display: flex;
2879
+ flex-direction: column;
2880
+ height: 100%;
2881
+ overflow: hidden;
2882
+ background: #f7f7f9;
2883
+ }
2884
+
2885
+ /* ── Search ── */
2886
+ .cpk-ml__search {
2887
+ padding: 10px 12px;
2888
+ border-bottom: 1px solid #dbdbe5;
2889
+ flex-shrink: 0;
2890
+ }
2891
+
2892
+ .cpk-ml__search-input {
2893
+ width: 100%;
2894
+ box-sizing: border-box;
2895
+ font-family: "Plus Jakarta Sans", sans-serif;
2896
+ font-size: 12px;
2897
+ padding: 7px 10px;
2898
+ border-radius: 6px;
2899
+ border: 1px solid #dbdbe5;
2900
+ background: #ffffff;
2901
+ color: #010507;
2902
+ outline: none;
2903
+ transition: border-color 0.15s;
2904
+ }
2905
+
2906
+ .cpk-ml__search-input:focus {
2907
+ border-color: #bec2ff;
2908
+ }
2909
+
2910
+ /* ── Kind filter ── */
2911
+ .cpk-ml__filter {
2912
+ display: flex;
2913
+ gap: 4px;
2914
+ padding: 8px 12px;
2915
+ border-bottom: 1px solid #dbdbe5;
2916
+ flex-shrink: 0;
2917
+ flex-wrap: wrap;
2918
+ }
2919
+
2920
+ .cpk-ml__filter-seg {
2921
+ font-family: "Plus Jakarta Sans", sans-serif;
2922
+ font-size: 11px;
2923
+ font-weight: 500;
2924
+ padding: 3px 9px;
2925
+ border-radius: 5px;
2926
+ border: 1px solid #dbdbe5;
2927
+ background: #ffffff;
2928
+ color: #57575b;
2929
+ cursor: pointer;
2930
+ transition:
2931
+ background 0.1s,
2932
+ border-color 0.1s,
2933
+ color 0.1s;
2934
+ user-select: none;
2935
+ }
2936
+
2937
+ .cpk-ml__filter-seg:hover {
2938
+ background: #f0f0f5;
2939
+ }
2940
+
2941
+ .cpk-ml__filter-seg--active {
2942
+ background: #bec2ff1a;
2943
+ border-color: #bec2ff;
2944
+ color: #010507;
2945
+ }
2946
+
2947
+ .cpk-ml__filter-count {
2948
+ font-family: "Spline Sans Mono", monospace;
2949
+ font-size: 9px;
2950
+ margin-left: 4px;
2951
+ color: #838389;
2952
+ }
2953
+
2954
+ /* ── List ── */
2955
+ .cpk-ml__list {
2956
+ flex: 1;
2957
+ overflow-y: auto;
2958
+ padding: 8px 12px;
2959
+ display: flex;
2960
+ flex-direction: column;
2961
+ gap: 8px;
2962
+ }
2963
+
2964
+ /* ── Card ── */
2965
+ .cpk-ml__card {
2966
+ background: #ffffff;
2967
+ border: 1px solid #e9e9ef;
2968
+ border-radius: 8px;
2969
+ padding: 10px 12px;
2970
+ display: flex;
2971
+ flex-direction: column;
2972
+ gap: 6px;
2973
+ }
2974
+
2975
+ .cpk-ml__card-badges {
2976
+ display: flex;
2977
+ gap: 6px;
2978
+ align-items: center;
2979
+ flex-wrap: wrap;
2980
+ }
2981
+
2982
+ /* Kind badge — color per kind */
2983
+ .cpk-ml__kind-badge {
2984
+ font-family: "Spline Sans Mono", monospace;
2985
+ font-size: 9px;
2986
+ padding: 1px 7px;
2987
+ border-radius: 4px;
2988
+ text-transform: uppercase;
2989
+ font-weight: 500;
2990
+ white-space: nowrap;
2991
+ }
2992
+
2993
+ .cpk-ml__kind-badge--topical {
2994
+ background: #eee6fe;
2995
+ color: #57575b;
2996
+ }
2997
+
2998
+ .cpk-ml__kind-badge--episodic {
2999
+ background: #e6f4fe;
3000
+ color: #2d5f80;
3001
+ }
3002
+
3003
+ .cpk-ml__kind-badge--operational {
3004
+ background: #e6feee;
3005
+ color: #2d6645;
3006
+ }
3007
+
3008
+ /* Scope badge */
3009
+ .cpk-ml__scope-badge {
3010
+ font-family: "Spline Sans Mono", monospace;
3011
+ font-size: 9px;
3012
+ padding: 1px 7px;
3013
+ border-radius: 4px;
3014
+ text-transform: uppercase;
3015
+ font-weight: 500;
3016
+ white-space: nowrap;
3017
+ background: #f0f0f5;
3018
+ color: #838389;
3019
+ }
3020
+
3021
+ /* Content */
3022
+ .cpk-ml__content {
3023
+ font-size: 12px;
3024
+ color: #010507;
3025
+ line-height: 1.5;
3026
+ word-break: break-word;
3027
+ }
3028
+
3029
+ /* Footer */
3030
+ .cpk-ml__footer {
3031
+ display: flex;
3032
+ align-items: center;
3033
+ justify-content: space-between;
3034
+ gap: 8px;
3035
+ margin-top: 2px;
3036
+ }
3037
+
3038
+ .cpk-ml__footer-threads {
3039
+ font-size: 10px;
3040
+ color: #838389;
3041
+ }
3042
+
3043
+ .cpk-ml__footer-id {
3044
+ font-family: "Spline Sans Mono", monospace;
3045
+ font-size: 9px;
3046
+ color: #c0c0c8;
3047
+ }
3048
+
3049
+ /* ── Empty state ── */
3050
+ .cpk-ml__empty {
3051
+ padding: 32px 16px;
3052
+ text-align: center;
3053
+ color: #838389;
3054
+ font-size: 12px;
3055
+ display: flex;
3056
+ flex-direction: column;
3057
+ align-items: center;
3058
+ gap: 8px;
3059
+ }
3060
+
3061
+ .cpk-ml__empty-icon {
3062
+ color: #c0c0c8;
3063
+ }
3064
+ `;
3065
+ }
3066
+ /** Memories that pass the current text search (before kind filter). */
3067
+ get searchFiltered() {
3068
+ const q = this.search.trim().toLowerCase();
3069
+ if (!q) return this.memories;
3070
+ return this.memories.filter((m) => m.content.toLowerCase().includes(q));
3071
+ }
3072
+ /** Memories that pass both search and kind filter. */
3073
+ get filtered() {
3074
+ const searched = this.searchFiltered;
3075
+ if (this.kind === "all") return searched;
3076
+ return searched.filter((m) => m.kind === this.kind);
3077
+ }
3078
+ /** Count of search-filtered memories for a given kind (for segment labels). */
3079
+ countForKind(kind) {
3080
+ return this.searchFiltered.filter((m) => m.kind === kind).length;
3081
+ }
3082
+ /** Truncate an id to first-4…last-4 characters. */
3083
+ shortId(id) {
3084
+ if (id.length <= 12) return id;
3085
+ return `${id.slice(0, 4)}…${id.slice(-4)}`;
3086
+ }
3087
+ renderKindBadge(kind) {
3088
+ return lit.html`<span class="cpk-ml__kind-badge cpk-ml__kind-badge--${kind}"
3089
+ >${kind}</span
3090
+ >`;
3091
+ }
3092
+ renderEmpty() {
3093
+ const q = this.search.trim();
3094
+ if (this.memories.length === 0) return lit.html`
3095
+ <div class="cpk-ml__empty">
3096
+ <svg
3097
+ width="24"
3098
+ height="24"
3099
+ viewBox="0 0 24 24"
3100
+ fill="none"
3101
+ stroke="currentColor"
3102
+ stroke-width="1.5"
3103
+ stroke-linecap="round"
3104
+ stroke-linejoin="round"
3105
+ class="cpk-ml__empty-icon"
3106
+ >
3107
+ <ellipse cx="12" cy="5" rx="9" ry="3" />
3108
+ <path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3" />
3109
+ <path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5" />
3110
+ </svg>
3111
+ No memories yet — tell the agent a durable fact and watch it appear.
3112
+ </div>
3113
+ `;
3114
+ if (q) return lit.html`
3115
+ <div class="cpk-ml__empty">
3116
+ No memories match &ldquo;${q}&rdquo;.
3117
+ </div>
3118
+ `;
3119
+ return lit.html`
3120
+ <div class="cpk-ml__empty">No ${this.kind} memories yet.</div>
3121
+ `;
3122
+ }
3123
+ render() {
3124
+ const filtered = this.filtered;
3125
+ return lit.html`
3126
+ <div class="cpk-ml">
3127
+ <!-- Search -->
3128
+ <div class="cpk-ml__search">
3129
+ <input
3130
+ type="text"
3131
+ placeholder="Search memories…"
3132
+ .value=${this.search}
3133
+ @input=${this.onSearchInput}
3134
+ class="cpk-ml__search-input"
3135
+ />
3136
+ </div>
3137
+
3138
+ <!-- Kind filter -->
3139
+ <div class="cpk-ml__filter" @click=${this.onKindClick}>
3140
+ <button
3141
+ class="cpk-ml__filter-seg ${this.kind === "all" ? "cpk-ml__filter-seg--active" : ""}"
3142
+ data-kind="all"
3143
+ >
3144
+ All<span class="cpk-ml__filter-count">${this.searchFiltered.length}</span>
3145
+ </button>
3146
+ ${[
3147
+ "topical",
3148
+ "episodic",
3149
+ "operational"
3150
+ ].map((k) => lit.html`
3151
+ <button
3152
+ class="cpk-ml__filter-seg ${this.kind === k ? "cpk-ml__filter-seg--active" : ""}"
3153
+ data-kind="${k}"
3154
+ >
3155
+ ${k}<span class="cpk-ml__filter-count">${this.countForKind(k)}</span>
3156
+ </button>
3157
+ `)}
3158
+ </div>
3159
+
3160
+ <!-- Memory list -->
3161
+ <div class="cpk-ml__list">
3162
+ ${filtered.map((m) => lit.html`
3163
+ <div class="cpk-ml__card">
3164
+ <div class="cpk-ml__card-badges">
3165
+ ${this.renderKindBadge(m.kind)}
3166
+ <span class="cpk-ml__scope-badge">${m.scope}</span>
3167
+ </div>
3168
+ <div class="cpk-ml__content">${m.content}</div>
3169
+ <div class="cpk-ml__footer">
3170
+ <span class="cpk-ml__footer-threads"
3171
+ >${m.sourceThreadIds.length} source thread${m.sourceThreadIds.length === 1 ? "" : "s"}</span
3172
+ >
3173
+ <span class="cpk-ml__footer-id">${this.shortId(m.id)}</span>
3174
+ </div>
3175
+ </div>
3176
+ `)}
3177
+ ${filtered.length === 0 ? this.renderEmpty() : lit.nothing}
3178
+ </div>
3179
+ </div>
3180
+ `;
3181
+ }
3182
+ };
3183
+ var ɵCpkThreadDetails = class extends CpkThreadInspector {};
3184
+ if (!customElements.get("cpk-thread-list")) customElements.define("cpk-thread-list", CpkThreadList);
3185
+ if (!customElements.get(THREAD_INSPECTOR_TAG)) customElements.define(THREAD_INSPECTOR_TAG, CpkThreadInspector);
3186
+ if (!customElements.get("cpk-thread-details")) customElements.define("cpk-thread-details", ɵCpkThreadDetails);
3187
+ if (!customElements.get("cpk-memory-list")) customElements.define("cpk-memory-list", CpkMemoryList);
3188
+ var WebInspectorElement = class extends lit.LitElement {
3189
+ constructor(..._args4) {
3190
+ super(..._args4);
3191
+ this._core = null;
3192
+ this.coreSubscriber = null;
3193
+ this.coreUnsubscribe = null;
3194
+ this._memories = [];
3195
+ this._memoriesLoading = false;
3196
+ this._memoriesError = null;
3197
+ this._memoriesAvailable = true;
3198
+ this._memoriesRealtimeStatus = "connecting";
3199
+ this._memoryUnsub = null;
3200
+ this._memorySubscribed = false;
3201
+ this._memoryStoreUnsupported = false;
3202
+ this.runtimeStatus = null;
3203
+ this.coreProperties = {};
3204
+ this.lastCoreError = null;
3205
+ this.agentSubscriptions = /* @__PURE__ */ new Map();
3206
+ this.agentEvents = /* @__PURE__ */ new Map();
3207
+ this.agentMessages = /* @__PURE__ */ new Map();
3208
+ this.liveMessageVersion = /* @__PURE__ */ new Map();
3209
+ this.agentStates = /* @__PURE__ */ new Map();
3210
+ this.flattenedEvents = [];
3211
+ this.eventCounter = 0;
3212
+ this.contextStore = {};
3213
+ this.pointerId = null;
3214
+ this.dragStart = null;
3215
+ this.dragOffset = {
3216
+ x: 0,
3217
+ y: 0
3218
+ };
3219
+ this.isDragging = false;
3220
+ this.pointerContext = null;
3221
+ this.isOpen = false;
3222
+ this.draggedDuringInteraction = false;
3223
+ this.ignoreNextButtonClick = false;
3224
+ this.selectedMenu = "ag-ui-events";
3225
+ this.selectedThreadId = null;
3226
+ this.threadListWidth = 290;
3227
+ this.threadDividerResizing = false;
3228
+ this.threadDividerPointerId = -1;
3229
+ this.threadDividerStartX = 0;
3230
+ this.threadDividerStartWidth = 0;
3231
+ this._threads = [];
3232
+ this._threadStoreSubscriptions = /* @__PURE__ */ new Map();
3233
+ this._threadsByAgent = /* @__PURE__ */ new Map();
3234
+ this._threadsErrorByAgent = /* @__PURE__ */ new Map();
3235
+ this._ownedThreadStores = /* @__PURE__ */ new Map();
3236
+ this.contextMenuOpen = false;
3237
+ this.dockMode = "floating";
3238
+ this.previousBodyMargins = null;
3239
+ this.transitionTimeoutId = null;
3240
+ this.bodyTransitionTimeoutIds = /* @__PURE__ */ new Set();
3241
+ this.pendingSelectedContext = null;
3242
+ this.autoAttachCore = true;
3243
+ this.attemptedAutoAttach = false;
3244
+ this.cachedTools = [];
3245
+ this.toolSignature = "";
3246
+ this.eventFilterText = "";
3247
+ this.eventTypeFilter = "all";
3248
+ this.evtColWidths = [
3249
+ 100,
3250
+ 80,
3251
+ 150
3252
+ ];
3253
+ this._evtColResize = null;
3254
+ this.announcementHtml = null;
3255
+ this.announcementTimestamp = null;
3256
+ this.announcementPreviewText = null;
3257
+ this.announcementCtaLabel = null;
3258
+ this.hasUnseenAnnouncement = false;
3259
+ this.announcementLoaded = false;
3260
+ this.announcementPromise = null;
3261
+ this.showAnnouncementPreview = true;
3262
+ this.announcementExpanded = false;
3263
+ this.viewedBannerTimestamps = /* @__PURE__ */ new Set();
3264
+ this.pendingBannerViewed = null;
3265
+ this.clickedBannerIds = /* @__PURE__ */ new Set();
3266
+ this.viewedThreadsTelemetryStates = /* @__PURE__ */ new Set();
3267
+ this.viewedExampleThreadIds = /* @__PURE__ */ new Set();
3268
+ this.selectedExampleThreadIds = /* @__PURE__ */ new Set();
3269
+ this.viewedExampleTourSteps = /* @__PURE__ */ new Set();
3270
+ this.exampleThreadProviders = /* @__PURE__ */ new Map();
3271
+ this.exampleTourDismissed = false;
3272
+ this.exampleTourActive = false;
3273
+ this.exampleTourStep = 0;
3274
+ this.exampleTourAutoShown = false;
3275
+ this.threadsExampleOverviewVideoShouldLoad = false;
3276
+ this.threadsExampleOverviewVideoReady = false;
3277
+ this.threadsExampleOverviewVideoLoadTimer = null;
3278
+ this.threadsExampleOverviewVideoIdleCallbackId = null;
3279
+ this.contextState = {
3280
+ button: {
3281
+ position: {
3282
+ x: EDGE_MARGIN,
3283
+ y: EDGE_MARGIN
3284
+ },
3285
+ size: { ...DEFAULT_BUTTON_SIZE },
3286
+ anchor: {
3287
+ horizontal: "right",
3288
+ vertical: "top"
3289
+ },
3290
+ anchorOffset: {
3291
+ x: EDGE_MARGIN,
3292
+ y: EDGE_MARGIN
3293
+ }
3294
+ },
3295
+ window: {
3296
+ position: {
3297
+ x: EDGE_MARGIN,
3298
+ y: EDGE_MARGIN
3299
+ },
3300
+ size: { ...DEFAULT_WINDOW_SIZE },
3301
+ anchor: {
3302
+ horizontal: "right",
3303
+ vertical: "top"
3304
+ },
3305
+ anchorOffset: {
3306
+ x: EDGE_MARGIN,
3307
+ y: EDGE_MARGIN
3308
+ }
3309
+ }
3310
+ };
3311
+ this.hasCustomPosition = {
3312
+ button: false,
3313
+ window: false
3314
+ };
3315
+ this.resizePointerId = null;
3316
+ this.resizeStart = null;
3317
+ this.resizeInitialSize = null;
3318
+ this.isResizing = false;
3319
+ this.customTabIcons = { threads: `<svg class="h-3.5 w-3.5" width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.04167 15C8.29167 15 7.65972 14.7431 7.14583 14.2292C6.63194 13.7153 6.375 13.0972 6.375 12.375C6.375 11.3194 6.80208 10.3646 7.65625 9.51042C8.51042 8.65625 9.57639 8.125 10.8542 7.91667C10.8125 7.41667 10.6875 7.03819 10.4792 6.78125C10.2708 6.52431 9.98611 6.39583 9.625 6.39583C9.20833 6.39583 8.75694 6.56944 8.27083 6.91667C7.78472 7.26389 7.20833 7.83333 6.54167 8.625C5.45833 9.91667 4.66319 10.7569 4.15625 11.1458C3.64931 11.5347 3.10417 11.7292 2.52083 11.7292C1.8125 11.7292 1.21528 11.4653 0.729167 10.9375C0.243056 10.4097 0 9.77083 0 9.02083C0 8.27083 0.163194 7.50347 0.489583 6.71875C0.815972 5.93403 1.36806 4.99306 2.14583 3.89583C2.40972 3.53472 2.60417 3.22917 2.72917 2.97917C2.85417 2.72917 2.91667 2.52778 2.91667 2.375C2.91667 2.27778 2.89931 2.20486 2.86458 2.15625C2.82986 2.10764 2.77778 2.08333 2.70833 2.08333C2.56944 2.08333 2.39583 2.17014 2.1875 2.34375C1.97917 2.51736 1.73611 2.78472 1.45833 3.14583L0 1.66667C0.444444 1.125 0.895833 0.711806 1.35417 0.427083C1.8125 0.142361 2.26389 0 2.70833 0C3.34722 0 3.88889 0.222222 4.33333 0.666667C4.77778 1.11111 5 1.66667 5 2.33333C5 2.73611 4.89583 3.18056 4.6875 3.66667C4.47917 4.15278 4.13194 4.73611 3.64583 5.41667C3.11806 6.16667 2.72569 6.82639 2.46875 7.39583C2.21181 7.96528 2.08333 8.46528 2.08333 8.89583C2.08333 9.13194 2.12153 9.31597 2.19792 9.44792C2.27431 9.57986 2.38194 9.64583 2.52083 9.64583C2.65972 9.64583 2.78125 9.60764 2.88542 9.53125C2.98958 9.45486 3.18056 9.27083 3.45833 8.97917C3.63889 8.78472 3.85417 8.54514 4.10417 8.26042C4.35417 7.97569 4.65972 7.625 5.02083 7.20833C5.89583 6.16667 6.6875 5.42361 7.39583 4.97917C8.10417 4.53472 8.84722 4.3125 9.625 4.3125C10.5556 4.3125 11.3194 4.625 11.9167 5.25C12.5139 5.875 12.8542 6.72917 12.9375 7.8125H15V9.89583H12.9375C12.8264 11.4514 12.4201 12.691 11.7188 13.6146C11.0174 14.5382 10.125 15 9.04167 15ZM9.08333 12.9167C9.52778 12.9167 9.90278 12.6632 10.2083 12.1562C10.5139 11.6493 10.7222 10.9444 10.8333 10.0417C10.1944 10.1944 9.63889 10.4965 9.16667 10.9479C8.69444 11.3993 8.45833 11.8472 8.45833 12.2917C8.45833 12.4861 8.51389 12.6389 8.625 12.75C8.73611 12.8611 8.88889 12.9167 9.08333 12.9167Z" fill="currentColor"/></svg>` };
3320
+ this.handlePointerDown = (event) => {
3321
+ if (this.dockMode !== "floating" && this.isOpen) return;
3322
+ const target = event.currentTarget;
3323
+ const context = target?.dataset.dragContext === "window" ? "window" : "button";
3324
+ const eventTarget = event.target;
3325
+ if (context === "window" && eventTarget?.closest("button")) return;
3326
+ this.pointerContext = context;
3327
+ this.measureContext(context);
3328
+ event.preventDefault();
3329
+ this.pointerId = event.pointerId;
3330
+ this.dragStart = {
3331
+ x: event.clientX,
3332
+ y: event.clientY
3333
+ };
3334
+ const state = this.contextState[context];
3335
+ this.dragOffset = {
3336
+ x: event.clientX - state.position.x,
3337
+ y: event.clientY - state.position.y
3338
+ };
3339
+ this.isDragging = false;
3340
+ this.draggedDuringInteraction = false;
3341
+ this.ignoreNextButtonClick = false;
3342
+ target?.setPointerCapture?.(this.pointerId);
3343
+ };
3344
+ this.handlePointerMove = (event) => {
3345
+ if (this.pointerId !== event.pointerId || !this.dragStart || !this.pointerContext) return;
3346
+ const distance = Math.hypot(event.clientX - this.dragStart.x, event.clientY - this.dragStart.y);
3347
+ if (!this.isDragging && distance < DRAG_THRESHOLD) return;
3348
+ event.preventDefault();
3349
+ this.setDragging(true);
3350
+ this.draggedDuringInteraction = true;
3351
+ const desired = {
3352
+ x: event.clientX - this.dragOffset.x,
3353
+ y: event.clientY - this.dragOffset.y
3354
+ };
3355
+ const constrained = this.constrainToViewport(desired, this.pointerContext);
3356
+ this.contextState[this.pointerContext].position = constrained;
3357
+ this.updateHostTransform(this.pointerContext);
3358
+ };
3359
+ this.handlePointerUp = (event) => {
3360
+ if (this.pointerId !== event.pointerId) return;
3361
+ const target = event.currentTarget;
3362
+ if (target?.hasPointerCapture(this.pointerId)) target.releasePointerCapture(this.pointerId);
3363
+ const context = this.pointerContext ?? this.activeContext;
3364
+ if (this.isDragging && this.pointerContext) {
3365
+ event.preventDefault();
3366
+ this.setDragging(false);
3367
+ if (this.pointerContext === "window") {
3368
+ this.updateAnchorFromPosition(this.pointerContext);
3369
+ this.hasCustomPosition.window = true;
3370
+ this.applyAnchorPosition(this.pointerContext);
3371
+ } else if (this.pointerContext === "button") {
3372
+ this.snapButtonToCorner();
3373
+ this.hasCustomPosition.button = true;
3374
+ if (this.draggedDuringInteraction) this.ignoreNextButtonClick = true;
3375
+ }
3376
+ } else if (context === "button" && !this.isOpen && !this.draggedDuringInteraction) this.openInspector();
3377
+ this.resetPointerTracking();
3378
+ };
3379
+ this.handlePointerCancel = (event) => {
3380
+ if (this.pointerId !== event.pointerId) return;
3381
+ const target = event.currentTarget;
3382
+ if (target?.hasPointerCapture(this.pointerId)) target.releasePointerCapture(this.pointerId);
3383
+ this.resetPointerTracking();
3384
+ };
3385
+ this.handleButtonClick = (event) => {
3386
+ if (this.isDragging) {
3387
+ event.preventDefault();
3388
+ return;
3389
+ }
3390
+ if (this.ignoreNextButtonClick) {
3391
+ event.preventDefault();
3392
+ this.ignoreNextButtonClick = false;
3393
+ return;
3394
+ }
3395
+ if (!this.isOpen) {
3396
+ event.preventDefault();
3397
+ this.openInspector();
3398
+ }
3399
+ };
3400
+ this.handleClosePointerDown = (event) => {
3401
+ event.stopPropagation();
3402
+ event.preventDefault();
3403
+ };
3404
+ this.handleCloseClick = () => {
3405
+ this.closeInspector();
3406
+ };
3407
+ this.handleResizePointerDown = (event) => {
3408
+ event.stopPropagation();
3409
+ event.preventDefault();
3410
+ this.hasCustomPosition.window = true;
3411
+ this.isResizing = true;
3412
+ this.resizePointerId = event.pointerId;
3413
+ this.resizeStart = {
3414
+ x: event.clientX,
3415
+ y: event.clientY
3416
+ };
2844
3417
  this.resizeInitialSize = { ...this.contextState.window.size };
2845
3418
  if (document.body && this.dockMode !== "floating") document.body.style.transition = "";
2846
3419
  event.currentTarget?.setPointerCapture?.(event.pointerId);
@@ -2949,6 +3522,10 @@ var WebInspectorElement = class extends lit.LitElement {
2949
3522
  if (target.hasPointerCapture(this.threadDividerPointerId)) target.releasePointerCapture(this.threadDividerPointerId);
2950
3523
  this.threadDividerResizing = false;
2951
3524
  };
3525
+ this.handleThreadsExampleOverviewVideoLoaded = () => {
3526
+ this.threadsExampleOverviewVideoReady = true;
3527
+ this.requestUpdate();
3528
+ };
2952
3529
  this.handleClearEvents = () => {
2953
3530
  if (this.selectedContext === "all-agents") {
2954
3531
  this.agentEvents.clear();
@@ -3053,6 +3630,11 @@ var WebInspectorElement = class extends lit.LitElement {
3053
3630
  key: "threads",
3054
3631
  label: "Threads",
3055
3632
  icon: "MessageSquare"
3633
+ },
3634
+ {
3635
+ key: "memories",
3636
+ label: "Learning",
3637
+ icon: "Brain"
3056
3638
  }
3057
3639
  ];
3058
3640
  }
@@ -3064,6 +3646,16 @@ var WebInspectorElement = class extends lit.LitElement {
3064
3646
  areThreadEndpointsAvailable() {
3065
3647
  return this.getThreadServiceStatus() !== "unavailable";
3066
3648
  }
3649
+ getActiveThreadsState() {
3650
+ const displayThreads = this.selectedContext === "all-agents" ? this._threads : this._threadsByAgent.get(this.selectedContext) ?? [];
3651
+ let threadsErrorMessage = null;
3652
+ if (this.selectedContext === "all-agents") threadsErrorMessage = this._threadsErrorByAgent.values().next().value?.message ?? null;
3653
+ else threadsErrorMessage = this._threadsErrorByAgent.get(this.selectedContext)?.message ?? null;
3654
+ return {
3655
+ displayThreads,
3656
+ threadsErrorMessage
3657
+ };
3658
+ }
3067
3659
  getThreadsTelemetryProps(extra = {}, options = {}) {
3068
3660
  const distinctId = options.includeUrlAttribution && !this.core?.telemetryDisabled ? require_telemetry.getTelemetryDistinctIdForUrl() : null;
3069
3661
  const threadServiceStatus = this.getThreadServiceStatus();
@@ -3078,12 +3670,31 @@ var WebInspectorElement = class extends lit.LitElement {
3078
3670
  ...extra
3079
3671
  };
3080
3672
  }
3673
+ getMemoriesTelemetryProps() {
3674
+ return {
3675
+ posthog_distinct_id: (!this.core?.telemetryDisabled ? require_telemetry.getTelemetryDistinctIdForUrl() : null) ?? void 0,
3676
+ memory_count: this._memories.length,
3677
+ available: this._memoriesAvailable
3678
+ };
3679
+ }
3081
3680
  getIntelligenceSignupUrl() {
3082
3681
  return this.appendRefParam(INTELLIGENCE_SIGNUP_URL, "cpk-inspector");
3083
3682
  }
3683
+ getThreadsIntelligenceSignupUrl() {
3684
+ return this.appendRefParam(THREADS_INTELLIGENCE_SIGNIN_URL, "cpk-inspector");
3685
+ }
3084
3686
  getTalkToEngineerUrl() {
3085
3687
  return this.appendRefParam(TALK_TO_ENGINEER_URL, "cpk-inspector-threads");
3086
3688
  }
3689
+ getThreadsTalkToEngineerUrl() {
3690
+ return this.appendRefParam(TALK_TO_ENGINEER_URL, "cpk-inspector-threads");
3691
+ }
3692
+ getThreadsDocsUrl() {
3693
+ return this.appendRefParam(THREADS_DOCS_URL, "cpk-inspector-threads");
3694
+ }
3695
+ getSelfHostedIntelligenceUrl() {
3696
+ return this.appendRefParam(SELF_HOSTED_INTELLIGENCE_URL, "cpk-inspector-threads");
3697
+ }
3087
3698
  subscribeToThreadStore(agentId, store) {
3088
3699
  if (!this.areThreadEndpointsAvailable()) return;
3089
3700
  if (this._threadStoreSubscriptions.has(agentId)) return;
@@ -3112,7 +3723,7 @@ var WebInspectorElement = class extends lit.LitElement {
3112
3723
  }
3113
3724
  autoSelectLatestThread() {
3114
3725
  if (this._threads.length === 0) return;
3115
- if (!(this.selectedThreadId != null && this._threads.some((t) => t.id === this.selectedThreadId))) this.selectedThreadId = this._threads[0].id;
3726
+ if (!(this.selectedThreadId != null && !this.isExampleThreadId(this.selectedThreadId) && this._threads.some((t) => t.id === this.selectedThreadId))) this.selectedThreadId = this._threads[0].id;
3116
3727
  }
3117
3728
  teardownThreadStoreSubscriptions() {
3118
3729
  for (const unsub of this._threadStoreSubscriptions.values()) unsub();
@@ -3242,12 +3853,75 @@ var WebInspectorElement = class extends lit.LitElement {
3242
3853
  const threadStores = typeof core.getThreadStores === "function" ? core.getThreadStores() : {};
3243
3854
  for (const [agentId, store] of Object.entries(threadStores)) this.subscribeToThreadStore(agentId, store);
3244
3855
  if (core.context) this.contextStore = this.normalizeContextStore(core.context);
3856
+ if (this.selectedMenu === "memories") this.ensureMemorySubscription();
3857
+ }
3858
+ /**
3859
+ * Lazily subscribes to the singleton memory store the first time the user
3860
+ * activates the Memories tab. This is deferred out of `attachToCore` because
3861
+ * `core.getMemoryStore()` is what creates + starts the store and opens
3862
+ * realtime — doing it on attach would start memory for apps that never use
3863
+ * it. Idempotent: repeated tab activations are guarded by
3864
+ * `_memorySubscribed`. On an older @copilotkit/core without `getMemoryStore`,
3865
+ * records the unsupported state so the teaser can guide an SDK upgrade.
3866
+ */
3867
+ ensureMemorySubscription() {
3868
+ if (this._memorySubscribed) return;
3869
+ const core = this._core;
3870
+ if (!core) return;
3871
+ if (typeof core.getMemoryStore !== "function") {
3872
+ this._memoryStoreUnsupported = true;
3873
+ this._memoriesAvailable = false;
3874
+ this.requestUpdate();
3875
+ return;
3876
+ }
3877
+ this._memorySubscribed = true;
3878
+ this._memoryStoreUnsupported = false;
3879
+ const memoryStore = core.getMemoryStore();
3880
+ const ms = memoryStore.getState();
3881
+ this._memories = (0, _copilotkit_core.ɵselectMemories)(ms);
3882
+ this._memoriesLoading = (0, _copilotkit_core.ɵselectMemoriesIsLoading)(ms);
3883
+ this._memoriesError = (0, _copilotkit_core.ɵselectMemoriesError)(ms);
3884
+ this._memoriesAvailable = (0, _copilotkit_core.ɵselectMemoriesAvailable)(ms);
3885
+ this._memoriesRealtimeStatus = (0, _copilotkit_core.ɵselectMemoriesRealtimeStatus)(ms);
3886
+ const memSubs = [
3887
+ memoryStore.select(_copilotkit_core.ɵselectMemories).subscribe((v) => {
3888
+ this._memories = v;
3889
+ this.requestUpdate();
3890
+ }),
3891
+ memoryStore.select(_copilotkit_core.ɵselectMemoriesIsLoading).subscribe((v) => {
3892
+ this._memoriesLoading = v;
3893
+ this.requestUpdate();
3894
+ }),
3895
+ memoryStore.select(_copilotkit_core.ɵselectMemoriesError).subscribe((v) => {
3896
+ this._memoriesError = v;
3897
+ this.requestUpdate();
3898
+ }),
3899
+ memoryStore.select(_copilotkit_core.ɵselectMemoriesAvailable).subscribe((v) => {
3900
+ this._memoriesAvailable = v;
3901
+ this.requestUpdate();
3902
+ }),
3903
+ memoryStore.select(_copilotkit_core.ɵselectMemoriesRealtimeStatus).subscribe((v) => {
3904
+ this._memoriesRealtimeStatus = v;
3905
+ this.requestUpdate();
3906
+ })
3907
+ ];
3908
+ this._memoryUnsub = () => memSubs.forEach((s) => s.unsubscribe());
3909
+ this.requestUpdate();
3245
3910
  }
3246
3911
  detachFromCore() {
3247
3912
  if (this.coreUnsubscribe) {
3248
3913
  this.coreUnsubscribe();
3249
3914
  this.coreUnsubscribe = null;
3250
3915
  }
3916
+ this._memoryUnsub?.();
3917
+ this._memoryUnsub = null;
3918
+ this._memories = [];
3919
+ this._memoriesLoading = false;
3920
+ this._memoriesError = null;
3921
+ this._memoriesAvailable = true;
3922
+ this._memoriesRealtimeStatus = "connecting";
3923
+ this._memorySubscribed = false;
3924
+ this._memoryStoreUnsupported = false;
3251
3925
  this.coreSubscriber = null;
3252
3926
  this.runtimeStatus = null;
3253
3927
  this.lastCoreError = null;
@@ -4244,6 +4918,35 @@ ${argsString}</pre
4244
4918
  .cpk-tab-active {
4245
4919
  cursor: pointer;
4246
4920
  }
4921
+ .cpk-threads-overview-video-frame {
4922
+ position: relative;
4923
+ display: block;
4924
+ width: 100%;
4925
+ max-width: 440px;
4926
+ aspect-ratio: 16 / 9;
4927
+ margin: 0 0 14px;
4928
+ overflow: hidden;
4929
+ border: 1px solid #dbdbe5;
4930
+ border-radius: 8px;
4931
+ background:
4932
+ linear-gradient(
4933
+ 135deg,
4934
+ rgba(190, 194, 255, 0.18),
4935
+ rgba(133, 236, 206, 0.12)
4936
+ ),
4937
+ #ffffff;
4938
+ box-shadow: 0 8px 20px rgba(1, 5, 7, 0.08);
4939
+ }
4940
+ .cpk-threads-overview-video {
4941
+ width: 100%;
4942
+ height: 100%;
4943
+ object-fit: cover;
4944
+ opacity: 0;
4945
+ transition: opacity 220ms ease;
4946
+ }
4947
+ .cpk-threads-overview-video[data-ready="true"] {
4948
+ opacity: 1;
4949
+ }
4247
4950
 
4248
4951
  /* ── Header control buttons (dock, close) — first row only ───── */
4249
4952
  .drag-handle > div:first-child button {
@@ -4420,6 +5123,7 @@ ${argsString}</pre
4420
5123
  window.addEventListener("resize", this.handleResize);
4421
5124
  window.addEventListener("pointerdown", this.handleGlobalPointerDown);
4422
5125
  this.hydrateStateFromStorageEarly();
5126
+ this.exampleTourDismissed = this.readThreadsExampleTourDismissed();
4423
5127
  this.tryAutoAttachCore();
4424
5128
  this.ensureAnnouncementLoading();
4425
5129
  }
@@ -4445,6 +5149,14 @@ ${argsString}</pre
4445
5149
  clearTimeout(this.transitionTimeoutId);
4446
5150
  this.transitionTimeoutId = null;
4447
5151
  }
5152
+ if (this.threadsExampleOverviewVideoLoadTimer !== null) {
5153
+ window.clearTimeout(this.threadsExampleOverviewVideoLoadTimer);
5154
+ this.threadsExampleOverviewVideoLoadTimer = null;
5155
+ }
5156
+ if (this.threadsExampleOverviewVideoIdleCallbackId !== null && typeof window.cancelIdleCallback === "function") {
5157
+ window.cancelIdleCallback(this.threadsExampleOverviewVideoIdleCallbackId);
5158
+ this.threadsExampleOverviewVideoIdleCallbackId = null;
5159
+ }
4448
5160
  this.removeDockStyles(true);
4449
5161
  this.detachFromCore();
4450
5162
  }
@@ -4470,6 +5182,7 @@ ${argsString}</pre
4470
5182
  y: EDGE_MARGIN
4471
5183
  };
4472
5184
  this.hydrateStateFromStorage();
5185
+ if (this.selectedMenu === "memories") this.ensureMemorySubscription();
4473
5186
  if (this.isOpen && this.dockMode !== "floating") this.applyDockStyles(true);
4474
5187
  this.applyAnchorPosition("button");
4475
5188
  if (this.dockMode === "floating") if (this.hasCustomPosition.window) this.applyAnchorPosition("window");
@@ -4640,6 +5353,17 @@ ${argsString}</pre
4640
5353
  </button>
4641
5354
  `;
4642
5355
  })}
5356
+ ${this.selectedMenu === "threads" ? lit.html`
5357
+ <a
5358
+ href=${this.getThreadsTalkToEngineerUrl()}
5359
+ target="_blank"
5360
+ rel="noopener"
5361
+ style="margin-left:auto;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;"
5362
+ @click=${this.handleTalkToEngineerClick}
5363
+ >
5364
+ Talk to an Engineer
5365
+ </a>
5366
+ ` : lit.nothing}
4643
5367
  </div>
4644
5368
  </div>
4645
5369
  <div class="flex flex-1 flex-col overflow-hidden">
@@ -5165,65 +5889,432 @@ ${argsString}</pre
5165
5889
  if (this.selectedMenu === "frontend-tools") return this.renderToolsView();
5166
5890
  if (this.selectedMenu === "agent-context") return this.renderContextView();
5167
5891
  if (this.selectedMenu === "threads") return this.renderThreadsView();
5892
+ if (this.selectedMenu === "memories") return this.renderMemoriesView();
5168
5893
  if (this.selectedMenu === "settings") return this.renderSettingsPanel();
5169
5894
  return lit.nothing;
5170
5895
  }
5171
- renderSettingsPanel() {
5172
- const optedOut = this.core?.telemetryDisabled ?? false;
5896
+ renderSettingsPanel() {
5897
+ const optedOut = this.core?.telemetryDisabled ?? false;
5898
+ return lit.html`
5899
+ <div class="flex h-full flex-col overflow-hidden">
5900
+ <div class="overflow-auto p-4">
5901
+ <div class="space-y-3">
5902
+ <h2 class="text-sm font-semibold text-slate-900">Settings</h2>
5903
+
5904
+ <div class="space-y-2">
5905
+ <h3 class="text-sm text-slate-500">Privacy</h3>
5906
+ <div
5907
+ class="rounded-lg border border-slate-200 bg-white p-4 space-y-3"
5908
+ >
5909
+ <p class="text-sm text-gray-600 flex items-start gap-2">
5910
+ <span>${optedOut ? "❌" : "✅"}</span>
5911
+ <span>
5912
+ ${optedOut ? "You have disabled anonymous interaction data collection." : "CopilotKit is currently collecting anonymous interaction data from the inspector so we know which features people use. We never collect message content, agent state, prompts, or completions."}
5913
+ </span>
5914
+ </p>
5915
+ <a
5916
+ class="inline-flex items-center gap-1 text-sm text-slate-700 underline hover:text-slate-900"
5917
+ href=${require_telemetry.TELEMETRY_DOCS_URL}
5918
+ target="_blank"
5919
+ rel="noopener"
5920
+ >Learn more →</a
5921
+ >
5922
+ </div>
5923
+ </div>
5924
+ </div>
5925
+ </div>
5926
+ </div>
5927
+ `;
5928
+ }
5929
+ trackBannerClickedOnce(opts) {
5930
+ if (this.core?.telemetryDisabled) return;
5931
+ const id = this.announcementTimestamp;
5932
+ if (!id) return;
5933
+ const key = `${id}:${opts.cta}`;
5934
+ if (this.clickedBannerIds.has(key)) return;
5935
+ this.clickedBannerIds.add(key);
5936
+ require_telemetry.trackBannerClicked({
5937
+ banner_id: id,
5938
+ cta: opts.cta,
5939
+ cta_label: this.announcementCtaLabel ?? void 0
5940
+ });
5941
+ }
5942
+ trackThreadsViewStateOnce(state, threadCount) {
5943
+ if (this.core?.telemetryDisabled) return;
5944
+ const key = `${state}:${this.getThreadServiceStatus()}`;
5945
+ if (this.viewedThreadsTelemetryStates.has(key)) return;
5946
+ this.viewedThreadsTelemetryStates.add(key);
5947
+ const props = this.getThreadsTelemetryProps({ thread_count: threadCount });
5948
+ if (state === "locked") require_telemetry.trackThreadsLockedViewed(props);
5949
+ else if (state === "empty_enabled") require_telemetry.trackThreadsEmptyEnabledViewed(props);
5950
+ else require_telemetry.trackThreadsEnabledViewed(props);
5951
+ }
5952
+ shouldRenderExampleThreads(displayThreads, threadsErrorMessage) {
5953
+ return this.areThreadEndpointsAvailable() && !threadsErrorMessage && displayThreads.length === 0;
5954
+ }
5955
+ getVisibleThreads(displayThreads, threadsErrorMessage) {
5956
+ return this.shouldRenderExampleThreads(displayThreads, threadsErrorMessage) ? THREADS_EXAMPLE_THREADS : displayThreads;
5957
+ }
5958
+ isExampleThreadId(threadId) {
5959
+ return THREADS_EXAMPLE_THREADS.some((thread) => thread.id === threadId);
5960
+ }
5961
+ getExampleThreadProvider(threadId) {
5962
+ const cached = this.exampleThreadProviders.get(threadId);
5963
+ if (cached) return cached;
5964
+ const thread = THREADS_EXAMPLE_THREADS.find((item) => item.id === threadId);
5965
+ const details = THREADS_EXAMPLE_DETAILS[threadId];
5966
+ const provider = {
5967
+ getThreadMetadata: async () => thread ? {
5968
+ id: thread.id,
5969
+ name: thread.name,
5970
+ agentId: thread.agentId,
5971
+ endUserId: "example-user",
5972
+ status: "completed",
5973
+ updatedAt: thread.updatedAt
5974
+ } : null,
5975
+ getMessages: async () => details?.messages ?? [],
5976
+ getEvents: async () => details?.events ?? [],
5977
+ getState: async () => details?.state ?? null
5978
+ };
5979
+ this.exampleThreadProviders.set(threadId, provider);
5980
+ return provider;
5981
+ }
5982
+ trackThreadsExampleViewedOnce() {
5983
+ if (this.core?.telemetryDisabled) return;
5984
+ for (const thread of THREADS_EXAMPLE_THREADS) {
5985
+ if (this.viewedExampleThreadIds.has(thread.id)) continue;
5986
+ this.viewedExampleThreadIds.add(thread.id);
5987
+ require_telemetry.trackThreadsExampleViewed(this.getThreadsTelemetryProps({
5988
+ example_thread_id: thread.id,
5989
+ thread_count: 0
5990
+ }));
5991
+ }
5992
+ }
5993
+ trackThreadsExampleSelectedOnce(threadId) {
5994
+ if (this.core?.telemetryDisabled) return;
5995
+ if (this.selectedExampleThreadIds.has(threadId)) return;
5996
+ this.selectedExampleThreadIds.add(threadId);
5997
+ require_telemetry.trackThreadsExampleSelected(this.getThreadsTelemetryProps({
5998
+ example_thread_id: threadId,
5999
+ thread_count: 0
6000
+ }));
6001
+ }
6002
+ getCurrentExampleTourProps() {
6003
+ const step = THREADS_EXAMPLE_TOUR_STEPS[this.exampleTourStep] ?? THREADS_EXAMPLE_TOUR_STEPS[0];
6004
+ return this.getThreadsTelemetryProps({
6005
+ example_thread_id: this.selectedThreadId ?? void 0,
6006
+ thread_count: 0,
6007
+ tour_step: this.exampleTourStep + 1,
6008
+ tour_tab: step?.tab
6009
+ });
6010
+ }
6011
+ trackThreadsExampleTourStepViewedOnce() {
6012
+ if (this.core?.telemetryDisabled || !this.selectedThreadId) return;
6013
+ if (!(THREADS_EXAMPLE_TOUR_STEPS[this.exampleTourStep] ?? THREADS_EXAMPLE_TOUR_STEPS[0])) return;
6014
+ const key = `${this.selectedThreadId}:${this.exampleTourStep}`;
6015
+ if (this.viewedExampleTourSteps.has(key)) return;
6016
+ this.viewedExampleTourSteps.add(key);
6017
+ require_telemetry.trackThreadsExampleTourStepViewed(this.getCurrentExampleTourProps());
6018
+ }
6019
+ syncExampleTourTab() {
6020
+ const step = THREADS_EXAMPLE_TOUR_STEPS[this.exampleTourStep] ?? THREADS_EXAMPLE_TOUR_STEPS[0];
6021
+ if (!step) return;
6022
+ this.updateComplete.then(() => {
6023
+ (this.shadowRoot?.querySelector("cpk-thread-details"))?.selectTab?.(step.tab);
6024
+ });
6025
+ }
6026
+ startExampleTour(autoStarted) {
6027
+ if (!this.selectedThreadId) return;
6028
+ this.exampleTourActive = true;
6029
+ this.exampleTourStep = 0;
6030
+ if (autoStarted) {
6031
+ this.exampleTourAutoShown = true;
6032
+ if (!this.core?.telemetryDisabled) require_telemetry.trackThreadsExampleTourStarted(this.getCurrentExampleTourProps());
6033
+ } else if (!this.core?.telemetryDisabled) require_telemetry.trackThreadsExampleTourReopened(this.getCurrentExampleTourProps());
6034
+ this.trackThreadsExampleTourStepViewedOnce();
6035
+ this.syncExampleTourTab();
6036
+ this.requestUpdate();
6037
+ }
6038
+ setExampleTourStep(nextStep) {
6039
+ this.exampleTourStep = Math.max(0, Math.min(THREADS_EXAMPLE_TOUR_STEPS.length - 1, nextStep));
6040
+ this.trackThreadsExampleTourStepViewedOnce();
6041
+ this.syncExampleTourTab();
6042
+ this.requestUpdate();
6043
+ }
6044
+ dismissExampleTour(method) {
6045
+ if (!this.selectedThreadId) return;
6046
+ const props = {
6047
+ ...this.getCurrentExampleTourProps(),
6048
+ dismiss_method: method
6049
+ };
6050
+ this.exampleTourActive = false;
6051
+ this.exampleTourDismissed = true;
6052
+ this.writeThreadsExampleTourDismissed();
6053
+ if (!this.core?.telemetryDisabled) if (method === "done") require_telemetry.trackThreadsExampleTourCompleted(props);
6054
+ else require_telemetry.trackThreadsExampleTourDismissed(props);
6055
+ this.requestUpdate();
6056
+ }
6057
+ handleThreadsThreadSelected(threadId, showingExamples) {
6058
+ if (showingExamples && this.selectedThreadId === threadId) {
6059
+ this.selectedThreadId = null;
6060
+ this.exampleTourActive = false;
6061
+ this.requestUpdate();
6062
+ return;
6063
+ }
6064
+ this.selectedThreadId = threadId;
6065
+ if (showingExamples && this.isExampleThreadId(threadId)) {
6066
+ this.trackThreadsExampleSelectedOnce(threadId);
6067
+ if (!this.exampleTourDismissed && !this.exampleTourAutoShown) this.startExampleTour(true);
6068
+ else this.exampleTourActive = false;
6069
+ } else this.exampleTourActive = false;
6070
+ this.requestUpdate();
6071
+ }
6072
+ readThreadsExampleTourDismissed() {
6073
+ if (typeof window === "undefined") return false;
6074
+ try {
6075
+ const raw = window.localStorage.getItem(THREADS_EXAMPLE_TOUR_STORAGE_KEY);
6076
+ if (!raw) return false;
6077
+ return JSON.parse(raw).dismissed === true;
6078
+ } catch {
6079
+ return false;
6080
+ }
6081
+ }
6082
+ writeThreadsExampleTourDismissed() {
6083
+ if (typeof window === "undefined") return;
6084
+ try {
6085
+ window.localStorage.setItem(THREADS_EXAMPLE_TOUR_STORAGE_KEY, JSON.stringify({ dismissed: true }));
6086
+ } catch {}
6087
+ }
6088
+ scheduleThreadsExampleOverviewVideoLoad() {
6089
+ if (this.threadsExampleOverviewVideoShouldLoad || this.threadsExampleOverviewVideoLoadTimer !== null || this.threadsExampleOverviewVideoIdleCallbackId !== null || typeof window === "undefined") return;
6090
+ if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) return;
6091
+ const loadVideo = () => {
6092
+ this.threadsExampleOverviewVideoLoadTimer = null;
6093
+ this.threadsExampleOverviewVideoIdleCallbackId = null;
6094
+ this.threadsExampleOverviewVideoShouldLoad = true;
6095
+ this.requestUpdate();
6096
+ };
6097
+ if (typeof window.requestIdleCallback === "function") {
6098
+ this.threadsExampleOverviewVideoIdleCallbackId = window.requestIdleCallback(loadVideo, { timeout: 1200 });
6099
+ return;
6100
+ }
6101
+ this.threadsExampleOverviewVideoLoadTimer = window.setTimeout(loadVideo, 450);
6102
+ }
6103
+ renderThreadsExampleOverviewVideo() {
6104
+ this.scheduleThreadsExampleOverviewVideoLoad();
6105
+ return lit.html`
6106
+ <div class="cpk-threads-overview-video-frame" aria-hidden="true">
6107
+ ${this.threadsExampleOverviewVideoShouldLoad ? lit.html`
6108
+ <video
6109
+ class="cpk-threads-overview-video"
6110
+ data-ready=${this.threadsExampleOverviewVideoReady}
6111
+ src=${THREADS_EXAMPLE_OVERVIEW_VIDEO_URL}
6112
+ autoplay
6113
+ loop
6114
+ muted
6115
+ playsinline
6116
+ preload="metadata"
6117
+ @loadeddata=${this.handleThreadsExampleOverviewVideoLoaded}
6118
+ ></video>
6119
+ ` : lit.nothing}
6120
+ </div>
6121
+ `;
6122
+ }
6123
+ renderThreadsExampleOverview() {
6124
+ return lit.html`
6125
+ <div
6126
+ style="
6127
+ flex: 1;
6128
+ min-width: 0;
6129
+ display: flex;
6130
+ align-items: center;
6131
+ justify-content: center;
6132
+ padding: 32px;
6133
+ background: #f7f7f9;
6134
+ "
6135
+ >
6136
+ <div style="max-width: 440px; color: #57575b;">
6137
+ <h2
6138
+ style="
6139
+ margin: 0 0 10px;
6140
+ font-size: 20px;
6141
+ line-height: 1.25;
6142
+ font-weight: 600;
6143
+ color: #010507;
6144
+ "
6145
+ >
6146
+ Threads are persistent, inspectable conversations
6147
+ </h2>
6148
+ ${this.renderThreadsExampleOverviewVideo()}
6149
+ <p
6150
+ style="
6151
+ margin: 0 0 16px;
6152
+ font-size: 13px;
6153
+ line-height: 1.55;
6154
+ color: #57575b;
6155
+ "
6156
+ >
6157
+ Take a tour with the example threads in the sidebar. Then, start
6158
+ chatting in your app to create the first real thread.
6159
+ </p>
6160
+ <div style="display:flex;flex-wrap:wrap;gap:8px;">
6161
+ <a
6162
+ href=${this.getThreadsDocsUrl()}
6163
+ target="_blank"
6164
+ rel="noopener"
6165
+ style="
6166
+ display: inline-flex;
6167
+ align-items: center;
6168
+ justify-content: center;
6169
+ gap: 6px;
6170
+ min-height: 34px;
6171
+ border-radius: 6px;
6172
+ background: #010507;
6173
+ padding: 8px 12px;
6174
+ font-size: 12px;
6175
+ font-weight: 600;
6176
+ color: #ffffff;
6177
+ text-decoration: none;
6178
+ "
6179
+ >
6180
+ Learn how Threads work
6181
+ </a>
6182
+ <a
6183
+ href=${this.getSelfHostedIntelligenceUrl()}
6184
+ target="_blank"
6185
+ rel="noopener"
6186
+ style="
6187
+ display: inline-flex;
6188
+ align-items: center;
6189
+ justify-content: center;
6190
+ gap: 6px;
6191
+ min-height: 34px;
6192
+ border-radius: 6px;
6193
+ border: 1px solid #dbdbe5;
6194
+ background: #ffffff;
6195
+ padding: 8px 12px;
6196
+ font-size: 12px;
6197
+ font-weight: 600;
6198
+ color: #010507;
6199
+ text-decoration: none;
6200
+ "
6201
+ >
6202
+ Explore self-hosted Intelligence
6203
+ </a>
6204
+ </div>
6205
+ </div>
6206
+ </div>
6207
+ `;
6208
+ }
6209
+ renderThreadsExampleTour() {
6210
+ if (!this.selectedThreadId || !this.isExampleThreadId(this.selectedThreadId)) return lit.nothing;
6211
+ if (!this.exampleTourActive) return lit.html`
6212
+ <button
6213
+ type="button"
6214
+ style="
6215
+ position: absolute;
6216
+ right: 16px;
6217
+ bottom: 16px;
6218
+ z-index: 2;
6219
+ border: 1px solid #dbdbe5;
6220
+ border-radius: 6px;
6221
+ background: #ffffff;
6222
+ padding: 7px 10px;
6223
+ color: #57575b;
6224
+ font-size: 12px;
6225
+ font-weight: 600;
6226
+ cursor: pointer;
6227
+ box-shadow: 0 8px 18px rgba(1, 5, 7, 0.08);
6228
+ "
6229
+ @click=${() => this.startExampleTour(false)}
6230
+ >
6231
+ Show tour
6232
+ </button>
6233
+ `;
6234
+ const step = THREADS_EXAMPLE_TOUR_STEPS[this.exampleTourStep] ?? THREADS_EXAMPLE_TOUR_STEPS[0];
6235
+ const isFirst = this.exampleTourStep === 0;
6236
+ const isLast = this.exampleTourStep === THREADS_EXAMPLE_TOUR_STEPS.length - 1;
5173
6237
  return lit.html`
5174
- <div class="flex h-full flex-col overflow-hidden">
5175
- <div class="overflow-auto p-4">
5176
- <div class="space-y-3">
5177
- <h2 class="text-sm font-semibold text-slate-900">Settings</h2>
5178
-
5179
- <div class="space-y-2">
5180
- <h3 class="text-sm text-slate-500">Privacy</h3>
5181
- <div
5182
- class="rounded-lg border border-slate-200 bg-white p-4 space-y-3"
5183
- >
5184
- <p class="text-sm text-gray-600 flex items-start gap-2">
5185
- <span>${optedOut ? "❌" : "✅"}</span>
5186
- <span>
5187
- ${optedOut ? "You have disabled anonymous interaction data collection." : "CopilotKit is currently collecting anonymous interaction data from the inspector so we know which features people use. We never collect message content, agent state, prompts, or completions."}
5188
- </span>
5189
- </p>
5190
- <a
5191
- class="inline-flex items-center gap-1 text-sm text-slate-700 underline hover:text-slate-900"
5192
- href=${require_telemetry.TELEMETRY_DOCS_URL}
5193
- target="_blank"
5194
- rel="noopener"
5195
- >Learn more →</a
5196
- >
5197
- </div>
5198
- </div>
6238
+ <div
6239
+ role="dialog"
6240
+ aria-label="Example thread tour"
6241
+ style="
6242
+ position: absolute;
6243
+ right: 16px;
6244
+ bottom: 16px;
6245
+ z-index: 3;
6246
+ width: min(340px, calc(100% - 32px));
6247
+ border: 1px solid #dbdbe5;
6248
+ border-radius: 8px;
6249
+ background: #ffffff;
6250
+ padding: 14px;
6251
+ box-shadow: 0 16px 36px rgba(1, 5, 7, 0.14);
6252
+ color: #57575b;
6253
+ "
6254
+ >
6255
+ <div
6256
+ style="
6257
+ margin-bottom: 8px;
6258
+ font-family: 'Spline Sans Mono', monospace;
6259
+ font-size: 10px;
6260
+ font-weight: 600;
6261
+ color: #189370;
6262
+ text-transform: uppercase;
6263
+ "
6264
+ >
6265
+ ${this.exampleTourStep + 1}/${THREADS_EXAMPLE_TOUR_STEPS.length}
6266
+ ${step.label}
6267
+ </div>
6268
+ <div
6269
+ style="
6270
+ margin-bottom: 6px;
6271
+ font-size: 14px;
6272
+ line-height: 1.35;
6273
+ font-weight: 600;
6274
+ color: #010507;
6275
+ "
6276
+ >
6277
+ ${step.title}
6278
+ </div>
6279
+ <div style="font-size: 12px; line-height: 1.5; color: #57575b;">
6280
+ ${step.body}
6281
+ </div>
6282
+ <div
6283
+ style="
6284
+ display: flex;
6285
+ justify-content: space-between;
6286
+ gap: 8px;
6287
+ margin-top: 14px;
6288
+ "
6289
+ >
6290
+ <button
6291
+ type="button"
6292
+ style="border:0;background:transparent;color:#838389;font-size:12px;font-weight:600;cursor:pointer;padding:7px 0;"
6293
+ @click=${() => this.dismissExampleTour("skip")}
6294
+ >
6295
+ Skip
6296
+ </button>
6297
+ <div style="display:flex;gap:8px;">
6298
+ <button
6299
+ type="button"
6300
+ style="border:1px solid #dbdbe5;border-radius:6px;background:#ffffff;color:#57575b;font-size:12px;font-weight:600;cursor:pointer;padding:7px 10px;"
6301
+ ?disabled=${isFirst}
6302
+ @click=${() => this.setExampleTourStep(this.exampleTourStep - 1)}
6303
+ >
6304
+ Back
6305
+ </button>
6306
+ <button
6307
+ type="button"
6308
+ style="border:1px solid #010507;border-radius:6px;background:#010507;color:#ffffff;font-size:12px;font-weight:600;cursor:pointer;padding:7px 10px;"
6309
+ @click=${() => isLast ? this.dismissExampleTour("done") : this.setExampleTourStep(this.exampleTourStep + 1)}
6310
+ >
6311
+ ${isLast ? "Done" : "Next"}
6312
+ </button>
5199
6313
  </div>
5200
6314
  </div>
5201
6315
  </div>
5202
6316
  `;
5203
6317
  }
5204
- trackBannerClickedOnce(opts) {
5205
- if (this.core?.telemetryDisabled) return;
5206
- const id = this.announcementTimestamp;
5207
- if (!id) return;
5208
- const key = `${id}:${opts.cta}`;
5209
- if (this.clickedBannerIds.has(key)) return;
5210
- this.clickedBannerIds.add(key);
5211
- require_telemetry.trackBannerClicked({
5212
- banner_id: id,
5213
- cta: opts.cta,
5214
- cta_label: this.announcementCtaLabel ?? void 0
5215
- });
5216
- }
5217
- trackThreadsViewStateOnce(state, threadCount) {
5218
- if (this.core?.telemetryDisabled) return;
5219
- const key = `${state}:${this.getThreadServiceStatus()}`;
5220
- if (this.viewedThreadsTelemetryStates.has(key)) return;
5221
- this.viewedThreadsTelemetryStates.add(key);
5222
- const props = this.getThreadsTelemetryProps({ thread_count: threadCount });
5223
- if (state === "locked") require_telemetry.trackThreadsLockedViewed(props);
5224
- else if (state === "empty_enabled") require_telemetry.trackThreadsEmptyEnabledViewed(props);
5225
- else require_telemetry.trackThreadsEnabledViewed(props);
5226
- }
5227
6318
  renderThreadsLockedBackgroundMockup() {
5228
6319
  return lit.html`
5229
6320
  <div
@@ -5469,7 +6560,7 @@ ${argsString}</pre
5469
6560
  "
5470
6561
  >
5471
6562
  <a
5472
- href=${this.getTalkToEngineerUrl()}
6563
+ href=${this.getThreadsIntelligenceSignupUrl()}
5473
6564
  target="_blank"
5474
6565
  rel="noopener"
5475
6566
  style="
@@ -5479,68 +6570,338 @@ ${argsString}</pre
5479
6570
  justify-content: center;
5480
6571
  gap: 6px;
5481
6572
  border-radius: 6px;
5482
- background: #010507;
6573
+ border: 1px solid #dbdbe5;
6574
+ background: #ffffff;
5483
6575
  padding: 8px 12px;
5484
6576
  font-size: 12px;
5485
6577
  font-weight: 600;
5486
- color: #ffffff;
6578
+ color: #57575b;
5487
6579
  text-decoration: none;
5488
6580
  "
5489
- @click=${this.handleThreadsTalkToEngineerClick}
6581
+ @click=${this.handleThreadsIntelligenceSignupClick}
5490
6582
  >
5491
- Talk to an Engineer
6583
+ Sign up for Intelligence
5492
6584
  </a>
5493
- <a
5494
- href=${this.getIntelligenceSignupUrl()}
5495
- target="_blank"
5496
- rel="noopener"
6585
+ </div>
6586
+ </div>
6587
+ </div>
6588
+ `;
6589
+ }
6590
+ /**
6591
+ * Renders the realtime-connection indicator in the memory-store header.
6592
+ * Only `"connected"` shows the live (green-dot) state; `"connecting"` shows a
6593
+ * muted amber "reconnecting" and `"unavailable"` a muted grey "offline", so
6594
+ * the indicator never claims "live" over a frozen snapshot once the realtime
6595
+ * socket has permanently given up.
6596
+ */
6597
+ renderMemoryRealtimeIndicator() {
6598
+ const status = this._memoriesRealtimeStatus;
6599
+ const connected = status === "connected";
6600
+ return lit.html`
6601
+ <span
6602
+ style="
6603
+ display: inline-flex;
6604
+ align-items: center;
6605
+ gap: 4px;
6606
+ font-size: 10px;
6607
+ font-weight: 500;
6608
+ color: ${connected ? "#57575b" : "#838389"};
6609
+ "
6610
+ >
6611
+ <span
6612
+ style="
6613
+ display: inline-block;
6614
+ width: 6px;
6615
+ height: 6px;
6616
+ border-radius: 50%;
6617
+ background: ${connected ? "#22c55e" : status === "connecting" ? "#f59e0b" : "#9ca3af"};
6618
+ "
6619
+ ></span>
6620
+ ${status === "connected" ? "live" : status === "connecting" ? "reconnecting" : "offline"}
6621
+ </span>
6622
+ `;
6623
+ }
6624
+ renderMemoriesView() {
6625
+ if (!this.core?.intelligence || !this._memoriesAvailable) return lit.html`
6626
+ <div
6627
+ style="
6628
+ position: relative;
6629
+ height: 100%;
6630
+ display: flex;
6631
+ align-items: center;
6632
+ justify-content: center;
6633
+ padding: 32px;
6634
+ overflow: hidden;
6635
+ background: #ffffff;
6636
+ "
6637
+ >
6638
+ ${this.renderThreadsLockedBackgroundMockup()}
6639
+ <div
6640
+ aria-hidden="true"
6641
+ style="
6642
+ position: absolute;
6643
+ inset: 0;
6644
+ pointer-events: none;
6645
+ background:
6646
+ 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%);
6647
+ "
6648
+ ></div>
6649
+ <div
6650
+ style="
6651
+ position: relative;
6652
+ z-index: 1;
6653
+ max-width: 440px;
6654
+ text-align: center;
6655
+ color: #57575b;
6656
+ "
6657
+ >
6658
+ <div
6659
+ aria-hidden="true"
5497
6660
  style="
5498
- display: inline-flex;
5499
- min-height: 34px;
5500
- align-items: center;
6661
+ margin: 0 auto 18px;
6662
+ display: flex;
5501
6663
  justify-content: center;
5502
- gap: 6px;
5503
- border-radius: 6px;
5504
- border: 1px solid #dbdbe5;
5505
- background: #ffffff;
5506
- padding: 8px 12px;
5507
- font-size: 12px;
6664
+ "
6665
+ >
6666
+ <div
6667
+ style="
6668
+ display: flex;
6669
+ height: 44px;
6670
+ width: 44px;
6671
+ align-items: center;
6672
+ justify-content: center;
6673
+ border: 1px solid #dfd6fb;
6674
+ border-radius: 8px;
6675
+ background: #eee6fe;
6676
+ color: #57575b;
6677
+ box-shadow: 0 8px 18px rgba(87, 87, 91, 0.14);
6678
+ "
6679
+ >
6680
+ ${this.renderIcon("Lock")}
6681
+ </div>
6682
+ </div>
6683
+ <h2
6684
+ style="
6685
+ margin: 0 0 8px;
6686
+ font-size: 16px;
6687
+ line-height: 1.35;
5508
6688
  font-weight: 600;
6689
+ color: #010507;
6690
+ "
6691
+ >
6692
+ Long-term memory
6693
+ </h2>
6694
+ <p
6695
+ style="
6696
+ margin: 0 auto 18px;
6697
+ max-width: 380px;
6698
+ font-size: 13px;
6699
+ line-height: 1.55;
5509
6700
  color: #57575b;
5510
- text-decoration: none;
5511
6701
  "
5512
- @click=${this.handleThreadsIntelligenceSignupClick}
5513
6702
  >
5514
- Sign up for Intelligence
5515
- </a>
6703
+ ${this._memoryStoreUnsupported ? "Long-term memory isn't available in this version of the @copilotkit SDK. Upgrade @copilotkit/core (and @copilotkit/react) to a version that supports memory." : "Long-term memory isn't enabled on this deployment."}
6704
+ </p>
6705
+ <div
6706
+ style="
6707
+ display: flex;
6708
+ flex-wrap: wrap;
6709
+ justify-content: center;
6710
+ gap: 8px;
6711
+ "
6712
+ >
6713
+ <a
6714
+ href=${this.getTalkToEngineerUrl()}
6715
+ target="_blank"
6716
+ rel="noopener"
6717
+ style="
6718
+ display: inline-flex;
6719
+ min-height: 34px;
6720
+ align-items: center;
6721
+ justify-content: center;
6722
+ gap: 6px;
6723
+ border-radius: 6px;
6724
+ background: #010507;
6725
+ padding: 8px 12px;
6726
+ font-size: 12px;
6727
+ font-weight: 600;
6728
+ color: #ffffff;
6729
+ text-decoration: none;
6730
+ "
6731
+ @click=${this.handleThreadsTalkToEngineerClick}
6732
+ >
6733
+ Talk to an Engineer
6734
+ </a>
6735
+ <a
6736
+ href=${this.getIntelligenceSignupUrl()}
6737
+ target="_blank"
6738
+ rel="noopener"
6739
+ style="
6740
+ display: inline-flex;
6741
+ min-height: 34px;
6742
+ align-items: center;
6743
+ justify-content: center;
6744
+ gap: 6px;
6745
+ border-radius: 6px;
6746
+ border: 1px solid #dbdbe5;
6747
+ background: #ffffff;
6748
+ padding: 8px 12px;
6749
+ font-size: 12px;
6750
+ font-weight: 600;
6751
+ color: #57575b;
6752
+ text-decoration: none;
6753
+ "
6754
+ @click=${this.handleThreadsIntelligenceSignupClick}
6755
+ >
6756
+ Sign up for Intelligence
6757
+ </a>
6758
+ </div>
5516
6759
  </div>
5517
6760
  </div>
6761
+ `;
6762
+ if (this._memoriesError && this._memories.length === 0) return lit.html`
6763
+ <div
6764
+ style="
6765
+ display: flex;
6766
+ height: 100%;
6767
+ flex-direction: column;
6768
+ align-items: center;
6769
+ justify-content: center;
6770
+ gap: 8px;
6771
+ color: #838389;
6772
+ "
6773
+ >
6774
+ <svg
6775
+ width="24"
6776
+ height="24"
6777
+ viewBox="0 0 24 24"
6778
+ fill="none"
6779
+ stroke="#c0333a"
6780
+ stroke-width="1.5"
6781
+ stroke-linecap="round"
6782
+ stroke-linejoin="round"
6783
+ >
6784
+ <circle cx="12" cy="12" r="10" />
6785
+ <line x1="12" y1="8" x2="12" y2="12" />
6786
+ <line x1="12" y1="16" x2="12.01" y2="16" />
6787
+ </svg>
6788
+ <span style="font-size: 13px; color: #c0333a;">
6789
+ Failed to load memories
6790
+ </span>
6791
+ <span
6792
+ style="
6793
+ max-width: 320px;
6794
+ text-align: center;
6795
+ font-size: 11px;
6796
+ line-height: 1.5;
6797
+ color: #c0333a;
6798
+ "
6799
+ >
6800
+ ${this._memoriesError.message}
6801
+ </span>
6802
+ </div>
6803
+ `;
6804
+ if (this._memoriesLoading && this._memories.length === 0) return lit.html`
6805
+ <div
6806
+ style="
6807
+ display: flex;
6808
+ height: 100%;
6809
+ flex-direction: column;
6810
+ align-items: center;
6811
+ justify-content: center;
6812
+ gap: 8px;
6813
+ color: #838389;
6814
+ "
6815
+ >
6816
+ <svg
6817
+ width="24"
6818
+ height="24"
6819
+ viewBox="0 0 24 24"
6820
+ fill="none"
6821
+ stroke="#c0c0c8"
6822
+ stroke-width="1.5"
6823
+ stroke-linecap="round"
6824
+ stroke-linejoin="round"
6825
+ >
6826
+ <path d="M21 12a9 9 0 1 1-6.219-8.56" />
6827
+ </svg>
6828
+ <span style="font-size: 13px">Loading memories…</span>
6829
+ </div>
6830
+ `;
6831
+ return lit.html`
6832
+ <div style="display:flex;height:100%;overflow:hidden;flex-direction:column;">
6833
+ <div class="cpk-section-header" style="display:flex;align-items:center;justify-content:space-between;">
6834
+ <h4>Learning</h4>
6835
+ <div style="display:flex;align-items:center;gap:6px;">
6836
+ ${this.renderMemoryRealtimeIndicator()}
6837
+ <span
6838
+ style="
6839
+ font-size: 11px;
6840
+ font-weight: 500;
6841
+ color: #57575b;
6842
+ background: rgba(0,0,0,0.07);
6843
+ border-radius: 9999px;
6844
+ padding: 1px 7px;
6845
+ "
6846
+ >
6847
+ ${this._memories.length}
6848
+ </span>
6849
+ </div>
6850
+ </div>
6851
+ ${this._memoriesError ? lit.html`
6852
+ <div
6853
+ role="alert"
6854
+ style="
6855
+ display: flex;
6856
+ align-items: flex-start;
6857
+ gap: 8px;
6858
+ flex-shrink: 0;
6859
+ border-bottom: 1px solid #f1c7c9;
6860
+ background: #fdf3f3;
6861
+ padding: 8px 12px;
6862
+ color: #c0333a;
6863
+ font-size: 12px;
6864
+ line-height: 1.45;
6865
+ "
6866
+ >
6867
+ <svg
6868
+ width="16"
6869
+ height="16"
6870
+ viewBox="0 0 24 24"
6871
+ fill="none"
6872
+ stroke="#c0333a"
6873
+ stroke-width="1.5"
6874
+ stroke-linecap="round"
6875
+ stroke-linejoin="round"
6876
+ style="flex-shrink:0;margin-top:1px;"
6877
+ >
6878
+ <circle cx="12" cy="12" r="10" />
6879
+ <line x1="12" y1="8" x2="12" y2="12" />
6880
+ <line x1="12" y1="16" x2="12.01" y2="16" />
6881
+ </svg>
6882
+ <span>Action failed: ${this._memoriesError.message}</span>
6883
+ </div>
6884
+ ` : lit.nothing}
6885
+ <div style="flex:1;min-height:0;overflow:hidden;">
6886
+ <cpk-memory-list
6887
+ style="height:100%;"
6888
+ .memories=${this._memories}
6889
+ ></cpk-memory-list>
6890
+ </div>
5518
6891
  </div>
5519
6892
  `;
5520
6893
  }
5521
6894
  renderThreadsView() {
5522
6895
  if (!this.areThreadEndpointsAvailable()) return this.renderThreadsLockedView();
5523
- const displayThreads = this.selectedContext === "all-agents" ? this._threads : this._threadsByAgent.get(this.selectedContext) ?? [];
5524
- let threadsErrorMessage = null;
5525
- if (this.selectedContext === "all-agents") threadsErrorMessage = this._threadsErrorByAgent.values().next().value?.message ?? null;
5526
- else threadsErrorMessage = this._threadsErrorByAgent.get(this.selectedContext)?.message ?? null;
5527
- const selectedThread = this.selectedThreadId != null ? displayThreads.find((t) => t.id === this.selectedThreadId) ?? null : null;
6896
+ const { displayThreads, threadsErrorMessage } = this.getActiveThreadsState();
6897
+ const showingExamples = this.shouldRenderExampleThreads(displayThreads, threadsErrorMessage);
6898
+ const visibleThreads = this.getVisibleThreads(displayThreads, threadsErrorMessage);
6899
+ if (showingExamples) this.trackThreadsExampleViewedOnce();
6900
+ const selectedThread = this.selectedThreadId != null ? visibleThreads.find((t) => t.id === this.selectedThreadId) ?? null : null;
6901
+ const selectedThreadIsExample = this.isExampleThreadId(selectedThread?.id);
5528
6902
  if (!threadsErrorMessage) this.trackThreadsViewStateOnce(displayThreads.length === 0 ? "empty_enabled" : "enabled", displayThreads.length);
5529
6903
  return lit.html`
5530
6904
  <div style="display:flex;height:100%;overflow:hidden;flex-direction:column;">
5531
- <div
5532
- style="display:flex;align-items:center;justify-content:flex-end;border-bottom:1px solid #DBDBE5;background:#ffffff;padding:8px 12px;flex-shrink:0;"
5533
- >
5534
- <a
5535
- href=${this.getTalkToEngineerUrl()}
5536
- target="_blank"
5537
- rel="noopener"
5538
- 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;"
5539
- @click=${this.handleTalkToEngineerClick}
5540
- >
5541
- Talk to an Engineer
5542
- </a>
5543
- </div>
5544
6905
  <div style="display:flex;min-height:0;flex:1;overflow:hidden;">
5545
6906
  <!-- Left sidebar: thread list -->
5546
6907
  <div
@@ -5548,12 +6909,11 @@ ${argsString}</pre
5548
6909
  >
5549
6910
  <cpk-thread-list
5550
6911
  style="height:100%;"
5551
- .threads=${displayThreads}
6912
+ .threads=${visibleThreads}
5552
6913
  .selectedThreadId=${this.selectedThreadId}
5553
6914
  .errorMessage=${threadsErrorMessage}
5554
6915
  @threadSelected=${(e) => {
5555
- this.selectedThreadId = e.detail;
5556
- this.requestUpdate();
6916
+ this.handleThreadsThreadSelected(e.detail, showingExamples);
5557
6917
  }}
5558
6918
  ></cpk-thread-list>
5559
6919
  </div>
@@ -5568,18 +6928,20 @@ ${argsString}</pre
5568
6928
  ></div>
5569
6929
 
5570
6930
  <!-- Center + right: thread details or empty state -->
5571
- <div style="flex:1;min-width:0;overflow:hidden;display:flex;">
6931
+ <div style="flex:1;min-width:0;overflow:hidden;display:flex;position:relative;">
5572
6932
  ${selectedThread ? lit.html`<cpk-thread-details
5573
6933
  style="flex:1;min-width:0;"
5574
6934
  .threadId=${selectedThread.id}
5575
6935
  .thread=${selectedThread}
6936
+ .provider=${selectedThreadIsExample ? this.getExampleThreadProvider(selectedThread.id) : null}
5576
6937
  .runtimeUrl=${this._core?.runtimeUrl ?? ""}
5577
6938
  .headers=${this._core?.headers ?? {}}
5578
- .threadInspectionAvailable=${this._core?.threadEndpoints?.inspect !== false}
6939
+ .threadInspectionAvailable=${selectedThreadIsExample || this._core?.threadEndpoints?.inspect !== false}
5579
6940
  .liveMessageVersion=${this.liveMessageVersion.get(selectedThread.id) ?? 0}
5580
6941
  .agentStateInput=${this.getLatestStateForAgent(selectedThread.agentId)}
5581
6942
  .agentEventsInput=${this.agentEvents.get(selectedThread.agentId) ?? []}
5582
- ></cpk-thread-details>` : lit.html`
6943
+ ></cpk-thread-details>
6944
+ ${selectedThreadIsExample ? this.renderThreadsExampleTour() : lit.nothing}` : showingExamples ? this.renderThreadsExampleOverview() : lit.html`
5583
6945
  <div
5584
6946
  style="
5585
6947
  flex: 1;
@@ -6135,6 +7497,10 @@ ${prettyEvent}</pre
6135
7497
  if (previousMenu !== "threads" && !this.core?.telemetryDisabled) require_telemetry.trackThreadsTabClicked(this.getThreadsTelemetryProps());
6136
7498
  this.autoSelectLatestThread();
6137
7499
  }
7500
+ if (key === "memories") {
7501
+ this.ensureMemorySubscription();
7502
+ if (previousMenu !== "memories" && !this.core?.telemetryDisabled) require_telemetry.trackMemoriesTabClicked(this.getMemoriesTelemetryProps());
7503
+ }
6138
7504
  if (key === "ag-ui-events" || key === "agents") requestAnimationFrame(() => {
6139
7505
  const scroller = this.shadowRoot?.getElementById("cpk-main-scroll");
6140
7506
  if (scroller) scroller.scrollTop = 0;