@copilotkit/web-inspector 1.62.2 → 1.62.3
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 +736 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +28 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +738 -4
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +762 -23
- package/dist/index.umd.js.map +1 -1
- package/dist/lib/telemetry.cjs +7 -2
- package/dist/lib/telemetry.cjs.map +1 -1
- package/dist/lib/telemetry.mjs +7 -3
- package/dist/lib/telemetry.mjs.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/package.json +2 -2
- package/src/__tests__/web-inspector.spec.ts +1054 -0
- package/src/index.ts +871 -1
- package/src/lib/telemetry.ts +18 -1
- package/src/styles/generated.css +1 -1
package/src/index.ts
CHANGED
|
@@ -13,12 +13,19 @@ import {
|
|
|
13
13
|
ɵselectThreads,
|
|
14
14
|
ɵselectThreadsError,
|
|
15
15
|
ɵcreateThreadStore,
|
|
16
|
+
ɵselectMemories,
|
|
17
|
+
ɵselectMemoriesIsLoading,
|
|
18
|
+
ɵselectMemoriesError,
|
|
19
|
+
ɵselectMemoriesAvailable,
|
|
20
|
+
ɵselectMemoriesRealtimeStatus,
|
|
16
21
|
} from "@copilotkit/core";
|
|
17
22
|
import type {
|
|
18
23
|
CopilotKitCoreSubscriber,
|
|
19
24
|
CopilotKitCoreErrorCode,
|
|
20
25
|
ɵThreadStore,
|
|
21
26
|
ɵThread,
|
|
27
|
+
Memory,
|
|
28
|
+
MemoryRealtimeStatus,
|
|
22
29
|
} from "@copilotkit/core";
|
|
23
30
|
import type { AbstractAgent, AgentSubscriber } from "@ag-ui/client";
|
|
24
31
|
import type {
|
|
@@ -60,10 +67,14 @@ import {
|
|
|
60
67
|
trackThreadsEnabledViewed,
|
|
61
68
|
trackThreadsIntelligenceSignupClicked,
|
|
62
69
|
trackThreadsLockedViewed,
|
|
70
|
+
trackMemoriesTabClicked,
|
|
63
71
|
trackThreadsTabClicked,
|
|
64
72
|
trackThreadsTalkToEngineerClicked,
|
|
65
73
|
} from "./lib/telemetry.js";
|
|
66
|
-
import type {
|
|
74
|
+
import type {
|
|
75
|
+
InspectorMemoryTelemetryProps,
|
|
76
|
+
InspectorThreadTelemetryProps,
|
|
77
|
+
} from "./lib/telemetry.js";
|
|
67
78
|
|
|
68
79
|
export type { Anchor } from "./lib/types.js";
|
|
69
80
|
|
|
@@ -78,6 +89,7 @@ type MenuKey =
|
|
|
78
89
|
| "frontend-tools"
|
|
79
90
|
| "agent-context"
|
|
80
91
|
| "threads"
|
|
92
|
+
| "memories"
|
|
81
93
|
| "settings";
|
|
82
94
|
|
|
83
95
|
type MenuItem = {
|
|
@@ -3418,6 +3430,368 @@ ${unsafeHTML(highlightedJson(stateValue))}</pre
|
|
|
3418
3430
|
}
|
|
3419
3431
|
}
|
|
3420
3432
|
|
|
3433
|
+
// ─── cpk-memory-list ─────────────────────────────────────────────────────────
|
|
3434
|
+
|
|
3435
|
+
/** Memory kind values including the "all" sentinel used by the filter UI. */
|
|
3436
|
+
type MemoryKindFilter = "all" | "topical" | "episodic" | "operational";
|
|
3437
|
+
|
|
3438
|
+
class CpkMemoryList extends LitElement {
|
|
3439
|
+
static properties = {
|
|
3440
|
+
memories: { attribute: false },
|
|
3441
|
+
search: { state: true },
|
|
3442
|
+
kind: { state: true },
|
|
3443
|
+
};
|
|
3444
|
+
|
|
3445
|
+
/** Ordered (newest-first) list of memories supplied by the parent. */
|
|
3446
|
+
memories: Memory[] = [];
|
|
3447
|
+
private search = "";
|
|
3448
|
+
private kind: MemoryKindFilter = "all";
|
|
3449
|
+
|
|
3450
|
+
static styles = css`
|
|
3451
|
+
@import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600&family=Spline+Sans+Mono:wght@400;500&display=swap");
|
|
3452
|
+
|
|
3453
|
+
:host {
|
|
3454
|
+
display: flex;
|
|
3455
|
+
flex-direction: column;
|
|
3456
|
+
height: 100%;
|
|
3457
|
+
overflow: hidden;
|
|
3458
|
+
}
|
|
3459
|
+
|
|
3460
|
+
.cpk-ml {
|
|
3461
|
+
font-family: "Plus Jakarta Sans", sans-serif;
|
|
3462
|
+
display: flex;
|
|
3463
|
+
flex-direction: column;
|
|
3464
|
+
height: 100%;
|
|
3465
|
+
overflow: hidden;
|
|
3466
|
+
background: #f7f7f9;
|
|
3467
|
+
}
|
|
3468
|
+
|
|
3469
|
+
/* ── Search ── */
|
|
3470
|
+
.cpk-ml__search {
|
|
3471
|
+
padding: 10px 12px;
|
|
3472
|
+
border-bottom: 1px solid #dbdbe5;
|
|
3473
|
+
flex-shrink: 0;
|
|
3474
|
+
}
|
|
3475
|
+
|
|
3476
|
+
.cpk-ml__search-input {
|
|
3477
|
+
width: 100%;
|
|
3478
|
+
box-sizing: border-box;
|
|
3479
|
+
font-family: "Plus Jakarta Sans", sans-serif;
|
|
3480
|
+
font-size: 12px;
|
|
3481
|
+
padding: 7px 10px;
|
|
3482
|
+
border-radius: 6px;
|
|
3483
|
+
border: 1px solid #dbdbe5;
|
|
3484
|
+
background: #ffffff;
|
|
3485
|
+
color: #010507;
|
|
3486
|
+
outline: none;
|
|
3487
|
+
transition: border-color 0.15s;
|
|
3488
|
+
}
|
|
3489
|
+
|
|
3490
|
+
.cpk-ml__search-input:focus {
|
|
3491
|
+
border-color: #bec2ff;
|
|
3492
|
+
}
|
|
3493
|
+
|
|
3494
|
+
/* ── Kind filter ── */
|
|
3495
|
+
.cpk-ml__filter {
|
|
3496
|
+
display: flex;
|
|
3497
|
+
gap: 4px;
|
|
3498
|
+
padding: 8px 12px;
|
|
3499
|
+
border-bottom: 1px solid #dbdbe5;
|
|
3500
|
+
flex-shrink: 0;
|
|
3501
|
+
flex-wrap: wrap;
|
|
3502
|
+
}
|
|
3503
|
+
|
|
3504
|
+
.cpk-ml__filter-seg {
|
|
3505
|
+
font-family: "Plus Jakarta Sans", sans-serif;
|
|
3506
|
+
font-size: 11px;
|
|
3507
|
+
font-weight: 500;
|
|
3508
|
+
padding: 3px 9px;
|
|
3509
|
+
border-radius: 5px;
|
|
3510
|
+
border: 1px solid #dbdbe5;
|
|
3511
|
+
background: #ffffff;
|
|
3512
|
+
color: #57575b;
|
|
3513
|
+
cursor: pointer;
|
|
3514
|
+
transition:
|
|
3515
|
+
background 0.1s,
|
|
3516
|
+
border-color 0.1s,
|
|
3517
|
+
color 0.1s;
|
|
3518
|
+
user-select: none;
|
|
3519
|
+
}
|
|
3520
|
+
|
|
3521
|
+
.cpk-ml__filter-seg:hover {
|
|
3522
|
+
background: #f0f0f5;
|
|
3523
|
+
}
|
|
3524
|
+
|
|
3525
|
+
.cpk-ml__filter-seg--active {
|
|
3526
|
+
background: #bec2ff1a;
|
|
3527
|
+
border-color: #bec2ff;
|
|
3528
|
+
color: #010507;
|
|
3529
|
+
}
|
|
3530
|
+
|
|
3531
|
+
.cpk-ml__filter-count {
|
|
3532
|
+
font-family: "Spline Sans Mono", monospace;
|
|
3533
|
+
font-size: 9px;
|
|
3534
|
+
margin-left: 4px;
|
|
3535
|
+
color: #838389;
|
|
3536
|
+
}
|
|
3537
|
+
|
|
3538
|
+
/* ── List ── */
|
|
3539
|
+
.cpk-ml__list {
|
|
3540
|
+
flex: 1;
|
|
3541
|
+
overflow-y: auto;
|
|
3542
|
+
padding: 8px 12px;
|
|
3543
|
+
display: flex;
|
|
3544
|
+
flex-direction: column;
|
|
3545
|
+
gap: 8px;
|
|
3546
|
+
}
|
|
3547
|
+
|
|
3548
|
+
/* ── Card ── */
|
|
3549
|
+
.cpk-ml__card {
|
|
3550
|
+
background: #ffffff;
|
|
3551
|
+
border: 1px solid #e9e9ef;
|
|
3552
|
+
border-radius: 8px;
|
|
3553
|
+
padding: 10px 12px;
|
|
3554
|
+
display: flex;
|
|
3555
|
+
flex-direction: column;
|
|
3556
|
+
gap: 6px;
|
|
3557
|
+
}
|
|
3558
|
+
|
|
3559
|
+
.cpk-ml__card-badges {
|
|
3560
|
+
display: flex;
|
|
3561
|
+
gap: 6px;
|
|
3562
|
+
align-items: center;
|
|
3563
|
+
flex-wrap: wrap;
|
|
3564
|
+
}
|
|
3565
|
+
|
|
3566
|
+
/* Kind badge — color per kind */
|
|
3567
|
+
.cpk-ml__kind-badge {
|
|
3568
|
+
font-family: "Spline Sans Mono", monospace;
|
|
3569
|
+
font-size: 9px;
|
|
3570
|
+
padding: 1px 7px;
|
|
3571
|
+
border-radius: 4px;
|
|
3572
|
+
text-transform: uppercase;
|
|
3573
|
+
font-weight: 500;
|
|
3574
|
+
white-space: nowrap;
|
|
3575
|
+
}
|
|
3576
|
+
|
|
3577
|
+
.cpk-ml__kind-badge--topical {
|
|
3578
|
+
background: #eee6fe;
|
|
3579
|
+
color: #57575b;
|
|
3580
|
+
}
|
|
3581
|
+
|
|
3582
|
+
.cpk-ml__kind-badge--episodic {
|
|
3583
|
+
background: #e6f4fe;
|
|
3584
|
+
color: #2d5f80;
|
|
3585
|
+
}
|
|
3586
|
+
|
|
3587
|
+
.cpk-ml__kind-badge--operational {
|
|
3588
|
+
background: #e6feee;
|
|
3589
|
+
color: #2d6645;
|
|
3590
|
+
}
|
|
3591
|
+
|
|
3592
|
+
/* Scope badge */
|
|
3593
|
+
.cpk-ml__scope-badge {
|
|
3594
|
+
font-family: "Spline Sans Mono", monospace;
|
|
3595
|
+
font-size: 9px;
|
|
3596
|
+
padding: 1px 7px;
|
|
3597
|
+
border-radius: 4px;
|
|
3598
|
+
text-transform: uppercase;
|
|
3599
|
+
font-weight: 500;
|
|
3600
|
+
white-space: nowrap;
|
|
3601
|
+
background: #f0f0f5;
|
|
3602
|
+
color: #838389;
|
|
3603
|
+
}
|
|
3604
|
+
|
|
3605
|
+
/* Content */
|
|
3606
|
+
.cpk-ml__content {
|
|
3607
|
+
font-size: 12px;
|
|
3608
|
+
color: #010507;
|
|
3609
|
+
line-height: 1.5;
|
|
3610
|
+
word-break: break-word;
|
|
3611
|
+
}
|
|
3612
|
+
|
|
3613
|
+
/* Footer */
|
|
3614
|
+
.cpk-ml__footer {
|
|
3615
|
+
display: flex;
|
|
3616
|
+
align-items: center;
|
|
3617
|
+
justify-content: space-between;
|
|
3618
|
+
gap: 8px;
|
|
3619
|
+
margin-top: 2px;
|
|
3620
|
+
}
|
|
3621
|
+
|
|
3622
|
+
.cpk-ml__footer-threads {
|
|
3623
|
+
font-size: 10px;
|
|
3624
|
+
color: #838389;
|
|
3625
|
+
}
|
|
3626
|
+
|
|
3627
|
+
.cpk-ml__footer-id {
|
|
3628
|
+
font-family: "Spline Sans Mono", monospace;
|
|
3629
|
+
font-size: 9px;
|
|
3630
|
+
color: #c0c0c8;
|
|
3631
|
+
}
|
|
3632
|
+
|
|
3633
|
+
/* ── Empty state ── */
|
|
3634
|
+
.cpk-ml__empty {
|
|
3635
|
+
padding: 32px 16px;
|
|
3636
|
+
text-align: center;
|
|
3637
|
+
color: #838389;
|
|
3638
|
+
font-size: 12px;
|
|
3639
|
+
display: flex;
|
|
3640
|
+
flex-direction: column;
|
|
3641
|
+
align-items: center;
|
|
3642
|
+
gap: 8px;
|
|
3643
|
+
}
|
|
3644
|
+
|
|
3645
|
+
.cpk-ml__empty-icon {
|
|
3646
|
+
color: #c0c0c8;
|
|
3647
|
+
}
|
|
3648
|
+
`;
|
|
3649
|
+
|
|
3650
|
+
/** Memories that pass the current text search (before kind filter). */
|
|
3651
|
+
private get searchFiltered(): Memory[] {
|
|
3652
|
+
const q = this.search.trim().toLowerCase();
|
|
3653
|
+
if (!q) return this.memories;
|
|
3654
|
+
return this.memories.filter((m) => m.content.toLowerCase().includes(q));
|
|
3655
|
+
}
|
|
3656
|
+
|
|
3657
|
+
/** Memories that pass both search and kind filter. */
|
|
3658
|
+
private get filtered(): Memory[] {
|
|
3659
|
+
const searched = this.searchFiltered;
|
|
3660
|
+
if (this.kind === "all") return searched;
|
|
3661
|
+
return searched.filter((m) => m.kind === this.kind);
|
|
3662
|
+
}
|
|
3663
|
+
|
|
3664
|
+
/** Count of search-filtered memories for a given kind (for segment labels). */
|
|
3665
|
+
private countForKind(kind: Exclude<MemoryKindFilter, "all">): number {
|
|
3666
|
+
return this.searchFiltered.filter((m) => m.kind === kind).length;
|
|
3667
|
+
}
|
|
3668
|
+
|
|
3669
|
+
private onSearchInput = (event: Event): void => {
|
|
3670
|
+
this.search = (event.target as HTMLInputElement).value;
|
|
3671
|
+
};
|
|
3672
|
+
|
|
3673
|
+
private onKindClick = (event: Event): void => {
|
|
3674
|
+
const seg = (event.target as HTMLElement).closest("[data-kind]");
|
|
3675
|
+
if (!seg) return;
|
|
3676
|
+
const k = (seg as HTMLElement).dataset["kind"] as MemoryKindFilter;
|
|
3677
|
+
this.kind = k;
|
|
3678
|
+
};
|
|
3679
|
+
|
|
3680
|
+
/** Truncate an id to first-4…last-4 characters. */
|
|
3681
|
+
private shortId(id: string): string {
|
|
3682
|
+
if (id.length <= 12) return id;
|
|
3683
|
+
return `${id.slice(0, 4)}…${id.slice(-4)}`;
|
|
3684
|
+
}
|
|
3685
|
+
|
|
3686
|
+
private renderKindBadge(kind: string): TemplateResult {
|
|
3687
|
+
return html`<span class="cpk-ml__kind-badge cpk-ml__kind-badge--${kind}"
|
|
3688
|
+
>${kind}</span
|
|
3689
|
+
>`;
|
|
3690
|
+
}
|
|
3691
|
+
|
|
3692
|
+
private renderEmpty(): TemplateResult {
|
|
3693
|
+
const q = this.search.trim();
|
|
3694
|
+
if (this.memories.length === 0) {
|
|
3695
|
+
return html`
|
|
3696
|
+
<div class="cpk-ml__empty">
|
|
3697
|
+
<svg
|
|
3698
|
+
width="24"
|
|
3699
|
+
height="24"
|
|
3700
|
+
viewBox="0 0 24 24"
|
|
3701
|
+
fill="none"
|
|
3702
|
+
stroke="currentColor"
|
|
3703
|
+
stroke-width="1.5"
|
|
3704
|
+
stroke-linecap="round"
|
|
3705
|
+
stroke-linejoin="round"
|
|
3706
|
+
class="cpk-ml__empty-icon"
|
|
3707
|
+
>
|
|
3708
|
+
<ellipse cx="12" cy="5" rx="9" ry="3" />
|
|
3709
|
+
<path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3" />
|
|
3710
|
+
<path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5" />
|
|
3711
|
+
</svg>
|
|
3712
|
+
No memories yet — tell the agent a durable fact and watch it appear.
|
|
3713
|
+
</div>
|
|
3714
|
+
`;
|
|
3715
|
+
}
|
|
3716
|
+
if (q) {
|
|
3717
|
+
return html`
|
|
3718
|
+
<div class="cpk-ml__empty">
|
|
3719
|
+
No memories match “${q}”.
|
|
3720
|
+
</div>
|
|
3721
|
+
`;
|
|
3722
|
+
}
|
|
3723
|
+
return html`
|
|
3724
|
+
<div class="cpk-ml__empty">No ${this.kind} memories yet.</div>
|
|
3725
|
+
`;
|
|
3726
|
+
}
|
|
3727
|
+
|
|
3728
|
+
render() {
|
|
3729
|
+
const filtered = this.filtered;
|
|
3730
|
+
const kinds: Array<Exclude<MemoryKindFilter, "all">> = [
|
|
3731
|
+
"topical",
|
|
3732
|
+
"episodic",
|
|
3733
|
+
"operational",
|
|
3734
|
+
];
|
|
3735
|
+
|
|
3736
|
+
return html`
|
|
3737
|
+
<div class="cpk-ml">
|
|
3738
|
+
<!-- Search -->
|
|
3739
|
+
<div class="cpk-ml__search">
|
|
3740
|
+
<input
|
|
3741
|
+
type="text"
|
|
3742
|
+
placeholder="Search memories…"
|
|
3743
|
+
.value=${this.search}
|
|
3744
|
+
@input=${this.onSearchInput}
|
|
3745
|
+
class="cpk-ml__search-input"
|
|
3746
|
+
/>
|
|
3747
|
+
</div>
|
|
3748
|
+
|
|
3749
|
+
<!-- Kind filter -->
|
|
3750
|
+
<div class="cpk-ml__filter" @click=${this.onKindClick}>
|
|
3751
|
+
<button
|
|
3752
|
+
class="cpk-ml__filter-seg ${this.kind === "all" ? "cpk-ml__filter-seg--active" : ""}"
|
|
3753
|
+
data-kind="all"
|
|
3754
|
+
>
|
|
3755
|
+
All<span class="cpk-ml__filter-count">${this.searchFiltered.length}</span>
|
|
3756
|
+
</button>
|
|
3757
|
+
${kinds.map(
|
|
3758
|
+
(k) => html`
|
|
3759
|
+
<button
|
|
3760
|
+
class="cpk-ml__filter-seg ${this.kind === k ? "cpk-ml__filter-seg--active" : ""}"
|
|
3761
|
+
data-kind="${k}"
|
|
3762
|
+
>
|
|
3763
|
+
${k}<span class="cpk-ml__filter-count">${this.countForKind(k)}</span>
|
|
3764
|
+
</button>
|
|
3765
|
+
`,
|
|
3766
|
+
)}
|
|
3767
|
+
</div>
|
|
3768
|
+
|
|
3769
|
+
<!-- Memory list -->
|
|
3770
|
+
<div class="cpk-ml__list">
|
|
3771
|
+
${filtered.map(
|
|
3772
|
+
(m) => html`
|
|
3773
|
+
<div class="cpk-ml__card">
|
|
3774
|
+
<div class="cpk-ml__card-badges">
|
|
3775
|
+
${this.renderKindBadge(m.kind)}
|
|
3776
|
+
<span class="cpk-ml__scope-badge">${m.scope}</span>
|
|
3777
|
+
</div>
|
|
3778
|
+
<div class="cpk-ml__content">${m.content}</div>
|
|
3779
|
+
<div class="cpk-ml__footer">
|
|
3780
|
+
<span class="cpk-ml__footer-threads"
|
|
3781
|
+
>${m.sourceThreadIds.length} source thread${m.sourceThreadIds.length === 1 ? "" : "s"}</span
|
|
3782
|
+
>
|
|
3783
|
+
<span class="cpk-ml__footer-id">${this.shortId(m.id)}</span>
|
|
3784
|
+
</div>
|
|
3785
|
+
</div>
|
|
3786
|
+
`,
|
|
3787
|
+
)}
|
|
3788
|
+
${filtered.length === 0 ? this.renderEmpty() : nothing}
|
|
3789
|
+
</div>
|
|
3790
|
+
</div>
|
|
3791
|
+
`;
|
|
3792
|
+
}
|
|
3793
|
+
}
|
|
3794
|
+
|
|
3421
3795
|
// Backwards-compatible internal element name used by the full CopilotKit
|
|
3422
3796
|
// Inspector shell. Keep this class thin so the public body remains the single
|
|
3423
3797
|
// implementation.
|
|
@@ -3432,6 +3806,9 @@ if (!customElements.get(THREAD_INSPECTOR_TAG)) {
|
|
|
3432
3806
|
if (!customElements.get("cpk-thread-details")) {
|
|
3433
3807
|
customElements.define("cpk-thread-details", ɵCpkThreadDetails);
|
|
3434
3808
|
}
|
|
3809
|
+
if (!customElements.get("cpk-memory-list")) {
|
|
3810
|
+
customElements.define("cpk-memory-list", CpkMemoryList);
|
|
3811
|
+
}
|
|
3435
3812
|
|
|
3436
3813
|
export class WebInspectorElement extends LitElement {
|
|
3437
3814
|
static properties = {
|
|
@@ -3442,6 +3819,25 @@ export class WebInspectorElement extends LitElement {
|
|
|
3442
3819
|
private _core: CopilotKitCore | null = null;
|
|
3443
3820
|
private coreSubscriber: CopilotKitCoreSubscriber | null = null;
|
|
3444
3821
|
private coreUnsubscribe: (() => void) | null = null;
|
|
3822
|
+
private _memories: Memory[] = [];
|
|
3823
|
+
private _memoriesLoading = false;
|
|
3824
|
+
private _memoriesError: Error | null = null;
|
|
3825
|
+
private _memoriesAvailable = true;
|
|
3826
|
+
// Realtime-connection health, independent of `_memoriesAvailable` (the REST
|
|
3827
|
+
// list route). Drives the "live" indicator: only "connected" shows "live".
|
|
3828
|
+
private _memoriesRealtimeStatus: MemoryRealtimeStatus = "connecting";
|
|
3829
|
+
private _memoryUnsub: (() => void) | null = null;
|
|
3830
|
+
// Lazy-subscription guard. The memory store is created + started + opens
|
|
3831
|
+
// realtime the first time `core.getMemoryStore()` is called, so we defer
|
|
3832
|
+
// that call until the user actually activates the Memories tab (see
|
|
3833
|
+
// `ensureMemorySubscription`). This flag prevents a repeated tab click from
|
|
3834
|
+
// double-subscribing; `detachFromCore` resets it so a later attach + tab
|
|
3835
|
+
// activation re-subscribes cleanly.
|
|
3836
|
+
private _memorySubscribed = false;
|
|
3837
|
+
// True when the attached core predates `getMemoryStore` (older @copilotkit
|
|
3838
|
+
// SDK). Distinct from `_memoriesAvailable` (memory not enabled on an
|
|
3839
|
+
// otherwise-current deployment) so the teaser can show upgrade-the-SDK copy.
|
|
3840
|
+
private _memoryStoreUnsupported = false;
|
|
3445
3841
|
private runtimeStatus: CopilotKitCoreRuntimeConnectionStatus | null = null;
|
|
3446
3842
|
private coreProperties: Readonly<Record<string, unknown>> = {};
|
|
3447
3843
|
private lastCoreError: {
|
|
@@ -3619,6 +4015,7 @@ export class WebInspectorElement extends LitElement {
|
|
|
3619
4015
|
label: "Threads",
|
|
3620
4016
|
icon: "MessageSquare" as LucideIconName,
|
|
3621
4017
|
},
|
|
4018
|
+
{ key: "memories", label: "Learning", icon: "Brain" as LucideIconName },
|
|
3622
4019
|
];
|
|
3623
4020
|
}
|
|
3624
4021
|
|
|
@@ -3660,6 +4057,17 @@ export class WebInspectorElement extends LitElement {
|
|
|
3660
4057
|
};
|
|
3661
4058
|
}
|
|
3662
4059
|
|
|
4060
|
+
private getMemoriesTelemetryProps(): InspectorMemoryTelemetryProps {
|
|
4061
|
+
const distinctId = !this.core?.telemetryDisabled
|
|
4062
|
+
? getTelemetryDistinctIdForUrl()
|
|
4063
|
+
: null;
|
|
4064
|
+
return {
|
|
4065
|
+
posthog_distinct_id: distinctId ?? undefined,
|
|
4066
|
+
memory_count: this._memories.length,
|
|
4067
|
+
available: this._memoriesAvailable,
|
|
4068
|
+
};
|
|
4069
|
+
}
|
|
4070
|
+
|
|
3663
4071
|
private getIntelligenceSignupUrl(): string {
|
|
3664
4072
|
return this.appendRefParam(INTELLIGENCE_SIGNUP_URL, "cpk-inspector");
|
|
3665
4073
|
}
|
|
@@ -3886,6 +4294,91 @@ export class WebInspectorElement extends LitElement {
|
|
|
3886
4294
|
if (core.context) {
|
|
3887
4295
|
this.contextStore = this.normalizeContextStore(core.context);
|
|
3888
4296
|
}
|
|
4297
|
+
|
|
4298
|
+
// NOTE: the memory store is intentionally NOT touched here. Calling
|
|
4299
|
+
// `core.getMemoryStore()` lazily creates + `.start()`s the store and opens
|
|
4300
|
+
// a realtime connection, so merely attaching the inspector would spin up a
|
|
4301
|
+
// memory store + realtime even in apps that never use memory. Instead, the
|
|
4302
|
+
// store is created + subscribed on first Memories-tab activation via
|
|
4303
|
+
// `ensureMemorySubscription` (user-initiated, acceptable). Attaching the
|
|
4304
|
+
// inspector creates nothing.
|
|
4305
|
+
//
|
|
4306
|
+
// Exception: if the Memories tab is ALREADY the active tab when core is
|
|
4307
|
+
// wired (e.g. core attaches after `firstUpdated` restored a persisted
|
|
4308
|
+
// `selectedMenu: "memories"`), subscribe now so the live store + realtime
|
|
4309
|
+
// status paint instead of the stuck defaults. This preserves INSP-1 (no
|
|
4310
|
+
// unconditional subscribe on attach) because it is gated on the active tab,
|
|
4311
|
+
// and is safe to call when already subscribed — `ensureMemorySubscription`
|
|
4312
|
+
// early-returns on `_memorySubscribed`.
|
|
4313
|
+
if (this.selectedMenu === "memories") {
|
|
4314
|
+
this.ensureMemorySubscription();
|
|
4315
|
+
}
|
|
4316
|
+
}
|
|
4317
|
+
|
|
4318
|
+
/**
|
|
4319
|
+
* Lazily subscribes to the singleton memory store the first time the user
|
|
4320
|
+
* activates the Memories tab. This is deferred out of `attachToCore` because
|
|
4321
|
+
* `core.getMemoryStore()` is what creates + starts the store and opens
|
|
4322
|
+
* realtime — doing it on attach would start memory for apps that never use
|
|
4323
|
+
* it. Idempotent: repeated tab activations are guarded by
|
|
4324
|
+
* `_memorySubscribed`. On an older @copilotkit/core without `getMemoryStore`,
|
|
4325
|
+
* records the unsupported state so the teaser can guide an SDK upgrade.
|
|
4326
|
+
*/
|
|
4327
|
+
private ensureMemorySubscription(): void {
|
|
4328
|
+
if (this._memorySubscribed) {
|
|
4329
|
+
return;
|
|
4330
|
+
}
|
|
4331
|
+
const core = this._core;
|
|
4332
|
+
if (!core) {
|
|
4333
|
+
return;
|
|
4334
|
+
}
|
|
4335
|
+
|
|
4336
|
+
// Guard like getThreadStores: older @copilotkit/core has no getMemoryStore.
|
|
4337
|
+
// When absent, flag the unsupported state so the teaser shows upgrade copy
|
|
4338
|
+
// instead of throwing a TypeError that would break the entire inspector.
|
|
4339
|
+
if (typeof core.getMemoryStore !== "function") {
|
|
4340
|
+
this._memoryStoreUnsupported = true;
|
|
4341
|
+
this._memoriesAvailable = false;
|
|
4342
|
+
this.requestUpdate();
|
|
4343
|
+
return;
|
|
4344
|
+
}
|
|
4345
|
+
|
|
4346
|
+
this._memorySubscribed = true;
|
|
4347
|
+
this._memoryStoreUnsupported = false;
|
|
4348
|
+
|
|
4349
|
+
// First touch of getMemoryStore() — creates + starts the store, opens realtime.
|
|
4350
|
+
const memoryStore = core.getMemoryStore();
|
|
4351
|
+
const ms = memoryStore.getState();
|
|
4352
|
+
this._memories = ɵselectMemories(ms);
|
|
4353
|
+
this._memoriesLoading = ɵselectMemoriesIsLoading(ms);
|
|
4354
|
+
this._memoriesError = ɵselectMemoriesError(ms);
|
|
4355
|
+
this._memoriesAvailable = ɵselectMemoriesAvailable(ms);
|
|
4356
|
+
this._memoriesRealtimeStatus = ɵselectMemoriesRealtimeStatus(ms);
|
|
4357
|
+
const memSubs = [
|
|
4358
|
+
memoryStore.select(ɵselectMemories).subscribe((v) => {
|
|
4359
|
+
this._memories = v;
|
|
4360
|
+
this.requestUpdate();
|
|
4361
|
+
}),
|
|
4362
|
+
memoryStore.select(ɵselectMemoriesIsLoading).subscribe((v) => {
|
|
4363
|
+
this._memoriesLoading = v;
|
|
4364
|
+
this.requestUpdate();
|
|
4365
|
+
}),
|
|
4366
|
+
memoryStore.select(ɵselectMemoriesError).subscribe((v) => {
|
|
4367
|
+
this._memoriesError = v;
|
|
4368
|
+
this.requestUpdate();
|
|
4369
|
+
}),
|
|
4370
|
+
memoryStore.select(ɵselectMemoriesAvailable).subscribe((v) => {
|
|
4371
|
+
this._memoriesAvailable = v;
|
|
4372
|
+
this.requestUpdate();
|
|
4373
|
+
}),
|
|
4374
|
+
// Group E — realtime connection health.
|
|
4375
|
+
memoryStore.select(ɵselectMemoriesRealtimeStatus).subscribe((v) => {
|
|
4376
|
+
this._memoriesRealtimeStatus = v;
|
|
4377
|
+
this.requestUpdate();
|
|
4378
|
+
}),
|
|
4379
|
+
];
|
|
4380
|
+
this._memoryUnsub = () => memSubs.forEach((s) => s.unsubscribe());
|
|
4381
|
+
this.requestUpdate();
|
|
3889
4382
|
}
|
|
3890
4383
|
|
|
3891
4384
|
private detachFromCore(): void {
|
|
@@ -3893,6 +4386,17 @@ export class WebInspectorElement extends LitElement {
|
|
|
3893
4386
|
this.coreUnsubscribe();
|
|
3894
4387
|
this.coreUnsubscribe = null;
|
|
3895
4388
|
}
|
|
4389
|
+
this._memoryUnsub?.();
|
|
4390
|
+
this._memoryUnsub = null;
|
|
4391
|
+
this._memories = [];
|
|
4392
|
+
this._memoriesLoading = false;
|
|
4393
|
+
this._memoriesError = null;
|
|
4394
|
+
this._memoriesAvailable = true;
|
|
4395
|
+
this._memoriesRealtimeStatus = "connecting";
|
|
4396
|
+
// Reset the lazy-subscription guards so a later attach + Memories-tab
|
|
4397
|
+
// activation re-subscribes (and re-evaluates SDK support) cleanly.
|
|
4398
|
+
this._memorySubscribed = false;
|
|
4399
|
+
this._memoryStoreUnsupported = false;
|
|
3896
4400
|
this.coreSubscriber = null;
|
|
3897
4401
|
this.runtimeStatus = null;
|
|
3898
4402
|
this.lastCoreError = null;
|
|
@@ -5439,6 +5943,18 @@ ${argsString}</pre
|
|
|
5439
5943
|
|
|
5440
5944
|
this.hydrateStateFromStorage();
|
|
5441
5945
|
|
|
5946
|
+
// `hydrateStateFromStorage` may have restored `selectedMenu: "memories"`.
|
|
5947
|
+
// The memory subscription is normally created on a Memories-tab CLICK via
|
|
5948
|
+
// `handleMenuSelect`, which never fires when the tab boots already active —
|
|
5949
|
+
// leaving the realtime indicator stuck on the default "connecting" and the
|
|
5950
|
+
// list empty until the user toggles tabs. Subscribe now when the Memories
|
|
5951
|
+
// tab is the active tab. Gated on the active tab to preserve INSP-1 (no
|
|
5952
|
+
// unconditional subscribe), and safe if core is not yet attached or already
|
|
5953
|
+
// subscribed — `ensureMemorySubscription` early-returns in both cases.
|
|
5954
|
+
if (this.selectedMenu === "memories") {
|
|
5955
|
+
this.ensureMemorySubscription();
|
|
5956
|
+
}
|
|
5957
|
+
|
|
5442
5958
|
// Apply docking styles if open and docked (skip transition on initial load)
|
|
5443
5959
|
if (this.isOpen && this.dockMode !== "floating") {
|
|
5444
5960
|
this.applyDockStyles(true);
|
|
@@ -6896,6 +7412,10 @@ ${argsString}</pre
|
|
|
6896
7412
|
return this.renderThreadsView();
|
|
6897
7413
|
}
|
|
6898
7414
|
|
|
7415
|
+
if (this.selectedMenu === "memories") {
|
|
7416
|
+
return this.renderMemoriesView();
|
|
7417
|
+
}
|
|
7418
|
+
|
|
6899
7419
|
if (this.selectedMenu === "settings") {
|
|
6900
7420
|
return this.renderSettingsPanel();
|
|
6901
7421
|
}
|
|
@@ -7343,6 +7863,346 @@ ${argsString}</pre
|
|
|
7343
7863
|
`;
|
|
7344
7864
|
}
|
|
7345
7865
|
|
|
7866
|
+
/**
|
|
7867
|
+
* Renders the realtime-connection indicator in the memory-store header.
|
|
7868
|
+
* Only `"connected"` shows the live (green-dot) state; `"connecting"` shows a
|
|
7869
|
+
* muted amber "reconnecting" and `"unavailable"` a muted grey "offline", so
|
|
7870
|
+
* the indicator never claims "live" over a frozen snapshot once the realtime
|
|
7871
|
+
* socket has permanently given up.
|
|
7872
|
+
*/
|
|
7873
|
+
private renderMemoryRealtimeIndicator() {
|
|
7874
|
+
const status = this._memoriesRealtimeStatus;
|
|
7875
|
+
const connected = status === "connected";
|
|
7876
|
+
const dotColor = connected
|
|
7877
|
+
? "#22c55e"
|
|
7878
|
+
: status === "connecting"
|
|
7879
|
+
? "#f59e0b"
|
|
7880
|
+
: "#9ca3af";
|
|
7881
|
+
const label =
|
|
7882
|
+
status === "connected"
|
|
7883
|
+
? "live"
|
|
7884
|
+
: status === "connecting"
|
|
7885
|
+
? "reconnecting"
|
|
7886
|
+
: "offline";
|
|
7887
|
+
return html`
|
|
7888
|
+
<span
|
|
7889
|
+
style="
|
|
7890
|
+
display: inline-flex;
|
|
7891
|
+
align-items: center;
|
|
7892
|
+
gap: 4px;
|
|
7893
|
+
font-size: 10px;
|
|
7894
|
+
font-weight: 500;
|
|
7895
|
+
color: ${connected ? "#57575b" : "#838389"};
|
|
7896
|
+
"
|
|
7897
|
+
>
|
|
7898
|
+
<span
|
|
7899
|
+
style="
|
|
7900
|
+
display: inline-block;
|
|
7901
|
+
width: 6px;
|
|
7902
|
+
height: 6px;
|
|
7903
|
+
border-radius: 50%;
|
|
7904
|
+
background: ${dotColor};
|
|
7905
|
+
"
|
|
7906
|
+
></span>
|
|
7907
|
+
${label}
|
|
7908
|
+
</span>
|
|
7909
|
+
`;
|
|
7910
|
+
}
|
|
7911
|
+
|
|
7912
|
+
private renderMemoriesView() {
|
|
7913
|
+
// 1. Locked teaser — intelligence not configured or memories not available.
|
|
7914
|
+
if (!this.core?.intelligence || !this._memoriesAvailable) {
|
|
7915
|
+
return html`
|
|
7916
|
+
<div
|
|
7917
|
+
style="
|
|
7918
|
+
position: relative;
|
|
7919
|
+
height: 100%;
|
|
7920
|
+
display: flex;
|
|
7921
|
+
align-items: center;
|
|
7922
|
+
justify-content: center;
|
|
7923
|
+
padding: 32px;
|
|
7924
|
+
overflow: hidden;
|
|
7925
|
+
background: #ffffff;
|
|
7926
|
+
"
|
|
7927
|
+
>
|
|
7928
|
+
${this.renderThreadsLockedBackgroundMockup()}
|
|
7929
|
+
<div
|
|
7930
|
+
aria-hidden="true"
|
|
7931
|
+
style="
|
|
7932
|
+
position: absolute;
|
|
7933
|
+
inset: 0;
|
|
7934
|
+
pointer-events: none;
|
|
7935
|
+
background:
|
|
7936
|
+
radial-gradient(circle at center, rgba(255,255,255,0.9) 0, rgba(255,255,255,0.78) 24%, rgba(255,255,255,0.34) 48%, rgba(255,255,255,0.56) 100%);
|
|
7937
|
+
"
|
|
7938
|
+
></div>
|
|
7939
|
+
<div
|
|
7940
|
+
style="
|
|
7941
|
+
position: relative;
|
|
7942
|
+
z-index: 1;
|
|
7943
|
+
max-width: 440px;
|
|
7944
|
+
text-align: center;
|
|
7945
|
+
color: #57575b;
|
|
7946
|
+
"
|
|
7947
|
+
>
|
|
7948
|
+
<div
|
|
7949
|
+
aria-hidden="true"
|
|
7950
|
+
style="
|
|
7951
|
+
margin: 0 auto 18px;
|
|
7952
|
+
display: flex;
|
|
7953
|
+
justify-content: center;
|
|
7954
|
+
"
|
|
7955
|
+
>
|
|
7956
|
+
<div
|
|
7957
|
+
style="
|
|
7958
|
+
display: flex;
|
|
7959
|
+
height: 44px;
|
|
7960
|
+
width: 44px;
|
|
7961
|
+
align-items: center;
|
|
7962
|
+
justify-content: center;
|
|
7963
|
+
border: 1px solid #dfd6fb;
|
|
7964
|
+
border-radius: 8px;
|
|
7965
|
+
background: #eee6fe;
|
|
7966
|
+
color: #57575b;
|
|
7967
|
+
box-shadow: 0 8px 18px rgba(87, 87, 91, 0.14);
|
|
7968
|
+
"
|
|
7969
|
+
>
|
|
7970
|
+
${this.renderIcon("Lock")}
|
|
7971
|
+
</div>
|
|
7972
|
+
</div>
|
|
7973
|
+
<h2
|
|
7974
|
+
style="
|
|
7975
|
+
margin: 0 0 8px;
|
|
7976
|
+
font-size: 16px;
|
|
7977
|
+
line-height: 1.35;
|
|
7978
|
+
font-weight: 600;
|
|
7979
|
+
color: #010507;
|
|
7980
|
+
"
|
|
7981
|
+
>
|
|
7982
|
+
Long-term memory
|
|
7983
|
+
</h2>
|
|
7984
|
+
<p
|
|
7985
|
+
style="
|
|
7986
|
+
margin: 0 auto 18px;
|
|
7987
|
+
max-width: 380px;
|
|
7988
|
+
font-size: 13px;
|
|
7989
|
+
line-height: 1.55;
|
|
7990
|
+
color: #57575b;
|
|
7991
|
+
"
|
|
7992
|
+
>
|
|
7993
|
+
${
|
|
7994
|
+
this._memoryStoreUnsupported
|
|
7995
|
+
? "Long-term memory isn't available in this version of the @copilotkit SDK. Upgrade @copilotkit/core (and @copilotkit/react) to a version that supports memory."
|
|
7996
|
+
: "Long-term memory isn't enabled on this deployment."
|
|
7997
|
+
}
|
|
7998
|
+
</p>
|
|
7999
|
+
<div
|
|
8000
|
+
style="
|
|
8001
|
+
display: flex;
|
|
8002
|
+
flex-wrap: wrap;
|
|
8003
|
+
justify-content: center;
|
|
8004
|
+
gap: 8px;
|
|
8005
|
+
"
|
|
8006
|
+
>
|
|
8007
|
+
<a
|
|
8008
|
+
href=${this.getTalkToEngineerUrl()}
|
|
8009
|
+
target="_blank"
|
|
8010
|
+
rel="noopener"
|
|
8011
|
+
style="
|
|
8012
|
+
display: inline-flex;
|
|
8013
|
+
min-height: 34px;
|
|
8014
|
+
align-items: center;
|
|
8015
|
+
justify-content: center;
|
|
8016
|
+
gap: 6px;
|
|
8017
|
+
border-radius: 6px;
|
|
8018
|
+
background: #010507;
|
|
8019
|
+
padding: 8px 12px;
|
|
8020
|
+
font-size: 12px;
|
|
8021
|
+
font-weight: 600;
|
|
8022
|
+
color: #ffffff;
|
|
8023
|
+
text-decoration: none;
|
|
8024
|
+
"
|
|
8025
|
+
@click=${this.handleThreadsTalkToEngineerClick}
|
|
8026
|
+
>
|
|
8027
|
+
Talk to an Engineer
|
|
8028
|
+
</a>
|
|
8029
|
+
<a
|
|
8030
|
+
href=${this.getIntelligenceSignupUrl()}
|
|
8031
|
+
target="_blank"
|
|
8032
|
+
rel="noopener"
|
|
8033
|
+
style="
|
|
8034
|
+
display: inline-flex;
|
|
8035
|
+
min-height: 34px;
|
|
8036
|
+
align-items: center;
|
|
8037
|
+
justify-content: center;
|
|
8038
|
+
gap: 6px;
|
|
8039
|
+
border-radius: 6px;
|
|
8040
|
+
border: 1px solid #dbdbe5;
|
|
8041
|
+
background: #ffffff;
|
|
8042
|
+
padding: 8px 12px;
|
|
8043
|
+
font-size: 12px;
|
|
8044
|
+
font-weight: 600;
|
|
8045
|
+
color: #57575b;
|
|
8046
|
+
text-decoration: none;
|
|
8047
|
+
"
|
|
8048
|
+
@click=${this.handleThreadsIntelligenceSignupClick}
|
|
8049
|
+
>
|
|
8050
|
+
Sign up for Intelligence
|
|
8051
|
+
</a>
|
|
8052
|
+
</div>
|
|
8053
|
+
</div>
|
|
8054
|
+
</div>
|
|
8055
|
+
`;
|
|
8056
|
+
}
|
|
8057
|
+
|
|
8058
|
+
// 2. Full-screen error — only for a snapshot-LOAD failure (no memories
|
|
8059
|
+
// loaded). A mutation failure that arrives while memories are already on
|
|
8060
|
+
// screen must NOT blank the list; it is surfaced inline below (step 4).
|
|
8061
|
+
if (this._memoriesError && this._memories.length === 0) {
|
|
8062
|
+
return html`
|
|
8063
|
+
<div
|
|
8064
|
+
style="
|
|
8065
|
+
display: flex;
|
|
8066
|
+
height: 100%;
|
|
8067
|
+
flex-direction: column;
|
|
8068
|
+
align-items: center;
|
|
8069
|
+
justify-content: center;
|
|
8070
|
+
gap: 8px;
|
|
8071
|
+
color: #838389;
|
|
8072
|
+
"
|
|
8073
|
+
>
|
|
8074
|
+
<svg
|
|
8075
|
+
width="24"
|
|
8076
|
+
height="24"
|
|
8077
|
+
viewBox="0 0 24 24"
|
|
8078
|
+
fill="none"
|
|
8079
|
+
stroke="#c0333a"
|
|
8080
|
+
stroke-width="1.5"
|
|
8081
|
+
stroke-linecap="round"
|
|
8082
|
+
stroke-linejoin="round"
|
|
8083
|
+
>
|
|
8084
|
+
<circle cx="12" cy="12" r="10" />
|
|
8085
|
+
<line x1="12" y1="8" x2="12" y2="12" />
|
|
8086
|
+
<line x1="12" y1="16" x2="12.01" y2="16" />
|
|
8087
|
+
</svg>
|
|
8088
|
+
<span style="font-size: 13px; color: #c0333a;">
|
|
8089
|
+
Failed to load memories
|
|
8090
|
+
</span>
|
|
8091
|
+
<span
|
|
8092
|
+
style="
|
|
8093
|
+
max-width: 320px;
|
|
8094
|
+
text-align: center;
|
|
8095
|
+
font-size: 11px;
|
|
8096
|
+
line-height: 1.5;
|
|
8097
|
+
color: #c0333a;
|
|
8098
|
+
"
|
|
8099
|
+
>
|
|
8100
|
+
${this._memoriesError.message}
|
|
8101
|
+
</span>
|
|
8102
|
+
</div>
|
|
8103
|
+
`;
|
|
8104
|
+
}
|
|
8105
|
+
|
|
8106
|
+
// 3. Initial loading placeholder (no memories yet to show behind it).
|
|
8107
|
+
if (this._memoriesLoading && this._memories.length === 0) {
|
|
8108
|
+
return html`
|
|
8109
|
+
<div
|
|
8110
|
+
style="
|
|
8111
|
+
display: flex;
|
|
8112
|
+
height: 100%;
|
|
8113
|
+
flex-direction: column;
|
|
8114
|
+
align-items: center;
|
|
8115
|
+
justify-content: center;
|
|
8116
|
+
gap: 8px;
|
|
8117
|
+
color: #838389;
|
|
8118
|
+
"
|
|
8119
|
+
>
|
|
8120
|
+
<svg
|
|
8121
|
+
width="24"
|
|
8122
|
+
height="24"
|
|
8123
|
+
viewBox="0 0 24 24"
|
|
8124
|
+
fill="none"
|
|
8125
|
+
stroke="#c0c0c8"
|
|
8126
|
+
stroke-width="1.5"
|
|
8127
|
+
stroke-linecap="round"
|
|
8128
|
+
stroke-linejoin="round"
|
|
8129
|
+
>
|
|
8130
|
+
<path d="M21 12a9 9 0 1 1-6.219-8.56" />
|
|
8131
|
+
</svg>
|
|
8132
|
+
<span style="font-size: 13px">Loading memories…</span>
|
|
8133
|
+
</div>
|
|
8134
|
+
`;
|
|
8135
|
+
}
|
|
8136
|
+
|
|
8137
|
+
// 4. Content — header + memory list.
|
|
8138
|
+
return html`
|
|
8139
|
+
<div style="display:flex;height:100%;overflow:hidden;flex-direction:column;">
|
|
8140
|
+
<div class="cpk-section-header" style="display:flex;align-items:center;justify-content:space-between;">
|
|
8141
|
+
<h4>Learning</h4>
|
|
8142
|
+
<div style="display:flex;align-items:center;gap:6px;">
|
|
8143
|
+
${this.renderMemoryRealtimeIndicator()}
|
|
8144
|
+
<span
|
|
8145
|
+
style="
|
|
8146
|
+
font-size: 11px;
|
|
8147
|
+
font-weight: 500;
|
|
8148
|
+
color: #57575b;
|
|
8149
|
+
background: rgba(0,0,0,0.07);
|
|
8150
|
+
border-radius: 9999px;
|
|
8151
|
+
padding: 1px 7px;
|
|
8152
|
+
"
|
|
8153
|
+
>
|
|
8154
|
+
${this._memories.length}
|
|
8155
|
+
</span>
|
|
8156
|
+
</div>
|
|
8157
|
+
</div>
|
|
8158
|
+
${
|
|
8159
|
+
this._memoriesError
|
|
8160
|
+
? html`
|
|
8161
|
+
<div
|
|
8162
|
+
role="alert"
|
|
8163
|
+
style="
|
|
8164
|
+
display: flex;
|
|
8165
|
+
align-items: flex-start;
|
|
8166
|
+
gap: 8px;
|
|
8167
|
+
flex-shrink: 0;
|
|
8168
|
+
border-bottom: 1px solid #f1c7c9;
|
|
8169
|
+
background: #fdf3f3;
|
|
8170
|
+
padding: 8px 12px;
|
|
8171
|
+
color: #c0333a;
|
|
8172
|
+
font-size: 12px;
|
|
8173
|
+
line-height: 1.45;
|
|
8174
|
+
"
|
|
8175
|
+
>
|
|
8176
|
+
<svg
|
|
8177
|
+
width="16"
|
|
8178
|
+
height="16"
|
|
8179
|
+
viewBox="0 0 24 24"
|
|
8180
|
+
fill="none"
|
|
8181
|
+
stroke="#c0333a"
|
|
8182
|
+
stroke-width="1.5"
|
|
8183
|
+
stroke-linecap="round"
|
|
8184
|
+
stroke-linejoin="round"
|
|
8185
|
+
style="flex-shrink:0;margin-top:1px;"
|
|
8186
|
+
>
|
|
8187
|
+
<circle cx="12" cy="12" r="10" />
|
|
8188
|
+
<line x1="12" y1="8" x2="12" y2="12" />
|
|
8189
|
+
<line x1="12" y1="16" x2="12.01" y2="16" />
|
|
8190
|
+
</svg>
|
|
8191
|
+
<span>Action failed: ${this._memoriesError.message}</span>
|
|
8192
|
+
</div>
|
|
8193
|
+
`
|
|
8194
|
+
: nothing
|
|
8195
|
+
}
|
|
8196
|
+
<div style="flex:1;min-height:0;overflow:hidden;">
|
|
8197
|
+
<cpk-memory-list
|
|
8198
|
+
style="height:100%;"
|
|
8199
|
+
.memories=${this._memories}
|
|
8200
|
+
></cpk-memory-list>
|
|
8201
|
+
</div>
|
|
8202
|
+
</div>
|
|
8203
|
+
`;
|
|
8204
|
+
}
|
|
8205
|
+
|
|
7346
8206
|
private renderThreadsView() {
|
|
7347
8207
|
if (!this.areThreadEndpointsAvailable()) {
|
|
7348
8208
|
return this.renderThreadsLockedView();
|
|
@@ -8162,6 +9022,16 @@ ${prettyEvent}</pre
|
|
|
8162
9022
|
this.autoSelectLatestThread();
|
|
8163
9023
|
}
|
|
8164
9024
|
|
|
9025
|
+
if (key === "memories") {
|
|
9026
|
+
// Lazily create + subscribe to the memory store on first activation. This
|
|
9027
|
+
// is the only place that touches getMemoryStore(), so the store/realtime
|
|
9028
|
+
// are never started just by attaching the inspector.
|
|
9029
|
+
this.ensureMemorySubscription();
|
|
9030
|
+
if (previousMenu !== "memories" && !this.core?.telemetryDisabled) {
|
|
9031
|
+
trackMemoriesTabClicked(this.getMemoriesTelemetryProps());
|
|
9032
|
+
}
|
|
9033
|
+
}
|
|
9034
|
+
|
|
8165
9035
|
if (key === "ag-ui-events" || key === "agents") {
|
|
8166
9036
|
requestAnimationFrame(() => {
|
|
8167
9037
|
const scroller = this.shadowRoot?.getElementById("cpk-main-scroll");
|