@copilotkit/web-inspector 1.64.1 → 1.64.2-canary.1785366148

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -15,6 +15,12 @@ let _copilotkit_core = require("@copilotkit/core");
15
15
  //#region src/index.ts
16
16
  const WEB_INSPECTOR_TAG = "cpk-web-inspector";
17
17
  const THREAD_INSPECTOR_TAG = "cpk-thread-inspector";
18
+ /**
19
+ * User-facing label for the memory surface (nav item + view header). The menu
20
+ * KEY stays "memories" for persistence/telemetry stability; only the label
21
+ * changed from "Learning" to "Memory".
22
+ */
23
+ const MEMORY_VIEW_LABEL = "Memory";
18
24
  const EDGE_MARGIN = 16;
19
25
  const DRAG_THRESHOLD = 6;
20
26
  const MIN_WINDOW_WIDTH = 600;
@@ -37,6 +43,7 @@ const MAX_TOTAL_EVENTS = 500;
37
43
  const INTELLIGENCE_SIGNUP_URL = "https://go.copilotkit.ai/intelligence-signup";
38
44
  const THREADS_INTELLIGENCE_SIGNIN_URL = "https://dashboard.operations.copilotkit.ai/sign-in";
39
45
  const TALK_TO_ENGINEER_URL = "https://www.copilotkit.ai/talk-to-an-engineer";
46
+ const CAPABILITIES_TAB_LABEL = "Capabilities";
40
47
  const THREADS_DOCS_URL = "https://docs.copilotkit.ai/threads";
41
48
  const SELF_HOSTED_INTELLIGENCE_URL = "https://docs.copilotkit.ai/premium/self-hosting";
42
49
  const THREADS_EXAMPLE_OVERVIEW_VIDEO_URL = "https://cdn.copilotkit.ai/corp-site/videos/copilotkit-generative-ui-agentic-frontend-demo.webm";
@@ -67,6 +74,29 @@ const AGENT_EVENT_TYPES = [
67
74
  "ACTIVITY_SNAPSHOT",
68
75
  "ACTIVITY_DELTA"
69
76
  ];
77
+ /**
78
+ * Map core.tools (the registry INCLUDING disabled tools) into Capabilities-tab
79
+ * frontend-tool rows. Pure: no DOM, no `this`. Reads current on/off state from
80
+ * core.isToolEnabled(name, agentId?) per the A1 contract.
81
+ */
82
+ function buildCapabilityRows(core) {
83
+ const rows = [];
84
+ for (const tool of core.tools ?? []) {
85
+ const key = `${tool.agentId ?? ""}:${tool.name}`;
86
+ rows.push({
87
+ key,
88
+ name: tool.name,
89
+ description: tool.description,
90
+ agentId: tool.agentId,
91
+ enabled: core.isToolEnabled(tool.name, tool.agentId)
92
+ });
93
+ }
94
+ return rows.sort((a, b) => {
95
+ const agentCompare = (a.agentId ?? "").localeCompare(b.agentId ?? "");
96
+ if (agentCompare !== 0) return agentCompare;
97
+ return a.name.localeCompare(b.name);
98
+ });
99
+ }
70
100
  const THREADS_EXAMPLE_THREADS = [
71
101
  {
72
102
  id: "example-realtime-sync",
@@ -2845,10 +2875,45 @@ ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(stateValue))}</p
2845
2875
  `;
2846
2876
  }
2847
2877
  };
2878
+ /**
2879
+ * Normalizes a memory's raw recall score to a 0..1 relevance ratio relative to
2880
+ * the strongest result in the same result set. Recall scores are RRF scores
2881
+ * (relative), so a bar is only meaningful against the set max. Returns
2882
+ * `undefined` when no meaningful ranking exists (empty set, non-positive max,
2883
+ * missing score) so the caller renders no bar.
2884
+ */
2885
+ function normalizeRelevance(score, maxScore) {
2886
+ if (maxScore <= 0) return void 0;
2887
+ if (score === void 0 || !Number.isFinite(score)) return void 0;
2888
+ const ratio = score / maxScore;
2889
+ if (ratio <= 0) return 0;
2890
+ return ratio > 1 ? 1 : ratio;
2891
+ }
2892
+ /** Largest finite `score` across a result set, or 0 when none present. */
2893
+ function maxRecallScore(memories) {
2894
+ let max = 0;
2895
+ for (const m of memories) {
2896
+ const s = m.score;
2897
+ if (typeof s === "number" && Number.isFinite(s) && s > max) max = s;
2898
+ }
2899
+ return max;
2900
+ }
2901
+ /**
2902
+ * Percent width for a relevance bar. Mirrors the banking reference
2903
+ * (`max(6, round(rel*100))%`) so a matched-but-weak result still shows a sliver.
2904
+ * Returns a whole number in [6, 100].
2905
+ */
2906
+ function relevanceBarWidth(relevance) {
2907
+ return Math.max(6, Math.min(100, Math.round(relevance * 100)));
2908
+ }
2848
2909
  var CpkMemoryList = class extends lit.LitElement {
2849
2910
  constructor(..._args3) {
2850
2911
  super(..._args3);
2851
2912
  this.memories = [];
2913
+ this.recallResults = null;
2914
+ this.recallLoading = false;
2915
+ this.recallError = null;
2916
+ this.recallQueryText = "";
2852
2917
  this.search = "";
2853
2918
  this.kind = "all";
2854
2919
  this.onSearchInput = (event) => {
@@ -2859,10 +2924,39 @@ var CpkMemoryList = class extends lit.LitElement {
2859
2924
  if (!seg) return;
2860
2925
  this.kind = seg.dataset["kind"];
2861
2926
  };
2927
+ this.onRecallInput = (event) => {
2928
+ const value = event.target.value;
2929
+ this.recallQueryText = value;
2930
+ this.dispatchEvent(new CustomEvent("recallQueryChanged", {
2931
+ detail: value,
2932
+ bubbles: true,
2933
+ composed: true
2934
+ }));
2935
+ };
2936
+ this.onRecallSubmit = (event) => {
2937
+ event.preventDefault();
2938
+ const query = this.recallQueryText.trim();
2939
+ if (query.length === 0 || this.recallLoading) return;
2940
+ this.dispatchEvent(new CustomEvent("recallSubmitted", {
2941
+ detail: query,
2942
+ bubbles: true,
2943
+ composed: true
2944
+ }));
2945
+ };
2946
+ this.onRecallClear = () => {
2947
+ this.dispatchEvent(new CustomEvent("recallCleared", {
2948
+ bubbles: true,
2949
+ composed: true
2950
+ }));
2951
+ };
2862
2952
  }
2863
2953
  static {
2864
2954
  this.properties = {
2865
2955
  memories: { attribute: false },
2956
+ recallResults: { attribute: false },
2957
+ recallLoading: { attribute: false },
2958
+ recallError: { attribute: false },
2959
+ recallQueryText: { attribute: false },
2866
2960
  search: { state: true },
2867
2961
  kind: { state: true }
2868
2962
  };
@@ -3066,6 +3160,117 @@ var CpkMemoryList = class extends lit.LitElement {
3066
3160
  .cpk-ml__empty-icon {
3067
3161
  color: #c0c0c8;
3068
3162
  }
3163
+
3164
+ /* ── Recall ── */
3165
+ .cpk-ml__recall {
3166
+ display: flex;
3167
+ gap: 6px;
3168
+ padding: 10px 12px;
3169
+ border-bottom: 1px solid #dbdbe5;
3170
+ flex-shrink: 0;
3171
+ }
3172
+ .cpk-ml__recall-input {
3173
+ flex: 1;
3174
+ box-sizing: border-box;
3175
+ font-family: "Plus Jakarta Sans", sans-serif;
3176
+ font-size: 12px;
3177
+ padding: 7px 10px;
3178
+ border-radius: 6px;
3179
+ border: 1px solid #dbdbe5;
3180
+ background: #fff;
3181
+ color: #010507;
3182
+ outline: none;
3183
+ transition: border-color 0.15s;
3184
+ }
3185
+ .cpk-ml__recall-input:focus {
3186
+ border-color: #bec2ff;
3187
+ }
3188
+ .cpk-ml__recall-btn {
3189
+ font-family: "Plus Jakarta Sans", sans-serif;
3190
+ font-size: 12px;
3191
+ font-weight: 500;
3192
+ padding: 7px 12px;
3193
+ border-radius: 6px;
3194
+ border: 1px solid #dbdbe5;
3195
+ background: #fff;
3196
+ color: #010507;
3197
+ cursor: pointer;
3198
+ transition: background 0.1s;
3199
+ }
3200
+ .cpk-ml__recall-btn:hover:not(:disabled) {
3201
+ background: #f0f0f5;
3202
+ }
3203
+ .cpk-ml__recall-btn:disabled {
3204
+ opacity: 0.4;
3205
+ cursor: default;
3206
+ }
3207
+ .cpk-ml__recall-section {
3208
+ flex-shrink: 0;
3209
+ max-height: 45%;
3210
+ overflow-y: auto;
3211
+ padding: 8px 12px;
3212
+ border-bottom: 1px solid #dbdbe5;
3213
+ background: #fbfbfd;
3214
+ display: flex;
3215
+ flex-direction: column;
3216
+ gap: 8px;
3217
+ }
3218
+ .cpk-ml__recall-header {
3219
+ display: flex;
3220
+ align-items: center;
3221
+ justify-content: space-between;
3222
+ gap: 8px;
3223
+ }
3224
+ .cpk-ml__recall-title {
3225
+ font-family: "Plus Jakarta Sans", sans-serif;
3226
+ font-size: 12px;
3227
+ font-weight: 600;
3228
+ color: #010507;
3229
+ }
3230
+ .cpk-ml__recall-clear {
3231
+ font-family: "Plus Jakarta Sans", sans-serif;
3232
+ font-size: 10px;
3233
+ color: #838389;
3234
+ background: none;
3235
+ border: none;
3236
+ cursor: pointer;
3237
+ padding: 0;
3238
+ }
3239
+ .cpk-ml__recall-clear:hover {
3240
+ color: #010507;
3241
+ }
3242
+ .cpk-ml__recall-msg {
3243
+ font-size: 11px;
3244
+ color: #838389;
3245
+ line-height: 1.45;
3246
+ }
3247
+ .cpk-ml__recall-msg--error {
3248
+ color: #c0333a;
3249
+ }
3250
+
3251
+ /* ── Relevance bar ── */
3252
+ .cpk-ml__relevance {
3253
+ height: 4px;
3254
+ width: 100%;
3255
+ overflow: hidden;
3256
+ border-radius: 9999px;
3257
+ background: #f0f0f5;
3258
+ }
3259
+ .cpk-ml__relevance-fill {
3260
+ height: 100%;
3261
+ border-radius: 9999px;
3262
+ background: #6366f1;
3263
+ }
3264
+
3265
+ /* ── Scope badge variants ── */
3266
+ .cpk-ml__scope-badge--user {
3267
+ background: #f0f0f5;
3268
+ color: #838389;
3269
+ }
3270
+ .cpk-ml__scope-badge--project {
3271
+ background: #fef3c7;
3272
+ color: #92660c;
3273
+ }
3069
3274
  `;
3070
3275
  }
3071
3276
  /** Memories that pass the current text search (before kind filter). */
@@ -3093,6 +3298,86 @@ var CpkMemoryList = class extends lit.LitElement {
3093
3298
  return lit.html`<span class="cpk-ml__kind-badge cpk-ml__kind-badge--${kind}"
3094
3299
  >${kind}</span
3095
3300
  >`;
3301
+ }
3302
+ renderScopeBadge(scope) {
3303
+ return lit.html`<span
3304
+ class="cpk-ml__scope-badge cpk-ml__scope-badge--${scope === "project" ? "project" : "user"}"
3305
+ >${scope}</span
3306
+ >`;
3307
+ }
3308
+ /**
3309
+ * Renders one memory card. `relevance` (0..1) is supplied only for recall
3310
+ * results — when present a relevance bar is drawn; the full list omits it.
3311
+ */
3312
+ renderCard(m, relevance) {
3313
+ const threads = m.sourceThreadIds.length;
3314
+ return lit.html`
3315
+ <div class="cpk-ml__card">
3316
+ <div class="cpk-ml__card-badges">
3317
+ ${this.renderKindBadge(m.kind)}${this.renderScopeBadge(m.scope)}
3318
+ </div>
3319
+ <div class="cpk-ml__content">${m.content}</div>
3320
+ ${relevance !== void 0 ? lit.html`<div class="cpk-ml__relevance">
3321
+ <div
3322
+ class="cpk-ml__relevance-fill"
3323
+ style="width:${relevanceBarWidth(relevance)}%;"
3324
+ ></div>
3325
+ </div>` : lit.nothing}
3326
+ <div class="cpk-ml__footer">
3327
+ <span class="cpk-ml__footer-threads"
3328
+ >${threads} source thread${threads === 1 ? "" : "s"}</span
3329
+ >
3330
+ <span class="cpk-ml__footer-id">${this.shortId(m.id)}</span>
3331
+ </div>
3332
+ </div>
3333
+ `;
3334
+ }
3335
+ renderRecallForm() {
3336
+ const disabled = this.recallLoading || this.recallQueryText.trim().length === 0;
3337
+ return lit.html`
3338
+ <form class="cpk-ml__recall" @submit=${this.onRecallSubmit}>
3339
+ <input
3340
+ type="text"
3341
+ placeholder="Recall by meaning…"
3342
+ aria-label="Recall memories by meaning"
3343
+ class="cpk-ml__recall-input"
3344
+ .value=${this.recallQueryText}
3345
+ @input=${this.onRecallInput}
3346
+ />
3347
+ <button type="submit" class="cpk-ml__recall-btn" ?disabled=${disabled}>
3348
+ ${this.recallLoading ? "…" : "Recall"}
3349
+ </button>
3350
+ </form>
3351
+ `;
3352
+ }
3353
+ renderRecallSection() {
3354
+ const results = this.recallResults;
3355
+ if (results === null) return lit.html``;
3356
+ const max = maxRecallScore(results);
3357
+ return lit.html`
3358
+ <section
3359
+ class="cpk-ml__recall-section"
3360
+ aria-label="Semantic recall results"
3361
+ >
3362
+ <div class="cpk-ml__recall-header">
3363
+ <span class="cpk-ml__recall-title"
3364
+ >Semantic recall (${results.length})</span
3365
+ >
3366
+ <button
3367
+ type="button"
3368
+ class="cpk-ml__recall-clear"
3369
+ @click=${this.onRecallClear}
3370
+ >
3371
+ Clear
3372
+ </button>
3373
+ </div>
3374
+ ${this.recallError ? lit.html`<p class="cpk-ml__recall-msg cpk-ml__recall-msg--error">
3375
+ Recall failed: ${this.recallError}
3376
+ </p>` : results.length === 0 ? lit.html`
3377
+ <p class="cpk-ml__recall-msg">No memories matched that query.</p>
3378
+ ` : results.map((m) => this.renderCard(m, normalizeRelevance(m.score, max)))}
3379
+ </section>
3380
+ `;
3096
3381
  }
3097
3382
  renderEmpty() {
3098
3383
  const q = this.search.trim();
@@ -3129,6 +3414,9 @@ var CpkMemoryList = class extends lit.LitElement {
3129
3414
  const filtered = this.filtered;
3130
3415
  return lit.html`
3131
3416
  <div class="cpk-ml">
3417
+ <!-- Semantic recall -->
3418
+ ${this.renderRecallForm()} ${this.renderRecallSection()}
3419
+
3132
3420
  <!-- Search -->
3133
3421
  <div class="cpk-ml__search">
3134
3422
  <input
@@ -3164,21 +3452,7 @@ var CpkMemoryList = class extends lit.LitElement {
3164
3452
 
3165
3453
  <!-- Memory list -->
3166
3454
  <div class="cpk-ml__list">
3167
- ${filtered.map((m) => lit.html`
3168
- <div class="cpk-ml__card">
3169
- <div class="cpk-ml__card-badges">
3170
- ${this.renderKindBadge(m.kind)}
3171
- <span class="cpk-ml__scope-badge">${m.scope}</span>
3172
- </div>
3173
- <div class="cpk-ml__content">${m.content}</div>
3174
- <div class="cpk-ml__footer">
3175
- <span class="cpk-ml__footer-threads"
3176
- >${m.sourceThreadIds.length} source thread${m.sourceThreadIds.length === 1 ? "" : "s"}</span
3177
- >
3178
- <span class="cpk-ml__footer-id">${this.shortId(m.id)}</span>
3179
- </div>
3180
- </div>
3181
- `)}
3455
+ ${filtered.map((m) => this.renderCard(m))}
3182
3456
  ${filtered.length === 0 ? this.renderEmpty() : lit.nothing}
3183
3457
  </div>
3184
3458
  </div>
@@ -3204,6 +3478,11 @@ var WebInspectorElement = class extends lit.LitElement {
3204
3478
  this._memoryUnsub = null;
3205
3479
  this._memorySubscribed = false;
3206
3480
  this._memoryStoreUnsupported = false;
3481
+ this._recallResults = null;
3482
+ this._recallLoading = false;
3483
+ this._recallError = null;
3484
+ this._recallQuery = "";
3485
+ this._recallSeq = 0;
3207
3486
  this.runtimeStatus = null;
3208
3487
  this.coreProperties = {};
3209
3488
  this.lastCoreError = null;
@@ -3248,6 +3527,7 @@ var WebInspectorElement = class extends lit.LitElement {
3248
3527
  this.attemptedAutoAttach = false;
3249
3528
  this.cachedTools = [];
3250
3529
  this.toolSignature = "";
3530
+ this._capabilitiesVersion = 0;
3251
3531
  this.eventFilterText = "";
3252
3532
  this.eventTypeFilter = "all";
3253
3533
  this.evtColWidths = [
@@ -3595,7 +3875,8 @@ var WebInspectorElement = class extends lit.LitElement {
3595
3875
  autoAttachCore: {
3596
3876
  type: Boolean,
3597
3877
  attribute: "auto-attach-core"
3598
- }
3878
+ },
3879
+ _capabilitiesVersion: { state: true }
3599
3880
  };
3600
3881
  }
3601
3882
  get core() {
@@ -3610,6 +3891,9 @@ var WebInspectorElement = class extends lit.LitElement {
3610
3891
  if (this._core) this.attachToCore(this._core);
3611
3892
  }
3612
3893
  get menuItems() {
3894
+ const hasFrontendTools = (this._core?.tools?.length ?? 0) > 0;
3895
+ const hasCatalog = (this._core?.catalogComponents?.length ?? 0) > 0;
3896
+ const hasCapabilities = hasFrontendTools || hasCatalog;
3613
3897
  return [
3614
3898
  {
3615
3899
  key: "ag-ui-events",
@@ -3621,11 +3905,16 @@ var WebInspectorElement = class extends lit.LitElement {
3621
3905
  label: "Agent",
3622
3906
  icon: "Bot"
3623
3907
  },
3624
- ...(this._core?.tools?.length ?? 0) > 0 ? [{
3908
+ ...hasFrontendTools ? [{
3625
3909
  key: "frontend-tools",
3626
3910
  label: "Frontend Tools",
3627
3911
  icon: "Hammer"
3628
3912
  }] : [],
3913
+ ...hasCapabilities ? [{
3914
+ key: "capabilities",
3915
+ label: CAPABILITIES_TAB_LABEL,
3916
+ icon: "SlidersHorizontal"
3917
+ }] : [],
3629
3918
  {
3630
3919
  key: "agent-context",
3631
3920
  label: "Context",
@@ -3638,7 +3927,7 @@ var WebInspectorElement = class extends lit.LitElement {
3638
3927
  },
3639
3928
  {
3640
3929
  key: "memories",
3641
- label: "Learning",
3930
+ label: MEMORY_VIEW_LABEL,
3642
3931
  icon: "Brain"
3643
3932
  }
3644
3933
  ];
@@ -3913,6 +4202,50 @@ var WebInspectorElement = class extends lit.LitElement {
3913
4202
  this._memoryUnsub = () => memSubs.forEach((s) => s.unsubscribe());
3914
4203
  this.requestUpdate();
3915
4204
  }
4205
+ /**
4206
+ * Runs a semantic recall via the memory store (`core.getMemoryStore().recall`,
4207
+ * from B2) and stores ranked results. Guarded by a monotonic sequence token
4208
+ * so a stale request cannot overwrite a newer result / Clear / detach. Only
4209
+ * reachable from the Intelligence-gated memory view, so it inherits the gate.
4210
+ */
4211
+ runRecall(query) {
4212
+ const trimmed = query.trim();
4213
+ if (trimmed.length === 0) return;
4214
+ const store = this._core?.getMemoryStore?.();
4215
+ if (!store || typeof store.recall !== "function") {
4216
+ this._recallResults = [];
4217
+ this._recallError = "Recall is not supported by this SDK version.";
4218
+ this._recallLoading = false;
4219
+ this.requestUpdate();
4220
+ return;
4221
+ }
4222
+ const seq = ++this._recallSeq;
4223
+ this._recallLoading = true;
4224
+ this._recallError = null;
4225
+ this.requestUpdate();
4226
+ store.recall(trimmed).then((results) => {
4227
+ if (seq !== this._recallSeq) return;
4228
+ this._recallResults = results;
4229
+ this._recallError = null;
4230
+ this._recallLoading = false;
4231
+ this.requestUpdate();
4232
+ }).catch((error) => {
4233
+ if (seq !== this._recallSeq) return;
4234
+ this._recallResults = [];
4235
+ this._recallError = error instanceof Error ? error.message : "unknown error";
4236
+ this._recallLoading = false;
4237
+ this.requestUpdate();
4238
+ });
4239
+ }
4240
+ /** Clears recall results/section and cancels any in-flight recall. */
4241
+ clearRecall() {
4242
+ this._recallSeq += 1;
4243
+ this._recallResults = null;
4244
+ this._recallError = null;
4245
+ this._recallLoading = false;
4246
+ this._recallQuery = "";
4247
+ this.requestUpdate();
4248
+ }
3916
4249
  detachFromCore() {
3917
4250
  if (this.coreUnsubscribe) {
3918
4251
  this.coreUnsubscribe();
@@ -3927,6 +4260,11 @@ var WebInspectorElement = class extends lit.LitElement {
3927
4260
  this._memoriesRealtimeStatus = "connecting";
3928
4261
  this._memorySubscribed = false;
3929
4262
  this._memoryStoreUnsupported = false;
4263
+ this._recallSeq += 1;
4264
+ this._recallResults = null;
4265
+ this._recallLoading = false;
4266
+ this._recallError = null;
4267
+ this._recallQuery = "";
3930
4268
  this.coreSubscriber = null;
3931
4269
  this.runtimeStatus = null;
3932
4270
  this.lastCoreError = null;
@@ -5892,6 +6230,7 @@ ${argsString}</pre
5892
6230
  if (this.selectedMenu === "ag-ui-events") return this.renderEventsTable();
5893
6231
  if (this.selectedMenu === "agents") return this.renderAgentsView();
5894
6232
  if (this.selectedMenu === "frontend-tools") return this.renderToolsView();
6233
+ if (this.selectedMenu === "capabilities") return this.renderCapabilitiesView();
5895
6234
  if (this.selectedMenu === "agent-context") return this.renderContextView();
5896
6235
  if (this.selectedMenu === "threads") return this.renderThreadsView();
5897
6236
  if (this.selectedMenu === "memories") return this.renderMemoriesView();
@@ -6836,7 +7175,7 @@ ${argsString}</pre
6836
7175
  return lit.html`
6837
7176
  <div style="display:flex;height:100%;overflow:hidden;flex-direction:column;">
6838
7177
  <div class="cpk-section-header" style="display:flex;align-items:center;justify-content:space-between;">
6839
- <h4>Learning</h4>
7178
+ <h4>${MEMORY_VIEW_LABEL}</h4>
6840
7179
  <div style="display:flex;align-items:center;gap:6px;">
6841
7180
  ${this.renderMemoryRealtimeIndicator()}
6842
7181
  <span
@@ -6891,6 +7230,19 @@ ${argsString}</pre
6891
7230
  <cpk-memory-list
6892
7231
  style="height:100%;"
6893
7232
  .memories=${this._memories}
7233
+ .recallResults=${this._recallResults}
7234
+ .recallLoading=${this._recallLoading}
7235
+ .recallError=${this._recallError}
7236
+ .recallQueryText=${this._recallQuery}
7237
+ @recallQueryChanged=${(e) => {
7238
+ this._recallQuery = e.detail;
7239
+ }}
7240
+ @recallSubmitted=${(e) => {
7241
+ this.runRecall(e.detail);
7242
+ }}
7243
+ @recallCleared=${() => {
7244
+ this.clearRecall();
7245
+ }}
6894
7246
  ></cpk-memory-list>
6895
7247
  </div>
6896
7248
  </div>
@@ -7530,6 +7882,112 @@ ${prettyEvent}</pre
7530
7882
  this.persistState();
7531
7883
  this.requestUpdate();
7532
7884
  }
7885
+ renderCapabilitiesView() {
7886
+ if (!this._core) return lit.html`
7887
+ <div
7888
+ class="flex h-full items-center justify-center px-4 py-8 text-xs text-gray-500"
7889
+ >
7890
+ No core instance available
7891
+ </div>
7892
+ `;
7893
+ const toolRows = buildCapabilityRows(this._core);
7894
+ const catalog = this._core.catalogComponents ?? [];
7895
+ const hasCatalog = catalog.length > 0;
7896
+ if (toolRows.length === 0 && !hasCatalog) return lit.html`
7897
+ <div class="flex h-full items-center justify-center px-4 py-8 text-center">
7898
+ <div class="max-w-md">
7899
+ <div class="mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8">
7900
+ ${this.renderIcon("SlidersHorizontal")}
7901
+ </div>
7902
+ <p class="text-sm text-gray-600">No capabilities registered</p>
7903
+ <p class="mt-2 text-xs text-gray-500">
7904
+ Frontend tools and A2UI catalog components will appear here once
7905
+ they are registered on the CopilotKit core.
7906
+ </p>
7907
+ </div>
7908
+ </div>
7909
+ `;
7910
+ return lit.html`
7911
+ <div class="flex h-full flex-col overflow-hidden">
7912
+ <div class="overflow-auto p-4">
7913
+ <div class="space-y-3">
7914
+ <p class="text-xs text-gray-500">
7915
+ Toggle a capability off to omit it from what the agent sees. This
7916
+ is a client-side experimentation surface and takes effect
7917
+ immediately.
7918
+ </p>
7919
+ </div>
7920
+
7921
+ ${toolRows.length > 0 ? lit.html`
7922
+ <div class="mt-4 space-y-2">
7923
+ <h3 class="text-sm text-slate-500">Frontend tools</h3>
7924
+ <div class="space-y-2">
7925
+ ${toolRows.map((row) => this.renderCapabilityRow(row))}
7926
+ </div>
7927
+ </div>
7928
+ ` : lit.nothing}
7929
+
7930
+ ${hasCatalog ? lit.html`
7931
+ <div class="mt-6 space-y-2">
7932
+ <h3 class="text-sm text-slate-500">A2UI catalog components</h3>
7933
+ <div class="space-y-2">
7934
+ ${catalog.map((component) => this.renderCapabilityRow({
7935
+ key: component.name,
7936
+ name: component.name,
7937
+ description: component.description,
7938
+ enabled: this._core.isCatalogComponentEnabled(component.name)
7939
+ }))}
7940
+ </div>
7941
+ </div>
7942
+ ` : lit.nothing}
7943
+ </div>
7944
+ </div>
7945
+ `;
7946
+ }
7947
+ renderCapabilityRow(row) {
7948
+ const isTool = row.key.includes(":");
7949
+ return lit.html`
7950
+ <div class="flex items-center justify-between gap-3 rounded-lg border border-gray-200 bg-white px-4 py-3">
7951
+ <div class="min-w-0 flex-1">
7952
+ <div class="flex items-center gap-2">
7953
+ <span class="font-mono text-sm font-semibold text-gray-900">${row.name}</span>
7954
+ ${row.agentId ? lit.html`<span class="inline-flex items-center gap-1 text-xs text-gray-500">
7955
+ ${this.renderIcon("Bot")}<span class="font-mono">${row.agentId}</span>
7956
+ </span>` : lit.nothing}
7957
+ </div>
7958
+ ${row.description ? lit.html`<p class="mt-1 text-xs text-gray-600">${row.description}</p>` : lit.nothing}
7959
+ </div>
7960
+ ${this.renderCapabilitySwitch(row.enabled, () => isTool ? this.handleToggleTool(row) : this.handleToggleCatalogComponent(row.name))}
7961
+ </div>
7962
+ `;
7963
+ }
7964
+ renderCapabilitySwitch(enabled, onToggle) {
7965
+ return lit.html`
7966
+ <button
7967
+ type="button"
7968
+ role="switch"
7969
+ aria-checked=${enabled ? "true" : "false"}
7970
+ class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-300 ${enabled ? "bg-emerald-500" : "bg-gray-300"}"
7971
+ @click=${onToggle}
7972
+ >
7973
+ <span class="inline-block h-4 w-4 transform rounded-full bg-white shadow transition-transform ${enabled ? "translate-x-4" : "translate-x-0.5"}"></span>
7974
+ </button>
7975
+ `;
7976
+ }
7977
+ handleToggleTool(row) {
7978
+ if (!this._core) return;
7979
+ const next = !row.enabled;
7980
+ this._core.setToolEnabled(row.name, next, row.agentId);
7981
+ this._capabilitiesVersion += 1;
7982
+ this.requestUpdate();
7983
+ }
7984
+ handleToggleCatalogComponent(name) {
7985
+ if (!this._core) return;
7986
+ const next = !this._core.isCatalogComponentEnabled(name);
7987
+ this._core.setCatalogComponentEnabled(name, next);
7988
+ this._capabilitiesVersion += 1;
7989
+ this.requestUpdate();
7990
+ }
7533
7991
  renderToolsView() {
7534
7992
  if (!this._core) return lit.html`
7535
7993
  <div
@@ -8235,4 +8693,8 @@ exports.WEB_INSPECTOR_TAG = WEB_INSPECTOR_TAG;
8235
8693
  exports.WebInspectorElement = WebInspectorElement;
8236
8694
  exports.defineWebInspector = defineWebInspector;
8237
8695
  exports.ɵCpkThreadDetails = ɵCpkThreadDetails;
8696
+ exports.ɵbuildCapabilityRows = buildCapabilityRows;
8697
+ exports.ɵmaxRecallScore = maxRecallScore;
8698
+ exports.ɵnormalizeRelevance = normalizeRelevance;
8699
+ exports.ɵrelevanceBarWidth = relevanceBarWidth;
8238
8700
  //# sourceMappingURL=index.cjs.map