@copilotkit/web-inspector 1.56.5 → 1.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2763 -199
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +265 -10
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +265 -10
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2764 -201
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +2801 -211
- 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 +2 -2
- package/src/__tests__/web-inspector.spec.ts +179 -1
- package/src/index.ts +3474 -300
- 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 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,20 @@ 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;
|
|
99
1871
|
this.announcementHtml = null;
|
|
100
1872
|
this.announcementTimestamp = null;
|
|
101
1873
|
this.announcementPreviewText = null;
|
|
102
1874
|
this.hasUnseenAnnouncement = false;
|
|
103
1875
|
this.announcementLoaded = false;
|
|
104
|
-
this.announcementLoadError = null;
|
|
105
1876
|
this.announcementPromise = null;
|
|
106
1877
|
this.showAnnouncementPreview = true;
|
|
1878
|
+
this.announcementExpanded = false;
|
|
107
1879
|
this.contextState = {
|
|
108
1880
|
button: {
|
|
109
1881
|
position: {
|
|
@@ -144,28 +1916,7 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
144
1916
|
this.resizeStart = null;
|
|
145
1917
|
this.resizeInitialSize = null;
|
|
146
1918
|
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
|
-
];
|
|
1919
|
+
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
1920
|
this.handlePointerDown = (event) => {
|
|
170
1921
|
if (this.dockMode !== "floating" && this.isOpen) return;
|
|
171
1922
|
const target = event.currentTarget;
|
|
@@ -330,6 +2081,26 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
330
2081
|
this.expandedTools = /* @__PURE__ */ new Set();
|
|
331
2082
|
this.expandedContextItems = /* @__PURE__ */ new Set();
|
|
332
2083
|
this.copiedContextItems = /* @__PURE__ */ new Set();
|
|
2084
|
+
this.handleThreadDividerPointerDown = (event) => {
|
|
2085
|
+
this.threadDividerResizing = true;
|
|
2086
|
+
this.threadDividerPointerId = event.pointerId;
|
|
2087
|
+
this.threadDividerStartX = event.clientX;
|
|
2088
|
+
this.threadDividerStartWidth = this.threadListWidth;
|
|
2089
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
2090
|
+
event.preventDefault();
|
|
2091
|
+
};
|
|
2092
|
+
this.handleThreadDividerPointerMove = (event) => {
|
|
2093
|
+
if (!this.threadDividerResizing || this.threadDividerPointerId !== event.pointerId) return;
|
|
2094
|
+
const delta = event.clientX - this.threadDividerStartX;
|
|
2095
|
+
this.threadListWidth = Math.max(180, Math.min(480, this.threadDividerStartWidth + delta));
|
|
2096
|
+
this.requestUpdate();
|
|
2097
|
+
};
|
|
2098
|
+
this.handleThreadDividerPointerUp = (event) => {
|
|
2099
|
+
if (this.threadDividerPointerId !== event.pointerId) return;
|
|
2100
|
+
const target = event.currentTarget;
|
|
2101
|
+
if (target.hasPointerCapture(this.threadDividerPointerId)) target.releasePointerCapture(this.threadDividerPointerId);
|
|
2102
|
+
this.threadDividerResizing = false;
|
|
2103
|
+
};
|
|
333
2104
|
this.handleClearEvents = () => {
|
|
334
2105
|
if (this.selectedContext === "all-agents") {
|
|
335
2106
|
this.agentEvents.clear();
|
|
@@ -354,6 +2125,31 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
354
2125
|
this.handleDismissAnnouncement = () => {
|
|
355
2126
|
this.markAnnouncementSeen();
|
|
356
2127
|
};
|
|
2128
|
+
this.copyResetTimeouts = /* @__PURE__ */ new WeakMap();
|
|
2129
|
+
this.handleAnnouncementContentClick = (event) => {
|
|
2130
|
+
const button = (event.target instanceof HTMLElement ? event.target : null)?.closest(".announcement-code__copy");
|
|
2131
|
+
if (!(button instanceof HTMLButtonElement)) return;
|
|
2132
|
+
event.preventDefault();
|
|
2133
|
+
event.stopPropagation();
|
|
2134
|
+
const encoded = button.getAttribute("data-copy") ?? "";
|
|
2135
|
+
const code = this.decodeBase64(encoded);
|
|
2136
|
+
if (!code) return;
|
|
2137
|
+
const showCopied = () => {
|
|
2138
|
+
const existing = this.copyResetTimeouts.get(button);
|
|
2139
|
+
if (existing !== void 0) window.clearTimeout(existing);
|
|
2140
|
+
button.setAttribute("data-copied", "true");
|
|
2141
|
+
button.setAttribute("aria-label", "Code copied");
|
|
2142
|
+
button.textContent = "Copied";
|
|
2143
|
+
const id = window.setTimeout(() => {
|
|
2144
|
+
button.removeAttribute("data-copied");
|
|
2145
|
+
button.setAttribute("aria-label", "Copy code");
|
|
2146
|
+
button.textContent = "Copy";
|
|
2147
|
+
this.copyResetTimeouts.delete(button);
|
|
2148
|
+
}, 1500);
|
|
2149
|
+
this.copyResetTimeouts.set(button, id);
|
|
2150
|
+
};
|
|
2151
|
+
if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) navigator.clipboard.writeText(code).then(showCopied, () => {});
|
|
2152
|
+
};
|
|
357
2153
|
}
|
|
358
2154
|
static {
|
|
359
2155
|
this.properties = {
|
|
@@ -375,6 +2171,106 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
375
2171
|
this.requestUpdate("core", oldValue);
|
|
376
2172
|
if (this._core) this.attachToCore(this._core);
|
|
377
2173
|
}
|
|
2174
|
+
get menuItems() {
|
|
2175
|
+
return [
|
|
2176
|
+
{
|
|
2177
|
+
key: "ag-ui-events",
|
|
2178
|
+
label: "AG-UI Events",
|
|
2179
|
+
icon: "Zap"
|
|
2180
|
+
},
|
|
2181
|
+
{
|
|
2182
|
+
key: "agents",
|
|
2183
|
+
label: "Agent",
|
|
2184
|
+
icon: "Bot"
|
|
2185
|
+
},
|
|
2186
|
+
...(this._core?.tools?.length ?? 0) > 0 ? [{
|
|
2187
|
+
key: "frontend-tools",
|
|
2188
|
+
label: "Frontend Tools",
|
|
2189
|
+
icon: "Hammer"
|
|
2190
|
+
}] : [],
|
|
2191
|
+
{
|
|
2192
|
+
key: "agent-context",
|
|
2193
|
+
label: "Context",
|
|
2194
|
+
icon: "FileText"
|
|
2195
|
+
},
|
|
2196
|
+
{
|
|
2197
|
+
key: "threads",
|
|
2198
|
+
label: "Threads",
|
|
2199
|
+
icon: "MessageSquare"
|
|
2200
|
+
}
|
|
2201
|
+
];
|
|
2202
|
+
}
|
|
2203
|
+
subscribeToThreadStore(agentId, store) {
|
|
2204
|
+
if (this._threadStoreSubscriptions.has(agentId)) return;
|
|
2205
|
+
const threadsSub = store.select(_copilotkit_core.ɵselectThreads).subscribe((threads) => {
|
|
2206
|
+
this._threadsByAgent.set(agentId, threads);
|
|
2207
|
+
this._threads = Array.from(this._threadsByAgent.values()).flat();
|
|
2208
|
+
this.autoSelectLatestThread();
|
|
2209
|
+
this.requestUpdate();
|
|
2210
|
+
});
|
|
2211
|
+
const errorSub = store.select(_copilotkit_core.ɵselectThreadsError).subscribe((error) => {
|
|
2212
|
+
if (error) this._threadsErrorByAgent.set(agentId, error);
|
|
2213
|
+
else this._threadsErrorByAgent.delete(agentId);
|
|
2214
|
+
this.requestUpdate();
|
|
2215
|
+
});
|
|
2216
|
+
this._threadStoreSubscriptions.set(agentId, () => {
|
|
2217
|
+
threadsSub.unsubscribe();
|
|
2218
|
+
errorSub.unsubscribe();
|
|
2219
|
+
});
|
|
2220
|
+
const initialState = store.getState();
|
|
2221
|
+
this._threadsByAgent.set(agentId, (0, _copilotkit_core.ɵselectThreads)(initialState));
|
|
2222
|
+
const initialError = (0, _copilotkit_core.ɵselectThreadsError)(initialState);
|
|
2223
|
+
if (initialError) this._threadsErrorByAgent.set(agentId, initialError);
|
|
2224
|
+
else this._threadsErrorByAgent.delete(agentId);
|
|
2225
|
+
this._threads = Array.from(this._threadsByAgent.values()).flat();
|
|
2226
|
+
this.autoSelectLatestThread();
|
|
2227
|
+
}
|
|
2228
|
+
autoSelectLatestThread() {
|
|
2229
|
+
if (this._threads.length === 0) return;
|
|
2230
|
+
if (!(this.selectedThreadId != null && this._threads.some((t) => t.id === this.selectedThreadId))) this.selectedThreadId = this._threads[0].id;
|
|
2231
|
+
}
|
|
2232
|
+
teardownThreadStoreSubscriptions() {
|
|
2233
|
+
for (const unsub of this._threadStoreSubscriptions.values()) unsub();
|
|
2234
|
+
this._threadStoreSubscriptions.clear();
|
|
2235
|
+
this._threadsByAgent.clear();
|
|
2236
|
+
this._threadsErrorByAgent.clear();
|
|
2237
|
+
this._threads = [];
|
|
2238
|
+
}
|
|
2239
|
+
ensureOwnedThreadStore(agentId) {
|
|
2240
|
+
if (this._ownedThreadStores.has(agentId)) return;
|
|
2241
|
+
if (this.core?.getThreadStore(agentId)) return;
|
|
2242
|
+
const core = this.core;
|
|
2243
|
+
if (!core?.runtimeUrl) return;
|
|
2244
|
+
const store = (0, _copilotkit_core.ɵcreateThreadStore)({ fetch: globalThis.fetch });
|
|
2245
|
+
store.start();
|
|
2246
|
+
store.setContext({
|
|
2247
|
+
runtimeUrl: core.runtimeUrl,
|
|
2248
|
+
headers: {},
|
|
2249
|
+
agentId
|
|
2250
|
+
});
|
|
2251
|
+
this._ownedThreadStores.set(agentId, store);
|
|
2252
|
+
this.subscribeToThreadStore(agentId, store);
|
|
2253
|
+
core.registerThreadStore(agentId, store);
|
|
2254
|
+
}
|
|
2255
|
+
refreshOwnedThreadStore(agentId) {
|
|
2256
|
+
const store = this._ownedThreadStores.get(agentId);
|
|
2257
|
+
if (!store) return;
|
|
2258
|
+
store.refresh();
|
|
2259
|
+
}
|
|
2260
|
+
removeOwnedThreadStore(agentId) {
|
|
2261
|
+
const store = this._ownedThreadStores.get(agentId);
|
|
2262
|
+
if (!store) return;
|
|
2263
|
+
store.stop();
|
|
2264
|
+
this.core?.unregisterThreadStore(agentId);
|
|
2265
|
+
this._ownedThreadStores.delete(agentId);
|
|
2266
|
+
}
|
|
2267
|
+
teardownOwnedThreadStores() {
|
|
2268
|
+
for (const [agentId, store] of this._ownedThreadStores) {
|
|
2269
|
+
store.stop();
|
|
2270
|
+
this.core?.unregisterThreadStore(agentId);
|
|
2271
|
+
}
|
|
2272
|
+
this._ownedThreadStores.clear();
|
|
2273
|
+
}
|
|
378
2274
|
attachToCore(core) {
|
|
379
2275
|
this.runtimeStatus = core.runtimeConnectionStatus;
|
|
380
2276
|
this.coreProperties = core.properties;
|
|
@@ -382,6 +2278,11 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
382
2278
|
this.coreSubscriber = {
|
|
383
2279
|
onRuntimeConnectionStatusChanged: ({ status }) => {
|
|
384
2280
|
this.runtimeStatus = status;
|
|
2281
|
+
if (status === "connected") for (const agentId of this._ownedThreadStores.keys()) this.refreshOwnedThreadStore(agentId);
|
|
2282
|
+
else {
|
|
2283
|
+
this._threadsByAgent.clear();
|
|
2284
|
+
this._threads = [];
|
|
2285
|
+
}
|
|
385
2286
|
this.requestUpdate();
|
|
386
2287
|
},
|
|
387
2288
|
onPropertiesChanged: ({ properties }) => {
|
|
@@ -398,16 +2299,36 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
398
2299
|
onAgentsChanged: ({ agents }) => {
|
|
399
2300
|
this.processAgentsChanged(agents);
|
|
400
2301
|
},
|
|
2302
|
+
onContextChanged: ({ context }) => {
|
|
2303
|
+
this.contextStore = this.normalizeContextStore(context);
|
|
2304
|
+
this.requestUpdate();
|
|
2305
|
+
},
|
|
2306
|
+
onThreadStoreRegistered: ({ agentId, store }) => {
|
|
2307
|
+
this.subscribeToThreadStore(agentId, store);
|
|
2308
|
+
this.requestUpdate();
|
|
2309
|
+
},
|
|
2310
|
+
onThreadStoreUnregistered: ({ agentId }) => {
|
|
2311
|
+
const unsub = this._threadStoreSubscriptions.get(agentId);
|
|
2312
|
+
if (unsub) {
|
|
2313
|
+
unsub();
|
|
2314
|
+
this._threadStoreSubscriptions.delete(agentId);
|
|
2315
|
+
}
|
|
2316
|
+
this._threadsByAgent.delete(agentId);
|
|
2317
|
+
this._threadsErrorByAgent.delete(agentId);
|
|
2318
|
+
this._threads = Array.from(this._threadsByAgent.values()).flat();
|
|
2319
|
+
this.requestUpdate();
|
|
2320
|
+
},
|
|
401
2321
|
onAgentRunStarted: ({ agent }) => {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
this.contextStore = this.normalizeContextStore(context);
|
|
2322
|
+
this.subscribeToAgent(agent);
|
|
2323
|
+
const runThreadId = agent.threadId;
|
|
2324
|
+
if (agent.agentId && runThreadId) this.agentRunThreadId.set(agent.agentId, runThreadId);
|
|
406
2325
|
this.requestUpdate();
|
|
407
2326
|
}
|
|
408
2327
|
};
|
|
409
2328
|
this.coreUnsubscribe = core.subscribe(this.coreSubscriber).unsubscribe;
|
|
410
2329
|
this.processAgentsChanged(core.agents);
|
|
2330
|
+
const threadStores = typeof core.getThreadStores === "function" ? core.getThreadStores() : {};
|
|
2331
|
+
for (const [agentId, store] of Object.entries(threadStores)) this.subscribeToThreadStore(agentId, store);
|
|
411
2332
|
if (core.context) this.contextStore = this.normalizeContextStore(core.context);
|
|
412
2333
|
}
|
|
413
2334
|
detachFromCore() {
|
|
@@ -422,6 +2343,8 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
422
2343
|
this.cachedTools = [];
|
|
423
2344
|
this.toolSignature = "";
|
|
424
2345
|
this.teardownAgentSubscriptions();
|
|
2346
|
+
this.teardownThreadStoreSubscriptions();
|
|
2347
|
+
this.teardownOwnedThreadStores();
|
|
425
2348
|
}
|
|
426
2349
|
teardownAgentSubscriptions() {
|
|
427
2350
|
for (const unsubscribe of this.agentSubscriptions.values()) unsubscribe();
|
|
@@ -438,6 +2361,7 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
438
2361
|
if (!agent?.agentId) continue;
|
|
439
2362
|
seenAgentIds.add(agent.agentId);
|
|
440
2363
|
this.subscribeToAgent(agent);
|
|
2364
|
+
this.ensureOwnedThreadStore(agent.agentId);
|
|
441
2365
|
}
|
|
442
2366
|
for (const agentId of Array.from(this.agentSubscriptions.keys())) if (!seenAgentIds.has(agentId)) {
|
|
443
2367
|
this.unsubscribeFromAgent(agentId);
|
|
@@ -496,6 +2420,7 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
496
2420
|
event,
|
|
497
2421
|
result
|
|
498
2422
|
});
|
|
2423
|
+
this.refreshOwnedThreadStore(agentId);
|
|
499
2424
|
},
|
|
500
2425
|
onRunErrorEvent: ({ event }) => {
|
|
501
2426
|
this.recordAgentEvent(agentId, "RUN_ERROR", event);
|
|
@@ -583,6 +2508,14 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
583
2508
|
},
|
|
584
2509
|
onReasoningEncryptedValueEvent: ({ event }) => {
|
|
585
2510
|
this.recordAgentEvent(agentId, "REASONING_ENCRYPTED_VALUE", event);
|
|
2511
|
+
},
|
|
2512
|
+
onActivitySnapshotEvent: ({ event }) => {
|
|
2513
|
+
this.recordAgentEvent(agentId, "ACTIVITY_SNAPSHOT", event);
|
|
2514
|
+
this.syncAgentMessages(agent);
|
|
2515
|
+
},
|
|
2516
|
+
onActivityDeltaEvent: ({ event }) => {
|
|
2517
|
+
this.recordAgentEvent(agentId, "ACTIVITY_DELTA", event);
|
|
2518
|
+
this.syncAgentMessages(agent);
|
|
586
2519
|
}
|
|
587
2520
|
});
|
|
588
2521
|
this.agentSubscriptions.set(agentId, unsubscribe);
|
|
@@ -597,6 +2530,15 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
597
2530
|
this.agentSubscriptions.delete(agentId);
|
|
598
2531
|
}
|
|
599
2532
|
}
|
|
2533
|
+
mapMessagesToConversation(messages) {
|
|
2534
|
+
if (!messages) return null;
|
|
2535
|
+
return messages.filter((m) => m.role === "user" || m.role === "assistant" || m.role === "activity").map((m, i) => ({
|
|
2536
|
+
id: m.id ?? `msg-${i}`,
|
|
2537
|
+
type: m.role === "user" ? "user" : m.role === "activity" ? "generative-ui" : "assistant",
|
|
2538
|
+
content: m.role === "activity" ? m.activityType ?? "unknown" : m.contentText,
|
|
2539
|
+
createdAt: ""
|
|
2540
|
+
}));
|
|
2541
|
+
}
|
|
600
2542
|
recordAgentEvent(agentId, type, payload) {
|
|
601
2543
|
const eventId = `${agentId}:${++this.eventCounter}`;
|
|
602
2544
|
const normalizedPayload = this.normalizeEventPayload(type, payload);
|
|
@@ -619,6 +2561,8 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
619
2561
|
const messages = this.normalizeAgentMessages(agent.messages);
|
|
620
2562
|
if (messages) this.agentMessages.set(agent.agentId, messages);
|
|
621
2563
|
else this.agentMessages.delete(agent.agentId);
|
|
2564
|
+
const runThreadId = this.agentRunThreadId.get(agent.agentId);
|
|
2565
|
+
if (runThreadId) this.liveMessageVersion.set(runThreadId, (this.liveMessageVersion.get(runThreadId) ?? 0) + 1);
|
|
622
2566
|
this.requestUpdate();
|
|
623
2567
|
} catch (error) {
|
|
624
2568
|
console.error(`[CopilotKit Inspector] Failed to sync messages for agent "${agent.agentId}":`, error);
|
|
@@ -646,18 +2590,23 @@ var WebInspectorElement = class extends lit.LitElement {
|
|
|
646
2590
|
if (this.contextOptions.length !== nextOptions.length || this.contextOptions.some((option, index) => option.key !== nextOptions[index]?.key)) this.contextOptions = nextOptions;
|
|
647
2591
|
const pendingContext = this.pendingSelectedContext;
|
|
648
2592
|
if (pendingContext) {
|
|
649
|
-
if (pendingContext === "all-agents" || agentIds.has(pendingContext)) {
|
|
2593
|
+
if ((pendingContext === "all-agents" || agentIds.has(pendingContext)) && (pendingContext === "all-agents" || agentIds.size === 1)) {
|
|
650
2594
|
if (this.selectedContext !== pendingContext) {
|
|
651
2595
|
this.selectedContext = pendingContext;
|
|
652
2596
|
this.expandedRows.clear();
|
|
653
2597
|
}
|
|
654
2598
|
this.pendingSelectedContext = null;
|
|
655
|
-
} else if (agentIds.size > 0)
|
|
2599
|
+
} else if (agentIds.size > 0) {
|
|
2600
|
+
if (this.selectedContext !== "all-agents") {
|
|
2601
|
+
this.selectedContext = "all-agents";
|
|
2602
|
+
this.expandedRows.clear();
|
|
2603
|
+
}
|
|
2604
|
+
this.pendingSelectedContext = null;
|
|
2605
|
+
}
|
|
656
2606
|
}
|
|
657
2607
|
if (!nextOptions.some((option) => option.key === this.selectedContext) && this.pendingSelectedContext === null) {
|
|
658
2608
|
let nextSelected = "all-agents";
|
|
659
|
-
if (agentIds.
|
|
660
|
-
else if (agentIds.size > 0) nextSelected = Array.from(agentIds).sort((a, b) => a.localeCompare(b))[0];
|
|
2609
|
+
if (agentIds.size === 1) nextSelected = Array.from(agentIds)[0];
|
|
661
2610
|
if (this.selectedContext !== nextSelected) {
|
|
662
2611
|
this.selectedContext = nextSelected;
|
|
663
2612
|
this.expandedRows.clear();
|
|
@@ -832,6 +2781,7 @@ ${argsString}</pre
|
|
|
832
2781
|
z-index: 2147483646;
|
|
833
2782
|
display: block;
|
|
834
2783
|
will-change: transform;
|
|
2784
|
+
font-family: "Plus Jakarta Sans", system-ui, sans-serif;
|
|
835
2785
|
}
|
|
836
2786
|
|
|
837
2787
|
:host([data-transitioning="true"]) {
|
|
@@ -887,13 +2837,14 @@ ${argsString}</pre
|
|
|
887
2837
|
left: 50%;
|
|
888
2838
|
transform: translateX(-50%) translateY(-4px);
|
|
889
2839
|
white-space: nowrap;
|
|
890
|
-
background: rgba(
|
|
2840
|
+
background: rgba(1, 5, 7, 0.95);
|
|
891
2841
|
color: white;
|
|
892
2842
|
padding: 4px 8px;
|
|
893
2843
|
border-radius: 6px;
|
|
894
2844
|
font-size: 10px;
|
|
2845
|
+
font-family: "Plus Jakarta Sans", system-ui, sans-serif;
|
|
895
2846
|
line-height: 1.2;
|
|
896
|
-
box-shadow: 0 4px 10px rgba(
|
|
2847
|
+
box-shadow: 0 4px 10px rgba(1, 5, 7, 0.18);
|
|
897
2848
|
opacity: 0;
|
|
898
2849
|
pointer-events: none;
|
|
899
2850
|
transition:
|
|
@@ -914,18 +2865,19 @@ ${argsString}</pre
|
|
|
914
2865
|
min-width: 300px;
|
|
915
2866
|
max-width: 300px;
|
|
916
2867
|
background: white;
|
|
917
|
-
color: #
|
|
2868
|
+
color: #010507;
|
|
918
2869
|
font-size: 13px;
|
|
2870
|
+
font-family: "Plus Jakarta Sans", system-ui, sans-serif;
|
|
919
2871
|
line-height: 1.4;
|
|
920
2872
|
border-radius: 12px;
|
|
921
|
-
box-shadow: 0 12px 28px rgba(
|
|
2873
|
+
box-shadow: 0 12px 28px rgba(1, 5, 7, 0.12);
|
|
922
2874
|
padding: 10px 12px;
|
|
923
2875
|
display: inline-flex;
|
|
924
2876
|
align-items: flex-start;
|
|
925
2877
|
gap: 8px;
|
|
926
2878
|
z-index: 4500;
|
|
927
2879
|
animation: fade-slide-in 160ms ease;
|
|
928
|
-
border: 1px solid rgba(
|
|
2880
|
+
border: 1px solid rgba(219, 219, 229, 0.4);
|
|
929
2881
|
white-space: normal;
|
|
930
2882
|
word-break: break-word;
|
|
931
2883
|
text-align: left;
|
|
@@ -946,7 +2898,7 @@ ${argsString}</pre
|
|
|
946
2898
|
width: 10px;
|
|
947
2899
|
height: 10px;
|
|
948
2900
|
background: white;
|
|
949
|
-
border: 1px solid rgba(
|
|
2901
|
+
border: 1px solid rgba(219, 219, 229, 0.4);
|
|
950
2902
|
transform: rotate(45deg);
|
|
951
2903
|
top: 50%;
|
|
952
2904
|
margin-top: -5px;
|
|
@@ -955,81 +2907,564 @@ ${argsString}</pre
|
|
|
955
2907
|
|
|
956
2908
|
.announcement-preview[data-side="left"] .announcement-preview__arrow {
|
|
957
2909
|
right: -5px;
|
|
958
|
-
box-shadow: 6px -6px 10px rgba(
|
|
2910
|
+
box-shadow: 6px -6px 10px rgba(1, 5, 7, 0.08);
|
|
959
2911
|
}
|
|
960
2912
|
|
|
961
2913
|
.announcement-preview[data-side="right"] .announcement-preview__arrow {
|
|
962
2914
|
left: -5px;
|
|
963
|
-
box-shadow: -6px 6px 10px rgba(
|
|
2915
|
+
box-shadow: -6px 6px 10px rgba(1, 5, 7, 0.08);
|
|
964
2916
|
}
|
|
965
2917
|
|
|
966
2918
|
.announcement-dismiss {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
2919
|
+
background: none;
|
|
2920
|
+
border: none;
|
|
2921
|
+
cursor: pointer;
|
|
2922
|
+
color: #838389;
|
|
2923
|
+
width: 28px;
|
|
2924
|
+
height: 28px;
|
|
2925
|
+
display: flex;
|
|
2926
|
+
align-items: center;
|
|
2927
|
+
justify-content: center;
|
|
2928
|
+
border-radius: 6px;
|
|
2929
|
+
padding: 0;
|
|
973
2930
|
transition:
|
|
974
2931
|
background 120ms ease,
|
|
975
2932
|
color 120ms ease;
|
|
976
2933
|
}
|
|
977
2934
|
|
|
978
2935
|
.announcement-dismiss:hover {
|
|
979
|
-
background: rgba(
|
|
980
|
-
color: #
|
|
2936
|
+
background: rgba(0, 0, 0, 0.06);
|
|
2937
|
+
color: #010507;
|
|
2938
|
+
}
|
|
2939
|
+
|
|
2940
|
+
/* ── Agent tab section cards ─────────────────────────────────────── */
|
|
2941
|
+
.cpk-section-card {
|
|
2942
|
+
border-radius: 8px;
|
|
2943
|
+
background: #ffffff;
|
|
2944
|
+
overflow: hidden;
|
|
2945
|
+
}
|
|
2946
|
+
|
|
2947
|
+
/* ── Agent icon bubble ───────────────────────────────────────────── */
|
|
2948
|
+
.cpk-agent-icon {
|
|
2949
|
+
background-color: #f0f0f4 !important;
|
|
2950
|
+
color: #57575b !important;
|
|
2951
|
+
}
|
|
2952
|
+
|
|
2953
|
+
/* ── Agent stat cards ────────────────────────────────────────────── */
|
|
2954
|
+
.cpk-stat-card {
|
|
2955
|
+
background-color: #ffffff !important;
|
|
2956
|
+
border: 1px solid #dbdbe5 !important;
|
|
2957
|
+
}
|
|
2958
|
+
button.cpk-stat-card:hover {
|
|
2959
|
+
background-color: #f7f7f9 !important;
|
|
2960
|
+
}
|
|
2961
|
+
|
|
2962
|
+
/* ── Circle chevron (Frontend Tools + Context) ──────────────────── */
|
|
2963
|
+
.cpk-chevron-circle {
|
|
2964
|
+
display: inline-flex;
|
|
2965
|
+
align-items: center;
|
|
2966
|
+
justify-content: center;
|
|
2967
|
+
width: 24px;
|
|
2968
|
+
height: 24px;
|
|
2969
|
+
border-radius: 50%;
|
|
2970
|
+
background-color: #f0f0f4;
|
|
2971
|
+
color: #838389;
|
|
2972
|
+
flex-shrink: 0;
|
|
2973
|
+
transition: transform 0.2s;
|
|
2974
|
+
}
|
|
2975
|
+
.cpk-chevron-circle svg {
|
|
2976
|
+
width: 14px !important;
|
|
2977
|
+
height: 14px !important;
|
|
2978
|
+
}
|
|
2979
|
+
.cpk-chevron-circle--open {
|
|
2980
|
+
transform: rotate(180deg);
|
|
2981
|
+
}
|
|
2982
|
+
|
|
2983
|
+
/* ── Inline copy button ─────────────────────────────────────────── */
|
|
2984
|
+
.cpk-copy-btn {
|
|
2985
|
+
font-size: 10px;
|
|
2986
|
+
font-weight: 500;
|
|
2987
|
+
color: #57575b;
|
|
2988
|
+
background: #ffffff;
|
|
2989
|
+
border: 1px solid #dbdbe5;
|
|
2990
|
+
cursor: pointer;
|
|
2991
|
+
padding: 2px 8px;
|
|
2992
|
+
border-radius: 4px;
|
|
2993
|
+
flex-shrink: 0;
|
|
2994
|
+
transition:
|
|
2995
|
+
background-color 0.15s,
|
|
2996
|
+
border-color 0.15s;
|
|
2997
|
+
}
|
|
2998
|
+
.cpk-copy-btn:hover {
|
|
2999
|
+
background-color: #f0f0f4;
|
|
3000
|
+
border-color: #afafb7;
|
|
3001
|
+
}
|
|
3002
|
+
|
|
3003
|
+
.cpk-section-header {
|
|
3004
|
+
background: #e8edf5;
|
|
3005
|
+
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
|
3006
|
+
padding: 10px 16px;
|
|
3007
|
+
}
|
|
3008
|
+
.cpk-section-header h4 {
|
|
3009
|
+
font-size: 11px;
|
|
3010
|
+
font-weight: 600;
|
|
3011
|
+
color: #181c1f;
|
|
3012
|
+
margin: 0;
|
|
3013
|
+
}
|
|
3014
|
+
|
|
3015
|
+
/* Inputs/selects inside the lavender header need an explicit white bg */
|
|
3016
|
+
.cpk-section-header input,
|
|
3017
|
+
.cpk-section-header select {
|
|
3018
|
+
background-color: #ffffff !important;
|
|
3019
|
+
box-shadow: none !important;
|
|
3020
|
+
}
|
|
3021
|
+
.cpk-section-header select {
|
|
3022
|
+
padding-right: 24px !important;
|
|
3023
|
+
}
|
|
3024
|
+
/* Events table column headers */
|
|
3025
|
+
table thead th {
|
|
3026
|
+
font-weight: 600 !important;
|
|
981
3027
|
}
|
|
982
3028
|
|
|
983
3029
|
.announcement-content {
|
|
984
|
-
color: #
|
|
985
|
-
font-size:
|
|
986
|
-
|
|
3030
|
+
color: #1f2230;
|
|
3031
|
+
font-size: 13px;
|
|
3032
|
+
font-family: "Plus Jakarta Sans", system-ui, sans-serif;
|
|
3033
|
+
line-height: 1.55;
|
|
987
3034
|
}
|
|
988
3035
|
|
|
989
3036
|
.announcement-content h1,
|
|
990
3037
|
.announcement-content h2,
|
|
991
3038
|
.announcement-content h3 {
|
|
3039
|
+
color: #010507;
|
|
992
3040
|
font-weight: 700;
|
|
993
|
-
|
|
3041
|
+
line-height: 1.3;
|
|
3042
|
+
margin: 0.9rem 0 0.4rem;
|
|
3043
|
+
}
|
|
3044
|
+
.announcement-content > h1:first-child,
|
|
3045
|
+
.announcement-content > h2:first-child,
|
|
3046
|
+
.announcement-content > h3:first-child {
|
|
3047
|
+
margin-top: 0;
|
|
994
3048
|
}
|
|
995
3049
|
|
|
996
3050
|
.announcement-content h1 {
|
|
997
|
-
font-size: 1.
|
|
3051
|
+
font-size: 1.15rem;
|
|
3052
|
+
letter-spacing: -0.01em;
|
|
998
3053
|
}
|
|
999
|
-
|
|
1000
3054
|
.announcement-content h2 {
|
|
1001
3055
|
font-size: 1rem;
|
|
1002
3056
|
}
|
|
1003
|
-
|
|
1004
3057
|
.announcement-content h3 {
|
|
1005
|
-
font-size: 0.
|
|
3058
|
+
font-size: 0.9rem;
|
|
3059
|
+
text-transform: none;
|
|
1006
3060
|
}
|
|
1007
3061
|
|
|
1008
3062
|
.announcement-content p {
|
|
1009
|
-
margin: 0.
|
|
3063
|
+
margin: 0.45rem 0;
|
|
3064
|
+
}
|
|
3065
|
+
|
|
3066
|
+
.announcement-content strong {
|
|
3067
|
+
color: #010507;
|
|
3068
|
+
font-weight: 700;
|
|
1010
3069
|
}
|
|
1011
3070
|
|
|
1012
3071
|
.announcement-content ul {
|
|
1013
3072
|
list-style: disc;
|
|
1014
3073
|
padding-left: 1.25rem;
|
|
1015
|
-
margin: 0.
|
|
3074
|
+
margin: 0.45rem 0;
|
|
1016
3075
|
}
|
|
1017
3076
|
|
|
1018
3077
|
.announcement-content ol {
|
|
1019
3078
|
list-style: decimal;
|
|
1020
3079
|
padding-left: 1.25rem;
|
|
1021
|
-
margin: 0.
|
|
3080
|
+
margin: 0.45rem 0;
|
|
3081
|
+
}
|
|
3082
|
+
|
|
3083
|
+
.announcement-content li + li {
|
|
3084
|
+
margin-top: 0.15rem;
|
|
1022
3085
|
}
|
|
1023
3086
|
|
|
1024
3087
|
.announcement-content a {
|
|
1025
|
-
color: #
|
|
3088
|
+
color: #757cf2;
|
|
1026
3089
|
text-decoration: underline;
|
|
1027
3090
|
}
|
|
3091
|
+
|
|
3092
|
+
.announcement-content :not(pre) > code {
|
|
3093
|
+
background: #f3f3f7;
|
|
3094
|
+
border: 1px solid #e4e4ec;
|
|
3095
|
+
border-radius: 4px;
|
|
3096
|
+
padding: 1px 5px;
|
|
3097
|
+
font-size: 0.85em;
|
|
3098
|
+
color: #4a3a8a;
|
|
3099
|
+
}
|
|
3100
|
+
|
|
3101
|
+
.announcement-code {
|
|
3102
|
+
position: relative;
|
|
3103
|
+
margin: 0.6rem 0;
|
|
3104
|
+
}
|
|
3105
|
+
|
|
3106
|
+
.announcement-code pre {
|
|
3107
|
+
background: #0f1117;
|
|
3108
|
+
color: #e6e8f2;
|
|
3109
|
+
border-radius: 8px;
|
|
3110
|
+
padding: 10px 12px;
|
|
3111
|
+
overflow-x: auto;
|
|
3112
|
+
font-size: 12px;
|
|
3113
|
+
line-height: 1.5;
|
|
3114
|
+
white-space: pre;
|
|
3115
|
+
}
|
|
3116
|
+
|
|
3117
|
+
.announcement-code pre code::after {
|
|
3118
|
+
content: "";
|
|
3119
|
+
display: inline-block;
|
|
3120
|
+
width: 80px;
|
|
3121
|
+
}
|
|
3122
|
+
|
|
3123
|
+
.announcement-code__copy-shield {
|
|
3124
|
+
position: absolute;
|
|
3125
|
+
top: 4px;
|
|
3126
|
+
right: 4px;
|
|
3127
|
+
padding: 4px 4px 4px 24px;
|
|
3128
|
+
border-top-right-radius: 8px;
|
|
3129
|
+
background: linear-gradient(
|
|
3130
|
+
to right,
|
|
3131
|
+
rgba(15, 17, 23, 0) 0%,
|
|
3132
|
+
rgba(15, 17, 23, 0.95) 40%,
|
|
3133
|
+
#0f1117 100%
|
|
3134
|
+
);
|
|
3135
|
+
pointer-events: none;
|
|
3136
|
+
}
|
|
3137
|
+
|
|
3138
|
+
.announcement-code pre code {
|
|
3139
|
+
background: transparent;
|
|
3140
|
+
border: none;
|
|
3141
|
+
padding: 0;
|
|
3142
|
+
color: inherit;
|
|
3143
|
+
font-size: inherit;
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3146
|
+
.announcement-code pre::-webkit-scrollbar {
|
|
3147
|
+
height: 6px;
|
|
3148
|
+
}
|
|
3149
|
+
.announcement-code pre::-webkit-scrollbar-track {
|
|
3150
|
+
background: transparent;
|
|
3151
|
+
}
|
|
3152
|
+
.announcement-code pre::-webkit-scrollbar-thumb {
|
|
3153
|
+
background: rgba(255, 255, 255, 0.2);
|
|
3154
|
+
border-radius: 3px;
|
|
3155
|
+
}
|
|
3156
|
+
|
|
3157
|
+
.announcement-code__copy {
|
|
3158
|
+
position: relative;
|
|
3159
|
+
pointer-events: auto;
|
|
3160
|
+
padding: 3px 8px;
|
|
3161
|
+
font-family: "Plus Jakarta Sans", system-ui, sans-serif;
|
|
3162
|
+
font-size: 11px;
|
|
3163
|
+
font-weight: 600;
|
|
3164
|
+
color: #e6e8f2;
|
|
3165
|
+
background: #1f222d;
|
|
3166
|
+
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
3167
|
+
border-radius: 5px;
|
|
3168
|
+
cursor: pointer;
|
|
3169
|
+
transition:
|
|
3170
|
+
background 0.12s ease,
|
|
3171
|
+
color 0.12s ease;
|
|
3172
|
+
}
|
|
3173
|
+
.announcement-code__copy:hover {
|
|
3174
|
+
background: #2a2e3c;
|
|
3175
|
+
}
|
|
3176
|
+
.announcement-code__copy[data-copied="true"] {
|
|
3177
|
+
background: #eee6fe;
|
|
3178
|
+
color: #6430ab;
|
|
3179
|
+
border-color: transparent;
|
|
3180
|
+
}
|
|
3181
|
+
|
|
3182
|
+
.announcement-body {
|
|
3183
|
+
position: relative;
|
|
3184
|
+
overflow: hidden;
|
|
3185
|
+
transition: max-height 0.25s ease;
|
|
3186
|
+
}
|
|
3187
|
+
.announcement-body--collapsed {
|
|
3188
|
+
max-height: 72px;
|
|
3189
|
+
}
|
|
3190
|
+
.announcement-body--expanded {
|
|
3191
|
+
max-height: 2000px;
|
|
3192
|
+
}
|
|
3193
|
+
.announcement-fade {
|
|
3194
|
+
position: absolute;
|
|
3195
|
+
bottom: 0;
|
|
3196
|
+
left: 0;
|
|
3197
|
+
right: 0;
|
|
3198
|
+
height: 48px;
|
|
3199
|
+
background: linear-gradient(to bottom, transparent, #ffffff);
|
|
3200
|
+
pointer-events: none;
|
|
3201
|
+
}
|
|
3202
|
+
.announcement-toggle {
|
|
3203
|
+
display: block;
|
|
3204
|
+
width: 100%;
|
|
3205
|
+
margin-top: 6px;
|
|
3206
|
+
padding: 0;
|
|
3207
|
+
background: none;
|
|
3208
|
+
border: none;
|
|
3209
|
+
font-family: "Plus Jakarta Sans", system-ui, sans-serif;
|
|
3210
|
+
font-size: 12px;
|
|
3211
|
+
font-weight: 500;
|
|
3212
|
+
color: #757cf2;
|
|
3213
|
+
cursor: pointer;
|
|
3214
|
+
text-align: center;
|
|
3215
|
+
}
|
|
3216
|
+
.announcement-toggle:hover {
|
|
3217
|
+
color: #6430ab;
|
|
3218
|
+
}
|
|
3219
|
+
|
|
3220
|
+
/* ── Brand typography ────────────────────────────────────────── */
|
|
3221
|
+
/* Override Tailwind font-mono stack → Spline Sans Mono */
|
|
3222
|
+
.font-mono,
|
|
3223
|
+
pre,
|
|
3224
|
+
code {
|
|
3225
|
+
font-family: "Spline Sans Mono", ui-monospace, "Cascadia Code", monospace;
|
|
3226
|
+
}
|
|
3227
|
+
|
|
3228
|
+
/* ── Floating button ─────────────────────────────────────────── */
|
|
3229
|
+
.console-button {
|
|
3230
|
+
background-color: rgba(1, 5, 7, 0.95) !important;
|
|
3231
|
+
border-color: rgba(190, 194, 255, 0.25) !important;
|
|
3232
|
+
box-shadow:
|
|
3233
|
+
0 0 0 1px rgba(190, 194, 255, 0.15),
|
|
3234
|
+
0 4px 14px rgba(1, 5, 7, 0.28) !important;
|
|
3235
|
+
}
|
|
3236
|
+
.console-button:hover {
|
|
3237
|
+
background-color: rgba(1, 5, 7, 1) !important;
|
|
3238
|
+
border-color: rgba(190, 194, 255, 0.45) !important;
|
|
3239
|
+
}
|
|
3240
|
+
.console-button:focus-visible {
|
|
3241
|
+
outline-color: #bec2ff !important;
|
|
3242
|
+
}
|
|
3243
|
+
|
|
3244
|
+
/* ── Inspector window ────────────────────────────────────────── */
|
|
3245
|
+
.inspector-window {
|
|
3246
|
+
border-color: #dbdbe5 !important;
|
|
3247
|
+
box-shadow:
|
|
3248
|
+
0 8px 32px rgba(1, 5, 7, 0.1),
|
|
3249
|
+
0 2px 8px rgba(1, 5, 7, 0.06) !important;
|
|
3250
|
+
}
|
|
3251
|
+
|
|
3252
|
+
/* ── Header drag area ────────────────────────────────────────── */
|
|
3253
|
+
.drag-handle {
|
|
3254
|
+
border-bottom-color: #dbdbe5 !important;
|
|
3255
|
+
/* Subtle pale lavender gradient — brand "light, spacious" surface */
|
|
3256
|
+
background: linear-gradient(180deg, #f4f4fd 0%, #ffffff 100%) !important;
|
|
3257
|
+
}
|
|
3258
|
+
|
|
3259
|
+
/* Tab strip row: soft off-white, separated from content */
|
|
3260
|
+
.drag-handle > div:last-child {
|
|
3261
|
+
border-top-color: #e2e2ea !important;
|
|
3262
|
+
background-color: #fafafc !important;
|
|
3263
|
+
}
|
|
3264
|
+
|
|
3265
|
+
/* ── Tab buttons ─────────────────────────────────────────────── */
|
|
3266
|
+
/*
|
|
3267
|
+
* Named classes owned by this component — no Tailwind conflict.
|
|
3268
|
+
* Active: brand surface/surfaceContainerActive (lilac tint) +
|
|
3269
|
+
* border/borderActionEnabled underline.
|
|
3270
|
+
* Dark fill is for primary action buttons only, not nav tabs.
|
|
3271
|
+
*/
|
|
3272
|
+
.cpk-tab-active {
|
|
3273
|
+
background-color: rgba(190, 194, 255, 0.18);
|
|
3274
|
+
color: #010507;
|
|
3275
|
+
font-weight: 600;
|
|
3276
|
+
}
|
|
3277
|
+
.cpk-tab-active .cpk-tab-icon {
|
|
3278
|
+
color: #757cf2;
|
|
3279
|
+
}
|
|
3280
|
+
.cpk-tab-inactive {
|
|
3281
|
+
background-color: transparent;
|
|
3282
|
+
color: #2b2b2b;
|
|
3283
|
+
}
|
|
3284
|
+
.cpk-tab-inactive .cpk-tab-icon {
|
|
3285
|
+
color: #838389;
|
|
3286
|
+
}
|
|
3287
|
+
.cpk-tab-inactive:hover {
|
|
3288
|
+
background-color: rgba(190, 194, 255, 0.08);
|
|
3289
|
+
color: #010507;
|
|
3290
|
+
cursor: pointer;
|
|
3291
|
+
}
|
|
3292
|
+
.cpk-tab-active {
|
|
3293
|
+
cursor: pointer;
|
|
3294
|
+
}
|
|
3295
|
+
|
|
3296
|
+
/* ── Header control buttons (dock, close) — first row only ───── */
|
|
3297
|
+
.drag-handle > div:first-child button {
|
|
3298
|
+
color: #838389 !important;
|
|
3299
|
+
}
|
|
3300
|
+
.drag-handle > div:first-child button:hover {
|
|
3301
|
+
background-color: #f0f0f4 !important;
|
|
3302
|
+
color: #57575b !important;
|
|
3303
|
+
}
|
|
3304
|
+
.drag-handle > div:first-child button:focus-visible {
|
|
3305
|
+
outline-color: #bec2ff !important;
|
|
3306
|
+
}
|
|
3307
|
+
|
|
3308
|
+
/* ── Agent/context dropdown ──────────────────────────────────── */
|
|
3309
|
+
[data-context-dropdown-root="true"] > button {
|
|
3310
|
+
border-color: #dbdbe5 !important;
|
|
3311
|
+
color: #010507 !important;
|
|
3312
|
+
}
|
|
3313
|
+
[data-context-dropdown-root="true"] > button:hover {
|
|
3314
|
+
border-color: #bec2ff !important;
|
|
3315
|
+
background-color: #f7f7f9 !important;
|
|
3316
|
+
}
|
|
3317
|
+
[data-context-dropdown-root="true"] > button > span:last-child {
|
|
3318
|
+
color: #838389 !important;
|
|
3319
|
+
}
|
|
3320
|
+
[data-context-dropdown-root="true"] > div {
|
|
3321
|
+
border-color: #dbdbe5 !important;
|
|
3322
|
+
box-shadow: 0 4px 12px rgba(1, 5, 7, 0.08) !important;
|
|
3323
|
+
}
|
|
3324
|
+
[data-context-dropdown-root="true"] > div button:hover,
|
|
3325
|
+
[data-context-dropdown-root="true"] > div button:focus {
|
|
3326
|
+
background-color: #f7f7f9 !important;
|
|
3327
|
+
}
|
|
3328
|
+
|
|
3329
|
+
/* ── Status bar (bottom chrome) ──────────────────────────────── */
|
|
3330
|
+
.inspector-window > div > div:last-child {
|
|
3331
|
+
border-top-color: #dbdbe5 !important;
|
|
3332
|
+
background-color: #f7f7f9 !important;
|
|
3333
|
+
}
|
|
3334
|
+
|
|
3335
|
+
/* ── Resize handle ───────────────────────────────────────────── */
|
|
3336
|
+
.resize-handle {
|
|
3337
|
+
color: #838389 !important;
|
|
3338
|
+
}
|
|
3339
|
+
.resize-handle:hover {
|
|
3340
|
+
color: #57575b !important;
|
|
3341
|
+
}
|
|
3342
|
+
|
|
3343
|
+
/* ── AG-UI Events tab ────────────────────────────────────────── */
|
|
3344
|
+
/* Row hover: replace blue tint with brand lilac */
|
|
3345
|
+
tr:hover td {
|
|
3346
|
+
background-color: rgba(190, 194, 255, 0.08) !important;
|
|
3347
|
+
}
|
|
3348
|
+
/* Reset/dark action button */
|
|
3349
|
+
button[class*="bg-gray-900"] {
|
|
3350
|
+
background-color: #010507 !important;
|
|
3351
|
+
}
|
|
3352
|
+
button[class*="bg-gray-800"] {
|
|
3353
|
+
background-color: #2b2b2b !important;
|
|
3354
|
+
}
|
|
3355
|
+
/* Copy "copied" state: generic green → brand mint */
|
|
3356
|
+
button[class*="bg-green-100"] {
|
|
3357
|
+
background-color: rgba(133, 236, 206, 0.2) !important;
|
|
3358
|
+
color: #189370 !important;
|
|
3359
|
+
}
|
|
3360
|
+
|
|
3361
|
+
/* ── Agents tab ──────────────────────────────────────────────── */
|
|
3362
|
+
/* Agent icon bubble: blue → lilac */
|
|
3363
|
+
span[class*="bg-blue-100"]:not([class*="text-blue-800"]) {
|
|
3364
|
+
background-color: rgba(190, 194, 255, 0.15) !important;
|
|
3365
|
+
}
|
|
3366
|
+
span[class*="text-blue-600"] {
|
|
3367
|
+
color: #757cf2 !important;
|
|
3368
|
+
}
|
|
3369
|
+
/* Running badge: emerald → mint */
|
|
3370
|
+
span[class*="bg-emerald-50"] {
|
|
3371
|
+
background-color: rgba(133, 236, 206, 0.15) !important;
|
|
3372
|
+
}
|
|
3373
|
+
span[class*="text-emerald-700"] {
|
|
3374
|
+
color: #189370 !important;
|
|
3375
|
+
}
|
|
3376
|
+
/* Running status dot */
|
|
3377
|
+
span[class*="bg-emerald-500"] {
|
|
3378
|
+
background-color: #85ecce !important;
|
|
3379
|
+
}
|
|
3380
|
+
/* Idle dot */
|
|
3381
|
+
span[class*="bg-gray-400"] {
|
|
3382
|
+
background-color: #afafb7 !important;
|
|
3383
|
+
}
|
|
3384
|
+
/* User role badge (blue → lilac) */
|
|
3385
|
+
span[class*="bg-blue-100"][class*="text-blue-800"] {
|
|
3386
|
+
background-color: rgba(190, 194, 255, 0.22) !important;
|
|
3387
|
+
border: 1px solid rgba(190, 194, 255, 0.45) !important;
|
|
3388
|
+
color: #57575b !important;
|
|
3389
|
+
}
|
|
3390
|
+
/* Assistant role badge (green → mint) */
|
|
3391
|
+
span[class*="bg-green-100"][class*="text-green-800"] {
|
|
3392
|
+
background-color: rgba(133, 236, 206, 0.18) !important;
|
|
3393
|
+
border: 1px solid rgba(133, 236, 206, 0.4) !important;
|
|
3394
|
+
color: #189370 !important;
|
|
3395
|
+
}
|
|
3396
|
+
/* Tool role badge (amber → orange brand) */
|
|
3397
|
+
span[class*="bg-amber-100"][class*="text-amber-800"] {
|
|
3398
|
+
background-color: rgba(255, 172, 77, 0.15) !important;
|
|
3399
|
+
color: #57575b !important;
|
|
3400
|
+
}
|
|
3401
|
+
|
|
3402
|
+
/* ── Frontend Tools tab ──────────────────────────────────────── */
|
|
3403
|
+
/* Handler badge (blue → lilac) */
|
|
3404
|
+
span[class*="bg-blue-50"][class*="text-blue-700"] {
|
|
3405
|
+
background-color: rgba(190, 194, 255, 0.12) !important;
|
|
3406
|
+
border-color: rgba(190, 194, 255, 0.3) !important;
|
|
3407
|
+
color: #010507 !important;
|
|
3408
|
+
}
|
|
3409
|
+
/* Renderer badge (purple → lilac-adjacent) */
|
|
3410
|
+
span[class*="bg-purple-50"][class*="text-purple-700"] {
|
|
3411
|
+
background-color: rgba(190, 194, 255, 0.12) !important;
|
|
3412
|
+
border-color: rgba(190, 194, 255, 0.3) !important;
|
|
3413
|
+
color: #57575b !important;
|
|
3414
|
+
}
|
|
3415
|
+
/* Required badge (rose → brand red) */
|
|
3416
|
+
span[class*="bg-rose-50"][class*="text-rose-700"] {
|
|
3417
|
+
background-color: rgba(250, 95, 103, 0.1) !important;
|
|
3418
|
+
border-color: rgba(250, 95, 103, 0.25) !important;
|
|
3419
|
+
color: #fa5f67 !important;
|
|
3420
|
+
}
|
|
3421
|
+
/* Code/default value blocks */
|
|
3422
|
+
code[class*="bg-gray-100"],
|
|
3423
|
+
span[class*="bg-gray-100"] {
|
|
3424
|
+
background-color: #f0f0f4 !important;
|
|
3425
|
+
}
|
|
3426
|
+
|
|
3427
|
+
/* ── Connected status bar: match threads header mint (#5BE4BB) ──── */
|
|
3428
|
+
/* Outer strip bg + top border + text when connected badge is present */
|
|
3429
|
+
.inspector-window
|
|
3430
|
+
> div
|
|
3431
|
+
> div:last-child
|
|
3432
|
+
> div:last-child:has(div[class*="bg-emerald-50"]) {
|
|
3433
|
+
background-color: rgba(91, 228, 187, 0.08) !important;
|
|
3434
|
+
border-top-color: rgba(91, 228, 187, 0.3) !important;
|
|
3435
|
+
color: #189370 !important;
|
|
3436
|
+
}
|
|
3437
|
+
/* Inner badge — slightly more opaque on the mint bg */
|
|
3438
|
+
div[class*="bg-emerald-50"][class*="border-emerald-200"] {
|
|
3439
|
+
background-color: rgba(91, 228, 187, 0.12) !important;
|
|
3440
|
+
border-color: rgba(91, 228, 187, 0.4) !important;
|
|
3441
|
+
color: #189370 !important;
|
|
3442
|
+
}
|
|
3443
|
+
/* Icon bubble inside connected badge → mint tint */
|
|
3444
|
+
div[class*="bg-emerald-50"] span[class*="bg-white"] {
|
|
3445
|
+
background-color: rgba(91, 228, 187, 0.3) !important;
|
|
3446
|
+
}
|
|
3447
|
+
|
|
3448
|
+
/* ── Announcement panel ──────────────────────────────────────── */
|
|
3449
|
+
div[class*="border-slate-200"][class*="bg-white"] {
|
|
3450
|
+
border-color: #dbdbe5 !important;
|
|
3451
|
+
}
|
|
3452
|
+
/* Announcement icon bubble: black → brand light lavender + lilac icon */
|
|
3453
|
+
span[class*="bg-slate-900"],
|
|
3454
|
+
div[class*="bg-slate-900"] {
|
|
3455
|
+
background-color: #eee6fe !important;
|
|
3456
|
+
color: #757cf2 !important;
|
|
3457
|
+
}
|
|
3458
|
+
span[class*="text-slate-800"],
|
|
3459
|
+
div[class*="text-slate-800"] {
|
|
3460
|
+
color: #010507 !important;
|
|
3461
|
+
}
|
|
1028
3462
|
`];
|
|
1029
3463
|
}
|
|
1030
3464
|
connectedCallback() {
|
|
1031
3465
|
super.connectedCallback();
|
|
1032
3466
|
if (typeof window !== "undefined") {
|
|
3467
|
+
this.ensureBrandFonts();
|
|
1033
3468
|
window.addEventListener("resize", this.handleResize);
|
|
1034
3469
|
window.addEventListener("pointerdown", this.handleGlobalPointerDown);
|
|
1035
3470
|
this.hydrateStateFromStorageEarly();
|
|
@@ -1037,6 +3472,15 @@ ${argsString}</pre
|
|
|
1037
3472
|
this.ensureAnnouncementLoading();
|
|
1038
3473
|
}
|
|
1039
3474
|
}
|
|
3475
|
+
ensureBrandFonts() {
|
|
3476
|
+
const FONT_LINK_ID = "cpk-inspector-brand-fonts";
|
|
3477
|
+
if (document.getElementById(FONT_LINK_ID)) return;
|
|
3478
|
+
const link = document.createElement("link");
|
|
3479
|
+
link.id = FONT_LINK_ID;
|
|
3480
|
+
link.rel = "stylesheet";
|
|
3481
|
+
link.href = "https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;600&family=Spline+Sans+Mono:wght@600&display=swap";
|
|
3482
|
+
document.head.appendChild(link);
|
|
3483
|
+
}
|
|
1040
3484
|
disconnectedCallback() {
|
|
1041
3485
|
super.disconnectedCallback();
|
|
1042
3486
|
if (typeof window !== "undefined") {
|
|
@@ -1114,7 +3558,7 @@ ${argsString}</pre
|
|
|
1114
3558
|
"focus-visible:outline",
|
|
1115
3559
|
"focus-visible:outline-2",
|
|
1116
3560
|
"focus-visible:outline-offset-2",
|
|
1117
|
-
"focus-visible:outline-
|
|
3561
|
+
"focus-visible:outline-[#BEC2FF]",
|
|
1118
3562
|
"touch-none",
|
|
1119
3563
|
"select-none",
|
|
1120
3564
|
this.isDragging ? "cursor-grabbing" : "cursor-grab"
|
|
@@ -1222,14 +3666,12 @@ ${argsString}</pre
|
|
|
1222
3666
|
return lit.html`
|
|
1223
3667
|
<button
|
|
1224
3668
|
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 ? "
|
|
3669
|
+
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
3670
|
aria-pressed=${isSelected}
|
|
1227
3671
|
@click=${() => this.handleMenuSelect(key)}
|
|
1228
3672
|
>
|
|
1229
|
-
<span
|
|
1230
|
-
|
|
1231
|
-
>
|
|
1232
|
-
${this.renderIcon(icon)}
|
|
3673
|
+
<span class="cpk-tab-icon">
|
|
3674
|
+
${key in this.customTabIcons ? (0, lit_directives_unsafe_html_js.unsafeHTML)(this.customTabIcons[key]) : this.renderIcon(icon)}
|
|
1233
3675
|
</span>
|
|
1234
3676
|
<span>${label}</span>
|
|
1235
3677
|
</button>
|
|
@@ -1238,8 +3680,8 @@ ${argsString}</pre
|
|
|
1238
3680
|
</div>
|
|
1239
3681
|
</div>
|
|
1240
3682
|
<div class="flex flex-1 flex-col overflow-hidden">
|
|
1241
|
-
<div class="flex-1 overflow-auto">
|
|
1242
|
-
${this.
|
|
3683
|
+
<div id="cpk-main-scroll" class="flex-1 overflow-auto">
|
|
3684
|
+
${this.renderAnnouncementBanner()}
|
|
1243
3685
|
${this.renderCoreWarningBanner()} ${this.renderMainContent()}
|
|
1244
3686
|
<slot></slot>
|
|
1245
3687
|
</div>
|
|
@@ -1683,7 +4125,8 @@ ${argsString}</pre
|
|
|
1683
4125
|
role,
|
|
1684
4126
|
contentText,
|
|
1685
4127
|
contentRaw: raw.content !== void 0 ? this.sanitizeForLogging(raw.content) : void 0,
|
|
1686
|
-
toolCalls
|
|
4128
|
+
toolCalls,
|
|
4129
|
+
activityType: typeof raw.activityType === "string" ? raw.activityType : void 0
|
|
1687
4130
|
};
|
|
1688
4131
|
}
|
|
1689
4132
|
normalizeAgentMessages(messages) {
|
|
@@ -1702,9 +4145,6 @@ ${argsString}</pre
|
|
|
1702
4145
|
} else normalized[key] = { value: entry };
|
|
1703
4146
|
return normalized;
|
|
1704
4147
|
}
|
|
1705
|
-
getSelectedMenu() {
|
|
1706
|
-
return this.menuItems.find((item) => item.key === this.selectedMenu) ?? this.menuItems[0];
|
|
1707
|
-
}
|
|
1708
4148
|
renderCoreWarningBanner() {
|
|
1709
4149
|
if (this._core) return lit.nothing;
|
|
1710
4150
|
return lit.html`
|
|
@@ -1761,27 +4201,99 @@ ${argsString}</pre
|
|
|
1761
4201
|
if (this.selectedMenu === "agents") return this.renderAgentsView();
|
|
1762
4202
|
if (this.selectedMenu === "frontend-tools") return this.renderToolsView();
|
|
1763
4203
|
if (this.selectedMenu === "agent-context") return this.renderContextView();
|
|
4204
|
+
if (this.selectedMenu === "threads") return this.renderThreadsView();
|
|
1764
4205
|
return lit.nothing;
|
|
1765
4206
|
}
|
|
4207
|
+
renderThreadsView() {
|
|
4208
|
+
const displayThreads = this.selectedContext === "all-agents" ? this._threads : this._threadsByAgent.get(this.selectedContext) ?? [];
|
|
4209
|
+
let threadsErrorMessage = null;
|
|
4210
|
+
if (this.selectedContext === "all-agents") threadsErrorMessage = this._threadsErrorByAgent.values().next().value?.message ?? null;
|
|
4211
|
+
else threadsErrorMessage = this._threadsErrorByAgent.get(this.selectedContext)?.message ?? null;
|
|
4212
|
+
const selectedThread = this.selectedThreadId != null ? displayThreads.find((t) => t.id === this.selectedThreadId) ?? null : null;
|
|
4213
|
+
return lit.html`
|
|
4214
|
+
<div style="display:flex;height:100%;overflow:hidden;">
|
|
4215
|
+
<!-- Left sidebar: thread list -->
|
|
4216
|
+
<div
|
|
4217
|
+
style="width:${this.threadListWidth}px;flex-shrink:0;overflow:hidden;display:flex;flex-direction:column;border-right:1px solid #DBDBE5;"
|
|
4218
|
+
>
|
|
4219
|
+
<cpk-thread-list
|
|
4220
|
+
style="height:100%;"
|
|
4221
|
+
.threads=${displayThreads}
|
|
4222
|
+
.selectedThreadId=${this.selectedThreadId}
|
|
4223
|
+
.errorMessage=${threadsErrorMessage}
|
|
4224
|
+
@threadSelected=${(e) => {
|
|
4225
|
+
this.selectedThreadId = e.detail;
|
|
4226
|
+
this.requestUpdate();
|
|
4227
|
+
}}
|
|
4228
|
+
></cpk-thread-list>
|
|
4229
|
+
</div>
|
|
4230
|
+
|
|
4231
|
+
<!-- Resize divider -->
|
|
4232
|
+
<div
|
|
4233
|
+
style="width:4px;flex-shrink:0;cursor:col-resize;background:transparent;position:relative;z-index:1;"
|
|
4234
|
+
@pointerdown=${this.handleThreadDividerPointerDown}
|
|
4235
|
+
@pointermove=${this.handleThreadDividerPointerMove}
|
|
4236
|
+
@pointerup=${this.handleThreadDividerPointerUp}
|
|
4237
|
+
@pointercancel=${this.handleThreadDividerPointerUp}
|
|
4238
|
+
></div>
|
|
4239
|
+
|
|
4240
|
+
<!-- Center + right: thread details or empty state -->
|
|
4241
|
+
<div style="flex:1;min-width:0;overflow:hidden;display:flex;">
|
|
4242
|
+
${this.selectedThreadId ? lit.html`<cpk-thread-details
|
|
4243
|
+
style="flex:1;min-width:0;"
|
|
4244
|
+
.threadId=${this.selectedThreadId}
|
|
4245
|
+
.thread=${selectedThread}
|
|
4246
|
+
.runtimeUrl=${this._core?.runtimeUrl ?? ""}
|
|
4247
|
+
.headers=${this._core?.headers ?? {}}
|
|
4248
|
+
.liveMessageVersion=${this.selectedThreadId ? this.liveMessageVersion.get(this.selectedThreadId) ?? 0 : 0}
|
|
4249
|
+
.agentStateInput=${selectedThread ? this.getLatestStateForAgent(selectedThread.agentId) : null}
|
|
4250
|
+
.agentEventsInput=${selectedThread ? this.agentEvents.get(selectedThread.agentId) ?? [] : []}
|
|
4251
|
+
></cpk-thread-details>` : lit.html`
|
|
4252
|
+
<div
|
|
4253
|
+
style="
|
|
4254
|
+
flex: 1;
|
|
4255
|
+
display: flex;
|
|
4256
|
+
flex-direction: column;
|
|
4257
|
+
align-items: center;
|
|
4258
|
+
justify-content: center;
|
|
4259
|
+
gap: 8px;
|
|
4260
|
+
color: #838389;
|
|
4261
|
+
"
|
|
4262
|
+
>
|
|
4263
|
+
<svg
|
|
4264
|
+
width="32"
|
|
4265
|
+
height="32"
|
|
4266
|
+
viewBox="0 0 24 24"
|
|
4267
|
+
fill="none"
|
|
4268
|
+
stroke="#c0c0c8"
|
|
4269
|
+
stroke-width="1.5"
|
|
4270
|
+
stroke-linecap="round"
|
|
4271
|
+
stroke-linejoin="round"
|
|
4272
|
+
>
|
|
4273
|
+
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
|
|
4274
|
+
</svg>
|
|
4275
|
+
<span style="font-size: 13px">${displayThreads.length === 0 ? "No threads yet" : "Select a thread to inspect"}</span>
|
|
4276
|
+
</div>
|
|
4277
|
+
`}
|
|
4278
|
+
</div>
|
|
4279
|
+
</div>
|
|
4280
|
+
`;
|
|
4281
|
+
}
|
|
1766
4282
|
renderEventsTable() {
|
|
1767
4283
|
const events = this.getEventsForSelectedContext();
|
|
1768
4284
|
const filteredEvents = this.filterEvents(events);
|
|
1769
4285
|
const selectedLabel = this.selectedContext === "all-agents" ? "all agents" : `agent ${this.selectedContext}`;
|
|
1770
4286
|
if (events.length === 0) return lit.html`
|
|
1771
4287
|
<div
|
|
1772
|
-
class="flex h-full items-center justify-center px-4 py-
|
|
4288
|
+
class="flex h-full flex-col items-center justify-center gap-2 px-4 py-10 text-center"
|
|
1773
4289
|
>
|
|
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>
|
|
4290
|
+
<div class="text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8">
|
|
4291
|
+
${this.renderIcon("Zap")}
|
|
1784
4292
|
</div>
|
|
4293
|
+
<span class="text-sm text-gray-600">No events yet</span>
|
|
4294
|
+
<span class="max-w-[240px] text-xs leading-snug text-gray-400"
|
|
4295
|
+
>Events are recorded live. Run the agent to see them here.</span
|
|
4296
|
+
>
|
|
1785
4297
|
</div>
|
|
1786
4298
|
`;
|
|
1787
4299
|
if (filteredEvents.length === 0) return lit.html`
|
|
@@ -1878,23 +4390,32 @@ ${argsString}</pre
|
|
|
1878
4390
|
</div>
|
|
1879
4391
|
<div class="relative h-full w-full overflow-y-auto overflow-x-hidden">
|
|
1880
4392
|
<table class="w-full table-fixed border-collapse text-xs box-border">
|
|
4393
|
+
<colgroup>
|
|
4394
|
+
<col style="width:${this.evtColWidths[0]}px">
|
|
4395
|
+
<col style="width:${this.evtColWidths[1]}px">
|
|
4396
|
+
<col style="width:${this.evtColWidths[2]}px">
|
|
4397
|
+
<col>
|
|
4398
|
+
</colgroup>
|
|
1881
4399
|
<thead class="sticky top-0 z-10">
|
|
1882
4400
|
<tr class="bg-white">
|
|
4401
|
+
${[
|
|
4402
|
+
"Agent",
|
|
4403
|
+
"Time",
|
|
4404
|
+
"Event Type"
|
|
4405
|
+
].map((label, col) => lit.html`
|
|
1883
4406
|
<th
|
|
1884
4407
|
class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900"
|
|
4408
|
+
style="position:relative;overflow:hidden;"
|
|
1885
4409
|
>
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
>
|
|
1896
|
-
Event Type
|
|
1897
|
-
</th>
|
|
4410
|
+
${label}
|
|
4411
|
+
<div
|
|
4412
|
+
style="position:absolute;top:0;right:0;width:5px;height:100%;cursor:col-resize;user-select:none;background:transparent;"
|
|
4413
|
+
@pointerdown=${(e) => this._onEvtColResizeStart(e, col)}
|
|
4414
|
+
@pointermove=${(e) => this._onEvtColResizeMove(e)}
|
|
4415
|
+
@pointerup=${() => this._onEvtColResizeEnd()}
|
|
4416
|
+
@pointercancel=${() => this._onEvtColResizeEnd()}
|
|
4417
|
+
></div>
|
|
4418
|
+
</th>`)}
|
|
1898
4419
|
<th
|
|
1899
4420
|
class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900"
|
|
1900
4421
|
>
|
|
@@ -1982,6 +4503,25 @@ ${prettyEvent}</pre
|
|
|
1982
4503
|
this.eventTypeFilter = "all";
|
|
1983
4504
|
this.requestUpdate();
|
|
1984
4505
|
}
|
|
4506
|
+
_onEvtColResizeStart(e, col) {
|
|
4507
|
+
e.preventDefault();
|
|
4508
|
+
e.stopPropagation();
|
|
4509
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
4510
|
+
this._evtColResize = {
|
|
4511
|
+
col,
|
|
4512
|
+
startX: e.clientX,
|
|
4513
|
+
startW: this.evtColWidths[col] ?? 0
|
|
4514
|
+
};
|
|
4515
|
+
}
|
|
4516
|
+
_onEvtColResizeMove(e) {
|
|
4517
|
+
if (!this._evtColResize) return;
|
|
4518
|
+
const { col, startX, startW } = this._evtColResize;
|
|
4519
|
+
this.evtColWidths = this.evtColWidths.map((w, i) => i === col ? Math.max(40, startW + (e.clientX - startX)) : w);
|
|
4520
|
+
this.requestUpdate();
|
|
4521
|
+
}
|
|
4522
|
+
_onEvtColResizeEnd() {
|
|
4523
|
+
this._evtColResize = null;
|
|
4524
|
+
}
|
|
1985
4525
|
exportEvents(events) {
|
|
1986
4526
|
try {
|
|
1987
4527
|
const payload = JSON.stringify(events, null, 2);
|
|
@@ -2026,7 +4566,7 @@ ${prettyEvent}</pre
|
|
|
2026
4566
|
<div class="flex items-start justify-between mb-4">
|
|
2027
4567
|
<div class="flex items-center gap-3">
|
|
2028
4568
|
<div
|
|
2029
|
-
class="flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-blue-600"
|
|
4569
|
+
class="flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-blue-600 cpk-agent-icon"
|
|
2030
4570
|
>
|
|
2031
4571
|
${this.renderIcon("Bot")}
|
|
2032
4572
|
</div>
|
|
@@ -2054,7 +4594,7 @@ ${prettyEvent}</pre
|
|
|
2054
4594
|
<div class="grid grid-cols-2 gap-4 md:grid-cols-4">
|
|
2055
4595
|
<button
|
|
2056
4596
|
type="button"
|
|
2057
|
-
class="rounded-md bg-gray-50 px-3 py-2 text-left transition hover:bg-gray-100 cursor-pointer overflow-hidden"
|
|
4597
|
+
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
4598
|
@click=${() => this.handleMenuSelect("ag-ui-events")}
|
|
2059
4599
|
title="View all events in AG-UI Events"
|
|
2060
4600
|
>
|
|
@@ -2065,7 +4605,9 @@ ${prettyEvent}</pre
|
|
|
2065
4605
|
${stats.totalEvents}
|
|
2066
4606
|
</div>
|
|
2067
4607
|
</button>
|
|
2068
|
-
<div
|
|
4608
|
+
<div
|
|
4609
|
+
class="rounded-md bg-gray-50 px-3 py-2 overflow-hidden cpk-stat-card"
|
|
4610
|
+
>
|
|
2069
4611
|
<div class="truncate whitespace-nowrap text-xs text-gray-600">
|
|
2070
4612
|
Messages
|
|
2071
4613
|
</div>
|
|
@@ -2073,7 +4615,9 @@ ${prettyEvent}</pre
|
|
|
2073
4615
|
${stats.messages}
|
|
2074
4616
|
</div>
|
|
2075
4617
|
</div>
|
|
2076
|
-
<div
|
|
4618
|
+
<div
|
|
4619
|
+
class="rounded-md bg-gray-50 px-3 py-2 overflow-hidden cpk-stat-card"
|
|
4620
|
+
>
|
|
2077
4621
|
<div class="truncate whitespace-nowrap text-xs text-gray-600">
|
|
2078
4622
|
Tool Calls
|
|
2079
4623
|
</div>
|
|
@@ -2081,7 +4625,9 @@ ${prettyEvent}</pre
|
|
|
2081
4625
|
${stats.toolCalls}
|
|
2082
4626
|
</div>
|
|
2083
4627
|
</div>
|
|
2084
|
-
<div
|
|
4628
|
+
<div
|
|
4629
|
+
class="rounded-md bg-gray-50 px-3 py-2 overflow-hidden cpk-stat-card"
|
|
4630
|
+
>
|
|
2085
4631
|
<div class="truncate whitespace-nowrap text-xs text-gray-600">
|
|
2086
4632
|
Errors
|
|
2087
4633
|
</div>
|
|
@@ -2093,9 +4639,9 @@ ${prettyEvent}</pre
|
|
|
2093
4639
|
</div>
|
|
2094
4640
|
|
|
2095
4641
|
<!-- Current State Section -->
|
|
2096
|
-
<div class="
|
|
2097
|
-
<div class="
|
|
2098
|
-
<h4
|
|
4642
|
+
<div class="cpk-section-card">
|
|
4643
|
+
<div class="cpk-section-header">
|
|
4644
|
+
<h4>Current State</h4>
|
|
2099
4645
|
</div>
|
|
2100
4646
|
<div class="overflow-auto p-4">
|
|
2101
4647
|
${this.hasRenderableState(state) ? lit.html`
|
|
@@ -2104,7 +4650,7 @@ ${prettyEvent}</pre
|
|
|
2104
4650
|
><code>${this.formatStateForDisplay(state)}</code></pre>
|
|
2105
4651
|
` : lit.html`
|
|
2106
4652
|
<div
|
|
2107
|
-
class="flex h-
|
|
4653
|
+
class="flex h-12 items-center justify-center text-xs text-gray-500"
|
|
2108
4654
|
>
|
|
2109
4655
|
<div class="flex items-center gap-2 text-gray-500">
|
|
2110
4656
|
<span class="text-lg text-gray-400"
|
|
@@ -2118,30 +4664,18 @@ ${prettyEvent}</pre
|
|
|
2118
4664
|
</div>
|
|
2119
4665
|
|
|
2120
4666
|
<!-- Current Messages Section -->
|
|
2121
|
-
<div class="
|
|
2122
|
-
<div class="
|
|
2123
|
-
<h4
|
|
2124
|
-
Current Messages
|
|
2125
|
-
</h4>
|
|
4667
|
+
<div class="cpk-section-card">
|
|
4668
|
+
<div class="cpk-section-header">
|
|
4669
|
+
<h4>Current Messages</h4>
|
|
2126
4670
|
</div>
|
|
2127
4671
|
<div class="overflow-auto">
|
|
2128
4672
|
${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">
|
|
4673
|
+
<div class="w-full text-xs">
|
|
4674
|
+
<div class="flex bg-gray-50">
|
|
4675
|
+
<div class="w-40 shrink-0 px-4 py-2 font-medium text-gray-700">Role</div>
|
|
4676
|
+
<div class="flex-1 px-4 py-2 font-medium text-gray-700">Content</div>
|
|
4677
|
+
</div>
|
|
4678
|
+
<div class="divide-y divide-gray-200">
|
|
2145
4679
|
${messages.map((msg) => {
|
|
2146
4680
|
const role = msg.role || "unknown";
|
|
2147
4681
|
const roleColors = {
|
|
@@ -2156,34 +4690,32 @@ ${prettyEvent}</pre
|
|
|
2156
4690
|
const hasContent = rawContent.trim().length > 0;
|
|
2157
4691
|
const contentFallback = toolCalls.length > 0 ? "Invoked tool call" : "—";
|
|
2158
4692
|
return lit.html`
|
|
2159
|
-
<
|
|
2160
|
-
<
|
|
4693
|
+
<div class="flex items-start">
|
|
4694
|
+
<div class="w-40 shrink-0 px-4 py-2">
|
|
2161
4695
|
<span
|
|
2162
4696
|
class="inline-flex rounded px-2 py-0.5 text-[10px] font-medium ${roleColors[role] || roleColors.unknown}"
|
|
2163
4697
|
>
|
|
2164
4698
|
${role}
|
|
2165
4699
|
</span>
|
|
2166
|
-
</
|
|
2167
|
-
<
|
|
4700
|
+
</div>
|
|
4701
|
+
<div class="flex-1 px-4 py-2">
|
|
2168
4702
|
${hasContent ? lit.html`<div
|
|
2169
|
-
class="
|
|
4703
|
+
class="whitespace-pre-line break-words text-gray-700"
|
|
2170
4704
|
>
|
|
2171
4705
|
${rawContent}
|
|
2172
|
-
</div>` : lit.html`<div
|
|
2173
|
-
class="text-xs italic text-gray-400"
|
|
2174
|
-
>
|
|
4706
|
+
</div>` : lit.html`<div class="italic text-gray-400">
|
|
2175
4707
|
${contentFallback}
|
|
2176
4708
|
</div>`}
|
|
2177
4709
|
${role === "assistant" && toolCalls.length > 0 ? this.renderToolCallDetails(toolCalls) : lit.nothing}
|
|
2178
|
-
</
|
|
2179
|
-
</
|
|
4710
|
+
</div>
|
|
4711
|
+
</div>
|
|
2180
4712
|
`;
|
|
2181
4713
|
})}
|
|
2182
|
-
</
|
|
2183
|
-
</
|
|
4714
|
+
</div>
|
|
4715
|
+
</div>
|
|
2184
4716
|
` : lit.html`
|
|
2185
4717
|
<div
|
|
2186
|
-
class="flex h-
|
|
4718
|
+
class="flex h-12 items-center justify-center text-xs text-gray-500"
|
|
2187
4719
|
>
|
|
2188
4720
|
<div class="flex items-center gap-2 text-gray-500">
|
|
2189
4721
|
<span class="text-lg text-gray-400"
|
|
@@ -2244,14 +4776,29 @@ ${prettyEvent}</pre
|
|
|
2244
4776
|
}
|
|
2245
4777
|
handleMenuSelect(key) {
|
|
2246
4778
|
if (!this.menuItems.some((item) => item.key === key)) return;
|
|
4779
|
+
const previousMenu = this.selectedMenu;
|
|
2247
4780
|
this.selectedMenu = key;
|
|
2248
4781
|
if (key === "agents" && this.selectedContext === "all-agents") {
|
|
2249
4782
|
const agentOptions = this.contextOptions.filter((opt) => opt.key !== "all-agents");
|
|
2250
4783
|
if (agentOptions.length > 0) {
|
|
2251
|
-
const
|
|
2252
|
-
|
|
4784
|
+
const mostRecent = agentOptions.reduce((best, opt) => {
|
|
4785
|
+
const ts = this.getAgentStats(opt.key).lastActivity ?? -1;
|
|
4786
|
+
return best === null || ts > best.ts ? {
|
|
4787
|
+
key: opt.key,
|
|
4788
|
+
ts
|
|
4789
|
+
} : best;
|
|
4790
|
+
}, null);
|
|
4791
|
+
this.selectedContext = mostRecent ? mostRecent.key : agentOptions[0].key;
|
|
2253
4792
|
}
|
|
2254
4793
|
}
|
|
4794
|
+
if (previousMenu === "agents" && key !== "agents") {
|
|
4795
|
+
if (this.contextOptions.filter((opt) => opt.key !== "all-agents").length > 1) this.selectedContext = "all-agents";
|
|
4796
|
+
}
|
|
4797
|
+
if (key === "threads") this.autoSelectLatestThread();
|
|
4798
|
+
if (key === "ag-ui-events" || key === "agents") requestAnimationFrame(() => {
|
|
4799
|
+
const scroller = this.shadowRoot?.getElementById("cpk-main-scroll");
|
|
4800
|
+
if (scroller) scroller.scrollTop = 0;
|
|
4801
|
+
});
|
|
2255
4802
|
this.contextMenuOpen = false;
|
|
2256
4803
|
this.persistState();
|
|
2257
4804
|
this.requestUpdate();
|
|
@@ -2639,9 +5186,19 @@ ${prettyEvent}</pre
|
|
|
2639
5186
|
<div class="mb-3">
|
|
2640
5187
|
<h5 class="mb-1 text-xs font-semibold text-gray-700">ID</h5>
|
|
2641
5188
|
<code
|
|
2642
|
-
class="
|
|
5189
|
+
class="font-mono text-xs font-medium text-gray-800 flex-1 truncate min-w-0"
|
|
2643
5190
|
>${id}</code
|
|
2644
5191
|
>
|
|
5192
|
+
<button
|
|
5193
|
+
type="button"
|
|
5194
|
+
class="cpk-copy-btn"
|
|
5195
|
+
@click=${(e) => {
|
|
5196
|
+
e.stopPropagation();
|
|
5197
|
+
this.copyContextValue(id, `${id}:id`);
|
|
5198
|
+
}}
|
|
5199
|
+
>
|
|
5200
|
+
${this.copiedContextItems.has(`${id}:id`) ? "✓" : "Copy"}
|
|
5201
|
+
</button>
|
|
2645
5202
|
</div>
|
|
2646
5203
|
${hasValue ? lit.html`
|
|
2647
5204
|
<div class="mb-2 flex items-center justify-between gap-2">
|
|
@@ -2649,8 +5206,8 @@ ${prettyEvent}</pre
|
|
|
2649
5206
|
Value
|
|
2650
5207
|
</h5>
|
|
2651
5208
|
<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
5209
|
type="button"
|
|
5210
|
+
class="cpk-copy-btn"
|
|
2654
5211
|
@click=${(e) => {
|
|
2655
5212
|
e.stopPropagation();
|
|
2656
5213
|
this.copyContextValue(context.value, id);
|
|
@@ -2659,13 +5216,6 @@ ${prettyEvent}</pre
|
|
|
2659
5216
|
${this.copiedContextItems.has(id) ? "Copied" : "Copy JSON"}
|
|
2660
5217
|
</button>
|
|
2661
5218
|
</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
5219
|
` : lit.html`
|
|
2670
5220
|
<div class="flex items-center justify-center py-4 text-xs text-gray-500">
|
|
2671
5221
|
<span>No value available</span>
|
|
@@ -2678,7 +5228,7 @@ ${prettyEvent}</pre
|
|
|
2678
5228
|
}
|
|
2679
5229
|
getContextValuePreview(value) {
|
|
2680
5230
|
if (value === void 0 || value === null) return "—";
|
|
2681
|
-
if (typeof value === "string") return value.length > 50 ? `${value.
|
|
5231
|
+
if (typeof value === "string") return value.length > 50 ? `${value.slice(0, 50)}...` : value;
|
|
2682
5232
|
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
2683
5233
|
if (Array.isArray(value)) return `Array(${value.length})`;
|
|
2684
5234
|
if (typeof value === "object") {
|
|
@@ -2728,50 +5278,25 @@ ${prettyEvent}</pre
|
|
|
2728
5278
|
else this.expandedRows.add(eventId);
|
|
2729
5279
|
this.requestUpdate();
|
|
2730
5280
|
}
|
|
2731
|
-
|
|
2732
|
-
if (!this.isOpen) return lit.nothing;
|
|
2733
|
-
this.ensureAnnouncementLoading();
|
|
5281
|
+
renderAnnouncementBanner() {
|
|
2734
5282
|
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)]"
|
|
5283
|
+
if (!this.announcementLoaded && !this.announcementHtml) return lit.html`<div
|
|
5284
|
+
class="flex items-center gap-2 px-4 py-3 text-sm font-semibold text-slate-800"
|
|
2749
5285
|
>
|
|
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>
|
|
5286
|
+
<span
|
|
5287
|
+
class="inline-flex h-6 w-6 items-center justify-center rounded-md bg-slate-900 text-white shadow-sm"
|
|
5288
|
+
>
|
|
5289
|
+
${this.renderIcon("Megaphone")}
|
|
5290
|
+
</span>
|
|
5291
|
+
<span>Loading latest announcement…</span>
|
|
2762
5292
|
</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
|
-
>
|
|
5293
|
+
if (!this.announcementHtml) return lit.nothing;
|
|
5294
|
+
return lit.html`<div class="mx-4 mt-3 mb-3 rounded-xl border border-slate-200 bg-white px-4 py-3">
|
|
2770
5295
|
<div
|
|
2771
|
-
class="mb-
|
|
5296
|
+
class="mb-2 flex items-center gap-2 text-xs font-semibold text-slate-900"
|
|
2772
5297
|
>
|
|
2773
5298
|
<span
|
|
2774
|
-
class="inline-flex h-
|
|
5299
|
+
class="inline-flex h-5 w-5 items-center justify-center rounded-md bg-slate-900 text-white shadow-sm"
|
|
2775
5300
|
>
|
|
2776
5301
|
${this.renderIcon("Megaphone")}
|
|
2777
5302
|
</span>
|
|
@@ -2782,12 +5307,30 @@ ${this.announcementMarkdown}</pre
|
|
|
2782
5307
|
@click=${this.handleDismissAnnouncement}
|
|
2783
5308
|
aria-label="Dismiss announcement"
|
|
2784
5309
|
>
|
|
2785
|
-
|
|
5310
|
+
${this.renderIcon("X")}
|
|
2786
5311
|
</button>
|
|
2787
5312
|
</div>
|
|
2788
|
-
<div class="announcement-
|
|
2789
|
-
|
|
5313
|
+
<div class="announcement-body ${this.announcementExpanded ? "announcement-body--expanded" : "announcement-body--collapsed"}">
|
|
5314
|
+
<div
|
|
5315
|
+
class="announcement-content"
|
|
5316
|
+
@click=${this.handleAnnouncementContentClick}
|
|
5317
|
+
>
|
|
5318
|
+
${(0, lit_directives_unsafe_html_js.unsafeHTML)(this.announcementHtml)}
|
|
5319
|
+
</div>
|
|
5320
|
+
${!this.announcementExpanded ? lit.html`
|
|
5321
|
+
<div class="announcement-fade"></div>
|
|
5322
|
+
` : lit.nothing}
|
|
2790
5323
|
</div>
|
|
5324
|
+
<button
|
|
5325
|
+
class="announcement-toggle"
|
|
5326
|
+
type="button"
|
|
5327
|
+
@click=${() => {
|
|
5328
|
+
this.announcementExpanded = !this.announcementExpanded;
|
|
5329
|
+
this.requestUpdate();
|
|
5330
|
+
}}
|
|
5331
|
+
>
|
|
5332
|
+
${this.announcementExpanded ? "Show less ↑" : "Show more ↓"}
|
|
5333
|
+
</button>
|
|
2791
5334
|
</div>`;
|
|
2792
5335
|
}
|
|
2793
5336
|
ensureAnnouncementLoading() {
|
|
@@ -2822,14 +5365,13 @@ ${this.announcementMarkdown}</pre
|
|
|
2822
5365
|
const storedTimestamp = this.loadStoredAnnouncementTimestamp();
|
|
2823
5366
|
this.announcementTimestamp = timestamp;
|
|
2824
5367
|
this.announcementPreviewText = previewText ?? "";
|
|
2825
|
-
this.announcementMarkdown = markdown;
|
|
2826
5368
|
this.hasUnseenAnnouncement = (!storedTimestamp || storedTimestamp !== timestamp) && !!this.announcementPreviewText;
|
|
2827
5369
|
this.showAnnouncementPreview = this.hasUnseenAnnouncement;
|
|
2828
5370
|
this.announcementHtml = await this.convertMarkdownToHtml(markdown);
|
|
2829
5371
|
this.announcementLoaded = true;
|
|
2830
5372
|
this.requestUpdate();
|
|
2831
5373
|
} catch (error) {
|
|
2832
|
-
|
|
5374
|
+
console.warn("[CopilotKit Inspector] Failed to load announcement", error);
|
|
2833
5375
|
this.announcementLoaded = true;
|
|
2834
5376
|
this.requestUpdate();
|
|
2835
5377
|
}
|
|
@@ -2839,7 +5381,28 @@ ${this.announcementMarkdown}</pre
|
|
|
2839
5381
|
renderer.link = (href, title, text) => {
|
|
2840
5382
|
return `<a href="${this.escapeHtmlAttr(this.appendRefParam(href ?? ""))}" target="_blank" rel="noopener"${title ? ` title="${this.escapeHtmlAttr(title)}"` : ""}>${text}</a>`;
|
|
2841
5383
|
};
|
|
2842
|
-
|
|
5384
|
+
renderer.code = (code, lang) => {
|
|
5385
|
+
const safeLang = (lang ?? "").replace(/[^a-z0-9-]/gi, "");
|
|
5386
|
+
return `<div class="announcement-code"><pre><code${safeLang ? ` class="language-${safeLang}"` : ""}>${escapeHtml(code)}</code></pre><div class="announcement-code__copy-shield"><button type="button" class="announcement-code__copy" data-copy="${this.encodeBase64(code)}" aria-label="Copy code">Copy</button></div></div>`;
|
|
5387
|
+
};
|
|
5388
|
+
return marked.marked.parse(markdown, {
|
|
5389
|
+
renderer,
|
|
5390
|
+
async: false
|
|
5391
|
+
});
|
|
5392
|
+
}
|
|
5393
|
+
encodeBase64(value) {
|
|
5394
|
+
if (typeof window === "undefined" || typeof window.btoa !== "function") return "";
|
|
5395
|
+
const bytes = new TextEncoder().encode(value);
|
|
5396
|
+
let binary = "";
|
|
5397
|
+
for (const b of bytes) binary += String.fromCharCode(b);
|
|
5398
|
+
return window.btoa(binary);
|
|
5399
|
+
}
|
|
5400
|
+
decodeBase64(value) {
|
|
5401
|
+
if (typeof window === "undefined" || typeof window.atob !== "function") return "";
|
|
5402
|
+
const decoded = window.atob(value);
|
|
5403
|
+
const bytes = new Uint8Array(decoded.length);
|
|
5404
|
+
for (let i = 0; i < decoded.length; i++) bytes[i] = decoded.charCodeAt(i);
|
|
5405
|
+
return new TextDecoder().decode(bytes);
|
|
2843
5406
|
}
|
|
2844
5407
|
appendRefParam(href) {
|
|
2845
5408
|
try {
|
|
@@ -2851,7 +5414,7 @@ ${this.announcementMarkdown}</pre
|
|
|
2851
5414
|
}
|
|
2852
5415
|
}
|
|
2853
5416
|
escapeHtmlAttr(value) {
|
|
2854
|
-
return value
|
|
5417
|
+
return escapeHtml(value).replace(/"/g, """).replace(/'/g, "'");
|
|
2855
5418
|
}
|
|
2856
5419
|
loadStoredAnnouncementTimestamp() {
|
|
2857
5420
|
if (typeof window === "undefined" || !window.localStorage) return null;
|
|
@@ -2892,4 +5455,5 @@ defineWebInspector();
|
|
|
2892
5455
|
exports.WEB_INSPECTOR_TAG = WEB_INSPECTOR_TAG;
|
|
2893
5456
|
exports.WebInspectorElement = WebInspectorElement;
|
|
2894
5457
|
exports.defineWebInspector = defineWebInspector;
|
|
5458
|
+
exports.ɵCpkThreadDetails = ɵCpkThreadDetails;
|
|
2895
5459
|
//# sourceMappingURL=index.cjs.map
|