@copilotkit/web-inspector 1.56.4 → 1.56.5-canary.1777671752
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 +2968 -197
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +273 -10
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +273 -10
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2969 -199
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +3053 -259
- package/dist/index.umd.js.map +1 -1
- package/dist/styles/generated.cjs +1 -1
- package/dist/styles/generated.cjs.map +1 -1
- package/dist/styles/generated.mjs +1 -1
- package/dist/styles/generated.mjs.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/web-inspector.spec.ts +179 -1
- package/src/index.ts +3681 -277
- package/src/styles/generated.css +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5,9 +5,9 @@ const require_inspector_logo_icon = require('./assets/inspector-logo-icon.cjs');
|
|
|
5
5
|
const require_context_helpers = require('./lib/context-helpers.cjs');
|
|
6
6
|
const require_persistence = require('./lib/persistence.cjs');
|
|
7
7
|
let lit = require("lit");
|
|
8
|
+
let marked = require("marked");
|
|
8
9
|
let lit_directives_style_map_js = require("lit/directives/style-map.js");
|
|
9
10
|
let lit_directives_unsafe_html_js = require("lit/directives/unsafe-html.js");
|
|
10
|
-
let marked = require("marked");
|
|
11
11
|
let lucide = require("lucide");
|
|
12
12
|
let _copilotkit_core = require("@copilotkit/core");
|
|
13
13
|
|
|
@@ -27,7 +27,7 @@ const DEFAULT_BUTTON_SIZE = {
|
|
|
27
27
|
};
|
|
28
28
|
const DEFAULT_WINDOW_SIZE = {
|
|
29
29
|
width: 840,
|
|
30
|
-
height:
|
|
30
|
+
height: 700
|
|
31
31
|
};
|
|
32
32
|
const DOCKED_LEFT_WIDTH = 500;
|
|
33
33
|
const MAX_AGENT_EVENTS = 200;
|
|
@@ -53,11 +53,1765 @@ const AGENT_EVENT_TYPES = [
|
|
|
53
53
|
"REASONING_MESSAGE_CONTENT",
|
|
54
54
|
"REASONING_MESSAGE_END",
|
|
55
55
|
"REASONING_END",
|
|
56
|
-
"REASONING_ENCRYPTED_VALUE"
|
|
56
|
+
"REASONING_ENCRYPTED_VALUE",
|
|
57
|
+
"ACTIVITY_SNAPSHOT",
|
|
58
|
+
"ACTIVITY_DELTA"
|
|
57
59
|
];
|
|
58
|
-
|
|
60
|
+
function escapeHtml(s) {
|
|
61
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
62
|
+
}
|
|
63
|
+
const highlightedJsonCache = /* @__PURE__ */ new WeakMap();
|
|
64
|
+
function highlightedJson(obj) {
|
|
65
|
+
if (typeof obj === "object" && obj !== null) {
|
|
66
|
+
const cached = highlightedJsonCache.get(obj);
|
|
67
|
+
if (cached !== void 0) return cached;
|
|
68
|
+
}
|
|
69
|
+
const colors = {
|
|
70
|
+
key: "#5558B2",
|
|
71
|
+
str: "#189370",
|
|
72
|
+
num: "#996300",
|
|
73
|
+
bool: "#c0333a",
|
|
74
|
+
nil: "#838389"
|
|
75
|
+
};
|
|
76
|
+
const json = JSON.stringify(obj, null, 2);
|
|
77
|
+
if (!json) return "";
|
|
78
|
+
const parts = [];
|
|
79
|
+
let lastIndex = 0;
|
|
80
|
+
const re = /("(?:\\u[a-fA-F0-9]{4}|\\[^u]|[^\\"])*"(?:\s*:)?|\b(?:true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)/g;
|
|
81
|
+
let match;
|
|
82
|
+
while ((match = re.exec(json)) !== null) {
|
|
83
|
+
parts.push(escapeHtml(json.slice(lastIndex, match.index)));
|
|
84
|
+
const m = match[0];
|
|
85
|
+
let color = colors.num;
|
|
86
|
+
if (m.startsWith("\"")) color = m.trimEnd().endsWith(":") ? colors.key : colors.str;
|
|
87
|
+
else if (m === "true" || m === "false") color = colors.bool;
|
|
88
|
+
else if (m === "null") color = colors.nil;
|
|
89
|
+
parts.push(`<span style="color:${color}">${escapeHtml(m)}</span>`);
|
|
90
|
+
lastIndex = match.index + m.length;
|
|
91
|
+
}
|
|
92
|
+
parts.push(escapeHtml(json.slice(lastIndex)));
|
|
93
|
+
const result = parts.join("");
|
|
94
|
+
if (typeof obj === "object" && obj !== null) highlightedJsonCache.set(obj, result);
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
function eventColors(type) {
|
|
98
|
+
if (type.startsWith("TEXT_MESSAGE")) return {
|
|
99
|
+
bg: "#EEE6FE",
|
|
100
|
+
fg: "#57575B"
|
|
101
|
+
};
|
|
102
|
+
if (type.startsWith("TOOL_CALL")) return {
|
|
103
|
+
bg: "rgba(133,236,206,0.15)",
|
|
104
|
+
fg: "#189370"
|
|
105
|
+
};
|
|
106
|
+
if (type.startsWith("STATE")) return {
|
|
107
|
+
bg: "rgba(190,194,255,0.102)",
|
|
108
|
+
fg: "#5558B2"
|
|
109
|
+
};
|
|
110
|
+
if (type.startsWith("RUN_") || type.startsWith("STEP_")) return {
|
|
111
|
+
bg: "rgba(255,172,77,0.2)",
|
|
112
|
+
fg: "#996300"
|
|
113
|
+
};
|
|
114
|
+
if (type === "ERROR") return {
|
|
115
|
+
bg: "rgba(250,95,103,0.13)",
|
|
116
|
+
fg: "#c0333a"
|
|
117
|
+
};
|
|
118
|
+
return {
|
|
119
|
+
bg: "#F7F7F9",
|
|
120
|
+
fg: "#838389"
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function formatTimestamp(ts) {
|
|
124
|
+
const date = typeof ts === "number" ? new Date(ts) : new Date(ts);
|
|
125
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
126
|
+
const ms = date.getMilliseconds().toString().padStart(3, "0");
|
|
127
|
+
return date.toLocaleTimeString("en-US", {
|
|
128
|
+
hour: "2-digit",
|
|
129
|
+
minute: "2-digit",
|
|
130
|
+
second: "2-digit",
|
|
131
|
+
hour12: false
|
|
132
|
+
}) + "." + ms;
|
|
133
|
+
}
|
|
134
|
+
var CpkThreadList = class extends lit.LitElement {
|
|
59
135
|
constructor(..._args) {
|
|
60
136
|
super(..._args);
|
|
137
|
+
this.threads = [];
|
|
138
|
+
this.selectedThreadId = null;
|
|
139
|
+
this.errorMessage = null;
|
|
140
|
+
this._query = "";
|
|
141
|
+
this.onSearchInput = (event) => {
|
|
142
|
+
this._query = event.target.value;
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
static {
|
|
146
|
+
this.properties = {
|
|
147
|
+
threads: { attribute: false },
|
|
148
|
+
selectedThreadId: { attribute: false },
|
|
149
|
+
errorMessage: { attribute: false },
|
|
150
|
+
_query: { state: true }
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
static {
|
|
154
|
+
this.styles = lit.css`
|
|
155
|
+
@import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600&family=Spline+Sans+Mono:wght@400;500&display=swap");
|
|
156
|
+
|
|
157
|
+
:host {
|
|
158
|
+
display: flex;
|
|
159
|
+
flex-direction: column;
|
|
160
|
+
height: 100%;
|
|
161
|
+
overflow: hidden;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.cpk-tl {
|
|
165
|
+
font-family: "Plus Jakarta Sans", sans-serif;
|
|
166
|
+
display: flex;
|
|
167
|
+
flex-direction: column;
|
|
168
|
+
height: 100%;
|
|
169
|
+
overflow: hidden;
|
|
170
|
+
background: #f7f7f9;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* ── Search ── */
|
|
174
|
+
.cpk-tl__search {
|
|
175
|
+
padding: 10px 12px;
|
|
176
|
+
border-bottom: 1px solid #dbdbe5;
|
|
177
|
+
flex-shrink: 0;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.cpk-tl__search-input {
|
|
181
|
+
width: 100%;
|
|
182
|
+
box-sizing: border-box;
|
|
183
|
+
font-family: "Plus Jakarta Sans", sans-serif;
|
|
184
|
+
font-size: 12px;
|
|
185
|
+
padding: 7px 10px;
|
|
186
|
+
border-radius: 6px;
|
|
187
|
+
border: 1px solid #dbdbe5;
|
|
188
|
+
background: #ffffff;
|
|
189
|
+
color: #010507;
|
|
190
|
+
outline: none;
|
|
191
|
+
transition: border-color 0.15s;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.cpk-tl__search-input:focus {
|
|
195
|
+
border-color: #bec2ff;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* ── List ── */
|
|
199
|
+
.cpk-tl__list {
|
|
200
|
+
flex: 1;
|
|
201
|
+
overflow-y: auto;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* ── Thread item ── */
|
|
205
|
+
.cpk-tl__item {
|
|
206
|
+
padding: 11px 13px;
|
|
207
|
+
cursor: pointer;
|
|
208
|
+
border-bottom: 1px solid #e9e9ef;
|
|
209
|
+
border-left: 3px solid transparent;
|
|
210
|
+
transition: background 0.1s;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.cpk-tl__item:hover {
|
|
214
|
+
background: #ffffff;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.cpk-tl__item--active {
|
|
218
|
+
background: #bec2ff1a;
|
|
219
|
+
border-left-color: #bec2ff;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.cpk-tl__item--active:hover {
|
|
223
|
+
background: #bec2ff33;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.cpk-tl__row1 {
|
|
227
|
+
display: flex;
|
|
228
|
+
align-items: center;
|
|
229
|
+
gap: 8px;
|
|
230
|
+
margin-bottom: 3px;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.cpk-tl__name {
|
|
234
|
+
font-size: 12px;
|
|
235
|
+
font-weight: 500;
|
|
236
|
+
color: #010507;
|
|
237
|
+
flex: 1;
|
|
238
|
+
overflow: hidden;
|
|
239
|
+
text-overflow: ellipsis;
|
|
240
|
+
white-space: nowrap;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.cpk-tl__name--unnamed {
|
|
244
|
+
color: #838389;
|
|
245
|
+
font-style: italic;
|
|
246
|
+
font-weight: 400;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.cpk-tl__time {
|
|
250
|
+
font-family: "Spline Sans Mono", monospace;
|
|
251
|
+
font-size: 10px;
|
|
252
|
+
color: #838389;
|
|
253
|
+
flex-shrink: 0;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.cpk-tl__meta {
|
|
257
|
+
display: flex;
|
|
258
|
+
gap: 6px;
|
|
259
|
+
align-items: center;
|
|
260
|
+
flex-wrap: wrap;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.cpk-tl__pill {
|
|
264
|
+
font-family: "Spline Sans Mono", monospace;
|
|
265
|
+
font-size: 9px;
|
|
266
|
+
padding: 1px 7px;
|
|
267
|
+
border-radius: 4px;
|
|
268
|
+
text-transform: uppercase;
|
|
269
|
+
font-weight: 500;
|
|
270
|
+
white-space: nowrap;
|
|
271
|
+
background: #eee6fe;
|
|
272
|
+
color: #57575b;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/* ── Empty state ── */
|
|
276
|
+
.cpk-tl__empty {
|
|
277
|
+
padding: 32px 16px;
|
|
278
|
+
text-align: center;
|
|
279
|
+
color: #838389;
|
|
280
|
+
font-size: 12px;
|
|
281
|
+
display: flex;
|
|
282
|
+
flex-direction: column;
|
|
283
|
+
align-items: center;
|
|
284
|
+
gap: 8px;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.cpk-tl__empty-icon {
|
|
288
|
+
color: #c0c0c8;
|
|
289
|
+
}
|
|
290
|
+
`;
|
|
291
|
+
}
|
|
292
|
+
relativeTime(dateStr) {
|
|
293
|
+
const date = new Date(dateStr);
|
|
294
|
+
const diffMs = Date.now() - date.getTime();
|
|
295
|
+
const diffSec = Math.floor(diffMs / 1e3);
|
|
296
|
+
if (diffSec < 60) return `${diffSec}s ago`;
|
|
297
|
+
const diffMin = Math.floor(diffSec / 60);
|
|
298
|
+
if (diffMin < 60) return `${diffMin}m ago`;
|
|
299
|
+
const diffH = Math.floor(diffMin / 60);
|
|
300
|
+
if (diffH < 24) return `${diffH}h ago`;
|
|
301
|
+
return `${Math.floor(diffH / 24)}d ago`;
|
|
302
|
+
}
|
|
303
|
+
get filtered() {
|
|
304
|
+
const q = this._query.toLowerCase();
|
|
305
|
+
if (!q) return this.threads;
|
|
306
|
+
return this.threads.filter((t) => (t.name?.toLowerCase().includes(q) ?? false) || t.agentId.toLowerCase().includes(q) || t.id.toLowerCase().includes(q));
|
|
307
|
+
}
|
|
308
|
+
onThreadClick(threadId) {
|
|
309
|
+
this.dispatchEvent(new CustomEvent("threadSelected", {
|
|
310
|
+
detail: threadId,
|
|
311
|
+
bubbles: true,
|
|
312
|
+
composed: true
|
|
313
|
+
}));
|
|
314
|
+
}
|
|
315
|
+
render() {
|
|
316
|
+
const filtered = this.filtered;
|
|
317
|
+
return lit.html`
|
|
318
|
+
<div class="cpk-tl">
|
|
319
|
+
<!-- Search -->
|
|
320
|
+
<div class="cpk-tl__search">
|
|
321
|
+
<input
|
|
322
|
+
type="text"
|
|
323
|
+
placeholder="Search threads…"
|
|
324
|
+
.value=${this._query}
|
|
325
|
+
@input=${this.onSearchInput}
|
|
326
|
+
class="cpk-tl__search-input"
|
|
327
|
+
/>
|
|
328
|
+
</div>
|
|
329
|
+
|
|
330
|
+
<!-- Thread list -->
|
|
331
|
+
<div class="cpk-tl__list">
|
|
332
|
+
${filtered.map((thread) => lit.html`
|
|
333
|
+
<div
|
|
334
|
+
class="cpk-tl__item ${this.selectedThreadId === thread.id ? "cpk-tl__item--active" : ""}"
|
|
335
|
+
@click=${() => this.onThreadClick(thread.id)}
|
|
336
|
+
>
|
|
337
|
+
<div class="cpk-tl__row1">
|
|
338
|
+
<span
|
|
339
|
+
class="cpk-tl__name ${!thread.name ? "cpk-tl__name--unnamed" : ""}"
|
|
340
|
+
>${thread.name ?? "Untitled"}</span
|
|
341
|
+
>
|
|
342
|
+
<span class="cpk-tl__time"
|
|
343
|
+
>${this.relativeTime(thread.updatedAt)}</span
|
|
344
|
+
>
|
|
345
|
+
</div>
|
|
346
|
+
<div class="cpk-tl__meta">
|
|
347
|
+
<span class="cpk-tl__pill">${thread.agentId}</span>
|
|
348
|
+
</div>
|
|
349
|
+
</div>
|
|
350
|
+
`)}
|
|
351
|
+
${filtered.length === 0 ? lit.html`
|
|
352
|
+
<div class="cpk-tl__empty">
|
|
353
|
+
${this.errorMessage ? lit.html`
|
|
354
|
+
<svg
|
|
355
|
+
width="24"
|
|
356
|
+
height="24"
|
|
357
|
+
viewBox="0 0 24 24"
|
|
358
|
+
fill="none"
|
|
359
|
+
stroke="currentColor"
|
|
360
|
+
stroke-width="1.5"
|
|
361
|
+
stroke-linecap="round"
|
|
362
|
+
stroke-linejoin="round"
|
|
363
|
+
class="cpk-tl__empty-icon"
|
|
364
|
+
>
|
|
365
|
+
<circle cx="12" cy="12" r="10" />
|
|
366
|
+
<line x1="12" y1="8" x2="12" y2="12" />
|
|
367
|
+
<line x1="12" y1="16" x2="12.01" y2="16" />
|
|
368
|
+
</svg>
|
|
369
|
+
<div>
|
|
370
|
+
Failed to load threads
|
|
371
|
+
<div style="font-size:11px;margin-top:4px;color:#c0333a;">
|
|
372
|
+
${this.errorMessage}
|
|
373
|
+
</div>
|
|
374
|
+
</div>
|
|
375
|
+
` : this.threads.length === 0 ? lit.html`
|
|
376
|
+
<svg
|
|
377
|
+
width="24"
|
|
378
|
+
height="24"
|
|
379
|
+
viewBox="0 0 24 24"
|
|
380
|
+
fill="none"
|
|
381
|
+
stroke="currentColor"
|
|
382
|
+
stroke-width="1.5"
|
|
383
|
+
stroke-linecap="round"
|
|
384
|
+
stroke-linejoin="round"
|
|
385
|
+
class="cpk-tl__empty-icon"
|
|
386
|
+
>
|
|
387
|
+
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
|
|
388
|
+
</svg>
|
|
389
|
+
No threads yet
|
|
390
|
+
` : lit.html`
|
|
391
|
+
No threads match your search.
|
|
392
|
+
`}
|
|
393
|
+
</div>
|
|
394
|
+
` : lit.nothing}
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
`;
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
var ɵCpkThreadDetails = class ɵCpkThreadDetails extends lit.LitElement {
|
|
401
|
+
constructor(..._args2) {
|
|
402
|
+
super(..._args2);
|
|
403
|
+
this.threadId = null;
|
|
404
|
+
this.thread = null;
|
|
405
|
+
this.runtimeUrl = "";
|
|
406
|
+
this.headers = {};
|
|
407
|
+
this.agentStateInput = null;
|
|
408
|
+
this.agentEventsInput = [];
|
|
409
|
+
this.liveMessageVersion = 0;
|
|
410
|
+
this._tab = "conversation";
|
|
411
|
+
this._conversation = [];
|
|
412
|
+
this._fetchedEvents = null;
|
|
413
|
+
this._fetchedState = null;
|
|
414
|
+
this._loadingMessages = false;
|
|
415
|
+
this._loadingEvents = false;
|
|
416
|
+
this._loadingState = false;
|
|
417
|
+
this._messagesError = null;
|
|
418
|
+
this._eventsError = null;
|
|
419
|
+
this._stateError = null;
|
|
420
|
+
this._expandedTools = /* @__PURE__ */ new Set();
|
|
421
|
+
this._expandedMessages = /* @__PURE__ */ new Set();
|
|
422
|
+
this._showDetailPanel = false;
|
|
423
|
+
this._detailPanelWidth = 250;
|
|
424
|
+
this._eventsNotAvailable = false;
|
|
425
|
+
this._stateNotAvailable = false;
|
|
426
|
+
this._panelInitializing = false;
|
|
427
|
+
this._activatedTabs = new Set(["conversation"]);
|
|
428
|
+
this._panelTplCache = /* @__PURE__ */ new Map();
|
|
429
|
+
this._eventsFetched = false;
|
|
430
|
+
this._stateFetched = false;
|
|
431
|
+
this._lastFetchedThreadId = null;
|
|
432
|
+
this._lastSeenLiveMessageVersion = 0;
|
|
433
|
+
this._messagesAbort = null;
|
|
434
|
+
this._eventsAbort = null;
|
|
435
|
+
this._stateAbort = null;
|
|
436
|
+
this._dividerResizing = false;
|
|
437
|
+
this._dividerPointerId = -1;
|
|
438
|
+
this._dividerStartX = 0;
|
|
439
|
+
this._dividerStartWidth = 0;
|
|
440
|
+
this.onDetailDividerDown = (event) => {
|
|
441
|
+
this._dividerResizing = true;
|
|
442
|
+
this._dividerPointerId = event.pointerId;
|
|
443
|
+
this._dividerStartX = event.clientX;
|
|
444
|
+
this._dividerStartWidth = this._detailPanelWidth;
|
|
445
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
446
|
+
event.preventDefault();
|
|
447
|
+
};
|
|
448
|
+
this.onDetailDividerMove = (event) => {
|
|
449
|
+
if (!this._dividerResizing || this._dividerPointerId !== event.pointerId) return;
|
|
450
|
+
const delta = this._dividerStartX - event.clientX;
|
|
451
|
+
this._detailPanelWidth = Math.max(160, Math.min(400, this._dividerStartWidth + delta));
|
|
452
|
+
};
|
|
453
|
+
this.onDetailDividerUp = (event) => {
|
|
454
|
+
if (this._dividerPointerId !== event.pointerId) return;
|
|
455
|
+
const target = event.currentTarget;
|
|
456
|
+
if (target.hasPointerCapture(this._dividerPointerId)) target.releasePointerCapture(this._dividerPointerId);
|
|
457
|
+
this._dividerResizing = false;
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
static {
|
|
461
|
+
this.properties = {
|
|
462
|
+
threadId: { attribute: false },
|
|
463
|
+
thread: { attribute: false },
|
|
464
|
+
runtimeUrl: { attribute: false },
|
|
465
|
+
headers: { attribute: false },
|
|
466
|
+
agentStateInput: { attribute: false },
|
|
467
|
+
agentEventsInput: { attribute: false },
|
|
468
|
+
liveMessageVersion: { attribute: false },
|
|
469
|
+
_tab: { state: true },
|
|
470
|
+
_conversation: { state: true },
|
|
471
|
+
_fetchedEvents: { state: true },
|
|
472
|
+
_fetchedState: { state: true },
|
|
473
|
+
_loadingMessages: { state: true },
|
|
474
|
+
_loadingEvents: { state: true },
|
|
475
|
+
_loadingState: { state: true },
|
|
476
|
+
_messagesError: { state: true },
|
|
477
|
+
_eventsError: { state: true },
|
|
478
|
+
_stateError: { state: true },
|
|
479
|
+
_expandedTools: { state: true },
|
|
480
|
+
_expandedMessages: { state: true },
|
|
481
|
+
_showDetailPanel: { state: true },
|
|
482
|
+
_detailPanelWidth: { state: true },
|
|
483
|
+
_eventsNotAvailable: { state: true },
|
|
484
|
+
_stateNotAvailable: { state: true },
|
|
485
|
+
_panelInitializing: { state: true },
|
|
486
|
+
_activatedTabs: { state: true }
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
static {
|
|
490
|
+
this.COLLAPSE_THRESHOLD = 800;
|
|
491
|
+
}
|
|
492
|
+
static {
|
|
493
|
+
this.TAB_LIST = [
|
|
494
|
+
{
|
|
495
|
+
id: "conversation",
|
|
496
|
+
label: "Conversation"
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
id: "agent-state",
|
|
500
|
+
label: "Agent State"
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
id: "ag-ui-events",
|
|
504
|
+
label: "AG-UI Events"
|
|
505
|
+
}
|
|
506
|
+
];
|
|
507
|
+
}
|
|
508
|
+
renderTabContent(id) {
|
|
509
|
+
if (id === "conversation") return this.renderConversation();
|
|
510
|
+
if (id === "agent-state") return this.renderState();
|
|
511
|
+
return this.renderEvents();
|
|
512
|
+
}
|
|
513
|
+
activateTab(id) {
|
|
514
|
+
if (this._tab === id) return;
|
|
515
|
+
const isFirstActivation = !this._activatedTabs.has(id);
|
|
516
|
+
this._tab = id;
|
|
517
|
+
if (isFirstActivation) {
|
|
518
|
+
this._panelInitializing = true;
|
|
519
|
+
requestAnimationFrame(() => {
|
|
520
|
+
this._activatedTabs = new Set([...this._activatedTabs, id]);
|
|
521
|
+
this._panelInitializing = false;
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
this.maybeFetchTabData(id);
|
|
525
|
+
}
|
|
526
|
+
maybeFetchTabData(id) {
|
|
527
|
+
if (!this.threadId) return;
|
|
528
|
+
if (id === "ag-ui-events" && !this._eventsFetched) {
|
|
529
|
+
this._eventsFetched = true;
|
|
530
|
+
this.fetchEvents(this.threadId);
|
|
531
|
+
} else if (id === "agent-state" && !this._stateFetched) {
|
|
532
|
+
this._stateFetched = true;
|
|
533
|
+
this.fetchState(this.threadId);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
static {
|
|
537
|
+
this.styles = lit.css`
|
|
538
|
+
@import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600&family=Spline+Sans+Mono:wght@400;500&display=swap");
|
|
539
|
+
|
|
540
|
+
/* ── Root ────────────────────────────────────────────────────────── */
|
|
541
|
+
:host {
|
|
542
|
+
display: flex;
|
|
543
|
+
flex-direction: row;
|
|
544
|
+
overflow: hidden;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
.cpk-td {
|
|
548
|
+
font-family: "Plus Jakarta Sans", sans-serif;
|
|
549
|
+
font-size: 13px;
|
|
550
|
+
display: flex;
|
|
551
|
+
flex-direction: row;
|
|
552
|
+
width: 100%;
|
|
553
|
+
height: 100%;
|
|
554
|
+
overflow: hidden;
|
|
555
|
+
background: #ffffff;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/* ── Left area ───────────────────────────────────────────────────── */
|
|
559
|
+
.cpk-td__left {
|
|
560
|
+
flex: 1;
|
|
561
|
+
min-width: 0;
|
|
562
|
+
display: flex;
|
|
563
|
+
flex-direction: column;
|
|
564
|
+
overflow: hidden;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/* ── Tab bar header ──────────────────────────────────────────────── */
|
|
568
|
+
.cpk-td__tabs-header {
|
|
569
|
+
/* No top/right padding so tabs and toggle sit flush against the
|
|
570
|
+
top and right edges of the inspector. */
|
|
571
|
+
padding: 0 0 0 12px;
|
|
572
|
+
border-bottom: 1px solid #dbdbe5;
|
|
573
|
+
flex-shrink: 0;
|
|
574
|
+
display: flex;
|
|
575
|
+
align-items: stretch;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
.cpk-td__tab-group {
|
|
579
|
+
display: flex;
|
|
580
|
+
gap: 0;
|
|
581
|
+
margin-bottom: -1px;
|
|
582
|
+
/* Allow the tab list to shrink rather than pushing the panel-toggle
|
|
583
|
+
button past the right edge of the inspector when horizontal space
|
|
584
|
+
gets tight (the drawer being open eats noticeably into width). */
|
|
585
|
+
min-width: 0;
|
|
586
|
+
flex-shrink: 1;
|
|
587
|
+
overflow: hidden;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.cpk-td__tab {
|
|
591
|
+
font-family: "Plus Jakarta Sans", sans-serif;
|
|
592
|
+
font-size: 11px;
|
|
593
|
+
font-weight: 500;
|
|
594
|
+
padding: 10px 12px;
|
|
595
|
+
border: none;
|
|
596
|
+
border-bottom: 2px solid transparent;
|
|
597
|
+
cursor: pointer;
|
|
598
|
+
background: transparent;
|
|
599
|
+
color: #838389;
|
|
600
|
+
transition:
|
|
601
|
+
color 0.12s,
|
|
602
|
+
border-color 0.12s;
|
|
603
|
+
white-space: nowrap;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
.cpk-td__tab:hover {
|
|
607
|
+
color: #010507;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
.cpk-td__tab--active {
|
|
611
|
+
color: #010507;
|
|
612
|
+
border-bottom-color: #bec2ff;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/* Toggle is a separate control, not a tab — so it does NOT use the
|
|
616
|
+
tabs' bottom-border active indicator. Instead, a subtle filled
|
|
617
|
+
state communicates "the drawer is open," and a vertical separator
|
|
618
|
+
on the left visually divorces it from the tab group. */
|
|
619
|
+
.cpk-td__panel-toggle {
|
|
620
|
+
margin-left: auto;
|
|
621
|
+
align-self: stretch;
|
|
622
|
+
display: flex;
|
|
623
|
+
align-items: center;
|
|
624
|
+
justify-content: center;
|
|
625
|
+
padding: 0 12px;
|
|
626
|
+
border: none;
|
|
627
|
+
border-left: 1px solid #dbdbe5;
|
|
628
|
+
background: transparent;
|
|
629
|
+
color: #838389;
|
|
630
|
+
cursor: pointer;
|
|
631
|
+
flex-shrink: 0;
|
|
632
|
+
transition:
|
|
633
|
+
color 0.12s,
|
|
634
|
+
background 0.12s;
|
|
635
|
+
}
|
|
636
|
+
.cpk-td__panel-toggle:hover {
|
|
637
|
+
color: #010507;
|
|
638
|
+
background: #f4f4f9;
|
|
639
|
+
}
|
|
640
|
+
.cpk-td__panel-toggle--active {
|
|
641
|
+
color: #5558b2;
|
|
642
|
+
background: #eee6fe;
|
|
643
|
+
}
|
|
644
|
+
.cpk-td__panel-toggle--active:hover {
|
|
645
|
+
background: #e4d8fc;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/* ── Scrollable content ──────────────────────────────────────────── */
|
|
649
|
+
.cpk-td__content {
|
|
650
|
+
flex: 1;
|
|
651
|
+
overflow-y: auto;
|
|
652
|
+
padding: 16px;
|
|
653
|
+
display: flex;
|
|
654
|
+
flex-direction: column;
|
|
655
|
+
gap: 8px;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/* Pin direct children so expanded tool bodies don't get flex-shrunk. */
|
|
659
|
+
.cpk-td__content > * {
|
|
660
|
+
flex-shrink: 0;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/*
|
|
664
|
+
* Each tab's content is wrapped in this panel so the keep-mounted
|
|
665
|
+
* inactive panels can be hidden via display:none without disturbing
|
|
666
|
+
* the gap between visible siblings. The flex column + gap gives each
|
|
667
|
+
* conversation item / event row breathing room (the cpk-td__content
|
|
668
|
+
* rule above no longer reaches them now that they are nested inside
|
|
669
|
+
* the per-panel wrapper).
|
|
670
|
+
*/
|
|
671
|
+
.cpk-td__panel {
|
|
672
|
+
display: flex;
|
|
673
|
+
flex-direction: column;
|
|
674
|
+
gap: 12px;
|
|
675
|
+
}
|
|
676
|
+
.cpk-td__panel > * {
|
|
677
|
+
flex-shrink: 0;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/* ── Empty state ─────────────────────────────────────────────────── */
|
|
681
|
+
.cpk-td__empty-state {
|
|
682
|
+
flex: 1;
|
|
683
|
+
display: flex;
|
|
684
|
+
flex-direction: column;
|
|
685
|
+
align-items: center;
|
|
686
|
+
justify-content: center;
|
|
687
|
+
gap: 8px;
|
|
688
|
+
color: #838389;
|
|
689
|
+
font-size: 13px;
|
|
690
|
+
padding: 40px 0;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
.cpk-td__empty-hint {
|
|
694
|
+
font-size: 11px;
|
|
695
|
+
color: #838389;
|
|
696
|
+
text-align: center;
|
|
697
|
+
max-width: 220px;
|
|
698
|
+
line-height: 1.5;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/* ── Status messages ─────────────────────────────────────────────── */
|
|
702
|
+
.cpk-td__status {
|
|
703
|
+
padding: 16px;
|
|
704
|
+
font-size: 12px;
|
|
705
|
+
color: #838389;
|
|
706
|
+
text-align: center;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
.cpk-td__status--error {
|
|
710
|
+
color: #c0333a;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/* ── Conversation bubbles ────────────────────────────────────────── */
|
|
714
|
+
.cpk-td__bubble {
|
|
715
|
+
display: flex;
|
|
716
|
+
margin-bottom: 2px;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
.cpk-td__bubble--user {
|
|
720
|
+
justify-content: flex-end;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
.cpk-td__bubble--assistant {
|
|
724
|
+
justify-content: flex-start;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
.cpk-td__bubble-inner {
|
|
728
|
+
padding: 9px 14px;
|
|
729
|
+
max-width: 75%;
|
|
730
|
+
font-size: 13px;
|
|
731
|
+
line-height: 1.55;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
.cpk-td__bubble-inner--user {
|
|
735
|
+
background: #eee6fe;
|
|
736
|
+
color: #57575b;
|
|
737
|
+
border-radius: 10px 10px 3px 10px;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
.cpk-td__show-more {
|
|
741
|
+
display: inline-block;
|
|
742
|
+
margin-top: 4px;
|
|
743
|
+
font-size: 11px;
|
|
744
|
+
font-weight: 500;
|
|
745
|
+
color: #57575b;
|
|
746
|
+
cursor: pointer;
|
|
747
|
+
text-decoration: underline;
|
|
748
|
+
text-underline-offset: 2px;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
.cpk-td__bubble-inner--assistant {
|
|
752
|
+
background: #f7f7f9;
|
|
753
|
+
color: #010507;
|
|
754
|
+
border-radius: 10px 10px 10px 3px;
|
|
755
|
+
border: 1px solid #e9e9ef;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/* ── Tool call blocks ────────────────────────────────────────────── */
|
|
759
|
+
.cpk-td__tool-block {
|
|
760
|
+
border: 1px solid #e9e9ef;
|
|
761
|
+
border-radius: 6px;
|
|
762
|
+
overflow: hidden;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
.cpk-td__tool-header {
|
|
766
|
+
display: flex;
|
|
767
|
+
align-items: center;
|
|
768
|
+
gap: 6px;
|
|
769
|
+
padding: 6px 10px;
|
|
770
|
+
background: rgba(133, 236, 206, 0.15);
|
|
771
|
+
cursor: pointer;
|
|
772
|
+
font-size: 11px;
|
|
773
|
+
user-select: none;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
.cpk-td__tool-header:hover {
|
|
777
|
+
background: rgba(133, 236, 206, 0.22);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
.cpk-td__tool-name {
|
|
781
|
+
font-family: "Spline Sans Mono", monospace;
|
|
782
|
+
font-size: 10px;
|
|
783
|
+
font-weight: 500;
|
|
784
|
+
color: #189370;
|
|
785
|
+
text-transform: uppercase;
|
|
786
|
+
flex: 1;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
.cpk-td__tool-status {
|
|
790
|
+
font-family: "Spline Sans Mono", monospace;
|
|
791
|
+
font-size: 9px;
|
|
792
|
+
text-transform: uppercase;
|
|
793
|
+
color: #189370;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
.cpk-td__tool-status--pending {
|
|
797
|
+
color: #996300;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
.cpk-td__tool-chevron {
|
|
801
|
+
color: #838389;
|
|
802
|
+
font-size: 10px;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
.cpk-td__tool-body {
|
|
806
|
+
padding: 8px 10px;
|
|
807
|
+
border-top: 1px solid #e9e9ef;
|
|
808
|
+
background: #ffffff;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
.cpk-td__tool-section-label {
|
|
812
|
+
font-family: "Spline Sans Mono", monospace;
|
|
813
|
+
font-size: 9px;
|
|
814
|
+
font-weight: 500;
|
|
815
|
+
color: #838389;
|
|
816
|
+
text-transform: uppercase;
|
|
817
|
+
margin-bottom: 4px;
|
|
818
|
+
letter-spacing: 0.3px;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
.cpk-td__tool-pre {
|
|
822
|
+
margin: 0;
|
|
823
|
+
font-family: "Spline Sans Mono", monospace;
|
|
824
|
+
font-size: 10px;
|
|
825
|
+
background: #f7f7f9;
|
|
826
|
+
padding: 6px 8px;
|
|
827
|
+
border-radius: 4px;
|
|
828
|
+
overflow-x: auto;
|
|
829
|
+
white-space: pre-wrap;
|
|
830
|
+
word-break: break-all;
|
|
831
|
+
color: #010507;
|
|
832
|
+
line-height: 1.6;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
/* ── Tool call group ─────────────────────────────────────────────── */
|
|
836
|
+
.cpk-td__tool-group {
|
|
837
|
+
border: 1px solid #e9e9ef;
|
|
838
|
+
border-radius: 6px;
|
|
839
|
+
overflow: hidden;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
.cpk-td__tool-group-header {
|
|
843
|
+
padding: 5px 10px;
|
|
844
|
+
background: rgba(133, 236, 206, 0.15);
|
|
845
|
+
font-family: "Spline Sans Mono", monospace;
|
|
846
|
+
font-size: 10px;
|
|
847
|
+
color: #189370;
|
|
848
|
+
text-transform: uppercase;
|
|
849
|
+
font-weight: 500;
|
|
850
|
+
border-bottom: 1px solid #e9e9ef;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
.cpk-td__tool-group .cpk-td__tool-block {
|
|
854
|
+
border: none;
|
|
855
|
+
border-bottom: 1px solid #e9e9ef;
|
|
856
|
+
border-radius: 0;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
.cpk-td__tool-group .cpk-td__tool-block:last-child {
|
|
860
|
+
border-bottom: none;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/* ── Inline chips (reasoning / state update) ─────────────────────── */
|
|
864
|
+
.cpk-td__inline-chip {
|
|
865
|
+
display: flex;
|
|
866
|
+
align-items: center;
|
|
867
|
+
gap: 8px;
|
|
868
|
+
padding: 5px 0;
|
|
869
|
+
color: #838389;
|
|
870
|
+
font-family: "Spline Sans Mono", monospace;
|
|
871
|
+
font-size: 9px;
|
|
872
|
+
text-transform: uppercase;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
.cpk-td__inline-chip::before,
|
|
876
|
+
.cpk-td__inline-chip::after {
|
|
877
|
+
content: "";
|
|
878
|
+
flex: 1;
|
|
879
|
+
height: 1px;
|
|
880
|
+
background: #e9e9ef;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
/* ── Generative UI ──────────────────────────────────────────────── */
|
|
884
|
+
@keyframes cpk-genui-enter {
|
|
885
|
+
from {
|
|
886
|
+
opacity: 0;
|
|
887
|
+
transform: translateY(8px);
|
|
888
|
+
}
|
|
889
|
+
to {
|
|
890
|
+
opacity: 1;
|
|
891
|
+
transform: translateY(0);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
.cpk-td__genui {
|
|
896
|
+
display: flex;
|
|
897
|
+
flex-direction: column;
|
|
898
|
+
gap: 6px;
|
|
899
|
+
padding: 4px 16px 8px;
|
|
900
|
+
animation: cpk-genui-enter 0.25s cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
.cpk-td__genui-badge {
|
|
904
|
+
display: inline-flex;
|
|
905
|
+
align-items: center;
|
|
906
|
+
gap: 4px;
|
|
907
|
+
padding: 2px 8px;
|
|
908
|
+
border-radius: 4px;
|
|
909
|
+
background: #eee6fe;
|
|
910
|
+
color: #57575b;
|
|
911
|
+
font-size: 10px;
|
|
912
|
+
font-weight: 600;
|
|
913
|
+
align-self: flex-start;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
.cpk-td__genui-card {
|
|
917
|
+
overflow: hidden;
|
|
918
|
+
border-radius: 12px;
|
|
919
|
+
border: 1px solid #e2e8f0;
|
|
920
|
+
background: #fff;
|
|
921
|
+
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.08);
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
.cpk-td__genui-placeholder {
|
|
925
|
+
padding: 8px 12px;
|
|
926
|
+
border-radius: 8px;
|
|
927
|
+
border: 1px solid #ede9fe;
|
|
928
|
+
background: #f5f3ff;
|
|
929
|
+
color: #7c3aed;
|
|
930
|
+
font-size: 11px;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
/* ── AG-UI Events ────────────────────────────────────────────────── */
|
|
934
|
+
.cpk-td__event {
|
|
935
|
+
flex-shrink: 0;
|
|
936
|
+
border: 1px solid #e9e9ef;
|
|
937
|
+
border-radius: 6px;
|
|
938
|
+
overflow: hidden;
|
|
939
|
+
/*
|
|
940
|
+
* content-visibility: auto lets the browser skip layout + paint for
|
|
941
|
+
* off-screen events while keeping them in the DOM (so scroll size
|
|
942
|
+
* stays correct). Without this, switching back to AG-UI Events on a
|
|
943
|
+
* thread with hundreds of events triggers a full layout pass over
|
|
944
|
+
* every event row, which on Martha's intelligence-backed example
|
|
945
|
+
* shows up as a multi-second freeze each time the panel becomes
|
|
946
|
+
* visible. The intrinsic-size hint avoids the visible jump as the
|
|
947
|
+
* browser swaps in real heights when items scroll into view.
|
|
948
|
+
*/
|
|
949
|
+
content-visibility: auto;
|
|
950
|
+
contain-intrinsic-size: 0 80px;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
.cpk-td__event-header {
|
|
954
|
+
display: flex;
|
|
955
|
+
justify-content: space-between;
|
|
956
|
+
align-items: center;
|
|
957
|
+
padding: 5px 10px;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
.cpk-td__event-type {
|
|
961
|
+
font-family: "Spline Sans Mono", monospace;
|
|
962
|
+
font-size: 9px;
|
|
963
|
+
font-weight: 500;
|
|
964
|
+
text-transform: uppercase;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
.cpk-td__event-time {
|
|
968
|
+
font-family: "Spline Sans Mono", monospace;
|
|
969
|
+
font-size: 9px;
|
|
970
|
+
color: #838389;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
.cpk-td__event-payload {
|
|
974
|
+
margin: 0;
|
|
975
|
+
font-family: "Spline Sans Mono", monospace;
|
|
976
|
+
font-size: 10px;
|
|
977
|
+
line-height: 1.6;
|
|
978
|
+
white-space: pre-wrap;
|
|
979
|
+
word-break: break-all;
|
|
980
|
+
color: #57575b;
|
|
981
|
+
padding: 8px 10px;
|
|
982
|
+
border-top: 1px solid #e9e9ef;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
/* ── JSON block (agent state) ────────────────────────────────────── */
|
|
986
|
+
.cpk-td__json-block {
|
|
987
|
+
margin: 0;
|
|
988
|
+
font-family: "Spline Sans Mono", monospace;
|
|
989
|
+
font-size: 11px;
|
|
990
|
+
line-height: 1.8;
|
|
991
|
+
white-space: pre-wrap;
|
|
992
|
+
word-break: break-all;
|
|
993
|
+
color: #57575b;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
/* ── Resize divider ──────────────────────────────────────────────── */
|
|
997
|
+
/* Floats over the drawer's left edge so the toggle and the drawer
|
|
998
|
+
touch directly without a 4px flex-gap between them. The hit zone
|
|
999
|
+
is wider than its visual hint to make it easy to grab. */
|
|
1000
|
+
.cpk-td__detail-divider {
|
|
1001
|
+
position: absolute;
|
|
1002
|
+
top: 0;
|
|
1003
|
+
bottom: 0;
|
|
1004
|
+
left: -3px;
|
|
1005
|
+
width: 7px;
|
|
1006
|
+
cursor: col-resize;
|
|
1007
|
+
background: transparent;
|
|
1008
|
+
z-index: 5;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
.cpk-td__detail-divider:hover {
|
|
1012
|
+
background: rgba(190, 194, 255, 0.3);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
/* ── Right detail panel ──────────────────────────────────────────── */
|
|
1016
|
+
.cpk-td__detail {
|
|
1017
|
+
flex-shrink: 0;
|
|
1018
|
+
overflow: hidden;
|
|
1019
|
+
background: #f7f7f9;
|
|
1020
|
+
display: flex;
|
|
1021
|
+
flex-direction: column;
|
|
1022
|
+
gap: 0;
|
|
1023
|
+
padding: 0;
|
|
1024
|
+
box-sizing: border-box;
|
|
1025
|
+
position: relative;
|
|
1026
|
+
/* Slide open/closed via width + padding transition. When closed,
|
|
1027
|
+
width and padding are 0 so the drawer fully collapses. */
|
|
1028
|
+
transition:
|
|
1029
|
+
width 220ms cubic-bezier(0.4, 0, 0.2, 1),
|
|
1030
|
+
padding 220ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
.cpk-td__detail[data-open="true"] {
|
|
1034
|
+
overflow-y: auto;
|
|
1035
|
+
padding: 16px;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
.cpk-tdp__section-title {
|
|
1039
|
+
font-family: "Spline Sans Mono", monospace;
|
|
1040
|
+
font-size: 10px;
|
|
1041
|
+
font-weight: 500;
|
|
1042
|
+
color: #838389;
|
|
1043
|
+
text-transform: uppercase;
|
|
1044
|
+
letter-spacing: 0.6px;
|
|
1045
|
+
margin-bottom: 8px;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
.cpk-tdp__divider {
|
|
1049
|
+
height: 1px;
|
|
1050
|
+
background: #dbdbe5;
|
|
1051
|
+
margin: 14px 0;
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
.cpk-tdp__row {
|
|
1055
|
+
display: flex;
|
|
1056
|
+
justify-content: space-between;
|
|
1057
|
+
align-items: flex-start;
|
|
1058
|
+
padding: 3px 0;
|
|
1059
|
+
gap: 8px;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
.cpk-tdp__label {
|
|
1063
|
+
color: #838389;
|
|
1064
|
+
font-size: 11px;
|
|
1065
|
+
white-space: nowrap;
|
|
1066
|
+
flex-shrink: 0;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
.cpk-tdp__value {
|
|
1070
|
+
color: #010507;
|
|
1071
|
+
font-family: "Spline Sans Mono", monospace;
|
|
1072
|
+
font-size: 11px;
|
|
1073
|
+
text-align: right;
|
|
1074
|
+
min-width: 0;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
.cpk-tdp__value--truncate {
|
|
1078
|
+
overflow: hidden;
|
|
1079
|
+
text-overflow: ellipsis;
|
|
1080
|
+
white-space: nowrap;
|
|
1081
|
+
max-width: 130px;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
.cpk-tdp__value--wrap {
|
|
1085
|
+
white-space: normal;
|
|
1086
|
+
word-break: break-all;
|
|
1087
|
+
text-align: right;
|
|
1088
|
+
}
|
|
1089
|
+
`;
|
|
1090
|
+
}
|
|
1091
|
+
updated(_changed) {
|
|
1092
|
+
if (this.threadId !== this._lastFetchedThreadId) {
|
|
1093
|
+
this._lastFetchedThreadId = this.threadId;
|
|
1094
|
+
this._lastSeenLiveMessageVersion = this.liveMessageVersion;
|
|
1095
|
+
this._tab = "conversation";
|
|
1096
|
+
this._activatedTabs = new Set(["conversation"]);
|
|
1097
|
+
this._panelTplCache = /* @__PURE__ */ new Map();
|
|
1098
|
+
this._expandedTools = /* @__PURE__ */ new Set();
|
|
1099
|
+
this._expandedMessages = /* @__PURE__ */ new Set();
|
|
1100
|
+
this._messagesAbort?.abort();
|
|
1101
|
+
this._messagesAbort = null;
|
|
1102
|
+
this._eventsAbort?.abort();
|
|
1103
|
+
this._eventsAbort = null;
|
|
1104
|
+
this._stateAbort?.abort();
|
|
1105
|
+
this._stateAbort = null;
|
|
1106
|
+
this._eventsFetched = false;
|
|
1107
|
+
this._stateFetched = false;
|
|
1108
|
+
this._fetchedEvents = null;
|
|
1109
|
+
this._fetchedState = null;
|
|
1110
|
+
if (this.threadId) this.fetchMessages(this.threadId);
|
|
1111
|
+
else this._conversation = [];
|
|
1112
|
+
} else if (this.threadId && this.liveMessageVersion !== this._lastSeenLiveMessageVersion) {
|
|
1113
|
+
this._lastSeenLiveMessageVersion = this.liveMessageVersion;
|
|
1114
|
+
this._messagesAbort?.abort();
|
|
1115
|
+
this._messagesAbort = null;
|
|
1116
|
+
this.fetchMessages(this.threadId, true);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
/**
|
|
1120
|
+
* Fetch the canonical conversation for `threadId` from the runtime.
|
|
1121
|
+
*
|
|
1122
|
+
* `silent` is true for live re-fetches triggered by `liveMessageVersion`
|
|
1123
|
+
* bumps during streaming. In that mode we never toggle the loading state
|
|
1124
|
+
* (which would flash "Loading messages…" between every message) and we
|
|
1125
|
+
* keep the previous conversation on transient errors instead of blanking
|
|
1126
|
+
* it. Initial threadId-change fetches use the default (`silent=false`)
|
|
1127
|
+
* so users see an explicit loading indicator on first load.
|
|
1128
|
+
*/
|
|
1129
|
+
async fetchMessages(threadId, silent = false) {
|
|
1130
|
+
if (!this.runtimeUrl) {
|
|
1131
|
+
if (!silent) this._conversation = [];
|
|
1132
|
+
return;
|
|
1133
|
+
}
|
|
1134
|
+
const controller = new AbortController();
|
|
1135
|
+
this._messagesAbort = controller;
|
|
1136
|
+
if (!silent) {
|
|
1137
|
+
this._loadingMessages = true;
|
|
1138
|
+
this._messagesError = null;
|
|
1139
|
+
}
|
|
1140
|
+
try {
|
|
1141
|
+
const res = await fetch(`${this.runtimeUrl}/threads/${encodeURIComponent(threadId)}/messages`, {
|
|
1142
|
+
headers: { ...this.headers },
|
|
1143
|
+
signal: controller.signal
|
|
1144
|
+
});
|
|
1145
|
+
if (controller.signal.aborted || this.threadId !== threadId) return;
|
|
1146
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
1147
|
+
const data = await res.json();
|
|
1148
|
+
if (controller.signal.aborted || this.threadId !== threadId) return;
|
|
1149
|
+
this._conversation = this.mapMessages(data.messages);
|
|
1150
|
+
} catch (err) {
|
|
1151
|
+
if (err instanceof Error && err.name === "AbortError") return;
|
|
1152
|
+
if (!silent) {
|
|
1153
|
+
this._messagesError = err instanceof Error ? err.message : "Failed to load messages";
|
|
1154
|
+
this._conversation = [];
|
|
1155
|
+
}
|
|
1156
|
+
} finally {
|
|
1157
|
+
if (!silent && !controller.signal.aborted) this._loadingMessages = false;
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
async fetchEvents(threadId) {
|
|
1161
|
+
this._eventsNotAvailable = false;
|
|
1162
|
+
if (!this.runtimeUrl) {
|
|
1163
|
+
this._fetchedEvents = null;
|
|
1164
|
+
return;
|
|
1165
|
+
}
|
|
1166
|
+
const controller = new AbortController();
|
|
1167
|
+
this._eventsAbort = controller;
|
|
1168
|
+
this._loadingEvents = true;
|
|
1169
|
+
this._eventsError = null;
|
|
1170
|
+
try {
|
|
1171
|
+
const res = await fetch(`${this.runtimeUrl}/threads/${encodeURIComponent(threadId)}/events`, {
|
|
1172
|
+
headers: { ...this.headers },
|
|
1173
|
+
signal: controller.signal
|
|
1174
|
+
});
|
|
1175
|
+
if (controller.signal.aborted || this.threadId !== threadId) return;
|
|
1176
|
+
if (res.status === 501) {
|
|
1177
|
+
this._eventsNotAvailable = true;
|
|
1178
|
+
this._fetchedEvents = null;
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
1182
|
+
const data = await res.json();
|
|
1183
|
+
if (controller.signal.aborted || this.threadId !== threadId) return;
|
|
1184
|
+
this._fetchedEvents = this.mapApiEvents(data.events);
|
|
1185
|
+
} catch (err) {
|
|
1186
|
+
if (err instanceof Error && err.name === "AbortError") return;
|
|
1187
|
+
if (this.threadId !== threadId) return;
|
|
1188
|
+
this._eventsError = err instanceof Error ? err.message : "Failed to load events";
|
|
1189
|
+
this._fetchedEvents = [];
|
|
1190
|
+
} finally {
|
|
1191
|
+
if (!controller.signal.aborted && this.threadId === threadId) this._loadingEvents = false;
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
async fetchState(threadId) {
|
|
1195
|
+
this._stateNotAvailable = false;
|
|
1196
|
+
if (!this.runtimeUrl) {
|
|
1197
|
+
this._fetchedState = null;
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
const controller = new AbortController();
|
|
1201
|
+
this._stateAbort = controller;
|
|
1202
|
+
this._loadingState = true;
|
|
1203
|
+
this._stateError = null;
|
|
1204
|
+
try {
|
|
1205
|
+
const res = await fetch(`${this.runtimeUrl}/threads/${encodeURIComponent(threadId)}/state`, {
|
|
1206
|
+
headers: { ...this.headers },
|
|
1207
|
+
signal: controller.signal
|
|
1208
|
+
});
|
|
1209
|
+
if (controller.signal.aborted || this.threadId !== threadId) return;
|
|
1210
|
+
if (res.status === 501) {
|
|
1211
|
+
this._stateNotAvailable = true;
|
|
1212
|
+
this._fetchedState = null;
|
|
1213
|
+
return;
|
|
1214
|
+
}
|
|
1215
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
1216
|
+
const data = await res.json();
|
|
1217
|
+
if (controller.signal.aborted || this.threadId !== threadId) return;
|
|
1218
|
+
this._fetchedState = data.state ?? null;
|
|
1219
|
+
} catch (err) {
|
|
1220
|
+
if (err instanceof Error && err.name === "AbortError") return;
|
|
1221
|
+
if (this.threadId !== threadId) return;
|
|
1222
|
+
this._stateError = err instanceof Error ? err.message : "Failed to load state";
|
|
1223
|
+
this._fetchedState = null;
|
|
1224
|
+
} finally {
|
|
1225
|
+
if (!controller.signal.aborted && this.threadId === threadId) this._loadingState = false;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
mapMessages(messages) {
|
|
1229
|
+
const items = [];
|
|
1230
|
+
const toolCallMap = /* @__PURE__ */ new Map();
|
|
1231
|
+
for (const msg of messages) if (msg.role === "user" && msg.content) items.push({
|
|
1232
|
+
id: msg.id,
|
|
1233
|
+
type: "user",
|
|
1234
|
+
content: msg.content,
|
|
1235
|
+
createdAt: ""
|
|
1236
|
+
});
|
|
1237
|
+
else if (msg.role === "assistant") {
|
|
1238
|
+
if (msg.toolCalls?.length) for (const tc of msg.toolCalls) {
|
|
1239
|
+
let args = {};
|
|
1240
|
+
try {
|
|
1241
|
+
args = JSON.parse(tc.args);
|
|
1242
|
+
} catch (err) {
|
|
1243
|
+
console.error("[CopilotKit Inspector] Failed to parse tool-call arguments", {
|
|
1244
|
+
toolCallId: tc.id,
|
|
1245
|
+
raw: tc.args,
|
|
1246
|
+
error: err
|
|
1247
|
+
});
|
|
1248
|
+
args = {
|
|
1249
|
+
__parseError: true,
|
|
1250
|
+
__raw: tc.args
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1253
|
+
const item = {
|
|
1254
|
+
id: tc.id,
|
|
1255
|
+
type: "tool_call",
|
|
1256
|
+
toolName: tc.name,
|
|
1257
|
+
toolCallId: tc.id,
|
|
1258
|
+
arguments: args,
|
|
1259
|
+
result: null,
|
|
1260
|
+
createdAt: ""
|
|
1261
|
+
};
|
|
1262
|
+
toolCallMap.set(tc.id, item);
|
|
1263
|
+
items.push(item);
|
|
1264
|
+
}
|
|
1265
|
+
if (msg.content) items.push({
|
|
1266
|
+
id: msg.id,
|
|
1267
|
+
type: "assistant",
|
|
1268
|
+
content: msg.content,
|
|
1269
|
+
createdAt: ""
|
|
1270
|
+
});
|
|
1271
|
+
} else if (msg.role === "activity") items.push({
|
|
1272
|
+
id: msg.id,
|
|
1273
|
+
type: "generative-ui",
|
|
1274
|
+
activityType: msg.activityType ?? "unknown",
|
|
1275
|
+
createdAt: ""
|
|
1276
|
+
});
|
|
1277
|
+
else if (msg.role === "tool" && msg.toolCallId) {
|
|
1278
|
+
const tc = toolCallMap.get(msg.toolCallId);
|
|
1279
|
+
if (tc) try {
|
|
1280
|
+
tc.result = JSON.parse(msg.content ?? "{}");
|
|
1281
|
+
} catch (err) {
|
|
1282
|
+
console.error("[CopilotKit Inspector] Failed to parse tool-call result content", {
|
|
1283
|
+
toolCallId: msg.toolCallId,
|
|
1284
|
+
raw: msg.content,
|
|
1285
|
+
error: err
|
|
1286
|
+
});
|
|
1287
|
+
tc.result = {
|
|
1288
|
+
__parseError: true,
|
|
1289
|
+
__raw: msg.content ?? null
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
return items;
|
|
1294
|
+
}
|
|
1295
|
+
mapApiEvents(events) {
|
|
1296
|
+
return events.map((event) => {
|
|
1297
|
+
const { type, timestamp, ...rest } = event;
|
|
1298
|
+
return {
|
|
1299
|
+
type: typeof type === "string" ? type : "UNKNOWN",
|
|
1300
|
+
timestamp: typeof timestamp === "string" || typeof timestamp === "number" ? timestamp : Date.now(),
|
|
1301
|
+
payload: rest
|
|
1302
|
+
};
|
|
1303
|
+
});
|
|
1304
|
+
}
|
|
1305
|
+
get renderItems() {
|
|
1306
|
+
const items = this._conversation;
|
|
1307
|
+
const result = [];
|
|
1308
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1309
|
+
for (const item of items) {
|
|
1310
|
+
if (item.type === "agent_responded") continue;
|
|
1311
|
+
if (item.type !== "tool_call" || !item.groupId) {
|
|
1312
|
+
result.push(item);
|
|
1313
|
+
continue;
|
|
1314
|
+
}
|
|
1315
|
+
if (seen.has(item.groupId)) continue;
|
|
1316
|
+
seen.add(item.groupId);
|
|
1317
|
+
const group = {
|
|
1318
|
+
type: "tool_call_group",
|
|
1319
|
+
id: item.groupId,
|
|
1320
|
+
items: items.filter((i) => i.type === "tool_call" && i.groupId === item.groupId)
|
|
1321
|
+
};
|
|
1322
|
+
result.push(group);
|
|
1323
|
+
}
|
|
1324
|
+
return result;
|
|
1325
|
+
}
|
|
1326
|
+
get activityCounts() {
|
|
1327
|
+
let messages = 0;
|
|
1328
|
+
let toolCalls = 0;
|
|
1329
|
+
let generativeUi = 0;
|
|
1330
|
+
for (const item of this._conversation) {
|
|
1331
|
+
if (item.type === "user" || item.type === "assistant") messages++;
|
|
1332
|
+
if (item.type === "tool_call") toolCalls++;
|
|
1333
|
+
if (item.type === "generative-ui") generativeUi++;
|
|
1334
|
+
}
|
|
1335
|
+
return {
|
|
1336
|
+
messages,
|
|
1337
|
+
toolCalls,
|
|
1338
|
+
generativeUi
|
|
1339
|
+
};
|
|
1340
|
+
}
|
|
1341
|
+
get duration() {
|
|
1342
|
+
const t = this.thread;
|
|
1343
|
+
if (!t?.createdAt || !t?.updatedAt) return "—";
|
|
1344
|
+
const ms = new Date(t.updatedAt).getTime() - new Date(t.createdAt).getTime();
|
|
1345
|
+
if (ms < 0) return "—";
|
|
1346
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
1347
|
+
const s = Math.floor(ms / 1e3);
|
|
1348
|
+
if (s < 60) return `${s}s`;
|
|
1349
|
+
return `${Math.floor(s / 60)}m ${s % 60}s`;
|
|
1350
|
+
}
|
|
1351
|
+
toggleToolExpand(id) {
|
|
1352
|
+
const next = new Set(this._expandedTools);
|
|
1353
|
+
if (next.has(id)) next.delete(id);
|
|
1354
|
+
else next.add(id);
|
|
1355
|
+
this._expandedTools = next;
|
|
1356
|
+
}
|
|
1357
|
+
toggleMessageExpand(id) {
|
|
1358
|
+
const next = new Set(this._expandedMessages);
|
|
1359
|
+
if (next.has(id)) next.delete(id);
|
|
1360
|
+
else next.add(id);
|
|
1361
|
+
this._expandedMessages = next;
|
|
1362
|
+
}
|
|
1363
|
+
get activeEvents() {
|
|
1364
|
+
if (this._eventsNotAvailable) return [];
|
|
1365
|
+
return this._fetchedEvents ?? this.agentEventsInput ?? [];
|
|
1366
|
+
}
|
|
1367
|
+
get activeState() {
|
|
1368
|
+
if (this._stateNotAvailable) return null;
|
|
1369
|
+
return this._fetchedState ?? this.agentStateInput ?? null;
|
|
1370
|
+
}
|
|
1371
|
+
hasRenderableState() {
|
|
1372
|
+
const s = this.activeState;
|
|
1373
|
+
return !!s && typeof s === "object" && Object.keys(s).length > 0;
|
|
1374
|
+
}
|
|
1375
|
+
shortId(id) {
|
|
1376
|
+
if (!id) return "—";
|
|
1377
|
+
return id.length > 20 ? id.slice(0, 8) + "…" : id;
|
|
1378
|
+
}
|
|
1379
|
+
fmtTime(dateStr) {
|
|
1380
|
+
if (!dateStr) return "—";
|
|
1381
|
+
const d = new Date(dateStr);
|
|
1382
|
+
if (Number.isNaN(d.getTime())) return "—";
|
|
1383
|
+
return d.toLocaleTimeString("en-US", {
|
|
1384
|
+
hour: "2-digit",
|
|
1385
|
+
minute: "2-digit",
|
|
1386
|
+
second: "2-digit",
|
|
1387
|
+
hour12: false
|
|
1388
|
+
});
|
|
1389
|
+
}
|
|
1390
|
+
render() {
|
|
1391
|
+
return lit.html`
|
|
1392
|
+
<div class="cpk-td">
|
|
1393
|
+
<!-- ── Left area: tabs + content ─────────────────────────────────── -->
|
|
1394
|
+
<div class="cpk-td__left">
|
|
1395
|
+
<!-- Tab bar -->
|
|
1396
|
+
<div class="cpk-td__tabs-header">
|
|
1397
|
+
<div class="cpk-td__tab-group" role="tablist">
|
|
1398
|
+
${ɵCpkThreadDetails.TAB_LIST.map((tab) => lit.html`
|
|
1399
|
+
<button
|
|
1400
|
+
role="tab"
|
|
1401
|
+
class="cpk-td__tab ${this._tab === tab.id ? "cpk-td__tab--active" : ""}"
|
|
1402
|
+
@click=${() => this.activateTab(tab.id)}
|
|
1403
|
+
>
|
|
1404
|
+
${tab.label}
|
|
1405
|
+
</button>
|
|
1406
|
+
`)}
|
|
1407
|
+
</div>
|
|
1408
|
+
${this.renderPanelToggle()}
|
|
1409
|
+
</div>
|
|
1410
|
+
|
|
1411
|
+
<!-- Scrollable content -->
|
|
1412
|
+
<div class="cpk-td__content">
|
|
1413
|
+
${this._panelInitializing ? lit.html`
|
|
1414
|
+
<div class="cpk-td__status">Loading…</div>
|
|
1415
|
+
` : lit.nothing}
|
|
1416
|
+
${ɵCpkThreadDetails.TAB_LIST.map((tab) => this._activatedTabs.has(tab.id) ? lit.html`<div
|
|
1417
|
+
class="cpk-td__panel"
|
|
1418
|
+
style=${this._tab === tab.id && !this._panelInitializing ? "" : "display:none"}
|
|
1419
|
+
>
|
|
1420
|
+
${this.renderTabContent(tab.id)}
|
|
1421
|
+
</div>` : lit.nothing)}
|
|
1422
|
+
</div>
|
|
1423
|
+
</div>
|
|
1424
|
+
|
|
1425
|
+
<!--
|
|
1426
|
+
Drawer always rendered so width animates between 0 and its
|
|
1427
|
+
target. Divider lives INSIDE the drawer and is absolutely
|
|
1428
|
+
positioned over its left edge so the toggle (rightmost of the
|
|
1429
|
+
tab row) and the drawer touch with no flex-gap between them.
|
|
1430
|
+
-->
|
|
1431
|
+
<div
|
|
1432
|
+
class="cpk-td__detail"
|
|
1433
|
+
data-open=${this._showDetailPanel ? "true" : "false"}
|
|
1434
|
+
style="width:${this._showDetailPanel ? this._detailPanelWidth : 0}px"
|
|
1435
|
+
aria-hidden=${this._showDetailPanel ? "false" : "true"}
|
|
1436
|
+
>
|
|
1437
|
+
${this._showDetailPanel ? lit.html`
|
|
1438
|
+
<div
|
|
1439
|
+
class="cpk-td__detail-divider"
|
|
1440
|
+
@pointerdown=${this.onDetailDividerDown}
|
|
1441
|
+
@pointermove=${this.onDetailDividerMove}
|
|
1442
|
+
@pointerup=${this.onDetailDividerUp}
|
|
1443
|
+
@pointercancel=${this.onDetailDividerUp}
|
|
1444
|
+
></div>
|
|
1445
|
+
` : lit.nothing}
|
|
1446
|
+
${this.renderDetailPanel()}
|
|
1447
|
+
</div>
|
|
1448
|
+
</div>
|
|
1449
|
+
`;
|
|
1450
|
+
}
|
|
1451
|
+
renderConversation() {
|
|
1452
|
+
if (this._loadingMessages) return lit.html`
|
|
1453
|
+
<div class="cpk-td__status">Loading messages…</div>
|
|
1454
|
+
`;
|
|
1455
|
+
if (this._messagesError) return lit.html`<div class="cpk-td__status cpk-td__status--error">
|
|
1456
|
+
${this._messagesError}
|
|
1457
|
+
</div>`;
|
|
1458
|
+
if (this._conversation.length === 0) return lit.html`
|
|
1459
|
+
<div class="cpk-td__empty-state">
|
|
1460
|
+
<svg
|
|
1461
|
+
width="28"
|
|
1462
|
+
height="28"
|
|
1463
|
+
viewBox="0 0 24 24"
|
|
1464
|
+
fill="none"
|
|
1465
|
+
stroke="currentColor"
|
|
1466
|
+
stroke-width="1.5"
|
|
1467
|
+
stroke-linecap="round"
|
|
1468
|
+
stroke-linejoin="round"
|
|
1469
|
+
>
|
|
1470
|
+
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
|
|
1471
|
+
</svg>
|
|
1472
|
+
<span>No messages yet</span>
|
|
1473
|
+
</div>
|
|
1474
|
+
`;
|
|
1475
|
+
return this.cachedPanelTpl("conversation", [
|
|
1476
|
+
this._conversation,
|
|
1477
|
+
this._expandedTools,
|
|
1478
|
+
this._expandedMessages
|
|
1479
|
+
], () => {
|
|
1480
|
+
return lit.html`${this.renderItems.map((item) => this.renderRenderItem(item))}`;
|
|
1481
|
+
});
|
|
1482
|
+
}
|
|
1483
|
+
/**
|
|
1484
|
+
* Memoize the rendered TemplateResult for `slot` keyed by tuple
|
|
1485
|
+
* element-wise reference equality. The hot path for tab switches: when
|
|
1486
|
+
* the underlying data hasn't changed, return the previously built
|
|
1487
|
+
* TemplateResult so Lit's diff short-circuits. Each panel's `key` is
|
|
1488
|
+
* the tuple of inputs the template reads — pass everything the template
|
|
1489
|
+
* depends on, or the cache will return stale output when those inputs
|
|
1490
|
+
* change without the listed key flipping.
|
|
1491
|
+
*/
|
|
1492
|
+
cachedPanelTpl(slot, key, build) {
|
|
1493
|
+
const cached = this._panelTplCache.get(slot);
|
|
1494
|
+
if (cached && cached.key.length === key.length && cached.key.every((v, i) => v === key[i])) return cached.tpl;
|
|
1495
|
+
const tpl = build();
|
|
1496
|
+
this._panelTplCache.set(slot, {
|
|
1497
|
+
key,
|
|
1498
|
+
tpl
|
|
1499
|
+
});
|
|
1500
|
+
return tpl;
|
|
1501
|
+
}
|
|
1502
|
+
renderRenderItem(item) {
|
|
1503
|
+
switch (item.type) {
|
|
1504
|
+
case "user":
|
|
1505
|
+
case "assistant": return this.renderBubble(item);
|
|
1506
|
+
case "tool_call": return this.renderToolBlock(item);
|
|
1507
|
+
case "tool_call_group": return this.renderToolGroup(item);
|
|
1508
|
+
case "reasoning": return lit.html`<div class="cpk-td__inline-chip">
|
|
1509
|
+
<span>Reasoned for ${item.duration}</span>
|
|
1510
|
+
</div>`;
|
|
1511
|
+
case "state_update": return lit.html`
|
|
1512
|
+
<div class="cpk-td__inline-chip">
|
|
1513
|
+
<span>Updated agent state</span>
|
|
1514
|
+
</div>
|
|
1515
|
+
`;
|
|
1516
|
+
case "generative-ui": return this.renderGenerativeUI(item);
|
|
1517
|
+
case "agent_responded": return lit.nothing;
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
renderBubble(item) {
|
|
1521
|
+
const isUser = item.type === "user";
|
|
1522
|
+
const threshold = ɵCpkThreadDetails.COLLAPSE_THRESHOLD;
|
|
1523
|
+
const expanded = this._expandedMessages.has(item.id);
|
|
1524
|
+
const tooLong = item.content.length > threshold;
|
|
1525
|
+
const shown = tooLong && !expanded ? item.content.slice(0, threshold) + "…" : item.content;
|
|
1526
|
+
return lit.html`
|
|
1527
|
+
<div
|
|
1528
|
+
class="cpk-td__bubble ${isUser ? "cpk-td__bubble--user" : "cpk-td__bubble--assistant"}"
|
|
1529
|
+
>
|
|
1530
|
+
<div
|
|
1531
|
+
class="cpk-td__bubble-inner ${isUser ? "cpk-td__bubble-inner--user" : "cpk-td__bubble-inner--assistant"}"
|
|
1532
|
+
>
|
|
1533
|
+
${shown}
|
|
1534
|
+
${tooLong ? lit.html`<span
|
|
1535
|
+
class="cpk-td__show-more"
|
|
1536
|
+
@click=${() => this.toggleMessageExpand(item.id)}
|
|
1537
|
+
>${expanded ? "Show less" : "Show more"}</span
|
|
1538
|
+
>` : lit.nothing}
|
|
1539
|
+
</div>
|
|
1540
|
+
</div>
|
|
1541
|
+
`;
|
|
1542
|
+
}
|
|
1543
|
+
renderToolBlock(item) {
|
|
1544
|
+
const expanded = this._expandedTools.has(item.id);
|
|
1545
|
+
return lit.html`
|
|
1546
|
+
<div class="cpk-td__tool-block">
|
|
1547
|
+
<div
|
|
1548
|
+
class="cpk-td__tool-header"
|
|
1549
|
+
@click=${() => this.toggleToolExpand(item.id)}
|
|
1550
|
+
>
|
|
1551
|
+
<svg width="10" height="10" viewBox="0 0 10 10" fill="none">
|
|
1552
|
+
<path
|
|
1553
|
+
d="M1 9C1 9 2 7 5 7C8 7 9 9 9 9M5 1C5 1 7 2.5 7 4.5C7 6.5 5 7 5 7C5 7 3 6.5 3 4.5C3 2.5 5 1 5 1Z"
|
|
1554
|
+
stroke="#189370"
|
|
1555
|
+
stroke-width="1.2"
|
|
1556
|
+
stroke-linecap="round"
|
|
1557
|
+
stroke-linejoin="round"
|
|
1558
|
+
/>
|
|
1559
|
+
</svg>
|
|
1560
|
+
<span class="cpk-td__tool-name">${item.toolName}</span>
|
|
1561
|
+
${item.result || Object.keys(item.arguments).length > 0 ? lit.html`
|
|
1562
|
+
<span class="cpk-td__tool-status">DONE</span>
|
|
1563
|
+
` : lit.html`
|
|
1564
|
+
<span class="cpk-td__tool-status cpk-td__tool-status--pending">PENDING</span>
|
|
1565
|
+
`}
|
|
1566
|
+
<span class="cpk-td__tool-chevron">${expanded ? "▾" : "▸"}</span>
|
|
1567
|
+
</div>
|
|
1568
|
+
${expanded ? lit.html`
|
|
1569
|
+
<div class="cpk-td__tool-body">
|
|
1570
|
+
<div class="cpk-td__tool-section-label">Arguments</div>
|
|
1571
|
+
<pre class="cpk-td__tool-pre">
|
|
1572
|
+
${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(item.arguments))}</pre
|
|
1573
|
+
>
|
|
1574
|
+
${item.result ? lit.html`
|
|
1575
|
+
<div
|
|
1576
|
+
class="cpk-td__tool-section-label"
|
|
1577
|
+
style="margin-top:8px"
|
|
1578
|
+
>
|
|
1579
|
+
Result
|
|
1580
|
+
</div>
|
|
1581
|
+
<pre class="cpk-td__tool-pre">
|
|
1582
|
+
${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(item.result))}</pre
|
|
1583
|
+
>
|
|
1584
|
+
` : lit.nothing}
|
|
1585
|
+
</div>
|
|
1586
|
+
` : lit.nothing}
|
|
1587
|
+
</div>
|
|
1588
|
+
`;
|
|
1589
|
+
}
|
|
1590
|
+
renderToolGroup(group) {
|
|
1591
|
+
return lit.html`
|
|
1592
|
+
<div class="cpk-td__tool-group">
|
|
1593
|
+
<div class="cpk-td__tool-group-header">
|
|
1594
|
+
${group.items.length} tool call${group.items.length !== 1 ? "s" : ""}
|
|
1595
|
+
</div>
|
|
1596
|
+
${group.items.map((tc) => this.renderToolBlock(tc))}
|
|
1597
|
+
</div>
|
|
1598
|
+
`;
|
|
1599
|
+
}
|
|
1600
|
+
renderGenerativeUI(item) {
|
|
1601
|
+
return lit.html`
|
|
1602
|
+
<div class="cpk-td__genui">
|
|
1603
|
+
<div class="cpk-td__genui-badge">
|
|
1604
|
+
<svg width="9" height="9" viewBox="0 0 24 24" fill="currentColor">
|
|
1605
|
+
<path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" />
|
|
1606
|
+
</svg>
|
|
1607
|
+
Generative UI
|
|
1608
|
+
</div>
|
|
1609
|
+
<div class="cpk-td__genui-placeholder">
|
|
1610
|
+
${item.activityType} — rendered in chat
|
|
1611
|
+
</div>
|
|
1612
|
+
</div>
|
|
1613
|
+
`;
|
|
1614
|
+
}
|
|
1615
|
+
renderState() {
|
|
1616
|
+
if (this._loadingState) return lit.html`
|
|
1617
|
+
<div class="cpk-td__status">Loading state…</div>
|
|
1618
|
+
`;
|
|
1619
|
+
if (this._stateError) return lit.html`<div class="cpk-td__status cpk-td__status--error">
|
|
1620
|
+
${this._stateError}
|
|
1621
|
+
</div>`;
|
|
1622
|
+
if (this._stateNotAvailable) return lit.html`
|
|
1623
|
+
<div class="cpk-td__empty-state">
|
|
1624
|
+
<svg
|
|
1625
|
+
width="28"
|
|
1626
|
+
height="28"
|
|
1627
|
+
viewBox="0 0 24 24"
|
|
1628
|
+
fill="none"
|
|
1629
|
+
stroke="currentColor"
|
|
1630
|
+
stroke-width="1.5"
|
|
1631
|
+
stroke-linecap="round"
|
|
1632
|
+
stroke-linejoin="round"
|
|
1633
|
+
>
|
|
1634
|
+
<ellipse cx="12" cy="5" rx="9" ry="3" />
|
|
1635
|
+
<path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3" />
|
|
1636
|
+
<path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5" />
|
|
1637
|
+
</svg>
|
|
1638
|
+
<span>State history not available</span>
|
|
1639
|
+
<span class="cpk-td__empty-hint"
|
|
1640
|
+
>This runtime doesn't yet expose per-thread agent state. Available when
|
|
1641
|
+
running against the in-memory runner.</span
|
|
1642
|
+
>
|
|
1643
|
+
</div>
|
|
1644
|
+
`;
|
|
1645
|
+
if (!this.hasRenderableState()) return lit.html`
|
|
1646
|
+
<div class="cpk-td__empty-state">
|
|
1647
|
+
<svg
|
|
1648
|
+
width="28"
|
|
1649
|
+
height="28"
|
|
1650
|
+
viewBox="0 0 24 24"
|
|
1651
|
+
fill="none"
|
|
1652
|
+
stroke="currentColor"
|
|
1653
|
+
stroke-width="1.5"
|
|
1654
|
+
stroke-linecap="round"
|
|
1655
|
+
stroke-linejoin="round"
|
|
1656
|
+
>
|
|
1657
|
+
<ellipse cx="12" cy="5" rx="9" ry="3" />
|
|
1658
|
+
<path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3" />
|
|
1659
|
+
<path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5" />
|
|
1660
|
+
</svg>
|
|
1661
|
+
<span>No state captured</span>
|
|
1662
|
+
<span class="cpk-td__empty-hint"
|
|
1663
|
+
>Emitted live from STATE_SNAPSHOT events.</span
|
|
1664
|
+
>
|
|
1665
|
+
</div>
|
|
1666
|
+
`;
|
|
1667
|
+
const stateValue = this.activeState;
|
|
1668
|
+
return this.cachedPanelTpl("agent-state", [stateValue], () => {
|
|
1669
|
+
return lit.html`<pre class="cpk-td__json-block">
|
|
1670
|
+
${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(stateValue))}</pre
|
|
1671
|
+
>`;
|
|
1672
|
+
});
|
|
1673
|
+
}
|
|
1674
|
+
renderEvents() {
|
|
1675
|
+
if (this._loadingEvents) return lit.html`
|
|
1676
|
+
<div class="cpk-td__status">Loading events…</div>
|
|
1677
|
+
`;
|
|
1678
|
+
if (this._eventsError) return lit.html`<div class="cpk-td__status cpk-td__status--error">
|
|
1679
|
+
${this._eventsError}
|
|
1680
|
+
</div>`;
|
|
1681
|
+
if (this._eventsNotAvailable) return lit.html`
|
|
1682
|
+
<div class="cpk-td__empty-state">
|
|
1683
|
+
<span>Event history not available</span>
|
|
1684
|
+
<span class="cpk-td__empty-hint"
|
|
1685
|
+
>This runtime doesn't yet expose per-thread AG-UI events. Available when
|
|
1686
|
+
running against the in-memory runner.</span
|
|
1687
|
+
>
|
|
1688
|
+
</div>
|
|
1689
|
+
`;
|
|
1690
|
+
const events = this.activeEvents;
|
|
1691
|
+
if (events.length === 0) return lit.html`
|
|
1692
|
+
<div class="cpk-td__empty-state">
|
|
1693
|
+
<span>No events captured</span>
|
|
1694
|
+
<span class="cpk-td__empty-hint"
|
|
1695
|
+
>Events are recorded live. Run the agent to see them here.</span
|
|
1696
|
+
>
|
|
1697
|
+
</div>
|
|
1698
|
+
`;
|
|
1699
|
+
return this.cachedPanelTpl("ag-ui-events", [events], () => {
|
|
1700
|
+
return lit.html`${events.map((event) => {
|
|
1701
|
+
const { bg, fg } = eventColors(event.type);
|
|
1702
|
+
return lit.html`
|
|
1703
|
+
<div class="cpk-td__event">
|
|
1704
|
+
<div class="cpk-td__event-header" style="background:${bg}">
|
|
1705
|
+
<span class="cpk-td__event-type" style="color:${fg}"
|
|
1706
|
+
>${event.type}</span
|
|
1707
|
+
>
|
|
1708
|
+
<span class="cpk-td__event-time"
|
|
1709
|
+
>${formatTimestamp(event.timestamp)}</span
|
|
1710
|
+
>
|
|
1711
|
+
</div>
|
|
1712
|
+
<pre class="cpk-td__event-payload">
|
|
1713
|
+
${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(event.payload))}</pre
|
|
1714
|
+
>
|
|
1715
|
+
</div>
|
|
1716
|
+
`;
|
|
1717
|
+
})}`;
|
|
1718
|
+
});
|
|
1719
|
+
}
|
|
1720
|
+
renderPanelToggle() {
|
|
1721
|
+
return lit.html`
|
|
1722
|
+
<button
|
|
1723
|
+
class="cpk-td__panel-toggle ${this._showDetailPanel ? "cpk-td__panel-toggle--active" : ""}"
|
|
1724
|
+
@click=${() => {
|
|
1725
|
+
this._showDetailPanel = !this._showDetailPanel;
|
|
1726
|
+
}}
|
|
1727
|
+
title="Toggle thread details"
|
|
1728
|
+
type="button"
|
|
1729
|
+
>
|
|
1730
|
+
<svg
|
|
1731
|
+
width="14"
|
|
1732
|
+
height="14"
|
|
1733
|
+
viewBox="0 0 24 24"
|
|
1734
|
+
fill="none"
|
|
1735
|
+
stroke="currentColor"
|
|
1736
|
+
stroke-width="2"
|
|
1737
|
+
stroke-linecap="round"
|
|
1738
|
+
stroke-linejoin="round"
|
|
1739
|
+
>
|
|
1740
|
+
<rect x="3" y="3" width="18" height="18" rx="2" />
|
|
1741
|
+
<line x1="15" y1="3" x2="15" y2="21" />
|
|
1742
|
+
</svg>
|
|
1743
|
+
</button>
|
|
1744
|
+
`;
|
|
1745
|
+
}
|
|
1746
|
+
renderDetailPanel() {
|
|
1747
|
+
const counts = this.activityCounts;
|
|
1748
|
+
return lit.html`
|
|
1749
|
+
<!-- Thread -->
|
|
1750
|
+
<div class="cpk-tdp__section-title">Thread</div>
|
|
1751
|
+
<div class="cpk-tdp__row">
|
|
1752
|
+
<span class="cpk-tdp__label">ID</span>
|
|
1753
|
+
<span class="cpk-tdp__value cpk-tdp__value--wrap"
|
|
1754
|
+
>${this.shortId(this.thread?.id)}</span
|
|
1755
|
+
>
|
|
1756
|
+
</div>
|
|
1757
|
+
<div class="cpk-tdp__row">
|
|
1758
|
+
<span class="cpk-tdp__label">Name</span>
|
|
1759
|
+
<span class="cpk-tdp__value">${this.thread?.name ?? "—"}</span>
|
|
1760
|
+
</div>
|
|
1761
|
+
<div class="cpk-tdp__row">
|
|
1762
|
+
<span class="cpk-tdp__label">Agent</span>
|
|
1763
|
+
<span class="cpk-tdp__value cpk-tdp__value--truncate"
|
|
1764
|
+
>${this.thread?.agentId ?? "—"}</span
|
|
1765
|
+
>
|
|
1766
|
+
</div>
|
|
1767
|
+
<div class="cpk-tdp__row">
|
|
1768
|
+
<span class="cpk-tdp__label">Created by</span>
|
|
1769
|
+
<span class="cpk-tdp__value cpk-tdp__value--truncate"
|
|
1770
|
+
>${this.thread?.createdById ?? "—"}</span
|
|
1771
|
+
>
|
|
1772
|
+
</div>
|
|
1773
|
+
|
|
1774
|
+
<div class="cpk-tdp__divider"></div>
|
|
1775
|
+
|
|
1776
|
+
<!-- Timestamps -->
|
|
1777
|
+
<div class="cpk-tdp__section-title">Timestamps</div>
|
|
1778
|
+
<div class="cpk-tdp__row">
|
|
1779
|
+
<span class="cpk-tdp__label">Created</span>
|
|
1780
|
+
<span class="cpk-tdp__value">${this.fmtTime(this.thread?.createdAt)}</span>
|
|
1781
|
+
</div>
|
|
1782
|
+
<div class="cpk-tdp__row">
|
|
1783
|
+
<span class="cpk-tdp__label">Updated</span>
|
|
1784
|
+
<span class="cpk-tdp__value">${this.fmtTime(this.thread?.updatedAt)}</span>
|
|
1785
|
+
</div>
|
|
1786
|
+
<div class="cpk-tdp__row">
|
|
1787
|
+
<span class="cpk-tdp__label">Duration</span>
|
|
1788
|
+
<span class="cpk-tdp__value">${this.duration}</span>
|
|
1789
|
+
</div>
|
|
1790
|
+
|
|
1791
|
+
<div class="cpk-tdp__divider"></div>
|
|
1792
|
+
|
|
1793
|
+
<!-- Activity -->
|
|
1794
|
+
<div class="cpk-tdp__section-title">Activity</div>
|
|
1795
|
+
<div class="cpk-tdp__row">
|
|
1796
|
+
<span class="cpk-tdp__label">Messages</span>
|
|
1797
|
+
<span class="cpk-tdp__value">${counts.messages}</span>
|
|
1798
|
+
</div>
|
|
1799
|
+
<div class="cpk-tdp__row">
|
|
1800
|
+
<span class="cpk-tdp__label">Tool calls</span>
|
|
1801
|
+
<span class="cpk-tdp__value">${counts.toolCalls}</span>
|
|
1802
|
+
</div>
|
|
1803
|
+
<div class="cpk-tdp__row">
|
|
1804
|
+
<span class="cpk-tdp__label">AG-UI events</span>
|
|
1805
|
+
<span class="cpk-tdp__value">${this.activeEvents.length}</span>
|
|
1806
|
+
</div>
|
|
1807
|
+
`;
|
|
1808
|
+
}
|
|
1809
|
+
};
|
|
1810
|
+
if (!customElements.get("cpk-thread-list")) customElements.define("cpk-thread-list", CpkThreadList);
|
|
1811
|
+
if (!customElements.get("cpk-thread-details")) customElements.define("cpk-thread-details", ɵCpkThreadDetails);
|
|
1812
|
+
var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
|
|
1813
|
+
constructor(..._args3) {
|
|
1814
|
+
super(..._args3);
|
|
61
1815
|
this._core = null;
|
|
62
1816
|
this.coreSubscriber = null;
|
|
63
1817
|
this.coreUnsubscribe = null;
|
|
@@ -67,6 +1821,8 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
67
1821
|
this.agentSubscriptions = /* @__PURE__ */ new Map();
|
|
68
1822
|
this.agentEvents = /* @__PURE__ */ new Map();
|
|
69
1823
|
this.agentMessages = /* @__PURE__ */ new Map();
|
|
1824
|
+
this.agentRunThreadId = /* @__PURE__ */ new Map();
|
|
1825
|
+
this.liveMessageVersion = /* @__PURE__ */ new Map();
|
|
70
1826
|
this.agentStates = /* @__PURE__ */ new Map();
|
|
71
1827
|
this.flattenedEvents = [];
|
|
72
1828
|
this.eventCounter = 0;
|
|
@@ -83,6 +1839,17 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
83
1839
|
this.draggedDuringInteraction = false;
|
|
84
1840
|
this.ignoreNextButtonClick = false;
|
|
85
1841
|
this.selectedMenu = "ag-ui-events";
|
|
1842
|
+
this.selectedThreadId = null;
|
|
1843
|
+
this.threadListWidth = 290;
|
|
1844
|
+
this.threadDividerResizing = false;
|
|
1845
|
+
this.threadDividerPointerId = -1;
|
|
1846
|
+
this.threadDividerStartX = 0;
|
|
1847
|
+
this.threadDividerStartWidth = 0;
|
|
1848
|
+
this._threads = [];
|
|
1849
|
+
this._threadStoreSubscriptions = /* @__PURE__ */ new Map();
|
|
1850
|
+
this._threadsByAgent = /* @__PURE__ */ new Map();
|
|
1851
|
+
this._threadsErrorByAgent = /* @__PURE__ */ new Map();
|
|
1852
|
+
this._ownedThreadStores = /* @__PURE__ */ new Map();
|
|
86
1853
|
this.contextMenuOpen = false;
|
|
87
1854
|
this.dockMode = "floating";
|
|
88
1855
|
this.previousBodyMargins = null;
|
|
@@ -95,15 +1862,26 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
95
1862
|
this.toolSignature = "";
|
|
96
1863
|
this.eventFilterText = "";
|
|
97
1864
|
this.eventTypeFilter = "all";
|
|
98
|
-
this.
|
|
1865
|
+
this.evtColWidths = [
|
|
1866
|
+
100,
|
|
1867
|
+
80,
|
|
1868
|
+
150
|
|
1869
|
+
];
|
|
1870
|
+
this._evtColResize = null;
|
|
1871
|
+
this._threadsUnlocked = false;
|
|
1872
|
+
this._threadsUnlocking = false;
|
|
1873
|
+
this._threadsGateError = null;
|
|
1874
|
+
this._threadsGateCodeInvalid = false;
|
|
1875
|
+
this._threadsGateInvalidTimer = null;
|
|
1876
|
+
this._threadsUnlockingTimer = null;
|
|
99
1877
|
this.announcementHtml = null;
|
|
100
1878
|
this.announcementTimestamp = null;
|
|
101
1879
|
this.announcementPreviewText = null;
|
|
102
1880
|
this.hasUnseenAnnouncement = false;
|
|
103
1881
|
this.announcementLoaded = false;
|
|
104
|
-
this.announcementLoadError = null;
|
|
105
1882
|
this.announcementPromise = null;
|
|
106
1883
|
this.showAnnouncementPreview = true;
|
|
1884
|
+
this.announcementExpanded = false;
|
|
107
1885
|
this.contextState = {
|
|
108
1886
|
button: {
|
|
109
1887
|
position: {
|
|
@@ -144,28 +1922,7 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
144
1922
|
this.resizeStart = null;
|
|
145
1923
|
this.resizeInitialSize = null;
|
|
146
1924
|
this.isResizing = false;
|
|
147
|
-
this.
|
|
148
|
-
{
|
|
149
|
-
key: "ag-ui-events",
|
|
150
|
-
label: "AG-UI Events",
|
|
151
|
-
icon: "Zap"
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
key: "agents",
|
|
155
|
-
label: "Agent",
|
|
156
|
-
icon: "Bot"
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
key: "frontend-tools",
|
|
160
|
-
label: "Frontend Tools",
|
|
161
|
-
icon: "Hammer"
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
key: "agent-context",
|
|
165
|
-
label: "Context",
|
|
166
|
-
icon: "FileText"
|
|
167
|
-
}
|
|
168
|
-
];
|
|
1925
|
+
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>` };
|
|
169
1926
|
this.handlePointerDown = (event) => {
|
|
170
1927
|
if (this.dockMode !== "floating" && this.isOpen) return;
|
|
171
1928
|
const target = event.currentTarget;
|
|
@@ -330,6 +2087,26 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
330
2087
|
this.expandedTools = /* @__PURE__ */ new Set();
|
|
331
2088
|
this.expandedContextItems = /* @__PURE__ */ new Set();
|
|
332
2089
|
this.copiedContextItems = /* @__PURE__ */ new Set();
|
|
2090
|
+
this.handleThreadDividerPointerDown = (event) => {
|
|
2091
|
+
this.threadDividerResizing = true;
|
|
2092
|
+
this.threadDividerPointerId = event.pointerId;
|
|
2093
|
+
this.threadDividerStartX = event.clientX;
|
|
2094
|
+
this.threadDividerStartWidth = this.threadListWidth;
|
|
2095
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
2096
|
+
event.preventDefault();
|
|
2097
|
+
};
|
|
2098
|
+
this.handleThreadDividerPointerMove = (event) => {
|
|
2099
|
+
if (!this.threadDividerResizing || this.threadDividerPointerId !== event.pointerId) return;
|
|
2100
|
+
const delta = event.clientX - this.threadDividerStartX;
|
|
2101
|
+
this.threadListWidth = Math.max(180, Math.min(480, this.threadDividerStartWidth + delta));
|
|
2102
|
+
this.requestUpdate();
|
|
2103
|
+
};
|
|
2104
|
+
this.handleThreadDividerPointerUp = (event) => {
|
|
2105
|
+
if (this.threadDividerPointerId !== event.pointerId) return;
|
|
2106
|
+
const target = event.currentTarget;
|
|
2107
|
+
if (target.hasPointerCapture(this.threadDividerPointerId)) target.releasePointerCapture(this.threadDividerPointerId);
|
|
2108
|
+
this.threadDividerResizing = false;
|
|
2109
|
+
};
|
|
333
2110
|
this.handleClearEvents = () => {
|
|
334
2111
|
if (this.selectedContext === "all-agents") {
|
|
335
2112
|
this.agentEvents.clear();
|
|
@@ -375,6 +2152,106 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
375
2152
|
this.requestUpdate("core", oldValue);
|
|
376
2153
|
if (this._core) this.attachToCore(this._core);
|
|
377
2154
|
}
|
|
2155
|
+
get menuItems() {
|
|
2156
|
+
return [
|
|
2157
|
+
{
|
|
2158
|
+
key: "ag-ui-events",
|
|
2159
|
+
label: "AG-UI Events",
|
|
2160
|
+
icon: "Zap"
|
|
2161
|
+
},
|
|
2162
|
+
{
|
|
2163
|
+
key: "agents",
|
|
2164
|
+
label: "Agent",
|
|
2165
|
+
icon: "Bot"
|
|
2166
|
+
},
|
|
2167
|
+
...(this._core?.tools?.length ?? 0) > 0 ? [{
|
|
2168
|
+
key: "frontend-tools",
|
|
2169
|
+
label: "Frontend Tools",
|
|
2170
|
+
icon: "Hammer"
|
|
2171
|
+
}] : [],
|
|
2172
|
+
{
|
|
2173
|
+
key: "agent-context",
|
|
2174
|
+
label: "Context",
|
|
2175
|
+
icon: "FileText"
|
|
2176
|
+
},
|
|
2177
|
+
{
|
|
2178
|
+
key: "threads",
|
|
2179
|
+
label: "Threads",
|
|
2180
|
+
icon: "MessageSquare"
|
|
2181
|
+
}
|
|
2182
|
+
];
|
|
2183
|
+
}
|
|
2184
|
+
subscribeToThreadStore(agentId, store) {
|
|
2185
|
+
if (this._threadStoreSubscriptions.has(agentId)) return;
|
|
2186
|
+
const threadsSub = store.select(_copilotkit_core.ɵselectThreads).subscribe((threads) => {
|
|
2187
|
+
this._threadsByAgent.set(agentId, threads);
|
|
2188
|
+
this._threads = Array.from(this._threadsByAgent.values()).flat();
|
|
2189
|
+
this.autoSelectLatestThread();
|
|
2190
|
+
this.requestUpdate();
|
|
2191
|
+
});
|
|
2192
|
+
const errorSub = store.select(_copilotkit_core.ɵselectThreadsError).subscribe((error) => {
|
|
2193
|
+
if (error) this._threadsErrorByAgent.set(agentId, error);
|
|
2194
|
+
else this._threadsErrorByAgent.delete(agentId);
|
|
2195
|
+
this.requestUpdate();
|
|
2196
|
+
});
|
|
2197
|
+
this._threadStoreSubscriptions.set(agentId, () => {
|
|
2198
|
+
threadsSub.unsubscribe();
|
|
2199
|
+
errorSub.unsubscribe();
|
|
2200
|
+
});
|
|
2201
|
+
const initialState = store.getState();
|
|
2202
|
+
this._threadsByAgent.set(agentId, (0, _copilotkit_core.ɵselectThreads)(initialState));
|
|
2203
|
+
const initialError = (0, _copilotkit_core.ɵselectThreadsError)(initialState);
|
|
2204
|
+
if (initialError) this._threadsErrorByAgent.set(agentId, initialError);
|
|
2205
|
+
else this._threadsErrorByAgent.delete(agentId);
|
|
2206
|
+
this._threads = Array.from(this._threadsByAgent.values()).flat();
|
|
2207
|
+
this.autoSelectLatestThread();
|
|
2208
|
+
}
|
|
2209
|
+
autoSelectLatestThread() {
|
|
2210
|
+
if (this._threads.length === 0) return;
|
|
2211
|
+
if (!(this.selectedThreadId != null && this._threads.some((t) => t.id === this.selectedThreadId))) this.selectedThreadId = this._threads[0].id;
|
|
2212
|
+
}
|
|
2213
|
+
teardownThreadStoreSubscriptions() {
|
|
2214
|
+
for (const unsub of this._threadStoreSubscriptions.values()) unsub();
|
|
2215
|
+
this._threadStoreSubscriptions.clear();
|
|
2216
|
+
this._threadsByAgent.clear();
|
|
2217
|
+
this._threadsErrorByAgent.clear();
|
|
2218
|
+
this._threads = [];
|
|
2219
|
+
}
|
|
2220
|
+
ensureOwnedThreadStore(agentId) {
|
|
2221
|
+
if (this._ownedThreadStores.has(agentId)) return;
|
|
2222
|
+
if (this.core?.getThreadStore(agentId)) return;
|
|
2223
|
+
const core = this.core;
|
|
2224
|
+
if (!core?.runtimeUrl) return;
|
|
2225
|
+
const store = (0, _copilotkit_core.ɵcreateThreadStore)({ fetch: globalThis.fetch });
|
|
2226
|
+
store.start();
|
|
2227
|
+
store.setContext({
|
|
2228
|
+
runtimeUrl: core.runtimeUrl,
|
|
2229
|
+
headers: {},
|
|
2230
|
+
agentId
|
|
2231
|
+
});
|
|
2232
|
+
this._ownedThreadStores.set(agentId, store);
|
|
2233
|
+
this.subscribeToThreadStore(agentId, store);
|
|
2234
|
+
core.registerThreadStore(agentId, store);
|
|
2235
|
+
}
|
|
2236
|
+
refreshOwnedThreadStore(agentId) {
|
|
2237
|
+
const store = this._ownedThreadStores.get(agentId);
|
|
2238
|
+
if (!store) return;
|
|
2239
|
+
store.refresh();
|
|
2240
|
+
}
|
|
2241
|
+
removeOwnedThreadStore(agentId) {
|
|
2242
|
+
const store = this._ownedThreadStores.get(agentId);
|
|
2243
|
+
if (!store) return;
|
|
2244
|
+
store.stop();
|
|
2245
|
+
this.core?.unregisterThreadStore(agentId);
|
|
2246
|
+
this._ownedThreadStores.delete(agentId);
|
|
2247
|
+
}
|
|
2248
|
+
teardownOwnedThreadStores() {
|
|
2249
|
+
for (const [agentId, store] of this._ownedThreadStores) {
|
|
2250
|
+
store.stop();
|
|
2251
|
+
this.core?.unregisterThreadStore(agentId);
|
|
2252
|
+
}
|
|
2253
|
+
this._ownedThreadStores.clear();
|
|
2254
|
+
}
|
|
378
2255
|
attachToCore(core) {
|
|
379
2256
|
this.runtimeStatus = core.runtimeConnectionStatus;
|
|
380
2257
|
this.coreProperties = core.properties;
|
|
@@ -382,6 +2259,11 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
382
2259
|
this.coreSubscriber = {
|
|
383
2260
|
onRuntimeConnectionStatusChanged: ({ status }) => {
|
|
384
2261
|
this.runtimeStatus = status;
|
|
2262
|
+
if (status === "connected") for (const agentId of this._ownedThreadStores.keys()) this.refreshOwnedThreadStore(agentId);
|
|
2263
|
+
else {
|
|
2264
|
+
this._threadsByAgent.clear();
|
|
2265
|
+
this._threads = [];
|
|
2266
|
+
}
|
|
385
2267
|
this.requestUpdate();
|
|
386
2268
|
},
|
|
387
2269
|
onPropertiesChanged: ({ properties }) => {
|
|
@@ -398,16 +2280,36 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
398
2280
|
onAgentsChanged: ({ agents }) => {
|
|
399
2281
|
this.processAgentsChanged(agents);
|
|
400
2282
|
},
|
|
401
|
-
onAgentRunStarted: ({ agent }) => {
|
|
402
|
-
if (agent?.agentId) this.subscribeToAgent(agent);
|
|
403
|
-
},
|
|
404
2283
|
onContextChanged: ({ context }) => {
|
|
405
2284
|
this.contextStore = this.normalizeContextStore(context);
|
|
406
2285
|
this.requestUpdate();
|
|
2286
|
+
},
|
|
2287
|
+
onThreadStoreRegistered: ({ agentId, store }) => {
|
|
2288
|
+
this.subscribeToThreadStore(agentId, store);
|
|
2289
|
+
this.requestUpdate();
|
|
2290
|
+
},
|
|
2291
|
+
onThreadStoreUnregistered: ({ agentId }) => {
|
|
2292
|
+
const unsub = this._threadStoreSubscriptions.get(agentId);
|
|
2293
|
+
if (unsub) {
|
|
2294
|
+
unsub();
|
|
2295
|
+
this._threadStoreSubscriptions.delete(agentId);
|
|
2296
|
+
}
|
|
2297
|
+
this._threadsByAgent.delete(agentId);
|
|
2298
|
+
this._threadsErrorByAgent.delete(agentId);
|
|
2299
|
+
this._threads = Array.from(this._threadsByAgent.values()).flat();
|
|
2300
|
+
this.requestUpdate();
|
|
2301
|
+
},
|
|
2302
|
+
onAgentRunStarted: ({ agent }) => {
|
|
2303
|
+
this.subscribeToAgent(agent);
|
|
2304
|
+
const runThreadId = agent.threadId;
|
|
2305
|
+
if (agent.agentId && runThreadId) this.agentRunThreadId.set(agent.agentId, runThreadId);
|
|
2306
|
+
this.requestUpdate();
|
|
407
2307
|
}
|
|
408
2308
|
};
|
|
409
2309
|
this.coreUnsubscribe = core.subscribe(this.coreSubscriber).unsubscribe;
|
|
410
2310
|
this.processAgentsChanged(core.agents);
|
|
2311
|
+
const threadStores = typeof core.getThreadStores === "function" ? core.getThreadStores() : {};
|
|
2312
|
+
for (const [agentId, store] of Object.entries(threadStores)) this.subscribeToThreadStore(agentId, store);
|
|
411
2313
|
if (core.context) this.contextStore = this.normalizeContextStore(core.context);
|
|
412
2314
|
}
|
|
413
2315
|
detachFromCore() {
|
|
@@ -422,6 +2324,8 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
422
2324
|
this.cachedTools = [];
|
|
423
2325
|
this.toolSignature = "";
|
|
424
2326
|
this.teardownAgentSubscriptions();
|
|
2327
|
+
this.teardownThreadStoreSubscriptions();
|
|
2328
|
+
this.teardownOwnedThreadStores();
|
|
425
2329
|
}
|
|
426
2330
|
teardownAgentSubscriptions() {
|
|
427
2331
|
for (const unsubscribe of this.agentSubscriptions.values()) unsubscribe();
|
|
@@ -438,6 +2342,7 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
438
2342
|
if (!agent?.agentId) continue;
|
|
439
2343
|
seenAgentIds.add(agent.agentId);
|
|
440
2344
|
this.subscribeToAgent(agent);
|
|
2345
|
+
this.ensureOwnedThreadStore(agent.agentId);
|
|
441
2346
|
}
|
|
442
2347
|
for (const agentId of Array.from(this.agentSubscriptions.keys())) if (!seenAgentIds.has(agentId)) {
|
|
443
2348
|
this.unsubscribeFromAgent(agentId);
|
|
@@ -496,6 +2401,7 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
496
2401
|
event,
|
|
497
2402
|
result
|
|
498
2403
|
});
|
|
2404
|
+
this.refreshOwnedThreadStore(agentId);
|
|
499
2405
|
},
|
|
500
2406
|
onRunErrorEvent: ({ event }) => {
|
|
501
2407
|
this.recordAgentEvent(agentId, "RUN_ERROR", event);
|
|
@@ -583,6 +2489,14 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
583
2489
|
},
|
|
584
2490
|
onReasoningEncryptedValueEvent: ({ event }) => {
|
|
585
2491
|
this.recordAgentEvent(agentId, "REASONING_ENCRYPTED_VALUE", event);
|
|
2492
|
+
},
|
|
2493
|
+
onActivitySnapshotEvent: ({ event }) => {
|
|
2494
|
+
this.recordAgentEvent(agentId, "ACTIVITY_SNAPSHOT", event);
|
|
2495
|
+
this.syncAgentMessages(agent);
|
|
2496
|
+
},
|
|
2497
|
+
onActivityDeltaEvent: ({ event }) => {
|
|
2498
|
+
this.recordAgentEvent(agentId, "ACTIVITY_DELTA", event);
|
|
2499
|
+
this.syncAgentMessages(agent);
|
|
586
2500
|
}
|
|
587
2501
|
});
|
|
588
2502
|
this.agentSubscriptions.set(agentId, unsubscribe);
|
|
@@ -597,6 +2511,15 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
597
2511
|
this.agentSubscriptions.delete(agentId);
|
|
598
2512
|
}
|
|
599
2513
|
}
|
|
2514
|
+
mapMessagesToConversation(messages) {
|
|
2515
|
+
if (!messages) return null;
|
|
2516
|
+
return messages.filter((m) => m.role === "user" || m.role === "assistant" || m.role === "activity").map((m, i) => ({
|
|
2517
|
+
id: m.id ?? `msg-${i}`,
|
|
2518
|
+
type: m.role === "user" ? "user" : m.role === "activity" ? "generative-ui" : "assistant",
|
|
2519
|
+
content: m.role === "activity" ? m.activityType ?? "unknown" : m.contentText,
|
|
2520
|
+
createdAt: ""
|
|
2521
|
+
}));
|
|
2522
|
+
}
|
|
600
2523
|
recordAgentEvent(agentId, type, payload) {
|
|
601
2524
|
const eventId = `${agentId}:${++this.eventCounter}`;
|
|
602
2525
|
const normalizedPayload = this.normalizeEventPayload(type, payload);
|
|
@@ -619,6 +2542,8 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
619
2542
|
const messages = this.normalizeAgentMessages(agent.messages);
|
|
620
2543
|
if (messages) this.agentMessages.set(agent.agentId, messages);
|
|
621
2544
|
else this.agentMessages.delete(agent.agentId);
|
|
2545
|
+
const runThreadId = this.agentRunThreadId.get(agent.agentId);
|
|
2546
|
+
if (runThreadId) this.liveMessageVersion.set(runThreadId, (this.liveMessageVersion.get(runThreadId) ?? 0) + 1);
|
|
622
2547
|
this.requestUpdate();
|
|
623
2548
|
} catch (error) {
|
|
624
2549
|
console.error(`[CopilotKit Inspector] Failed to sync messages for agent "${agent.agentId}":`, error);
|
|
@@ -646,18 +2571,23 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
646
2571
|
if (this.contextOptions.length !== nextOptions.length || this.contextOptions.some((option, index) => option.key !== nextOptions[index]?.key)) this.contextOptions = nextOptions;
|
|
647
2572
|
const pendingContext = this.pendingSelectedContext;
|
|
648
2573
|
if (pendingContext) {
|
|
649
|
-
if (pendingContext === "all-agents" || agentIds.has(pendingContext)) {
|
|
2574
|
+
if ((pendingContext === "all-agents" || agentIds.has(pendingContext)) && (pendingContext === "all-agents" || agentIds.size === 1)) {
|
|
650
2575
|
if (this.selectedContext !== pendingContext) {
|
|
651
2576
|
this.selectedContext = pendingContext;
|
|
652
2577
|
this.expandedRows.clear();
|
|
653
2578
|
}
|
|
654
2579
|
this.pendingSelectedContext = null;
|
|
655
|
-
} else if (agentIds.size > 0)
|
|
2580
|
+
} else if (agentIds.size > 0) {
|
|
2581
|
+
if (this.selectedContext !== "all-agents") {
|
|
2582
|
+
this.selectedContext = "all-agents";
|
|
2583
|
+
this.expandedRows.clear();
|
|
2584
|
+
}
|
|
2585
|
+
this.pendingSelectedContext = null;
|
|
2586
|
+
}
|
|
656
2587
|
}
|
|
657
2588
|
if (!nextOptions.some((option) => option.key === this.selectedContext) && this.pendingSelectedContext === null) {
|
|
658
2589
|
let nextSelected = "all-agents";
|
|
659
|
-
if (agentIds.
|
|
660
|
-
else if (agentIds.size > 0) nextSelected = Array.from(agentIds).sort((a, b) => a.localeCompare(b))[0];
|
|
2590
|
+
if (agentIds.size === 1) nextSelected = Array.from(agentIds)[0];
|
|
661
2591
|
if (this.selectedContext !== nextSelected) {
|
|
662
2592
|
this.selectedContext = nextSelected;
|
|
663
2593
|
this.expandedRows.clear();
|
|
@@ -832,6 +2762,7 @@ ${argsString}</pre
|
|
|
832
2762
|
z-index: 2147483646;
|
|
833
2763
|
display: block;
|
|
834
2764
|
will-change: transform;
|
|
2765
|
+
font-family: "Plus Jakarta Sans", system-ui, sans-serif;
|
|
835
2766
|
}
|
|
836
2767
|
|
|
837
2768
|
:host([data-transitioning="true"]) {
|
|
@@ -887,13 +2818,14 @@ ${argsString}</pre
|
|
|
887
2818
|
left: 50%;
|
|
888
2819
|
transform: translateX(-50%) translateY(-4px);
|
|
889
2820
|
white-space: nowrap;
|
|
890
|
-
background: rgba(
|
|
2821
|
+
background: rgba(1, 5, 7, 0.95);
|
|
891
2822
|
color: white;
|
|
892
2823
|
padding: 4px 8px;
|
|
893
2824
|
border-radius: 6px;
|
|
894
2825
|
font-size: 10px;
|
|
2826
|
+
font-family: "Plus Jakarta Sans", system-ui, sans-serif;
|
|
895
2827
|
line-height: 1.2;
|
|
896
|
-
box-shadow: 0 4px 10px rgba(
|
|
2828
|
+
box-shadow: 0 4px 10px rgba(1, 5, 7, 0.18);
|
|
897
2829
|
opacity: 0;
|
|
898
2830
|
pointer-events: none;
|
|
899
2831
|
transition:
|
|
@@ -914,18 +2846,19 @@ ${argsString}</pre
|
|
|
914
2846
|
min-width: 300px;
|
|
915
2847
|
max-width: 300px;
|
|
916
2848
|
background: white;
|
|
917
|
-
color: #
|
|
2849
|
+
color: #010507;
|
|
918
2850
|
font-size: 13px;
|
|
2851
|
+
font-family: "Plus Jakarta Sans", system-ui, sans-serif;
|
|
919
2852
|
line-height: 1.4;
|
|
920
2853
|
border-radius: 12px;
|
|
921
|
-
box-shadow: 0 12px 28px rgba(
|
|
2854
|
+
box-shadow: 0 12px 28px rgba(1, 5, 7, 0.12);
|
|
922
2855
|
padding: 10px 12px;
|
|
923
2856
|
display: inline-flex;
|
|
924
2857
|
align-items: flex-start;
|
|
925
2858
|
gap: 8px;
|
|
926
2859
|
z-index: 4500;
|
|
927
2860
|
animation: fade-slide-in 160ms ease;
|
|
928
|
-
border: 1px solid rgba(
|
|
2861
|
+
border: 1px solid rgba(219, 219, 229, 0.4);
|
|
929
2862
|
white-space: normal;
|
|
930
2863
|
word-break: break-word;
|
|
931
2864
|
text-align: left;
|
|
@@ -946,7 +2879,7 @@ ${argsString}</pre
|
|
|
946
2879
|
width: 10px;
|
|
947
2880
|
height: 10px;
|
|
948
2881
|
background: white;
|
|
949
|
-
border: 1px solid rgba(
|
|
2882
|
+
border: 1px solid rgba(219, 219, 229, 0.4);
|
|
950
2883
|
transform: rotate(45deg);
|
|
951
2884
|
top: 50%;
|
|
952
2885
|
margin-top: -5px;
|
|
@@ -955,35 +2888,130 @@ ${argsString}</pre
|
|
|
955
2888
|
|
|
956
2889
|
.announcement-preview[data-side="left"] .announcement-preview__arrow {
|
|
957
2890
|
right: -5px;
|
|
958
|
-
box-shadow: 6px -6px 10px rgba(
|
|
2891
|
+
box-shadow: 6px -6px 10px rgba(1, 5, 7, 0.08);
|
|
959
2892
|
}
|
|
960
2893
|
|
|
961
2894
|
.announcement-preview[data-side="right"] .announcement-preview__arrow {
|
|
962
2895
|
left: -5px;
|
|
963
|
-
box-shadow: -6px 6px 10px rgba(
|
|
2896
|
+
box-shadow: -6px 6px 10px rgba(1, 5, 7, 0.08);
|
|
964
2897
|
}
|
|
965
2898
|
|
|
966
2899
|
.announcement-dismiss {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
2900
|
+
background: none;
|
|
2901
|
+
border: none;
|
|
2902
|
+
cursor: pointer;
|
|
2903
|
+
color: #838389;
|
|
2904
|
+
width: 28px;
|
|
2905
|
+
height: 28px;
|
|
2906
|
+
display: flex;
|
|
2907
|
+
align-items: center;
|
|
2908
|
+
justify-content: center;
|
|
2909
|
+
border-radius: 6px;
|
|
2910
|
+
padding: 0;
|
|
973
2911
|
transition:
|
|
974
2912
|
background 120ms ease,
|
|
975
2913
|
color 120ms ease;
|
|
976
2914
|
}
|
|
977
2915
|
|
|
978
|
-
.announcement-dismiss:hover {
|
|
979
|
-
background: rgba(
|
|
980
|
-
color: #
|
|
2916
|
+
.announcement-dismiss:hover {
|
|
2917
|
+
background: rgba(0, 0, 0, 0.06);
|
|
2918
|
+
color: #010507;
|
|
2919
|
+
}
|
|
2920
|
+
|
|
2921
|
+
/* ── Agent tab section cards ─────────────────────────────────────── */
|
|
2922
|
+
.cpk-section-card {
|
|
2923
|
+
border-radius: 8px;
|
|
2924
|
+
background: #ffffff;
|
|
2925
|
+
overflow: hidden;
|
|
2926
|
+
}
|
|
2927
|
+
|
|
2928
|
+
/* ── Agent icon bubble ───────────────────────────────────────────── */
|
|
2929
|
+
.cpk-agent-icon {
|
|
2930
|
+
background-color: #f0f0f4 !important;
|
|
2931
|
+
color: #57575b !important;
|
|
2932
|
+
}
|
|
2933
|
+
|
|
2934
|
+
/* ── Agent stat cards ────────────────────────────────────────────── */
|
|
2935
|
+
.cpk-stat-card {
|
|
2936
|
+
background-color: #ffffff !important;
|
|
2937
|
+
border: 1px solid #dbdbe5 !important;
|
|
2938
|
+
}
|
|
2939
|
+
button.cpk-stat-card:hover {
|
|
2940
|
+
background-color: #f7f7f9 !important;
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2943
|
+
/* ── Circle chevron (Frontend Tools + Context) ──────────────────── */
|
|
2944
|
+
.cpk-chevron-circle {
|
|
2945
|
+
display: inline-flex;
|
|
2946
|
+
align-items: center;
|
|
2947
|
+
justify-content: center;
|
|
2948
|
+
width: 24px;
|
|
2949
|
+
height: 24px;
|
|
2950
|
+
border-radius: 50%;
|
|
2951
|
+
background-color: #f0f0f4;
|
|
2952
|
+
color: #838389;
|
|
2953
|
+
flex-shrink: 0;
|
|
2954
|
+
transition: transform 0.2s;
|
|
2955
|
+
}
|
|
2956
|
+
.cpk-chevron-circle svg {
|
|
2957
|
+
width: 14px !important;
|
|
2958
|
+
height: 14px !important;
|
|
2959
|
+
}
|
|
2960
|
+
.cpk-chevron-circle--open {
|
|
2961
|
+
transform: rotate(180deg);
|
|
2962
|
+
}
|
|
2963
|
+
|
|
2964
|
+
/* ── Inline copy button ─────────────────────────────────────────── */
|
|
2965
|
+
.cpk-copy-btn {
|
|
2966
|
+
font-size: 10px;
|
|
2967
|
+
font-weight: 500;
|
|
2968
|
+
color: #57575b;
|
|
2969
|
+
background: #ffffff;
|
|
2970
|
+
border: 1px solid #dbdbe5;
|
|
2971
|
+
cursor: pointer;
|
|
2972
|
+
padding: 2px 8px;
|
|
2973
|
+
border-radius: 4px;
|
|
2974
|
+
flex-shrink: 0;
|
|
2975
|
+
transition:
|
|
2976
|
+
background-color 0.15s,
|
|
2977
|
+
border-color 0.15s;
|
|
2978
|
+
}
|
|
2979
|
+
.cpk-copy-btn:hover {
|
|
2980
|
+
background-color: #f0f0f4;
|
|
2981
|
+
border-color: #afafb7;
|
|
2982
|
+
}
|
|
2983
|
+
|
|
2984
|
+
.cpk-section-header {
|
|
2985
|
+
background: #e8edf5;
|
|
2986
|
+
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
|
2987
|
+
padding: 10px 16px;
|
|
2988
|
+
}
|
|
2989
|
+
.cpk-section-header h4 {
|
|
2990
|
+
font-size: 11px;
|
|
2991
|
+
font-weight: 600;
|
|
2992
|
+
color: #181c1f;
|
|
2993
|
+
margin: 0;
|
|
2994
|
+
}
|
|
2995
|
+
|
|
2996
|
+
/* Inputs/selects inside the lavender header need an explicit white bg */
|
|
2997
|
+
.cpk-section-header input,
|
|
2998
|
+
.cpk-section-header select {
|
|
2999
|
+
background-color: #ffffff !important;
|
|
3000
|
+
box-shadow: none !important;
|
|
3001
|
+
}
|
|
3002
|
+
.cpk-section-header select {
|
|
3003
|
+
padding-right: 24px !important;
|
|
3004
|
+
}
|
|
3005
|
+
/* Events table column headers */
|
|
3006
|
+
table thead th {
|
|
3007
|
+
font-weight: 600 !important;
|
|
981
3008
|
}
|
|
982
3009
|
|
|
983
3010
|
.announcement-content {
|
|
984
|
-
color: #
|
|
985
|
-
font-size:
|
|
986
|
-
|
|
3011
|
+
color: #010507;
|
|
3012
|
+
font-size: 12px;
|
|
3013
|
+
font-family: "Plus Jakarta Sans", system-ui, sans-serif;
|
|
3014
|
+
line-height: 1.5;
|
|
987
3015
|
}
|
|
988
3016
|
|
|
989
3017
|
.announcement-content h1,
|
|
@@ -994,42 +3022,322 @@ ${argsString}</pre
|
|
|
994
3022
|
}
|
|
995
3023
|
|
|
996
3024
|
.announcement-content h1 {
|
|
997
|
-
font-size:
|
|
3025
|
+
font-size: 0.75rem;
|
|
998
3026
|
}
|
|
999
|
-
|
|
1000
3027
|
.announcement-content h2 {
|
|
1001
|
-
font-size:
|
|
3028
|
+
font-size: 0.8rem;
|
|
1002
3029
|
}
|
|
1003
|
-
|
|
1004
3030
|
.announcement-content h3 {
|
|
1005
|
-
font-size: 0.
|
|
3031
|
+
font-size: 0.75rem;
|
|
1006
3032
|
}
|
|
1007
3033
|
|
|
1008
3034
|
.announcement-content p {
|
|
1009
|
-
margin: 0.
|
|
3035
|
+
margin: 0.2rem 0;
|
|
1010
3036
|
}
|
|
1011
3037
|
|
|
1012
3038
|
.announcement-content ul {
|
|
1013
3039
|
list-style: disc;
|
|
1014
3040
|
padding-left: 1.25rem;
|
|
1015
|
-
margin: 0.
|
|
3041
|
+
margin: 0.2rem 0;
|
|
1016
3042
|
}
|
|
1017
3043
|
|
|
1018
3044
|
.announcement-content ol {
|
|
1019
3045
|
list-style: decimal;
|
|
1020
3046
|
padding-left: 1.25rem;
|
|
1021
|
-
margin: 0.
|
|
3047
|
+
margin: 0.2rem 0;
|
|
1022
3048
|
}
|
|
1023
3049
|
|
|
1024
3050
|
.announcement-content a {
|
|
1025
|
-
color: #
|
|
3051
|
+
color: #757cf2;
|
|
1026
3052
|
text-decoration: underline;
|
|
1027
3053
|
}
|
|
3054
|
+
|
|
3055
|
+
.announcement-body {
|
|
3056
|
+
position: relative;
|
|
3057
|
+
overflow: hidden;
|
|
3058
|
+
transition: max-height 0.25s ease;
|
|
3059
|
+
}
|
|
3060
|
+
.announcement-body--collapsed {
|
|
3061
|
+
max-height: 72px;
|
|
3062
|
+
}
|
|
3063
|
+
.announcement-body--expanded {
|
|
3064
|
+
max-height: 2000px;
|
|
3065
|
+
}
|
|
3066
|
+
.announcement-fade {
|
|
3067
|
+
position: absolute;
|
|
3068
|
+
bottom: 0;
|
|
3069
|
+
left: 0;
|
|
3070
|
+
right: 0;
|
|
3071
|
+
height: 48px;
|
|
3072
|
+
background: linear-gradient(to bottom, transparent, #ffffff);
|
|
3073
|
+
pointer-events: none;
|
|
3074
|
+
}
|
|
3075
|
+
.announcement-toggle {
|
|
3076
|
+
display: block;
|
|
3077
|
+
width: 100%;
|
|
3078
|
+
margin-top: 6px;
|
|
3079
|
+
padding: 0;
|
|
3080
|
+
background: none;
|
|
3081
|
+
border: none;
|
|
3082
|
+
font-family: "Plus Jakarta Sans", system-ui, sans-serif;
|
|
3083
|
+
font-size: 12px;
|
|
3084
|
+
font-weight: 500;
|
|
3085
|
+
color: #757cf2;
|
|
3086
|
+
cursor: pointer;
|
|
3087
|
+
text-align: center;
|
|
3088
|
+
}
|
|
3089
|
+
.announcement-toggle:hover {
|
|
3090
|
+
color: #6430ab;
|
|
3091
|
+
}
|
|
3092
|
+
|
|
3093
|
+
/* ── Brand typography ────────────────────────────────────────── */
|
|
3094
|
+
/* Override Tailwind font-mono stack → Spline Sans Mono */
|
|
3095
|
+
.font-mono,
|
|
3096
|
+
pre,
|
|
3097
|
+
code {
|
|
3098
|
+
font-family: "Spline Sans Mono", ui-monospace, "Cascadia Code", monospace;
|
|
3099
|
+
}
|
|
3100
|
+
|
|
3101
|
+
/* ── Floating button ─────────────────────────────────────────── */
|
|
3102
|
+
.console-button {
|
|
3103
|
+
background-color: rgba(1, 5, 7, 0.95) !important;
|
|
3104
|
+
border-color: rgba(190, 194, 255, 0.25) !important;
|
|
3105
|
+
box-shadow:
|
|
3106
|
+
0 0 0 1px rgba(190, 194, 255, 0.15),
|
|
3107
|
+
0 4px 14px rgba(1, 5, 7, 0.28) !important;
|
|
3108
|
+
}
|
|
3109
|
+
.console-button:hover {
|
|
3110
|
+
background-color: rgba(1, 5, 7, 1) !important;
|
|
3111
|
+
border-color: rgba(190, 194, 255, 0.45) !important;
|
|
3112
|
+
}
|
|
3113
|
+
.console-button:focus-visible {
|
|
3114
|
+
outline-color: #bec2ff !important;
|
|
3115
|
+
}
|
|
3116
|
+
|
|
3117
|
+
/* ── Inspector window ────────────────────────────────────────── */
|
|
3118
|
+
.inspector-window {
|
|
3119
|
+
border-color: #dbdbe5 !important;
|
|
3120
|
+
box-shadow:
|
|
3121
|
+
0 8px 32px rgba(1, 5, 7, 0.1),
|
|
3122
|
+
0 2px 8px rgba(1, 5, 7, 0.06) !important;
|
|
3123
|
+
}
|
|
3124
|
+
|
|
3125
|
+
/* ── Header drag area ────────────────────────────────────────── */
|
|
3126
|
+
.drag-handle {
|
|
3127
|
+
border-bottom-color: #dbdbe5 !important;
|
|
3128
|
+
/* Subtle pale lavender gradient — brand "light, spacious" surface */
|
|
3129
|
+
background: linear-gradient(180deg, #f4f4fd 0%, #ffffff 100%) !important;
|
|
3130
|
+
}
|
|
3131
|
+
|
|
3132
|
+
/* Tab strip row: soft off-white, separated from content */
|
|
3133
|
+
.drag-handle > div:last-child {
|
|
3134
|
+
border-top-color: #e2e2ea !important;
|
|
3135
|
+
background-color: #fafafc !important;
|
|
3136
|
+
}
|
|
3137
|
+
|
|
3138
|
+
/* ── Tab buttons ─────────────────────────────────────────────── */
|
|
3139
|
+
/*
|
|
3140
|
+
* Named classes owned by this component — no Tailwind conflict.
|
|
3141
|
+
* Active: brand surface/surfaceContainerActive (lilac tint) +
|
|
3142
|
+
* border/borderActionEnabled underline.
|
|
3143
|
+
* Dark fill is for primary action buttons only, not nav tabs.
|
|
3144
|
+
*/
|
|
3145
|
+
.cpk-tab-active {
|
|
3146
|
+
background-color: rgba(190, 194, 255, 0.18);
|
|
3147
|
+
color: #010507;
|
|
3148
|
+
font-weight: 600;
|
|
3149
|
+
}
|
|
3150
|
+
.cpk-tab-active .cpk-tab-icon {
|
|
3151
|
+
color: #757cf2;
|
|
3152
|
+
}
|
|
3153
|
+
.cpk-tab-inactive {
|
|
3154
|
+
background-color: transparent;
|
|
3155
|
+
color: #2b2b2b;
|
|
3156
|
+
}
|
|
3157
|
+
.cpk-tab-inactive .cpk-tab-icon {
|
|
3158
|
+
color: #838389;
|
|
3159
|
+
}
|
|
3160
|
+
.cpk-tab-inactive:hover {
|
|
3161
|
+
background-color: rgba(190, 194, 255, 0.08);
|
|
3162
|
+
color: #010507;
|
|
3163
|
+
cursor: pointer;
|
|
3164
|
+
}
|
|
3165
|
+
.cpk-tab-active {
|
|
3166
|
+
cursor: pointer;
|
|
3167
|
+
}
|
|
3168
|
+
|
|
3169
|
+
/* ── Header control buttons (dock, close) — first row only ───── */
|
|
3170
|
+
.drag-handle > div:first-child button {
|
|
3171
|
+
color: #838389 !important;
|
|
3172
|
+
}
|
|
3173
|
+
.drag-handle > div:first-child button:hover {
|
|
3174
|
+
background-color: #f0f0f4 !important;
|
|
3175
|
+
color: #57575b !important;
|
|
3176
|
+
}
|
|
3177
|
+
.drag-handle > div:first-child button:focus-visible {
|
|
3178
|
+
outline-color: #bec2ff !important;
|
|
3179
|
+
}
|
|
3180
|
+
|
|
3181
|
+
/* ── Agent/context dropdown ──────────────────────────────────── */
|
|
3182
|
+
[data-context-dropdown-root="true"] > button {
|
|
3183
|
+
border-color: #dbdbe5 !important;
|
|
3184
|
+
color: #010507 !important;
|
|
3185
|
+
}
|
|
3186
|
+
[data-context-dropdown-root="true"] > button:hover {
|
|
3187
|
+
border-color: #bec2ff !important;
|
|
3188
|
+
background-color: #f7f7f9 !important;
|
|
3189
|
+
}
|
|
3190
|
+
[data-context-dropdown-root="true"] > button > span:last-child {
|
|
3191
|
+
color: #838389 !important;
|
|
3192
|
+
}
|
|
3193
|
+
[data-context-dropdown-root="true"] > div {
|
|
3194
|
+
border-color: #dbdbe5 !important;
|
|
3195
|
+
box-shadow: 0 4px 12px rgba(1, 5, 7, 0.08) !important;
|
|
3196
|
+
}
|
|
3197
|
+
[data-context-dropdown-root="true"] > div button:hover,
|
|
3198
|
+
[data-context-dropdown-root="true"] > div button:focus {
|
|
3199
|
+
background-color: #f7f7f9 !important;
|
|
3200
|
+
}
|
|
3201
|
+
|
|
3202
|
+
/* ── Status bar (bottom chrome) ──────────────────────────────── */
|
|
3203
|
+
.inspector-window > div > div:last-child {
|
|
3204
|
+
border-top-color: #dbdbe5 !important;
|
|
3205
|
+
background-color: #f7f7f9 !important;
|
|
3206
|
+
}
|
|
3207
|
+
|
|
3208
|
+
/* ── Resize handle ───────────────────────────────────────────── */
|
|
3209
|
+
.resize-handle {
|
|
3210
|
+
color: #838389 !important;
|
|
3211
|
+
}
|
|
3212
|
+
.resize-handle:hover {
|
|
3213
|
+
color: #57575b !important;
|
|
3214
|
+
}
|
|
3215
|
+
|
|
3216
|
+
/* ── AG-UI Events tab ────────────────────────────────────────── */
|
|
3217
|
+
/* Row hover: replace blue tint with brand lilac */
|
|
3218
|
+
tr:hover td {
|
|
3219
|
+
background-color: rgba(190, 194, 255, 0.08) !important;
|
|
3220
|
+
}
|
|
3221
|
+
/* Reset/dark action button */
|
|
3222
|
+
button[class*="bg-gray-900"] {
|
|
3223
|
+
background-color: #010507 !important;
|
|
3224
|
+
}
|
|
3225
|
+
button[class*="bg-gray-800"] {
|
|
3226
|
+
background-color: #2b2b2b !important;
|
|
3227
|
+
}
|
|
3228
|
+
/* Copy "copied" state: generic green → brand mint */
|
|
3229
|
+
button[class*="bg-green-100"] {
|
|
3230
|
+
background-color: rgba(133, 236, 206, 0.2) !important;
|
|
3231
|
+
color: #189370 !important;
|
|
3232
|
+
}
|
|
3233
|
+
|
|
3234
|
+
/* ── Agents tab ──────────────────────────────────────────────── */
|
|
3235
|
+
/* Agent icon bubble: blue → lilac */
|
|
3236
|
+
span[class*="bg-blue-100"]:not([class*="text-blue-800"]) {
|
|
3237
|
+
background-color: rgba(190, 194, 255, 0.15) !important;
|
|
3238
|
+
}
|
|
3239
|
+
span[class*="text-blue-600"] {
|
|
3240
|
+
color: #757cf2 !important;
|
|
3241
|
+
}
|
|
3242
|
+
/* Running badge: emerald → mint */
|
|
3243
|
+
span[class*="bg-emerald-50"] {
|
|
3244
|
+
background-color: rgba(133, 236, 206, 0.15) !important;
|
|
3245
|
+
}
|
|
3246
|
+
span[class*="text-emerald-700"] {
|
|
3247
|
+
color: #189370 !important;
|
|
3248
|
+
}
|
|
3249
|
+
/* Running status dot */
|
|
3250
|
+
span[class*="bg-emerald-500"] {
|
|
3251
|
+
background-color: #85ecce !important;
|
|
3252
|
+
}
|
|
3253
|
+
/* Idle dot */
|
|
3254
|
+
span[class*="bg-gray-400"] {
|
|
3255
|
+
background-color: #afafb7 !important;
|
|
3256
|
+
}
|
|
3257
|
+
/* User role badge (blue → lilac) */
|
|
3258
|
+
span[class*="bg-blue-100"][class*="text-blue-800"] {
|
|
3259
|
+
background-color: rgba(190, 194, 255, 0.22) !important;
|
|
3260
|
+
border: 1px solid rgba(190, 194, 255, 0.45) !important;
|
|
3261
|
+
color: #57575b !important;
|
|
3262
|
+
}
|
|
3263
|
+
/* Assistant role badge (green → mint) */
|
|
3264
|
+
span[class*="bg-green-100"][class*="text-green-800"] {
|
|
3265
|
+
background-color: rgba(133, 236, 206, 0.18) !important;
|
|
3266
|
+
border: 1px solid rgba(133, 236, 206, 0.4) !important;
|
|
3267
|
+
color: #189370 !important;
|
|
3268
|
+
}
|
|
3269
|
+
/* Tool role badge (amber → orange brand) */
|
|
3270
|
+
span[class*="bg-amber-100"][class*="text-amber-800"] {
|
|
3271
|
+
background-color: rgba(255, 172, 77, 0.15) !important;
|
|
3272
|
+
color: #57575b !important;
|
|
3273
|
+
}
|
|
3274
|
+
|
|
3275
|
+
/* ── Frontend Tools tab ──────────────────────────────────────── */
|
|
3276
|
+
/* Handler badge (blue → lilac) */
|
|
3277
|
+
span[class*="bg-blue-50"][class*="text-blue-700"] {
|
|
3278
|
+
background-color: rgba(190, 194, 255, 0.12) !important;
|
|
3279
|
+
border-color: rgba(190, 194, 255, 0.3) !important;
|
|
3280
|
+
color: #010507 !important;
|
|
3281
|
+
}
|
|
3282
|
+
/* Renderer badge (purple → lilac-adjacent) */
|
|
3283
|
+
span[class*="bg-purple-50"][class*="text-purple-700"] {
|
|
3284
|
+
background-color: rgba(190, 194, 255, 0.12) !important;
|
|
3285
|
+
border-color: rgba(190, 194, 255, 0.3) !important;
|
|
3286
|
+
color: #57575b !important;
|
|
3287
|
+
}
|
|
3288
|
+
/* Required badge (rose → brand red) */
|
|
3289
|
+
span[class*="bg-rose-50"][class*="text-rose-700"] {
|
|
3290
|
+
background-color: rgba(250, 95, 103, 0.1) !important;
|
|
3291
|
+
border-color: rgba(250, 95, 103, 0.25) !important;
|
|
3292
|
+
color: #fa5f67 !important;
|
|
3293
|
+
}
|
|
3294
|
+
/* Code/default value blocks */
|
|
3295
|
+
code[class*="bg-gray-100"],
|
|
3296
|
+
span[class*="bg-gray-100"] {
|
|
3297
|
+
background-color: #f0f0f4 !important;
|
|
3298
|
+
}
|
|
3299
|
+
|
|
3300
|
+
/* ── Connected status bar: match threads header mint (#5BE4BB) ──── */
|
|
3301
|
+
/* Outer strip bg + top border + text when connected badge is present */
|
|
3302
|
+
.inspector-window
|
|
3303
|
+
> div
|
|
3304
|
+
> div:last-child
|
|
3305
|
+
> div:last-child:has(div[class*="bg-emerald-50"]) {
|
|
3306
|
+
background-color: rgba(91, 228, 187, 0.08) !important;
|
|
3307
|
+
border-top-color: rgba(91, 228, 187, 0.3) !important;
|
|
3308
|
+
color: #189370 !important;
|
|
3309
|
+
}
|
|
3310
|
+
/* Inner badge — slightly more opaque on the mint bg */
|
|
3311
|
+
div[class*="bg-emerald-50"][class*="border-emerald-200"] {
|
|
3312
|
+
background-color: rgba(91, 228, 187, 0.12) !important;
|
|
3313
|
+
border-color: rgba(91, 228, 187, 0.4) !important;
|
|
3314
|
+
color: #189370 !important;
|
|
3315
|
+
}
|
|
3316
|
+
/* Icon bubble inside connected badge → mint tint */
|
|
3317
|
+
div[class*="bg-emerald-50"] span[class*="bg-white"] {
|
|
3318
|
+
background-color: rgba(91, 228, 187, 0.3) !important;
|
|
3319
|
+
}
|
|
3320
|
+
|
|
3321
|
+
/* ── Announcement panel ──────────────────────────────────────── */
|
|
3322
|
+
div[class*="border-slate-200"][class*="bg-white"] {
|
|
3323
|
+
border-color: #dbdbe5 !important;
|
|
3324
|
+
}
|
|
3325
|
+
/* Announcement icon bubble: black → brand light lavender + lilac icon */
|
|
3326
|
+
span[class*="bg-slate-900"],
|
|
3327
|
+
div[class*="bg-slate-900"] {
|
|
3328
|
+
background-color: #eee6fe !important;
|
|
3329
|
+
color: #757cf2 !important;
|
|
3330
|
+
}
|
|
3331
|
+
span[class*="text-slate-800"],
|
|
3332
|
+
div[class*="text-slate-800"] {
|
|
3333
|
+
color: #010507 !important;
|
|
3334
|
+
}
|
|
1028
3335
|
`];
|
|
1029
3336
|
}
|
|
1030
3337
|
connectedCallback() {
|
|
1031
3338
|
super.connectedCallback();
|
|
1032
3339
|
if (typeof window !== "undefined") {
|
|
3340
|
+
this.ensureBrandFonts();
|
|
1033
3341
|
window.addEventListener("resize", this.handleResize);
|
|
1034
3342
|
window.addEventListener("pointerdown", this.handleGlobalPointerDown);
|
|
1035
3343
|
this.hydrateStateFromStorageEarly();
|
|
@@ -1037,6 +3345,15 @@ ${argsString}</pre
|
|
|
1037
3345
|
this.ensureAnnouncementLoading();
|
|
1038
3346
|
}
|
|
1039
3347
|
}
|
|
3348
|
+
ensureBrandFonts() {
|
|
3349
|
+
const FONT_LINK_ID = "cpk-inspector-brand-fonts";
|
|
3350
|
+
if (document.getElementById(FONT_LINK_ID)) return;
|
|
3351
|
+
const link = document.createElement("link");
|
|
3352
|
+
link.id = FONT_LINK_ID;
|
|
3353
|
+
link.rel = "stylesheet";
|
|
3354
|
+
link.href = "https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;600&family=Spline+Sans+Mono:wght@600&display=swap";
|
|
3355
|
+
document.head.appendChild(link);
|
|
3356
|
+
}
|
|
1040
3357
|
disconnectedCallback() {
|
|
1041
3358
|
super.disconnectedCallback();
|
|
1042
3359
|
if (typeof window !== "undefined") {
|
|
@@ -1114,7 +3431,7 @@ ${argsString}</pre
|
|
|
1114
3431
|
"focus-visible:outline",
|
|
1115
3432
|
"focus-visible:outline-2",
|
|
1116
3433
|
"focus-visible:outline-offset-2",
|
|
1117
|
-
"focus-visible:outline-
|
|
3434
|
+
"focus-visible:outline-[#BEC2FF]",
|
|
1118
3435
|
"touch-none",
|
|
1119
3436
|
"select-none",
|
|
1120
3437
|
this.isDragging ? "cursor-grabbing" : "cursor-grab"
|
|
@@ -1214,6 +3531,7 @@ ${argsString}</pre
|
|
|
1214
3531
|
</div>
|
|
1215
3532
|
</div>
|
|
1216
3533
|
</div>
|
|
3534
|
+
${this.renderAnnouncementBanner()}
|
|
1217
3535
|
<div
|
|
1218
3536
|
class="flex flex-wrap items-center gap-2 border-t border-gray-100 px-3 py-2 text-xs"
|
|
1219
3537
|
>
|
|
@@ -1222,14 +3540,12 @@ ${argsString}</pre
|
|
|
1222
3540
|
return lit.html`
|
|
1223
3541
|
<button
|
|
1224
3542
|
type="button"
|
|
1225
|
-
class=${["inline-flex items-center gap-2 rounded-md px-3 py-2 transition focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-300", isSelected ? "
|
|
3543
|
+
class=${["inline-flex items-center gap-2 rounded-md px-3 py-2 transition focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-300", isSelected ? "cpk-tab-active" : "cpk-tab-inactive"].join(" ")}
|
|
1226
3544
|
aria-pressed=${isSelected}
|
|
1227
3545
|
@click=${() => this.handleMenuSelect(key)}
|
|
1228
3546
|
>
|
|
1229
|
-
<span
|
|
1230
|
-
|
|
1231
|
-
>
|
|
1232
|
-
${this.renderIcon(icon)}
|
|
3547
|
+
<span class="cpk-tab-icon">
|
|
3548
|
+
${key in this.customTabIcons ? (0, lit_directives_unsafe_html_js.unsafeHTML)(this.customTabIcons[key]) : this.renderIcon(icon)}
|
|
1233
3549
|
</span>
|
|
1234
3550
|
<span>${label}</span>
|
|
1235
3551
|
</button>
|
|
@@ -1238,8 +3554,7 @@ ${argsString}</pre
|
|
|
1238
3554
|
</div>
|
|
1239
3555
|
</div>
|
|
1240
3556
|
<div class="flex flex-1 flex-col overflow-hidden">
|
|
1241
|
-
<div class="flex-1 overflow-auto">
|
|
1242
|
-
${this.renderAnnouncementPanel()}
|
|
3557
|
+
<div id="cpk-main-scroll" class="flex-1 overflow-auto">
|
|
1243
3558
|
${this.renderCoreWarningBanner()} ${this.renderMainContent()}
|
|
1244
3559
|
<slot></slot>
|
|
1245
3560
|
</div>
|
|
@@ -1287,6 +3602,7 @@ ${argsString}</pre
|
|
|
1287
3602
|
}
|
|
1288
3603
|
hydrateStateFromStorageEarly() {
|
|
1289
3604
|
if (typeof document === "undefined" || typeof window === "undefined") return;
|
|
3605
|
+
if (document.cookie.includes("cpk_threads_access=1")) this._threadsUnlocked = true;
|
|
1290
3606
|
const persisted = require_persistence.loadInspectorState(INSPECTOR_STORAGE_KEY);
|
|
1291
3607
|
if (!persisted) return;
|
|
1292
3608
|
if (typeof persisted.isOpen === "boolean") this.isOpen = persisted.isOpen;
|
|
@@ -1683,7 +3999,8 @@ ${argsString}</pre
|
|
|
1683
3999
|
role,
|
|
1684
4000
|
contentText,
|
|
1685
4001
|
contentRaw: raw.content !== void 0 ? this.sanitizeForLogging(raw.content) : void 0,
|
|
1686
|
-
toolCalls
|
|
4002
|
+
toolCalls,
|
|
4003
|
+
activityType: typeof raw.activityType === "string" ? raw.activityType : void 0
|
|
1687
4004
|
};
|
|
1688
4005
|
}
|
|
1689
4006
|
normalizeAgentMessages(messages) {
|
|
@@ -1702,9 +4019,6 @@ ${argsString}</pre
|
|
|
1702
4019
|
} else normalized[key] = { value: entry };
|
|
1703
4020
|
return normalized;
|
|
1704
4021
|
}
|
|
1705
|
-
getSelectedMenu() {
|
|
1706
|
-
return this.menuItems.find((item) => item.key === this.selectedMenu) ?? this.menuItems[0];
|
|
1707
|
-
}
|
|
1708
4022
|
renderCoreWarningBanner() {
|
|
1709
4023
|
if (this._core) return lit.nothing;
|
|
1710
4024
|
return lit.html`
|
|
@@ -1761,27 +4075,456 @@ ${argsString}</pre
|
|
|
1761
4075
|
if (this.selectedMenu === "agents") return this.renderAgentsView();
|
|
1762
4076
|
if (this.selectedMenu === "frontend-tools") return this.renderToolsView();
|
|
1763
4077
|
if (this.selectedMenu === "agent-context") return this.renderContextView();
|
|
4078
|
+
if (this.selectedMenu === "threads") return this.renderThreadsView();
|
|
1764
4079
|
return lit.nothing;
|
|
1765
4080
|
}
|
|
4081
|
+
renderThreadsGate() {
|
|
4082
|
+
return lit.html`
|
|
4083
|
+
<div style="
|
|
4084
|
+
position:relative;
|
|
4085
|
+
display:flex;
|
|
4086
|
+
flex-direction:column;
|
|
4087
|
+
align-items:center;
|
|
4088
|
+
justify-content:center;
|
|
4089
|
+
padding:40px 24px;
|
|
4090
|
+
min-height:100%;
|
|
4091
|
+
text-align:center;
|
|
4092
|
+
background:linear-gradient(135deg,#f5f4ff 0%,#ede9fe 100%);
|
|
4093
|
+
overflow:hidden;
|
|
4094
|
+
">
|
|
4095
|
+
<!-- Blurred ellipses from Figma/storybook -->
|
|
4096
|
+
<div style="position:absolute;width:570px;height:570px;border-radius:50%;top:-80px;left:-120px;opacity:0.25;background:#757CF2;filter:blur(120px);pointer-events:none;"></div>
|
|
4097
|
+
<div style="position:absolute;width:570px;height:570px;border-radius:50%;bottom:-100px;right:-80px;opacity:0.2;background:#FFAC4D;filter:blur(120px);pointer-events:none;"></div>
|
|
4098
|
+
<div style="position:absolute;width:400px;height:400px;border-radius:50%;bottom:20px;left:-60px;opacity:0.15;background:#FFAC4D;filter:blur(100px);pointer-events:none;"></div>
|
|
4099
|
+
|
|
4100
|
+
${this._threadsUnlocking ? this._renderUnlockingCard() : this._renderEarlyAccessCard()}
|
|
4101
|
+
</div>
|
|
4102
|
+
`;
|
|
4103
|
+
}
|
|
4104
|
+
static {
|
|
4105
|
+
this.THREADS_REQUEST_URL = "https://r3x69.share-na2.hsforms.com/2uiZg8EkiT7a_KykeXV1ajQ";
|
|
4106
|
+
}
|
|
4107
|
+
_renderEarlyAccessCard() {
|
|
4108
|
+
const invalid = this._threadsGateCodeInvalid;
|
|
4109
|
+
return lit.html`
|
|
4110
|
+
<div
|
|
4111
|
+
style="
|
|
4112
|
+
position:relative;
|
|
4113
|
+
z-index:1;
|
|
4114
|
+
background:#ffffff;
|
|
4115
|
+
border:1px solid #E5E5EA;
|
|
4116
|
+
border-radius:20px;
|
|
4117
|
+
box-shadow:0 16px 48px rgba(1,5,7,0.12),0 2px 6px rgba(1,5,7,0.05);
|
|
4118
|
+
padding:28px;
|
|
4119
|
+
width:400px;
|
|
4120
|
+
max-width:100%;
|
|
4121
|
+
display:flex;
|
|
4122
|
+
flex-direction:column;
|
|
4123
|
+
gap:18px;
|
|
4124
|
+
text-align:left;
|
|
4125
|
+
font-family:'Plus Jakarta Sans', system-ui, sans-serif;
|
|
4126
|
+
"
|
|
4127
|
+
>
|
|
4128
|
+
<!-- Kicker pill -->
|
|
4129
|
+
<div>
|
|
4130
|
+
<span
|
|
4131
|
+
style="
|
|
4132
|
+
display:inline-flex;
|
|
4133
|
+
align-items:center;
|
|
4134
|
+
gap:4px;
|
|
4135
|
+
padding:4px 10px;
|
|
4136
|
+
border-radius:999px;
|
|
4137
|
+
background:#F3F3FC;
|
|
4138
|
+
color:#757CF2;
|
|
4139
|
+
font-family:'Spline Sans Mono', ui-monospace, monospace;
|
|
4140
|
+
font-size:10px;
|
|
4141
|
+
font-weight:500;
|
|
4142
|
+
letter-spacing:0.08em;
|
|
4143
|
+
text-transform:uppercase;
|
|
4144
|
+
"
|
|
4145
|
+
>Early Access</span
|
|
4146
|
+
>
|
|
4147
|
+
</div>
|
|
4148
|
+
|
|
4149
|
+
<!-- Title + description -->
|
|
4150
|
+
<div style="display:flex;flex-direction:column;gap:8px;">
|
|
4151
|
+
<h2
|
|
4152
|
+
style="
|
|
4153
|
+
font-family:'Plus Jakarta Sans', system-ui, sans-serif;
|
|
4154
|
+
font-size:24px;
|
|
4155
|
+
font-weight:700;
|
|
4156
|
+
color:#010507;
|
|
4157
|
+
line-height:1.2;
|
|
4158
|
+
letter-spacing:-0.015em;
|
|
4159
|
+
margin:0;
|
|
4160
|
+
"
|
|
4161
|
+
>
|
|
4162
|
+
<span
|
|
4163
|
+
style="
|
|
4164
|
+
background:linear-gradient(90deg, #757CF2 0%, #5AE4BB 100%);
|
|
4165
|
+
-webkit-background-clip:text;
|
|
4166
|
+
background-clip:text;
|
|
4167
|
+
color:transparent;
|
|
4168
|
+
-webkit-text-fill-color:transparent;
|
|
4169
|
+
"
|
|
4170
|
+
>Threads</span
|
|
4171
|
+
>
|
|
4172
|
+
are in private beta
|
|
4173
|
+
</h2>
|
|
4174
|
+
<p
|
|
4175
|
+
style="
|
|
4176
|
+
font-size:14px;
|
|
4177
|
+
font-weight:500;
|
|
4178
|
+
color:#5C5C66;
|
|
4179
|
+
line-height:1.55;
|
|
4180
|
+
margin:0;
|
|
4181
|
+
"
|
|
4182
|
+
>
|
|
4183
|
+
Spin up separate conversations with your agent, one per task, bug,
|
|
4184
|
+
or feature, and jump back into any of them without losing context.
|
|
4185
|
+
</p>
|
|
4186
|
+
</div>
|
|
4187
|
+
|
|
4188
|
+
<!-- Bullets -->
|
|
4189
|
+
<div
|
|
4190
|
+
style="display:flex;flex-direction:column;gap:8px;padding:4px 0;"
|
|
4191
|
+
>
|
|
4192
|
+
${[
|
|
4193
|
+
"One agent, many conversations",
|
|
4194
|
+
"Persistent history across sessions",
|
|
4195
|
+
"Jump between threads in a click"
|
|
4196
|
+
].map((label) => lit.html`
|
|
4197
|
+
<div style="display:flex;align-items:center;gap:10px;">
|
|
4198
|
+
<svg
|
|
4199
|
+
width="14"
|
|
4200
|
+
height="14"
|
|
4201
|
+
viewBox="0 0 24 24"
|
|
4202
|
+
fill="none"
|
|
4203
|
+
stroke="#010507"
|
|
4204
|
+
stroke-width="2.5"
|
|
4205
|
+
stroke-linecap="round"
|
|
4206
|
+
stroke-linejoin="round"
|
|
4207
|
+
style="flex-shrink:0;"
|
|
4208
|
+
>
|
|
4209
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
4210
|
+
</svg>
|
|
4211
|
+
<span style="font-size:13px;font-weight:500;color:#010507;"
|
|
4212
|
+
>${label}</span
|
|
4213
|
+
>
|
|
4214
|
+
</div>
|
|
4215
|
+
`)}
|
|
4216
|
+
</div>
|
|
4217
|
+
|
|
4218
|
+
<!-- Primary CTA: dark MonoPillButton with adjacent arrow circle -->
|
|
4219
|
+
<div>
|
|
4220
|
+
<a
|
|
4221
|
+
href=${WebInspectorElement.THREADS_REQUEST_URL}
|
|
4222
|
+
target="_blank"
|
|
4223
|
+
rel="noopener noreferrer"
|
|
4224
|
+
style="
|
|
4225
|
+
display:inline-flex;
|
|
4226
|
+
align-items:center;
|
|
4227
|
+
gap:8px;
|
|
4228
|
+
text-decoration:none;
|
|
4229
|
+
cursor:pointer;
|
|
4230
|
+
"
|
|
4231
|
+
>
|
|
4232
|
+
<span
|
|
4233
|
+
style="
|
|
4234
|
+
display:inline-flex;
|
|
4235
|
+
align-items:center;
|
|
4236
|
+
justify-content:center;
|
|
4237
|
+
background:#010507;
|
|
4238
|
+
color:#ffffff;
|
|
4239
|
+
font-family:'Spline Sans Mono', ui-monospace, monospace;
|
|
4240
|
+
font-size:13px;
|
|
4241
|
+
font-weight:500;
|
|
4242
|
+
letter-spacing:0.06em;
|
|
4243
|
+
text-transform:uppercase;
|
|
4244
|
+
padding:14px 22px;
|
|
4245
|
+
border-radius:999px;
|
|
4246
|
+
box-shadow:0 4px 12px rgba(1,5,7,0.18);
|
|
4247
|
+
"
|
|
4248
|
+
>Request Early Access</span
|
|
4249
|
+
>
|
|
4250
|
+
<span
|
|
4251
|
+
style="
|
|
4252
|
+
display:inline-flex;
|
|
4253
|
+
align-items:center;
|
|
4254
|
+
justify-content:center;
|
|
4255
|
+
width:36px;
|
|
4256
|
+
height:36px;
|
|
4257
|
+
border-radius:999px;
|
|
4258
|
+
background:#010507;
|
|
4259
|
+
color:#ffffff;
|
|
4260
|
+
box-shadow:0 4px 12px rgba(1,5,7,0.18);
|
|
4261
|
+
"
|
|
4262
|
+
>
|
|
4263
|
+
<svg
|
|
4264
|
+
width="14"
|
|
4265
|
+
height="14"
|
|
4266
|
+
viewBox="0 0 24 24"
|
|
4267
|
+
fill="none"
|
|
4268
|
+
stroke="currentColor"
|
|
4269
|
+
stroke-width="2"
|
|
4270
|
+
stroke-linecap="round"
|
|
4271
|
+
stroke-linejoin="round"
|
|
4272
|
+
>
|
|
4273
|
+
<line x1="5" y1="12" x2="19" y2="12"></line>
|
|
4274
|
+
<polyline points="12 5 19 12 12 19"></polyline>
|
|
4275
|
+
</svg>
|
|
4276
|
+
</span>
|
|
4277
|
+
</a>
|
|
4278
|
+
</div>
|
|
4279
|
+
|
|
4280
|
+
<!-- Divider + invite-code section -->
|
|
4281
|
+
<div
|
|
4282
|
+
style="
|
|
4283
|
+
display:flex;
|
|
4284
|
+
flex-direction:column;
|
|
4285
|
+
gap:8px;
|
|
4286
|
+
padding-top:14px;
|
|
4287
|
+
border-top:1px dashed #E5E5EA;
|
|
4288
|
+
"
|
|
4289
|
+
>
|
|
4290
|
+
<span style="font-size:12px;font-weight:500;color:#8A8A94;"
|
|
4291
|
+
>Have an invite code?</span
|
|
4292
|
+
>
|
|
4293
|
+
<div style="display:flex;gap:8px;">
|
|
4294
|
+
<div
|
|
4295
|
+
style="
|
|
4296
|
+
flex:1;
|
|
4297
|
+
background:#ffffff;
|
|
4298
|
+
border:1px solid ${invalid ? "#FA5F67" : "#E5E5EA"};
|
|
4299
|
+
border-radius:10px;
|
|
4300
|
+
padding:2px 4px 2px 12px;
|
|
4301
|
+
transition:border-color 150ms ease;
|
|
4302
|
+
"
|
|
4303
|
+
>
|
|
4304
|
+
<input
|
|
4305
|
+
id="cpk-gate-input"
|
|
4306
|
+
type="text"
|
|
4307
|
+
placeholder="Enter access code"
|
|
4308
|
+
style="
|
|
4309
|
+
width:100%;
|
|
4310
|
+
padding:10px 0;
|
|
4311
|
+
font-family:'Plus Jakarta Sans', system-ui, sans-serif;
|
|
4312
|
+
font-size:13px;
|
|
4313
|
+
font-weight:500;
|
|
4314
|
+
color:#010507;
|
|
4315
|
+
background:transparent;
|
|
4316
|
+
border:none;
|
|
4317
|
+
outline:none;
|
|
4318
|
+
"
|
|
4319
|
+
@keydown=${(e) => {
|
|
4320
|
+
if (e.key === "Enter") this._submitThreadsCode(e.currentTarget.value);
|
|
4321
|
+
}}
|
|
4322
|
+
/>
|
|
4323
|
+
</div>
|
|
4324
|
+
<button
|
|
4325
|
+
style="
|
|
4326
|
+
background:#010507;
|
|
4327
|
+
color:#ffffff;
|
|
4328
|
+
border:none;
|
|
4329
|
+
border-radius:10px;
|
|
4330
|
+
padding:0 16px;
|
|
4331
|
+
font-family:'Spline Sans Mono', ui-monospace, monospace;
|
|
4332
|
+
font-size:11px;
|
|
4333
|
+
font-weight:500;
|
|
4334
|
+
letter-spacing:0.06em;
|
|
4335
|
+
text-transform:uppercase;
|
|
4336
|
+
cursor:pointer;
|
|
4337
|
+
white-space:nowrap;
|
|
4338
|
+
"
|
|
4339
|
+
@click=${() => {
|
|
4340
|
+
const input = this.shadowRoot?.getElementById("cpk-gate-input");
|
|
4341
|
+
if (input) this._submitThreadsCode(input.value);
|
|
4342
|
+
}}
|
|
4343
|
+
>
|
|
4344
|
+
Unlock
|
|
4345
|
+
</button>
|
|
4346
|
+
</div>
|
|
4347
|
+
${invalid ? lit.html`
|
|
4348
|
+
<div style="font-size: 11px; font-weight: 500; color: #fa5f67">
|
|
4349
|
+
That code isn't valid. Double-check your invite email.
|
|
4350
|
+
</div>
|
|
4351
|
+
` : lit.nothing}
|
|
4352
|
+
</div>
|
|
4353
|
+
</div>
|
|
4354
|
+
`;
|
|
4355
|
+
}
|
|
4356
|
+
_renderUnlockingCard() {
|
|
4357
|
+
return lit.html`
|
|
4358
|
+
<div
|
|
4359
|
+
style="
|
|
4360
|
+
position: relative;
|
|
4361
|
+
z-index: 1;
|
|
4362
|
+
background: #ffffff;
|
|
4363
|
+
border: 1px solid #e5e5ea;
|
|
4364
|
+
border-radius: 20px;
|
|
4365
|
+
box-shadow:
|
|
4366
|
+
0 16px 48px rgba(1, 5, 7, 0.12),
|
|
4367
|
+
0 2px 6px rgba(1, 5, 7, 0.05);
|
|
4368
|
+
padding: 32px;
|
|
4369
|
+
width: 340px;
|
|
4370
|
+
max-width: 100%;
|
|
4371
|
+
display: flex;
|
|
4372
|
+
flex-direction: column;
|
|
4373
|
+
align-items: center;
|
|
4374
|
+
gap: 16px;
|
|
4375
|
+
text-align: center;
|
|
4376
|
+
font-family: "Plus Jakarta Sans", system-ui, sans-serif;
|
|
4377
|
+
"
|
|
4378
|
+
>
|
|
4379
|
+
<div
|
|
4380
|
+
style="
|
|
4381
|
+
width: 56px;
|
|
4382
|
+
height: 56px;
|
|
4383
|
+
border-radius: 999px;
|
|
4384
|
+
background: linear-gradient(135deg, #bec2ff 0%, #85ecce 100%);
|
|
4385
|
+
display: flex;
|
|
4386
|
+
align-items: center;
|
|
4387
|
+
justify-content: center;
|
|
4388
|
+
"
|
|
4389
|
+
>
|
|
4390
|
+
<svg
|
|
4391
|
+
width="24"
|
|
4392
|
+
height="24"
|
|
4393
|
+
viewBox="0 0 24 24"
|
|
4394
|
+
fill="none"
|
|
4395
|
+
stroke="#010507"
|
|
4396
|
+
stroke-width="2.5"
|
|
4397
|
+
stroke-linecap="round"
|
|
4398
|
+
stroke-linejoin="round"
|
|
4399
|
+
>
|
|
4400
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
4401
|
+
</svg>
|
|
4402
|
+
</div>
|
|
4403
|
+
<div style="font-size: 18px; font-weight: 700; color: #010507">
|
|
4404
|
+
Welcome to Threads
|
|
4405
|
+
</div>
|
|
4406
|
+
<div style="font-size: 13px; color: #5c5c66; line-height: 1.5">
|
|
4407
|
+
Loading your conversations…
|
|
4408
|
+
</div>
|
|
4409
|
+
</div>
|
|
4410
|
+
`;
|
|
4411
|
+
}
|
|
4412
|
+
_submitThreadsCode(value) {
|
|
4413
|
+
if (value.trim().toLowerCase() === "earlyaccess") {
|
|
4414
|
+
document.cookie = "cpk_threads_access=1; path=/; max-age=31536000; SameSite=Lax";
|
|
4415
|
+
this._threadsGateError = null;
|
|
4416
|
+
this._threadsGateCodeInvalid = false;
|
|
4417
|
+
this._threadsUnlocking = true;
|
|
4418
|
+
if (this._threadsUnlockingTimer !== null) clearTimeout(this._threadsUnlockingTimer);
|
|
4419
|
+
this._threadsUnlockingTimer = setTimeout(() => {
|
|
4420
|
+
this._threadsUnlocking = false;
|
|
4421
|
+
this._threadsUnlocked = true;
|
|
4422
|
+
this._threadsUnlockingTimer = null;
|
|
4423
|
+
this.requestUpdate();
|
|
4424
|
+
}, 2e3);
|
|
4425
|
+
} else {
|
|
4426
|
+
this._threadsGateCodeInvalid = true;
|
|
4427
|
+
this._threadsGateError = null;
|
|
4428
|
+
if (this._threadsGateInvalidTimer !== null) clearTimeout(this._threadsGateInvalidTimer);
|
|
4429
|
+
this._threadsGateInvalidTimer = setTimeout(() => {
|
|
4430
|
+
this._threadsGateCodeInvalid = false;
|
|
4431
|
+
this._threadsGateInvalidTimer = null;
|
|
4432
|
+
this.requestUpdate();
|
|
4433
|
+
}, 1600);
|
|
4434
|
+
}
|
|
4435
|
+
this.requestUpdate();
|
|
4436
|
+
}
|
|
4437
|
+
renderThreadsView() {
|
|
4438
|
+
if (!this._threadsUnlocked) return this.renderThreadsGate();
|
|
4439
|
+
const displayThreads = this.selectedContext === "all-agents" ? this._threads : this._threadsByAgent.get(this.selectedContext) ?? [];
|
|
4440
|
+
let threadsErrorMessage = null;
|
|
4441
|
+
if (this.selectedContext === "all-agents") threadsErrorMessage = this._threadsErrorByAgent.values().next().value?.message ?? null;
|
|
4442
|
+
else threadsErrorMessage = this._threadsErrorByAgent.get(this.selectedContext)?.message ?? null;
|
|
4443
|
+
const selectedThread = this.selectedThreadId != null ? displayThreads.find((t) => t.id === this.selectedThreadId) ?? null : null;
|
|
4444
|
+
return lit.html`
|
|
4445
|
+
<div style="display:flex;height:100%;overflow:hidden;">
|
|
4446
|
+
<!-- Left sidebar: thread list -->
|
|
4447
|
+
<div
|
|
4448
|
+
style="width:${this.threadListWidth}px;flex-shrink:0;overflow:hidden;display:flex;flex-direction:column;border-right:1px solid #DBDBE5;"
|
|
4449
|
+
>
|
|
4450
|
+
<cpk-thread-list
|
|
4451
|
+
style="height:100%;"
|
|
4452
|
+
.threads=${displayThreads}
|
|
4453
|
+
.selectedThreadId=${this.selectedThreadId}
|
|
4454
|
+
.errorMessage=${threadsErrorMessage}
|
|
4455
|
+
@threadSelected=${(e) => {
|
|
4456
|
+
this.selectedThreadId = e.detail;
|
|
4457
|
+
this.requestUpdate();
|
|
4458
|
+
}}
|
|
4459
|
+
></cpk-thread-list>
|
|
4460
|
+
</div>
|
|
4461
|
+
|
|
4462
|
+
<!-- Resize divider -->
|
|
4463
|
+
<div
|
|
4464
|
+
style="width:4px;flex-shrink:0;cursor:col-resize;background:transparent;position:relative;z-index:1;"
|
|
4465
|
+
@pointerdown=${this.handleThreadDividerPointerDown}
|
|
4466
|
+
@pointermove=${this.handleThreadDividerPointerMove}
|
|
4467
|
+
@pointerup=${this.handleThreadDividerPointerUp}
|
|
4468
|
+
@pointercancel=${this.handleThreadDividerPointerUp}
|
|
4469
|
+
></div>
|
|
4470
|
+
|
|
4471
|
+
<!-- Center + right: thread details or empty state -->
|
|
4472
|
+
<div style="flex:1;min-width:0;overflow:hidden;display:flex;">
|
|
4473
|
+
${this.selectedThreadId ? lit.html`<cpk-thread-details
|
|
4474
|
+
style="flex:1;min-width:0;"
|
|
4475
|
+
.threadId=${this.selectedThreadId}
|
|
4476
|
+
.thread=${selectedThread}
|
|
4477
|
+
.runtimeUrl=${this._core?.runtimeUrl ?? ""}
|
|
4478
|
+
.headers=${this._core?.headers ?? {}}
|
|
4479
|
+
.liveMessageVersion=${this.selectedThreadId ? this.liveMessageVersion.get(this.selectedThreadId) ?? 0 : 0}
|
|
4480
|
+
.agentStateInput=${selectedThread ? this.getLatestStateForAgent(selectedThread.agentId) : null}
|
|
4481
|
+
.agentEventsInput=${selectedThread ? this.agentEvents.get(selectedThread.agentId) ?? [] : []}
|
|
4482
|
+
></cpk-thread-details>` : lit.html`
|
|
4483
|
+
<div
|
|
4484
|
+
style="
|
|
4485
|
+
flex: 1;
|
|
4486
|
+
display: flex;
|
|
4487
|
+
flex-direction: column;
|
|
4488
|
+
align-items: center;
|
|
4489
|
+
justify-content: center;
|
|
4490
|
+
gap: 8px;
|
|
4491
|
+
color: #838389;
|
|
4492
|
+
"
|
|
4493
|
+
>
|
|
4494
|
+
<svg
|
|
4495
|
+
width="32"
|
|
4496
|
+
height="32"
|
|
4497
|
+
viewBox="0 0 24 24"
|
|
4498
|
+
fill="none"
|
|
4499
|
+
stroke="#c0c0c8"
|
|
4500
|
+
stroke-width="1.5"
|
|
4501
|
+
stroke-linecap="round"
|
|
4502
|
+
stroke-linejoin="round"
|
|
4503
|
+
>
|
|
4504
|
+
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
|
|
4505
|
+
</svg>
|
|
4506
|
+
<span style="font-size: 13px">${displayThreads.length === 0 ? "No threads yet" : "Select a thread to inspect"}</span>
|
|
4507
|
+
</div>
|
|
4508
|
+
`}
|
|
4509
|
+
</div>
|
|
4510
|
+
</div>
|
|
4511
|
+
`;
|
|
4512
|
+
}
|
|
1766
4513
|
renderEventsTable() {
|
|
1767
4514
|
const events = this.getEventsForSelectedContext();
|
|
1768
4515
|
const filteredEvents = this.filterEvents(events);
|
|
1769
4516
|
const selectedLabel = this.selectedContext === "all-agents" ? "all agents" : `agent ${this.selectedContext}`;
|
|
1770
4517
|
if (events.length === 0) return lit.html`
|
|
1771
4518
|
<div
|
|
1772
|
-
class="flex h-full items-center justify-center px-4 py-
|
|
4519
|
+
class="flex h-full flex-col items-center justify-center gap-2 px-4 py-10 text-center"
|
|
1773
4520
|
>
|
|
1774
|
-
<div class="
|
|
1775
|
-
|
|
1776
|
-
class="mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8"
|
|
1777
|
-
>
|
|
1778
|
-
${this.renderIcon("Zap")}
|
|
1779
|
-
</div>
|
|
1780
|
-
<p class="text-sm text-gray-600">No events yet</p>
|
|
1781
|
-
<p class="mt-2 text-xs text-gray-500">
|
|
1782
|
-
Trigger an agent run to see live activity.
|
|
1783
|
-
</p>
|
|
4521
|
+
<div class="text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8">
|
|
4522
|
+
${this.renderIcon("Zap")}
|
|
1784
4523
|
</div>
|
|
4524
|
+
<span class="text-sm text-gray-600">No events yet</span>
|
|
4525
|
+
<span class="max-w-[240px] text-xs leading-snug text-gray-400"
|
|
4526
|
+
>Events are recorded live. Run the agent to see them here.</span
|
|
4527
|
+
>
|
|
1785
4528
|
</div>
|
|
1786
4529
|
`;
|
|
1787
4530
|
if (filteredEvents.length === 0) return lit.html`
|
|
@@ -1878,23 +4621,32 @@ ${argsString}</pre
|
|
|
1878
4621
|
</div>
|
|
1879
4622
|
<div class="relative h-full w-full overflow-y-auto overflow-x-hidden">
|
|
1880
4623
|
<table class="w-full table-fixed border-collapse text-xs box-border">
|
|
4624
|
+
<colgroup>
|
|
4625
|
+
<col style="width:${this.evtColWidths[0]}px">
|
|
4626
|
+
<col style="width:${this.evtColWidths[1]}px">
|
|
4627
|
+
<col style="width:${this.evtColWidths[2]}px">
|
|
4628
|
+
<col>
|
|
4629
|
+
</colgroup>
|
|
1881
4630
|
<thead class="sticky top-0 z-10">
|
|
1882
4631
|
<tr class="bg-white">
|
|
4632
|
+
${[
|
|
4633
|
+
"Agent",
|
|
4634
|
+
"Time",
|
|
4635
|
+
"Event Type"
|
|
4636
|
+
].map((label, col) => lit.html`
|
|
1883
4637
|
<th
|
|
1884
4638
|
class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900"
|
|
4639
|
+
style="position:relative;overflow:hidden;"
|
|
1885
4640
|
>
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
>
|
|
1896
|
-
Event Type
|
|
1897
|
-
</th>
|
|
4641
|
+
${label}
|
|
4642
|
+
<div
|
|
4643
|
+
style="position:absolute;top:0;right:0;width:5px;height:100%;cursor:col-resize;user-select:none;background:transparent;"
|
|
4644
|
+
@pointerdown=${(e) => this._onEvtColResizeStart(e, col)}
|
|
4645
|
+
@pointermove=${(e) => this._onEvtColResizeMove(e)}
|
|
4646
|
+
@pointerup=${() => this._onEvtColResizeEnd()}
|
|
4647
|
+
@pointercancel=${() => this._onEvtColResizeEnd()}
|
|
4648
|
+
></div>
|
|
4649
|
+
</th>`)}
|
|
1898
4650
|
<th
|
|
1899
4651
|
class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900"
|
|
1900
4652
|
>
|
|
@@ -1982,6 +4734,25 @@ ${prettyEvent}</pre
|
|
|
1982
4734
|
this.eventTypeFilter = "all";
|
|
1983
4735
|
this.requestUpdate();
|
|
1984
4736
|
}
|
|
4737
|
+
_onEvtColResizeStart(e, col) {
|
|
4738
|
+
e.preventDefault();
|
|
4739
|
+
e.stopPropagation();
|
|
4740
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
4741
|
+
this._evtColResize = {
|
|
4742
|
+
col,
|
|
4743
|
+
startX: e.clientX,
|
|
4744
|
+
startW: this.evtColWidths[col] ?? 0
|
|
4745
|
+
};
|
|
4746
|
+
}
|
|
4747
|
+
_onEvtColResizeMove(e) {
|
|
4748
|
+
if (!this._evtColResize) return;
|
|
4749
|
+
const { col, startX, startW } = this._evtColResize;
|
|
4750
|
+
this.evtColWidths = this.evtColWidths.map((w, i) => i === col ? Math.max(40, startW + (e.clientX - startX)) : w);
|
|
4751
|
+
this.requestUpdate();
|
|
4752
|
+
}
|
|
4753
|
+
_onEvtColResizeEnd() {
|
|
4754
|
+
this._evtColResize = null;
|
|
4755
|
+
}
|
|
1985
4756
|
exportEvents(events) {
|
|
1986
4757
|
try {
|
|
1987
4758
|
const payload = JSON.stringify(events, null, 2);
|
|
@@ -2026,7 +4797,7 @@ ${prettyEvent}</pre
|
|
|
2026
4797
|
<div class="flex items-start justify-between mb-4">
|
|
2027
4798
|
<div class="flex items-center gap-3">
|
|
2028
4799
|
<div
|
|
2029
|
-
class="flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-blue-600"
|
|
4800
|
+
class="flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-blue-600 cpk-agent-icon"
|
|
2030
4801
|
>
|
|
2031
4802
|
${this.renderIcon("Bot")}
|
|
2032
4803
|
</div>
|
|
@@ -2054,7 +4825,7 @@ ${prettyEvent}</pre
|
|
|
2054
4825
|
<div class="grid grid-cols-2 gap-4 md:grid-cols-4">
|
|
2055
4826
|
<button
|
|
2056
4827
|
type="button"
|
|
2057
|
-
class="rounded-md bg-gray-50 px-3 py-2 text-left transition hover:bg-gray-100 cursor-pointer overflow-hidden"
|
|
4828
|
+
class="rounded-md bg-gray-50 px-3 py-2 text-left transition hover:bg-gray-100 cursor-pointer overflow-hidden cpk-stat-card"
|
|
2058
4829
|
@click=${() => this.handleMenuSelect("ag-ui-events")}
|
|
2059
4830
|
title="View all events in AG-UI Events"
|
|
2060
4831
|
>
|
|
@@ -2065,7 +4836,9 @@ ${prettyEvent}</pre
|
|
|
2065
4836
|
${stats.totalEvents}
|
|
2066
4837
|
</div>
|
|
2067
4838
|
</button>
|
|
2068
|
-
<div
|
|
4839
|
+
<div
|
|
4840
|
+
class="rounded-md bg-gray-50 px-3 py-2 overflow-hidden cpk-stat-card"
|
|
4841
|
+
>
|
|
2069
4842
|
<div class="truncate whitespace-nowrap text-xs text-gray-600">
|
|
2070
4843
|
Messages
|
|
2071
4844
|
</div>
|
|
@@ -2073,7 +4846,9 @@ ${prettyEvent}</pre
|
|
|
2073
4846
|
${stats.messages}
|
|
2074
4847
|
</div>
|
|
2075
4848
|
</div>
|
|
2076
|
-
<div
|
|
4849
|
+
<div
|
|
4850
|
+
class="rounded-md bg-gray-50 px-3 py-2 overflow-hidden cpk-stat-card"
|
|
4851
|
+
>
|
|
2077
4852
|
<div class="truncate whitespace-nowrap text-xs text-gray-600">
|
|
2078
4853
|
Tool Calls
|
|
2079
4854
|
</div>
|
|
@@ -2081,7 +4856,9 @@ ${prettyEvent}</pre
|
|
|
2081
4856
|
${stats.toolCalls}
|
|
2082
4857
|
</div>
|
|
2083
4858
|
</div>
|
|
2084
|
-
<div
|
|
4859
|
+
<div
|
|
4860
|
+
class="rounded-md bg-gray-50 px-3 py-2 overflow-hidden cpk-stat-card"
|
|
4861
|
+
>
|
|
2085
4862
|
<div class="truncate whitespace-nowrap text-xs text-gray-600">
|
|
2086
4863
|
Errors
|
|
2087
4864
|
</div>
|
|
@@ -2093,9 +4870,9 @@ ${prettyEvent}</pre
|
|
|
2093
4870
|
</div>
|
|
2094
4871
|
|
|
2095
4872
|
<!-- Current State Section -->
|
|
2096
|
-
<div class="
|
|
2097
|
-
<div class="
|
|
2098
|
-
<h4
|
|
4873
|
+
<div class="cpk-section-card">
|
|
4874
|
+
<div class="cpk-section-header">
|
|
4875
|
+
<h4>Current State</h4>
|
|
2099
4876
|
</div>
|
|
2100
4877
|
<div class="overflow-auto p-4">
|
|
2101
4878
|
${this.hasRenderableState(state) ? lit.html`
|
|
@@ -2104,7 +4881,7 @@ ${prettyEvent}</pre
|
|
|
2104
4881
|
><code>${this.formatStateForDisplay(state)}</code></pre>
|
|
2105
4882
|
` : lit.html`
|
|
2106
4883
|
<div
|
|
2107
|
-
class="flex h-
|
|
4884
|
+
class="flex h-12 items-center justify-center text-xs text-gray-500"
|
|
2108
4885
|
>
|
|
2109
4886
|
<div class="flex items-center gap-2 text-gray-500">
|
|
2110
4887
|
<span class="text-lg text-gray-400"
|
|
@@ -2118,30 +4895,18 @@ ${prettyEvent}</pre
|
|
|
2118
4895
|
</div>
|
|
2119
4896
|
|
|
2120
4897
|
<!-- Current Messages Section -->
|
|
2121
|
-
<div class="
|
|
2122
|
-
<div class="
|
|
2123
|
-
<h4
|
|
2124
|
-
Current Messages
|
|
2125
|
-
</h4>
|
|
4898
|
+
<div class="cpk-section-card">
|
|
4899
|
+
<div class="cpk-section-header">
|
|
4900
|
+
<h4>Current Messages</h4>
|
|
2126
4901
|
</div>
|
|
2127
4902
|
<div class="overflow-auto">
|
|
2128
4903
|
${messages && messages.length > 0 ? lit.html`
|
|
2129
|
-
<
|
|
2130
|
-
<
|
|
2131
|
-
<
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
Role
|
|
2136
|
-
</th>
|
|
2137
|
-
<th
|
|
2138
|
-
class="px-4 py-2 text-left font-medium text-gray-700"
|
|
2139
|
-
>
|
|
2140
|
-
Content
|
|
2141
|
-
</th>
|
|
2142
|
-
</tr>
|
|
2143
|
-
</thead>
|
|
2144
|
-
<tbody class="divide-y divide-gray-200">
|
|
4904
|
+
<div class="w-full text-xs">
|
|
4905
|
+
<div class="flex bg-gray-50">
|
|
4906
|
+
<div class="w-40 shrink-0 px-4 py-2 font-medium text-gray-700">Role</div>
|
|
4907
|
+
<div class="flex-1 px-4 py-2 font-medium text-gray-700">Content</div>
|
|
4908
|
+
</div>
|
|
4909
|
+
<div class="divide-y divide-gray-200">
|
|
2145
4910
|
${messages.map((msg) => {
|
|
2146
4911
|
const role = msg.role || "unknown";
|
|
2147
4912
|
const roleColors = {
|
|
@@ -2156,34 +4921,32 @@ ${prettyEvent}</pre
|
|
|
2156
4921
|
const hasContent = rawContent.trim().length > 0;
|
|
2157
4922
|
const contentFallback = toolCalls.length > 0 ? "Invoked tool call" : "—";
|
|
2158
4923
|
return lit.html`
|
|
2159
|
-
<
|
|
2160
|
-
<
|
|
4924
|
+
<div class="flex items-start">
|
|
4925
|
+
<div class="w-40 shrink-0 px-4 py-2">
|
|
2161
4926
|
<span
|
|
2162
4927
|
class="inline-flex rounded px-2 py-0.5 text-[10px] font-medium ${roleColors[role] || roleColors.unknown}"
|
|
2163
4928
|
>
|
|
2164
4929
|
${role}
|
|
2165
4930
|
</span>
|
|
2166
|
-
</
|
|
2167
|
-
<
|
|
4931
|
+
</div>
|
|
4932
|
+
<div class="flex-1 px-4 py-2">
|
|
2168
4933
|
${hasContent ? lit.html`<div
|
|
2169
|
-
class="
|
|
4934
|
+
class="whitespace-pre-line break-words text-gray-700"
|
|
2170
4935
|
>
|
|
2171
4936
|
${rawContent}
|
|
2172
|
-
</div>` : lit.html`<div
|
|
2173
|
-
class="text-xs italic text-gray-400"
|
|
2174
|
-
>
|
|
4937
|
+
</div>` : lit.html`<div class="italic text-gray-400">
|
|
2175
4938
|
${contentFallback}
|
|
2176
4939
|
</div>`}
|
|
2177
4940
|
${role === "assistant" && toolCalls.length > 0 ? this.renderToolCallDetails(toolCalls) : lit.nothing}
|
|
2178
|
-
</
|
|
2179
|
-
</
|
|
4941
|
+
</div>
|
|
4942
|
+
</div>
|
|
2180
4943
|
`;
|
|
2181
4944
|
})}
|
|
2182
|
-
</
|
|
2183
|
-
</
|
|
4945
|
+
</div>
|
|
4946
|
+
</div>
|
|
2184
4947
|
` : lit.html`
|
|
2185
4948
|
<div
|
|
2186
|
-
class="flex h-
|
|
4949
|
+
class="flex h-12 items-center justify-center text-xs text-gray-500"
|
|
2187
4950
|
>
|
|
2188
4951
|
<div class="flex items-center gap-2 text-gray-500">
|
|
2189
4952
|
<span class="text-lg text-gray-400"
|
|
@@ -2244,14 +5007,29 @@ ${prettyEvent}</pre
|
|
|
2244
5007
|
}
|
|
2245
5008
|
handleMenuSelect(key) {
|
|
2246
5009
|
if (!this.menuItems.some((item) => item.key === key)) return;
|
|
5010
|
+
const previousMenu = this.selectedMenu;
|
|
2247
5011
|
this.selectedMenu = key;
|
|
2248
5012
|
if (key === "agents" && this.selectedContext === "all-agents") {
|
|
2249
5013
|
const agentOptions = this.contextOptions.filter((opt) => opt.key !== "all-agents");
|
|
2250
5014
|
if (agentOptions.length > 0) {
|
|
2251
|
-
const
|
|
2252
|
-
|
|
5015
|
+
const mostRecent = agentOptions.reduce((best, opt) => {
|
|
5016
|
+
const ts = this.getAgentStats(opt.key).lastActivity ?? -1;
|
|
5017
|
+
return best === null || ts > best.ts ? {
|
|
5018
|
+
key: opt.key,
|
|
5019
|
+
ts
|
|
5020
|
+
} : best;
|
|
5021
|
+
}, null);
|
|
5022
|
+
this.selectedContext = mostRecent ? mostRecent.key : agentOptions[0].key;
|
|
2253
5023
|
}
|
|
2254
5024
|
}
|
|
5025
|
+
if (previousMenu === "agents" && key !== "agents") {
|
|
5026
|
+
if (this.contextOptions.filter((opt) => opt.key !== "all-agents").length > 1) this.selectedContext = "all-agents";
|
|
5027
|
+
}
|
|
5028
|
+
if (key === "threads") this.autoSelectLatestThread();
|
|
5029
|
+
if (key === "ag-ui-events" || key === "agents") requestAnimationFrame(() => {
|
|
5030
|
+
const scroller = this.shadowRoot?.getElementById("cpk-main-scroll");
|
|
5031
|
+
if (scroller) scroller.scrollTop = 0;
|
|
5032
|
+
});
|
|
2255
5033
|
this.contextMenuOpen = false;
|
|
2256
5034
|
this.persistState();
|
|
2257
5035
|
this.requestUpdate();
|
|
@@ -2639,9 +5417,19 @@ ${prettyEvent}</pre
|
|
|
2639
5417
|
<div class="mb-3">
|
|
2640
5418
|
<h5 class="mb-1 text-xs font-semibold text-gray-700">ID</h5>
|
|
2641
5419
|
<code
|
|
2642
|
-
class="
|
|
5420
|
+
class="font-mono text-xs font-medium text-gray-800 flex-1 truncate min-w-0"
|
|
2643
5421
|
>${id}</code
|
|
2644
5422
|
>
|
|
5423
|
+
<button
|
|
5424
|
+
type="button"
|
|
5425
|
+
class="cpk-copy-btn"
|
|
5426
|
+
@click=${(e) => {
|
|
5427
|
+
e.stopPropagation();
|
|
5428
|
+
this.copyContextValue(id, `${id}:id`);
|
|
5429
|
+
}}
|
|
5430
|
+
>
|
|
5431
|
+
${this.copiedContextItems.has(`${id}:id`) ? "✓" : "Copy"}
|
|
5432
|
+
</button>
|
|
2645
5433
|
</div>
|
|
2646
5434
|
${hasValue ? lit.html`
|
|
2647
5435
|
<div class="mb-2 flex items-center justify-between gap-2">
|
|
@@ -2649,8 +5437,8 @@ ${prettyEvent}</pre
|
|
|
2649
5437
|
Value
|
|
2650
5438
|
</h5>
|
|
2651
5439
|
<button
|
|
2652
|
-
class="flex items-center gap-1 rounded-md border border-gray-200 bg-white px-2 py-1 text-[10px] font-medium text-gray-700 transition hover:bg-gray-50"
|
|
2653
5440
|
type="button"
|
|
5441
|
+
class="cpk-copy-btn"
|
|
2654
5442
|
@click=${(e) => {
|
|
2655
5443
|
e.stopPropagation();
|
|
2656
5444
|
this.copyContextValue(context.value, id);
|
|
@@ -2659,13 +5447,6 @@ ${prettyEvent}</pre
|
|
|
2659
5447
|
${this.copiedContextItems.has(id) ? "Copied" : "Copy JSON"}
|
|
2660
5448
|
</button>
|
|
2661
5449
|
</div>
|
|
2662
|
-
<div
|
|
2663
|
-
class="rounded-md border border-gray-200 bg-white p-3"
|
|
2664
|
-
>
|
|
2665
|
-
<pre
|
|
2666
|
-
class="overflow-auto text-xs text-gray-800 max-h-96"
|
|
2667
|
-
><code>${this.formatContextValue(context.value)}</code></pre>
|
|
2668
|
-
</div>
|
|
2669
5450
|
` : lit.html`
|
|
2670
5451
|
<div class="flex items-center justify-center py-4 text-xs text-gray-500">
|
|
2671
5452
|
<span>No value available</span>
|
|
@@ -2678,7 +5459,7 @@ ${prettyEvent}</pre
|
|
|
2678
5459
|
}
|
|
2679
5460
|
getContextValuePreview(value) {
|
|
2680
5461
|
if (value === void 0 || value === null) return "—";
|
|
2681
|
-
if (typeof value === "string") return value.length > 50 ? `${value.
|
|
5462
|
+
if (typeof value === "string") return value.length > 50 ? `${value.slice(0, 50)}...` : value;
|
|
2682
5463
|
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
2683
5464
|
if (Array.isArray(value)) return `Array(${value.length})`;
|
|
2684
5465
|
if (typeof value === "object") {
|
|
@@ -2728,50 +5509,25 @@ ${prettyEvent}</pre
|
|
|
2728
5509
|
else this.expandedRows.add(eventId);
|
|
2729
5510
|
this.requestUpdate();
|
|
2730
5511
|
}
|
|
2731
|
-
|
|
2732
|
-
if (!this.isOpen) return lit.nothing;
|
|
2733
|
-
this.ensureAnnouncementLoading();
|
|
5512
|
+
renderAnnouncementBanner() {
|
|
2734
5513
|
if (!this.hasUnseenAnnouncement) return lit.nothing;
|
|
2735
|
-
if (!this.announcementLoaded && !this.
|
|
2736
|
-
class="
|
|
2737
|
-
>
|
|
2738
|
-
<div class="flex items-center gap-2 font-semibold">
|
|
2739
|
-
<span
|
|
2740
|
-
class="inline-flex h-6 w-6 items-center justify-center rounded-md bg-slate-900 text-white shadow-sm"
|
|
2741
|
-
>
|
|
2742
|
-
${this.renderIcon("Megaphone")}
|
|
2743
|
-
</span>
|
|
2744
|
-
<span>Loading latest announcement…</span>
|
|
2745
|
-
</div>
|
|
2746
|
-
</div>`;
|
|
2747
|
-
if (this.announcementLoadError) return lit.html`<div
|
|
2748
|
-
class="mx-4 my-3 rounded-xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-900 shadow-[0_12px_30px_rgba(15,23,42,0.12)]"
|
|
5514
|
+
if (!this.announcementLoaded && !this.announcementHtml) return lit.html`<div
|
|
5515
|
+
class="flex items-center gap-2 px-4 py-3 text-sm font-semibold text-slate-800"
|
|
2749
5516
|
>
|
|
2750
|
-
<
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
<span>Announcement unavailable</span>
|
|
2757
|
-
</div>
|
|
2758
|
-
<p class="mt-2 text-xs text-rose-800">
|
|
2759
|
-
We couldn’t load the latest notice. Please try opening the inspector
|
|
2760
|
-
again.
|
|
2761
|
-
</p>
|
|
5517
|
+
<span
|
|
5518
|
+
class="inline-flex h-6 w-6 items-center justify-center rounded-md bg-slate-900 text-white shadow-sm"
|
|
5519
|
+
>
|
|
5520
|
+
${this.renderIcon("Megaphone")}
|
|
5521
|
+
</span>
|
|
5522
|
+
<span>Loading latest announcement…</span>
|
|
2762
5523
|
</div>`;
|
|
2763
|
-
if (!this.
|
|
2764
|
-
|
|
2765
|
-
${this.announcementMarkdown}</pre
|
|
2766
|
-
>`;
|
|
2767
|
-
return lit.html`<div
|
|
2768
|
-
class="mx-4 my-3 rounded-xl border border-slate-200 bg-white px-4 py-4 shadow-[0_12px_30px_rgba(15,23,42,0.12)]"
|
|
2769
|
-
>
|
|
5524
|
+
if (!this.announcementHtml) return lit.nothing;
|
|
5525
|
+
return lit.html`<div class="mx-4 mb-3 rounded-xl border border-slate-200 bg-white px-4 py-3">
|
|
2770
5526
|
<div
|
|
2771
|
-
class="mb-
|
|
5527
|
+
class="mb-2 flex items-center gap-2 text-xs font-semibold text-slate-900"
|
|
2772
5528
|
>
|
|
2773
5529
|
<span
|
|
2774
|
-
class="inline-flex h-
|
|
5530
|
+
class="inline-flex h-5 w-5 items-center justify-center rounded-md bg-slate-900 text-white shadow-sm"
|
|
2775
5531
|
>
|
|
2776
5532
|
${this.renderIcon("Megaphone")}
|
|
2777
5533
|
</span>
|
|
@@ -2782,12 +5538,27 @@ ${this.announcementMarkdown}</pre
|
|
|
2782
5538
|
@click=${this.handleDismissAnnouncement}
|
|
2783
5539
|
aria-label="Dismiss announcement"
|
|
2784
5540
|
>
|
|
2785
|
-
|
|
5541
|
+
${this.renderIcon("X")}
|
|
2786
5542
|
</button>
|
|
2787
5543
|
</div>
|
|
2788
|
-
<div class="announcement-
|
|
2789
|
-
|
|
5544
|
+
<div class="announcement-body ${this.announcementExpanded ? "announcement-body--expanded" : "announcement-body--collapsed"}">
|
|
5545
|
+
<div class="announcement-content">
|
|
5546
|
+
${(0, lit_directives_unsafe_html_js.unsafeHTML)(this.announcementHtml)}
|
|
5547
|
+
</div>
|
|
5548
|
+
${!this.announcementExpanded ? lit.html`
|
|
5549
|
+
<div class="announcement-fade"></div>
|
|
5550
|
+
` : lit.nothing}
|
|
2790
5551
|
</div>
|
|
5552
|
+
<button
|
|
5553
|
+
class="announcement-toggle"
|
|
5554
|
+
type="button"
|
|
5555
|
+
@click=${() => {
|
|
5556
|
+
this.announcementExpanded = !this.announcementExpanded;
|
|
5557
|
+
this.requestUpdate();
|
|
5558
|
+
}}
|
|
5559
|
+
>
|
|
5560
|
+
${this.announcementExpanded ? "Show less ↑" : "Show more ↓"}
|
|
5561
|
+
</button>
|
|
2791
5562
|
</div>`;
|
|
2792
5563
|
}
|
|
2793
5564
|
ensureAnnouncementLoading() {
|
|
@@ -2822,14 +5593,13 @@ ${this.announcementMarkdown}</pre
|
|
|
2822
5593
|
const storedTimestamp = this.loadStoredAnnouncementTimestamp();
|
|
2823
5594
|
this.announcementTimestamp = timestamp;
|
|
2824
5595
|
this.announcementPreviewText = previewText ?? "";
|
|
2825
|
-
this.announcementMarkdown = markdown;
|
|
2826
5596
|
this.hasUnseenAnnouncement = (!storedTimestamp || storedTimestamp !== timestamp) && !!this.announcementPreviewText;
|
|
2827
5597
|
this.showAnnouncementPreview = this.hasUnseenAnnouncement;
|
|
2828
5598
|
this.announcementHtml = await this.convertMarkdownToHtml(markdown);
|
|
2829
5599
|
this.announcementLoaded = true;
|
|
2830
5600
|
this.requestUpdate();
|
|
2831
5601
|
} catch (error) {
|
|
2832
|
-
|
|
5602
|
+
console.warn("[CopilotKit Inspector] Failed to load announcement", error);
|
|
2833
5603
|
this.announcementLoaded = true;
|
|
2834
5604
|
this.requestUpdate();
|
|
2835
5605
|
}
|
|
@@ -2892,4 +5662,5 @@ defineWebInspector();
|
|
|
2892
5662
|
exports.WEB_INSPECTOR_TAG = WEB_INSPECTOR_TAG;
|
|
2893
5663
|
exports.WebInspectorElement = WebInspectorElement;
|
|
2894
5664
|
exports.defineWebInspector = defineWebInspector;
|
|
5665
|
+
exports.ɵCpkThreadDetails = ɵCpkThreadDetails;
|
|
2895
5666
|
//# sourceMappingURL=index.cjs.map
|