@tanstack/ai-devtools-core 0.4.24 → 0.5.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.
@@ -1,4 +1,4 @@
1
- import { delegateEvents, createComponent, insert, effect, className, setStyleProperty, addEventListener, memo, setAttribute, use, spread, mergeProps, template, Portal } from 'solid-js/web';
1
+ import { delegateEvents, createComponent, insert, effect, className, setStyleProperty, addEventListener, setAttribute, use, memo, spread, mergeProps, template, Portal } from 'solid-js/web';
2
2
  import { createContext, createSignal, onMount, onCleanup, createEffect, createMemo, Show, For, useContext, batch, Index, Switch, Match } from 'solid-js';
3
3
  import { ThemeContextProvider, MainPanel, Header, HeaderLogo, useTheme, JsonTree } from '@tanstack/devtools-ui';
4
4
  import { emitAIDevtoolsEvent, createAIDevtoolsEventEnvelope, aiEventClient } from '@tanstack/ai-event-client';
@@ -2202,6 +2202,118 @@ var stylesFactory = (theme) => {
2202
2202
  padding: 0 ${size[3]};
2203
2203
  `
2204
2204
  },
2205
+ // MemoryPanel component styles
2206
+ memoryPanel: {
2207
+ container: css2`
2208
+ display: flex;
2209
+ flex: 1;
2210
+ min-height: 0;
2211
+ flex-direction: column;
2212
+ gap: ${size[4]};
2213
+ overflow-y: auto;
2214
+ padding: ${size[4]};
2215
+ `,
2216
+ toolbar: css2`
2217
+ display: flex;
2218
+ align-items: center;
2219
+ justify-content: space-between;
2220
+ gap: ${size[3]};
2221
+ `,
2222
+ scopeControls: css2`
2223
+ display: flex;
2224
+ align-items: center;
2225
+ gap: ${size[2]};
2226
+ min-width: 0;
2227
+ `,
2228
+ scopeSelect: css2`
2229
+ max-width: 220px;
2230
+ border: 1px solid ${t(colors.gray[200], colors.darkGray[700])};
2231
+ border-radius: ${border.radius.sm};
2232
+ background: ${t(colors.white, colors.darkGray[800])};
2233
+ color: ${t(colors.gray[900], colors.gray[100])};
2234
+ font-family: ${fontFamily.mono};
2235
+ font-size: ${fontSize.xs};
2236
+ padding: ${size[1]} ${size[2]};
2237
+ `,
2238
+ clearButton: css2`
2239
+ border: 1px solid ${t(colors.gray[200], colors.darkGray[700])};
2240
+ border-radius: ${border.radius.sm};
2241
+ background: ${t(colors.gray[50], colors.darkGray[700])};
2242
+ color: ${t(colors.gray[700], colors.gray[200])};
2243
+ cursor: pointer;
2244
+ font-size: ${fontSize.xs};
2245
+ padding: ${size[1]} ${size[2]};
2246
+ &:hover {
2247
+ border-color: ${t(colors.blue[300], colors.blue[700])};
2248
+ }
2249
+ `,
2250
+ empty: css2`
2251
+ color: ${t(colors.gray[500], colors.gray[500])};
2252
+ font-size: ${fontSize.sm};
2253
+ padding: ${size[4]};
2254
+ text-align: center;
2255
+ `,
2256
+ section: css2`
2257
+ display: flex;
2258
+ flex-direction: column;
2259
+ gap: ${size[2]};
2260
+ `,
2261
+ sectionTitle: css2`
2262
+ color: ${t(colors.gray[600], colors.gray[300])};
2263
+ font-size: ${fontSize.xs};
2264
+ font-weight: ${font.weight.semibold};
2265
+ text-transform: uppercase;
2266
+ letter-spacing: 0.04em;
2267
+ `,
2268
+ sectionEmpty: css2`
2269
+ color: ${t(colors.gray[500], colors.gray[500])};
2270
+ font-size: ${fontSize.xs};
2271
+ `,
2272
+ list: css2`
2273
+ display: flex;
2274
+ flex-direction: column;
2275
+ gap: ${size[1]};
2276
+ `,
2277
+ row: css2`
2278
+ display: flex;
2279
+ flex-direction: column;
2280
+ gap: 2px;
2281
+ border: 1px solid ${t(colors.gray[200], colors.darkGray[700])};
2282
+ border-radius: ${border.radius.sm};
2283
+ background: ${t(colors.white, colors.darkGray[800])};
2284
+ padding: ${size[2]};
2285
+ `,
2286
+ rowError: css2`
2287
+ border-color: ${t(colors.red[300], colors.red[700])};
2288
+ background: ${t(colors.red[50], colors.red[900] + "20")};
2289
+ `,
2290
+ rowHeader: css2`
2291
+ display: flex;
2292
+ align-items: center;
2293
+ gap: ${size[2]};
2294
+ font-size: ${fontSize.xs};
2295
+ color: ${t(colors.gray[500], colors.gray[400])};
2296
+ `,
2297
+ badge: css2`
2298
+ border-radius: ${border.radius.xs};
2299
+ background: ${t(colors.blue[50], colors.blue[900] + "30")};
2300
+ color: ${t(colors.blue[700], colors.blue[300])};
2301
+ font-family: ${fontFamily.mono};
2302
+ font-size: 10px;
2303
+ padding: 1px 6px;
2304
+ `,
2305
+ time: css2`
2306
+ margin-left: auto;
2307
+ font-family: ${fontFamily.mono};
2308
+ font-size: 10px;
2309
+ `,
2310
+ rowText: css2`
2311
+ color: ${t(colors.gray[900], colors.gray[100])};
2312
+ font-size: ${fontSize.sm};
2313
+ white-space: pre-wrap;
2314
+ word-break: break-word;
2315
+ `
2316
+ },
2205
2317
  // ConversationDetails component styles
2206
2318
  conversationDetails: {
2207
2319
  emptyState: css2`
@@ -4391,8 +4503,8 @@ function removeHookRecord(state, hookId) {
4391
4503
  delete state.runs[runId];
4392
4504
  }
4393
4505
  }
4394
- for (const eventId of hookEventIds) {
4395
- delete state.events[eventId];
4506
+ for (const eventId2 of hookEventIds) {
4507
+ delete state.events[eventId2];
4396
4508
  }
4397
4509
  delete state.hooks[hookId];
4398
4510
  delete state.seenHookActivityCounts[hookId];
@@ -4400,7 +4512,7 @@ function removeHookRecord(state, hookId) {
4400
4512
  state.activeHookId = null;
4401
4513
  }
4402
4514
  }
4403
- function upsertRun(state, event, eventId) {
4515
+ function upsertRun(state, event, eventId2) {
4404
4516
  const existing = state.runs[event.runId];
4405
4517
  if (!existing) {
4406
4518
  state.runs[event.runId] = {
@@ -4414,7 +4526,7 @@ function upsertRun(state, event, eventId) {
4414
4526
  updatedAt: event.timestamp,
4415
4527
  ...isTerminalRunStatus(event.status) ? { completedAt: event.timestamp } : {},
4416
4528
  ...event.error ? { error: event.error } : {},
4417
- eventIds: [eventId]
4529
+ eventIds: [eventId2]
4418
4530
  };
4419
4531
  return;
4420
4532
  }
@@ -4430,8 +4542,8 @@ function upsertRun(state, event, eventId) {
4430
4542
  if (event.error) {
4431
4543
  existing.error = event.error;
4432
4544
  }
4433
- if (!existing.eventIds.includes(eventId)) {
4434
- existing.eventIds.push(eventId);
4545
+ if (!existing.eventIds.includes(eventId2)) {
4546
+ existing.eventIds.push(eventId2);
4435
4547
  }
4436
4548
  }
4437
4549
  function attachRunToHook(state, hookId, runId) {
@@ -4439,7 +4551,7 @@ function attachRunToHook(state, hookId, runId) {
4439
4551
  if (!hook || hook.runIds.includes(runId)) return;
4440
4552
  hook.runIds.push(runId);
4441
4553
  }
4442
- function syncRunsFromSnapshot(state, snapshot, eventId) {
4554
+ function syncRunsFromSnapshot(state, snapshot, eventId2) {
4443
4555
  const rawRuns = snapshot.state.runs;
4444
4556
  if (!Array.isArray(rawRuns)) return;
4445
4557
  for (const candidate of rawRuns) {
@@ -4462,7 +4574,7 @@ function syncRunsFromSnapshot(state, snapshot, eventId) {
4462
4574
  updatedAt,
4463
4575
  ...typeof run.completedAt === "number" ? { completedAt: run.completedAt } : isTerminalRunStatus(status) ? { completedAt: updatedAt } : {},
4464
4576
  ...typeof run.error === "string" ? { error: run.error } : {},
4465
- eventIds: [eventId]
4577
+ eventIds: [eventId2]
4466
4578
  };
4467
4579
  } else {
4468
4580
  existing.hookId = snapshot.hookId;
@@ -4474,8 +4586,8 @@ function syncRunsFromSnapshot(state, snapshot, eventId) {
4474
4586
  existing.completedAt = updatedAt;
4475
4587
  }
4476
4588
  if (typeof run.error === "string") existing.error = run.error;
4477
- if (!existing.eventIds.includes(eventId)) {
4478
- existing.eventIds.push(eventId);
4589
+ if (!existing.eventIds.includes(eventId2)) {
4590
+ existing.eventIds.push(eventId2);
4479
4591
  }
4480
4592
  }
4481
4593
  attachRunToHook(state, snapshot.hookId, run.id);
@@ -4505,11 +4617,11 @@ function attachActivityRunToHook(state, hookId, runId) {
4505
4617
  if (!hook || hook.activityRunIds.includes(runId)) return;
4506
4618
  hook.activityRunIds.push(runId);
4507
4619
  }
4508
- function attachEventToHook(state, hookId, eventId) {
4620
+ function attachEventToHook(state, hookId, eventId2) {
4509
4621
  if (!hookId) return;
4510
4622
  const hook = state.hooks[hookId];
4511
- if (!hook || hook.eventIds.includes(eventId)) return;
4512
- hook.eventIds.push(eventId);
4623
+ if (!hook || hook.eventIds.includes(eventId2)) return;
4624
+ hook.eventIds.push(eventId2);
4513
4625
  }
4514
4626
  function inferLifecycleFromSnapshot(state) {
4515
4627
  if (state.status === "error" || state.error) {
@@ -4551,6 +4663,107 @@ function shouldSkipClientAssistantPlaceholder(message) {
4551
4663
  return message.role === "assistant" && message.source === "client" && !message.content && (!message.toolCalls || message.toolCalls.length === 0) && (!message.parts || message.parts.length === 0);
4552
4664
  }
4553
4665
 
4666
+ // src/store/memory-registry.ts
4667
+ function createMemoryRegistryState() {
4668
+ return { scopes: {} };
4669
+ }
4670
+ function escapeScopeDim(value) {
4671
+ return value.replace(/[\\:_]/g, "\\$&");
4672
+ }
4673
+ function scopeDim(value) {
4674
+ return value != null && value.length > 0 ? escapeScopeDim(value) : "_";
4675
+ }
4676
+ function memoryScopeKey(scope) {
4677
+ if (!scope) return "(unknown)";
4678
+ return `${scopeDim(scope.tenantId)}:${scopeDim(scope.userId)}:${escapeScopeDim(scope.threadId)}:${scopeDim(scope.namespace)}`;
4679
+ }
4680
+ function memoryScopeLabel(entry) {
4681
+ if (entry.key === "(unknown)" || !entry.threadId) return "(unknown)";
4682
+ const parts = [
4683
+ entry.tenantId,
4684
+ entry.userId,
4685
+ entry.threadId,
4686
+ entry.namespace
4687
+ ].filter((p) => p != null && p.length > 0);
4688
+ return parts.join(" \xB7 ");
4689
+ }
4690
+ var MAX_EVENTS_PER_SCOPE = 200;
4691
+ function ensureScope(state, scope) {
4692
+ const key = memoryScopeKey(scope);
4693
+ let entry = state.scopes[key];
4694
+ if (!entry) {
4695
+ entry = {
4696
+ key,
4697
+ threadId: scope?.threadId ?? "",
4698
+ userId: scope?.userId,
4699
+ tenantId: scope?.tenantId,
4700
+ namespace: scope?.namespace,
4701
+ events: [],
4702
+ lastActivity: 0
4703
+ };
4704
+ state.scopes[key] = entry;
4705
+ }
4706
+ if (scope) {
4707
+ if (scope.userId) entry.userId = scope.userId;
4708
+ if (scope.tenantId) entry.tenantId = scope.tenantId;
4709
+ if (scope.namespace) entry.namespace = scope.namespace;
4710
+ }
4711
+ return entry;
4712
+ }
4713
+ var fallbackCounter = 0;
4714
+ function eventId(payload, type, ts) {
4715
+ if (payload.eventId && payload.eventId.length > 0) return payload.eventId;
4716
+ return `${type}:${ts}:${fallbackCounter++}`;
4717
+ }
4718
+ function applyMemoryEvent(state, event) {
4719
+ const entry = ensureScope(state, event.scope);
4720
+ entry.adapter = event.adapter;
4721
+ entry.lastActivity = Math.max(entry.lastActivity, event.timestamp);
4722
+ const record = {
4723
+ id: eventId(event, event.type, event.timestamp),
4724
+ type: event.type,
4725
+ timestamp: event.timestamp,
4726
+ adapter: event.adapter
4727
+ };
4728
+ switch (event.type) {
4729
+ case "retrieve:started":
4730
+ record.query = event.query;
4731
+ break;
4732
+ case "retrieve:completed":
4733
+ record.fragmentCount = event.fragmentCount;
4734
+ record.hasTools = event.hasTools;
4735
+ record.systemPromptChars = event.systemPromptChars;
4736
+ record.durationMs = event.durationMs;
4737
+ break;
4738
+ case "persist:completed":
4739
+ record.receiptCount = event.receiptCount;
4740
+ record.okCount = event.okCount;
4741
+ record.durationMs = event.durationMs;
4742
+ break;
4743
+ case "error":
4744
+ record.phase = event.phase;
4745
+ record.error = event.error;
4746
+ break;
4747
+ }
4748
+ entry.events.push(record);
4749
+ if (entry.events.length > MAX_EVENTS_PER_SCOPE) {
4750
+ entry.events.splice(0, entry.events.length - MAX_EVENTS_PER_SCOPE);
4751
+ }
4752
+ }
4753
+ function applyMemorySnapshot(state, event) {
4754
+ const entry = ensureScope(state, event.scope);
4755
+ entry.adapter = event.adapter;
4756
+ entry.lastActivity = Math.max(entry.lastActivity, event.timestamp);
4757
+ entry.snapshot = {
4758
+ takenAt: event.takenAt,
4759
+ data: event.data,
4760
+ facts: event.facts
4761
+ };
4762
+ }
4763
+ function clearMemoryRegistry(state) {
4764
+ state.scopes = {};
4765
+ }
4766
+
4554
4767
  // src/store/ai-context.tsx
4555
4768
  var AIContext = createContext();
4556
4769
  function useAIStore() {
@@ -4564,7 +4777,8 @@ var AIProvider = (props) => {
4564
4777
  const [state, setState] = createStore({
4565
4778
  conversations: {},
4566
4779
  activeConversationId: null,
4567
- hooks: createHookRegistryState()
4780
+ hooks: createHookRegistryState(),
4781
+ memory: createMemoryRegistryState()
4568
4782
  });
4569
4783
  const streamToConversation = /* @__PURE__ */ new Map();
4570
4784
  const requestToConversation = /* @__PURE__ */ new Map();
@@ -4816,6 +5030,11 @@ var AIProvider = (props) => {
4816
5030
  clearHookRegistry(hooks);
4817
5031
  }));
4818
5032
  }
5033
+ function clearMemory() {
5034
+ setState("memory", produce((memory) => {
5035
+ clearMemoryRegistry(memory);
5036
+ }));
5037
+ }
4819
5038
  function selectHook(id) {
4820
5039
  setState("hooks", produce((hooks) => {
4821
5040
  setActiveHook(hooks, id);
@@ -5118,6 +5337,29 @@ var AIProvider = (props) => {
5118
5337
  applyHookEvent(hooks, "hook:state-snapshot", e.payload);
5119
5338
  }));
5120
5339
  }));
5340
+ const recordMemoryEvent = (type, payload) => {
5341
+ setState("memory", produce((memory) => {
5342
+ applyMemoryEvent(memory, {
5343
+ ...payload,
5344
+ type
5345
+ });
5346
+ }));
5347
+ };
5348
+ cleanupFns.push(aiEventClient.on("memory:retrieve:started", (e) => {
5349
+ recordMemoryEvent("retrieve:started", e.payload);
5350
+ }), aiEventClient.on("memory:retrieve:completed", (e) => {
5351
+ recordMemoryEvent("retrieve:completed", e.payload);
5352
+ }), aiEventClient.on("memory:persist:started", (e) => {
5353
+ recordMemoryEvent("persist:started", e.payload);
5354
+ }), aiEventClient.on("memory:persist:completed", (e) => {
5355
+ recordMemoryEvent("persist:completed", e.payload);
5356
+ }), aiEventClient.on("memory:error", (e) => {
5357
+ recordMemoryEvent("error", e.payload);
5358
+ }), aiEventClient.on("memory:snapshot", (e) => {
5359
+ setState("memory", produce((memory) => {
5360
+ applyMemorySnapshot(memory, e.payload);
5361
+ }));
5362
+ }));
5121
5363
  const recordRunEvent = (eventName, payload) => {
5122
5364
  setState("hooks", produce((hooks) => {
5123
5365
  applyHookEvent(hooks, eventName, payload);
@@ -6692,6 +6934,7 @@ var AIProvider = (props) => {
6692
6934
  clearAllConversations,
6693
6935
  selectConversation,
6694
6936
  clearHooks,
6937
+ clearMemory,
6695
6938
  selectHook,
6696
6939
  saveToolFixture,
6697
6940
  deleteToolFixture,
@@ -6736,6 +6979,16 @@ function visibleHooks(hooks) {
6736
6979
  function getHookDisplayName(hook) {
6737
6980
  return hook.displayName ?? hook.hookName;
6738
6981
  }
6982
+ function getHookIdentityLabel(hook) {
6983
+ return hook.threadId ?? hook.id;
6984
+ }
6985
+ function getHookIdentitySubtitle(hook) {
6986
+ const identity = getHookIdentityLabel(hook);
6987
+ if (hook.displayName) {
6988
+ return `${hook.hookName} - ${identity}`;
6989
+ }
6990
+ return identity;
6991
+ }
6739
6992
  function groupHooksByCategory(hooks) {
6740
6993
  const groups = /* @__PURE__ */ new Map();
6741
6994
  for (const hook of hooks) {
@@ -6889,17 +7142,7 @@ var HookDashboard = () => {
6889
7142
  return _el$45;
6890
7143
  }
6891
7144
  }), null);
6892
- insert(_el$47, createComponent(Show, {
6893
- get when() {
6894
- return hook.displayName;
6895
- },
6896
- get fallback() {
6897
- return hook.id;
6898
- },
6899
- get children() {
6900
- return [memo(() => hook.hookName), " - ", memo(() => hook.id)];
6901
- }
6902
- }));
7145
+ insert(_el$47, () => getHookIdentitySubtitle(hook));
6903
7146
  insert(_el$49, () => hook.lifecycle);
6904
7147
  insert(_el$48, createComponent(Show, {
6905
7148
  get when() {
@@ -10323,31 +10566,383 @@ function isRecord3(value) {
10323
10566
  return typeof value === "object" && value !== null && !Array.isArray(value);
10324
10567
  }
10325
10568
  delegateEvents(["click"]);
10569
+ var _tmpl$38 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-memory-panel>`);
10570
+ var _tmpl$213 = /* @__PURE__ */ template(`<div>No memory activity yet. Send a message through a chat wired with<code> memoryMiddleware</code> and recall/save events will appear here.`);
10571
+ var _tmpl$39 = /* @__PURE__ */ template(`<select data-testid=ai-devtools-memory-scope-select>`);
10572
+ var _tmpl$46 = /* @__PURE__ */ template(`<div><div></div><button type=button>Clear`);
10573
+ var _tmpl$56 = /* @__PURE__ */ template(`<div>`);
10574
+ var _tmpl$66 = /* @__PURE__ */ template(`<section><div>Stored records (<!>)`);
10575
+ var _tmpl$76 = /* @__PURE__ */ template(`<section><div>listFacts() (<!>)`);
10576
+ var _tmpl$86 = /* @__PURE__ */ template(`<section><div>Operations (<!>)`);
10577
+ var _tmpl$96 = /* @__PURE__ */ template(`<span>`);
10578
+ var _tmpl$05 = /* @__PURE__ */ template(`<option>`);
10579
+ var _tmpl$114 = /* @__PURE__ */ template(`<span>snapshot `);
10580
+ var _tmpl$105 = /* @__PURE__ */ template(`<span>importance `);
10581
+ var _tmpl$115 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-memory-record><div><span></span><span></span></div><div>`);
10582
+ var _tmpl$123 = /* @__PURE__ */ template(`<div>No facts.`);
10583
+ var _tmpl$133 = /* @__PURE__ */ template(`<span>: `);
10584
+ var _tmpl$143 = /* @__PURE__ */ template(`<div><div>`);
10585
+ var _tmpl$153 = /* @__PURE__ */ template(`<div>No operations recorded.`);
10586
+ var _tmpl$163 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-memory-event><div><span></span><span></span></div><div>`);
10587
+ function extractRecords(data) {
10588
+ if (!data || typeof data !== "object") return [];
10589
+ const records = data.records;
10590
+ if (!Array.isArray(records)) return [];
10591
+ return records.filter((r) => Boolean(r) && typeof r === "object" && typeof r.id === "string" && typeof r.text === "string");
10592
+ }
10593
+ function formatTime2(value) {
10594
+ if (value === void 0) return "";
10595
+ const date = new Date(value);
10596
+ if (Number.isNaN(date.getTime())) return "";
10597
+ return date.toLocaleTimeString();
10598
+ }
10599
+ function eventSummary(event) {
10600
+ switch (event.type) {
10601
+ case "retrieve:started":
10602
+ return `recall "${event.query ?? ""}"`;
10603
+ case "retrieve:completed":
10604
+ return `recalled ${event.fragmentCount ?? 0} fragment(s), ${event.systemPromptChars ?? 0} prompt chars${event.hasTools ? ", +tools" : ""} (${event.durationMs ?? 0}ms)`;
10605
+ case "persist:started":
10606
+ return "save started";
10607
+ case "persist:completed":
10608
+ return `saved ${event.okCount ?? 0}/${event.receiptCount ?? 0} receipt(s) (${event.durationMs ?? 0}ms)`;
10609
+ case "error":
10610
+ return `${event.phase ?? ""} error: ${event.error?.message ?? "unknown"}`;
10611
+ default:
10612
+ return event.type;
10613
+ }
10614
+ }
10615
+ var MemoryPanel = () => {
10616
+ const {
10617
+ state,
10618
+ clearMemory
10619
+ } = useAIStore();
10620
+ const styles = useStyles();
10621
+ const [override, setOverride] = createSignal(null);
10622
+ const scopeKeys = createMemo(() => Object.values(state.memory.scopes).slice().sort((a, b) => b.lastActivity - a.lastActivity).map((s) => s.key));
10623
+ const selectedKey = createMemo(() => {
10624
+ const chosen = override();
10625
+ if (chosen && state.memory.scopes[chosen]) return chosen;
10626
+ return scopeKeys()[0] ?? null;
10627
+ });
10628
+ const scope = createMemo(() => {
10629
+ const key = selectedKey();
10630
+ return key ? state.memory.scopes[key] : void 0;
10631
+ });
10632
+ const records = createMemo(() => extractRecords(scope()?.snapshot?.data));
10633
+ const facts = createMemo(() => scope()?.snapshot?.facts ?? []);
10634
+ const events = createMemo(() => (scope()?.events ?? []).slice().sort((a, b) => b.timestamp - a.timestamp));
10635
+ return (() => {
10636
+ var _el$ = _tmpl$38();
10637
+ insert(_el$, createComponent(Show, {
10638
+ get when() {
10639
+ return scope();
10640
+ },
10641
+ get fallback() {
10642
+ return (() => {
10643
+ var _el$2 = _tmpl$213();
10644
+ effect(() => className(_el$2, styles().memoryPanel.empty));
10645
+ return _el$2;
10646
+ })();
10647
+ },
10648
+ children: (activeScope) => [(() => {
10649
+ var _el$3 = _tmpl$46(), _el$4 = _el$3.firstChild, _el$6 = _el$4.nextSibling;
10650
+ insert(_el$4, createComponent(Show, {
10651
+ get when() {
10652
+ return scopeKeys().length > 1;
10653
+ },
10654
+ get fallback() {
10655
+ return (() => {
10656
+ var _el$23 = _tmpl$96();
10657
+ insert(_el$23, () => activeScope().adapter ?? "memory");
10658
+ effect(() => className(_el$23, styles().memoryPanel.badge));
10659
+ return _el$23;
10660
+ })();
10661
+ },
10662
+ get children() {
10663
+ var _el$5 = _tmpl$39();
10664
+ _el$5.addEventListener("change", (e) => setOverride(e.currentTarget.value));
10665
+ insert(_el$5, createComponent(For, {
10666
+ get each() {
10667
+ return scopeKeys();
10668
+ },
10669
+ children: (key) => {
10670
+ const entry = state.memory.scopes[key];
10671
+ const label = entry ? memoryScopeLabel(entry) : key;
10672
+ return (() => {
10673
+ var _el$24 = _tmpl$05();
10674
+ _el$24.value = key;
10675
+ insert(_el$24, (() => {
10676
+ var _c$ = memo(() => !!entry?.adapter);
10677
+ return () => _c$() ? `${entry.adapter} \xB7 ` : "";
10678
+ })(), null);
10679
+ insert(_el$24, (() => {
10680
+ var _c$2 = memo(() => label.length > 40);
10681
+ return () => _c$2() ? `${label.slice(0, 40)}\u2026` : label;
10682
+ })(), null);
10683
+ return _el$24;
10684
+ })();
10685
+ }
10686
+ }));
10687
+ effect(() => className(_el$5, styles().memoryPanel.scopeSelect));
10688
+ effect(() => _el$5.value = selectedKey() ?? "");
10689
+ return _el$5;
10690
+ }
10691
+ }));
10692
+ _el$6.$$click = () => {
10693
+ setOverride(null);
10694
+ clearMemory();
10695
+ };
10696
+ effect((_p$) => {
10697
+ var _v$ = styles().memoryPanel.toolbar, _v$2 = styles().memoryPanel.scopeControls, _v$3 = styles().memoryPanel.clearButton;
10698
+ _v$ !== _p$.e && className(_el$3, _p$.e = _v$);
10699
+ _v$2 !== _p$.t && className(_el$4, _p$.t = _v$2);
10700
+ _v$3 !== _p$.a && className(_el$6, _p$.a = _v$3);
10701
+ return _p$;
10702
+ }, {
10703
+ e: void 0,
10704
+ t: void 0,
10705
+ a: void 0
10706
+ });
10707
+ return _el$3;
10708
+ })(), (() => {
10709
+ var _el$7 = _tmpl$66(), _el$8 = _el$7.firstChild, _el$9 = _el$8.firstChild, _el$1 = _el$9.nextSibling; _el$1.nextSibling;
10710
+ insert(_el$8, () => records().length, _el$1);
10711
+ insert(_el$8, createComponent(Show, {
10712
+ get when() {
10713
+ return activeScope().snapshot;
10714
+ },
10715
+ children: (snap) => (() => {
10716
+ var _el$25 = _tmpl$114(); _el$25.firstChild;
10717
+ insert(_el$25, () => formatTime2(snap().takenAt), null);
10718
+ effect(() => className(_el$25, styles().memoryPanel.time));
10719
+ return _el$25;
10720
+ })()
10721
+ }), null);
10722
+ insert(_el$7, createComponent(Show, {
10723
+ get when() {
10724
+ return records().length > 0;
10725
+ },
10726
+ get fallback() {
10727
+ return (() => {
10728
+ var _el$27 = _tmpl$56();
10729
+ insert(_el$27, () => activeScope().snapshot ? "Snapshot is empty." : "This adapter does not expose inspect() \u2014 see the timeline below for activity.");
10730
+ effect(() => className(_el$27, styles().memoryPanel.sectionEmpty));
10731
+ return _el$27;
10732
+ })();
10733
+ },
10734
+ get children() {
10735
+ var _el$10 = _tmpl$56();
10736
+ insert(_el$10, createComponent(For, {
10737
+ get each() {
10738
+ return records();
10739
+ },
10740
+ children: (rec) => (() => {
10741
+ var _el$28 = _tmpl$115(), _el$29 = _el$28.firstChild, _el$30 = _el$29.firstChild, _el$34 = _el$30.nextSibling, _el$35 = _el$29.nextSibling;
10742
+ insert(_el$30, () => rec.kind);
10743
+ insert(_el$29, createComponent(Show, {
10744
+ get when() {
10745
+ return rec.role;
10746
+ },
10747
+ get children() {
10748
+ var _el$31 = _tmpl$96();
10749
+ insert(_el$31, () => rec.role);
10750
+ return _el$31;
10751
+ }
10752
+ }), _el$34);
10753
+ insert(_el$29, createComponent(Show, {
10754
+ get when() {
10755
+ return rec.importance !== void 0;
10756
+ },
10757
+ get children() {
10758
+ var _el$32 = _tmpl$105(); _el$32.firstChild;
10759
+ insert(_el$32, () => rec.importance?.toFixed(2), null);
10760
+ return _el$32;
10761
+ }
10762
+ }), _el$34);
10763
+ insert(_el$34, () => formatTime2(rec.createdAt));
10764
+ insert(_el$35, () => rec.text);
10765
+ effect((_p$) => {
10766
+ var _v$0 = styles().memoryPanel.row, _v$1 = styles().memoryPanel.rowHeader, _v$10 = styles().memoryPanel.badge, _v$11 = styles().memoryPanel.time, _v$12 = styles().memoryPanel.rowText;
10767
+ _v$0 !== _p$.e && className(_el$28, _p$.e = _v$0);
10768
+ _v$1 !== _p$.t && className(_el$29, _p$.t = _v$1);
10769
+ _v$10 !== _p$.a && className(_el$30, _p$.a = _v$10);
10770
+ _v$11 !== _p$.o && className(_el$34, _p$.o = _v$11);
10771
+ _v$12 !== _p$.i && className(_el$35, _p$.i = _v$12);
10772
+ return _p$;
10773
+ }, {
10774
+ e: void 0,
10775
+ t: void 0,
10776
+ a: void 0,
10777
+ o: void 0,
10778
+ i: void 0
10779
+ });
10780
+ return _el$28;
10781
+ })()
10782
+ }));
10783
+ effect(() => className(_el$10, styles().memoryPanel.list));
10784
+ return _el$10;
10785
+ }
10786
+ }), null);
10787
+ effect((_p$) => {
10788
+ var _v$4 = styles().memoryPanel.section, _v$5 = styles().memoryPanel.sectionTitle;
10789
+ _v$4 !== _p$.e && className(_el$7, _p$.e = _v$4);
10790
+ _v$5 !== _p$.t && className(_el$8, _p$.t = _v$5);
10791
+ return _p$;
10792
+ }, {
10793
+ e: void 0,
10794
+ t: void 0
10795
+ });
10796
+ return _el$7;
10797
+ })(), (() => {
10798
+ var _el$11 = _tmpl$76(), _el$12 = _el$11.firstChild, _el$13 = _el$12.firstChild, _el$15 = _el$13.nextSibling; _el$15.nextSibling;
10799
+ insert(_el$12, () => facts().length, _el$15);
10800
+ insert(_el$11, createComponent(Show, {
10801
+ get when() {
10802
+ return facts().length > 0;
10803
+ },
10804
+ get fallback() {
10805
+ return (() => {
10806
+ var _el$36 = _tmpl$123();
10807
+ effect(() => className(_el$36, styles().memoryPanel.sectionEmpty));
10808
+ return _el$36;
10809
+ })();
10810
+ },
10811
+ get children() {
10812
+ var _el$16 = _tmpl$56();
10813
+ insert(_el$16, createComponent(For, {
10814
+ get each() {
10815
+ return facts();
10816
+ },
10817
+ children: (fact) => (() => {
10818
+ var _el$37 = _tmpl$143(), _el$38 = _el$37.firstChild;
10819
+ insert(_el$38, createComponent(Show, {
10820
+ get when() {
10821
+ return fact.source;
10822
+ },
10823
+ get children() {
10824
+ var _el$39 = _tmpl$133(), _el$40 = _el$39.firstChild;
10825
+ insert(_el$39, () => fact.source, _el$40);
10826
+ effect(() => className(_el$39, styles().memoryPanel.rowHeader));
10827
+ return _el$39;
10828
+ }
10829
+ }), null);
10830
+ insert(_el$38, () => fact.text, null);
10831
+ effect((_p$) => {
10832
+ var _v$13 = styles().memoryPanel.row, _v$14 = styles().memoryPanel.rowText;
10833
+ _v$13 !== _p$.e && className(_el$37, _p$.e = _v$13);
10834
+ _v$14 !== _p$.t && className(_el$38, _p$.t = _v$14);
10835
+ return _p$;
10836
+ }, {
10837
+ e: void 0,
10838
+ t: void 0
10839
+ });
10840
+ return _el$37;
10841
+ })()
10842
+ }));
10843
+ effect(() => className(_el$16, styles().memoryPanel.list));
10844
+ return _el$16;
10845
+ }
10846
+ }), null);
10847
+ effect((_p$) => {
10848
+ var _v$6 = styles().memoryPanel.section, _v$7 = styles().memoryPanel.sectionTitle;
10849
+ _v$6 !== _p$.e && className(_el$11, _p$.e = _v$6);
10850
+ _v$7 !== _p$.t && className(_el$12, _p$.t = _v$7);
10851
+ return _p$;
10852
+ }, {
10853
+ e: void 0,
10854
+ t: void 0
10855
+ });
10856
+ return _el$11;
10857
+ })(), (() => {
10858
+ var _el$17 = _tmpl$86(), _el$18 = _el$17.firstChild, _el$19 = _el$18.firstChild, _el$21 = _el$19.nextSibling; _el$21.nextSibling;
10859
+ insert(_el$18, () => events().length, _el$21);
10860
+ insert(_el$17, createComponent(Show, {
10861
+ get when() {
10862
+ return events().length > 0;
10863
+ },
10864
+ get fallback() {
10865
+ return (() => {
10866
+ var _el$41 = _tmpl$153();
10867
+ effect(() => className(_el$41, styles().memoryPanel.sectionEmpty));
10868
+ return _el$41;
10869
+ })();
10870
+ },
10871
+ get children() {
10872
+ var _el$22 = _tmpl$56();
10873
+ insert(_el$22, createComponent(For, {
10874
+ get each() {
10875
+ return events();
10876
+ },
10877
+ children: (event) => (() => {
10878
+ var _el$42 = _tmpl$163(), _el$43 = _el$42.firstChild, _el$44 = _el$43.firstChild, _el$45 = _el$44.nextSibling, _el$46 = _el$43.nextSibling;
10879
+ insert(_el$44, () => event.type);
10880
+ insert(_el$45, () => formatTime2(event.timestamp));
10881
+ insert(_el$46, () => eventSummary(event));
10882
+ effect((_p$) => {
10883
+ var _v$15 = `${styles().memoryPanel.row} ${event.type === "error" ? styles().memoryPanel.rowError : ""}`, _v$16 = styles().memoryPanel.rowHeader, _v$17 = styles().memoryPanel.badge, _v$18 = styles().memoryPanel.time, _v$19 = styles().memoryPanel.rowText;
10884
+ _v$15 !== _p$.e && className(_el$42, _p$.e = _v$15);
10885
+ _v$16 !== _p$.t && className(_el$43, _p$.t = _v$16);
10886
+ _v$17 !== _p$.a && className(_el$44, _p$.a = _v$17);
10887
+ _v$18 !== _p$.o && className(_el$45, _p$.o = _v$18);
10888
+ _v$19 !== _p$.i && className(_el$46, _p$.i = _v$19);
10889
+ return _p$;
10890
+ }, {
10891
+ e: void 0,
10892
+ t: void 0,
10893
+ a: void 0,
10894
+ o: void 0,
10895
+ i: void 0
10896
+ });
10897
+ return _el$42;
10898
+ })()
10899
+ }));
10900
+ effect(() => className(_el$22, styles().memoryPanel.list));
10901
+ return _el$22;
10902
+ }
10903
+ }), null);
10904
+ effect((_p$) => {
10905
+ var _v$8 = styles().memoryPanel.section, _v$9 = styles().memoryPanel.sectionTitle;
10906
+ _v$8 !== _p$.e && className(_el$17, _p$.e = _v$8);
10907
+ _v$9 !== _p$.t && className(_el$18, _p$.t = _v$9);
10908
+ return _p$;
10909
+ }, {
10910
+ e: void 0,
10911
+ t: void 0
10912
+ });
10913
+ return _el$17;
10914
+ })()]
10915
+ }));
10916
+ effect(() => className(_el$, styles().memoryPanel.container));
10917
+ return _el$;
10918
+ })();
10919
+ };
10920
+ delegateEvents(["click"]);
10326
10921
 
10327
10922
  // src/components/hooks/HookDetails.tsx
10328
- var _tmpl$38 = /* @__PURE__ */ template(`<aside data-testid=ai-devtools-preview-pane><div>`);
10329
- var _tmpl$213 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-hook-detail><nav data-testid=ai-devtools-hook-tabs></nav><div><main data-testid=ai-devtools-primary-pane>`);
10330
- var _tmpl$39 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-dashboard-overview><header><div><div>Hooks Dashboard</div><div>Select a hook from the left or open one of the active hooks below.</div></div></header><div></div><div>`);
10331
- var _tmpl$46 = /* @__PURE__ */ template(`<div>Open a page with TanStack AI hooks to inspect live state.`);
10332
- var _tmpl$56 = /* @__PURE__ */ template(`<section data-testid=ai-devtools-overview-category><div><span></span><span>`);
10333
- var _tmpl$66 = /* @__PURE__ */ template(`<span>running`);
10334
- var _tmpl$76 = /* @__PURE__ */ template(`<span> new`);
10335
- var _tmpl$86 = /* @__PURE__ */ template(`<button type=button data-testid=ai-devtools-overview-hook><div><span></span><span></span></div><div><span>`);
10336
- var _tmpl$96 = /* @__PURE__ */ template(`<div><span></span><span>`);
10337
- var _tmpl$05 = /* @__PURE__ */ template(`<span>`);
10338
- var _tmpl$114 = /* @__PURE__ */ template(`<span data-testid=ai-devtools-hook-technical-name>`);
10339
- var _tmpl$105 = /* @__PURE__ */ template(`<span>thread `);
10340
- var _tmpl$115 = /* @__PURE__ */ template(`<header data-testid=ai-devtools-hook-header><div><div><span data-testid=ai-devtools-hook-title></span><span></span></div><div><span></span></div></div><div>`);
10341
- var _tmpl$123 = /* @__PURE__ */ template(`<button type=button data-testid=ai-devtools-hook-tab>`);
10342
- var _tmpl$133 = /* @__PURE__ */ template(`<div><section><div>Current State`);
10343
- var _tmpl$143 = /* @__PURE__ */ template(`<div>`);
10344
- var _tmpl$153 = /* @__PURE__ */ template(`<div>No messages.`);
10345
- var _tmpl$163 = /* @__PURE__ */ template(`<div><div>`);
10923
+ var _tmpl$40 = /* @__PURE__ */ template(`<aside data-testid=ai-devtools-preview-pane><div>`);
10924
+ var _tmpl$214 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-hook-detail><nav data-testid=ai-devtools-hook-tabs></nav><div><main data-testid=ai-devtools-primary-pane>`);
10925
+ var _tmpl$310 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-dashboard-overview><header><div><div>Hooks Dashboard</div><div>Select a hook from the left or open one of the active hooks below.</div></div></header><div></div><div>`);
10926
+ var _tmpl$47 = /* @__PURE__ */ template(`<div>Open a page with TanStack AI hooks to inspect live state.`);
10927
+ var _tmpl$57 = /* @__PURE__ */ template(`<section data-testid=ai-devtools-overview-category><div><span></span><span>`);
10928
+ var _tmpl$67 = /* @__PURE__ */ template(`<span>running`);
10929
+ var _tmpl$77 = /* @__PURE__ */ template(`<span> new`);
10930
+ var _tmpl$87 = /* @__PURE__ */ template(`<button type=button data-testid=ai-devtools-overview-hook><div><span></span><span></span></div><div><span>`);
10931
+ var _tmpl$97 = /* @__PURE__ */ template(`<div><span></span><span>`);
10932
+ var _tmpl$06 = /* @__PURE__ */ template(`<span>`);
10933
+ var _tmpl$116 = /* @__PURE__ */ template(`<span data-testid=ai-devtools-hook-technical-name>`);
10934
+ var _tmpl$106 = /* @__PURE__ */ template(`<span data-testid=ai-devtools-hook-registry-id>id `);
10935
+ var _tmpl$117 = /* @__PURE__ */ template(`<header data-testid=ai-devtools-hook-header><div><div><span data-testid=ai-devtools-hook-title></span><span></span></div><div><span data-testid=ai-devtools-hook-identity></span></div></div><div>`);
10936
+ var _tmpl$124 = /* @__PURE__ */ template(`<button type=button data-testid=ai-devtools-hook-tab>`);
10937
+ var _tmpl$134 = /* @__PURE__ */ template(`<div><section><div>Current State`);
10938
+ var _tmpl$144 = /* @__PURE__ */ template(`<div>`);
10939
+ var _tmpl$154 = /* @__PURE__ */ template(`<div>No messages.`);
10940
+ var _tmpl$164 = /* @__PURE__ */ template(`<div><div>`);
10346
10941
  var _tmpl$173 = /* @__PURE__ */ template(`<div><button type=button data-testid=ai-devtools-preview-save-tool-call>Save</button><button type=button data-testid=ai-devtools-preview-replay-tool-call>Replay`);
10347
10942
  var _tmpl$182 = /* @__PURE__ */ template(`<div><span>`);
10348
10943
  var _tmpl$192 = /* @__PURE__ */ template(`<div><span></span><div>`);
10349
10944
  var _tmpl$202 = /* @__PURE__ */ template(`<div>No messages yet. Start a conversation to see messages here.`);
10350
- var _tmpl$214 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-tools><div></div><div>`);
10945
+ var _tmpl$215 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-tools><div></div><div>`);
10351
10946
  var _tmpl$223 = /* @__PURE__ */ template(`<div>No tools.`);
10352
10947
  var _tmpl$232 = /* @__PURE__ */ template(`<span>approval`);
10353
10948
  var _tmpl$242 = /* @__PURE__ */ template(`<button type=button data-testid=ai-devtools-tool-row><span>`);
@@ -10386,7 +10981,7 @@ var HookDetails = () => {
10386
10981
  return Boolean(outputKind && outputKind !== "chat" && outputKind !== "structured");
10387
10982
  });
10388
10983
  createEffect(() => {
10389
- if (isGenerationHook() && activeTab() === "tools") {
10984
+ if (isGenerationHook() && (activeTab() === "tools" || activeTab() === "memory")) {
10390
10985
  setActiveTab("conversation");
10391
10986
  }
10392
10987
  });
@@ -10431,7 +11026,7 @@ var HookDetails = () => {
10431
11026
  });
10432
11027
  },
10433
11028
  children: (activeHook) => (() => {
10434
- var _el$ = _tmpl$213(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.firstChild;
11029
+ var _el$ = _tmpl$214(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.firstChild;
10435
11030
  insert(_el$, createComponent(HookHeader, {
10436
11031
  get hook() {
10437
11032
  return activeHook();
@@ -10482,6 +11077,21 @@ var HookDetails = () => {
10482
11077
  },
10483
11078
  onSelect: setActiveTab
10484
11079
  }), null);
11080
+ insert(_el$2, createComponent(Show, {
11081
+ get when() {
11082
+ return !isGenerationHook();
11083
+ },
11084
+ get children() {
11085
+ return createComponent(TabButton, {
11086
+ label: "Memory",
11087
+ tab: "memory",
11088
+ get activeTab() {
11089
+ return activeTab();
11090
+ },
11091
+ onSelect: setActiveTab
11092
+ });
11093
+ }
11094
+ }), null);
10485
11095
  _el$4.addEventListener("mouseleave", () => setHoverTarget(null));
10486
11096
  _el$4.$$mouseover = (event) => setHoverTargetFromEvent(event, "timeline", setHoverTarget);
10487
11097
  use((el) => {
@@ -10550,12 +11160,20 @@ var HookDetails = () => {
10550
11160
  });
10551
11161
  }
10552
11162
  }), null);
11163
+ insert(_el$4, createComponent(Show, {
11164
+ get when() {
11165
+ return activeTab() === "memory";
11166
+ },
11167
+ get children() {
11168
+ return createComponent(MemoryPanel, {});
11169
+ }
11170
+ }), null);
10553
11171
  insert(_el$3, createComponent(Show, {
10554
11172
  get when() {
10555
11173
  return showSecondaryPane();
10556
11174
  },
10557
11175
  get children() {
10558
- var _el$5 = _tmpl$38(), _el$6 = _el$5.firstChild;
11176
+ var _el$5 = _tmpl$40(), _el$6 = _el$5.firstChild;
10559
11177
  _el$5.addEventListener("mouseleave", () => setHoverTarget(null));
10560
11178
  _el$5.$$mouseover = (event) => setHoverTargetFromEvent(event, "preview", setHoverTarget);
10561
11179
  use((el) => {
@@ -10636,13 +11254,13 @@ var HookOverview = (props) => {
10636
11254
  },
10637
11255
  get fallback() {
10638
11256
  return (() => {
10639
- var _el$12 = _tmpl$46();
11257
+ var _el$12 = _tmpl$47();
10640
11258
  effect(() => className(_el$12, styles().hookDetails.empty));
10641
11259
  return _el$12;
10642
11260
  })();
10643
11261
  },
10644
11262
  get children() {
10645
- var _el$7 = _tmpl$39(), _el$8 = _el$7.firstChild, _el$9 = _el$8.firstChild, _el$0 = _el$9.firstChild, _el$1 = _el$0.nextSibling, _el$10 = _el$8.nextSibling, _el$11 = _el$10.nextSibling;
11263
+ var _el$7 = _tmpl$310(), _el$8 = _el$7.firstChild, _el$9 = _el$8.firstChild, _el$0 = _el$9.firstChild, _el$1 = _el$0.nextSibling, _el$10 = _el$8.nextSibling, _el$11 = _el$10.nextSibling;
10646
11264
  insert(_el$10, createComponent(OverviewMetric, {
10647
11265
  label: "active hooks",
10648
11266
  get value() {
@@ -10696,7 +11314,7 @@ var HookOverview = (props) => {
10696
11314
  return groups();
10697
11315
  },
10698
11316
  children: (group) => (() => {
10699
- var _el$13 = _tmpl$56(), _el$14 = _el$13.firstChild, _el$15 = _el$14.firstChild, _el$16 = _el$15.nextSibling;
11317
+ var _el$13 = _tmpl$57(), _el$14 = _el$13.firstChild, _el$15 = _el$14.firstChild, _el$16 = _el$15.nextSibling;
10700
11318
  insert(_el$15, () => group.label);
10701
11319
  insert(_el$16, () => group.hooks.length);
10702
11320
  insert(_el$13, createComponent(For, {
@@ -10707,27 +11325,17 @@ var HookOverview = (props) => {
10707
11325
  const running = createMemo(() => isHookRunning(hook, state.hooks.runs));
10708
11326
  const unseenCount = createMemo(() => getHookUnseenEventCount(state.hooks, hook.id));
10709
11327
  return (() => {
10710
- var _el$17 = _tmpl$86(), _el$18 = _el$17.firstChild, _el$19 = _el$18.firstChild, _el$20 = _el$19.nextSibling, _el$21 = _el$18.nextSibling, _el$22 = _el$21.firstChild;
11328
+ var _el$17 = _tmpl$87(), _el$18 = _el$17.firstChild, _el$19 = _el$18.firstChild, _el$20 = _el$19.nextSibling, _el$21 = _el$18.nextSibling, _el$22 = _el$21.firstChild;
10711
11329
  _el$17.$$click = () => props.onSelectHook(hook);
10712
11330
  insert(_el$19, () => getHookDisplayName(hook));
10713
- insert(_el$20, createComponent(Show, {
10714
- get when() {
10715
- return hook.displayName;
10716
- },
10717
- get fallback() {
10718
- return hook.id;
10719
- },
10720
- get children() {
10721
- return [memo(() => hook.hookName), " - ", memo(() => hook.id)];
10722
- }
10723
- }));
11331
+ insert(_el$20, () => getHookIdentitySubtitle(hook));
10724
11332
  insert(_el$22, () => hook.outputKind ?? "hook");
10725
11333
  insert(_el$21, createComponent(Show, {
10726
11334
  get when() {
10727
11335
  return running();
10728
11336
  },
10729
11337
  get children() {
10730
- var _el$23 = _tmpl$66();
11338
+ var _el$23 = _tmpl$67();
10731
11339
  effect(() => className(_el$23, styles().hookDetails.lifecycle));
10732
11340
  return _el$23;
10733
11341
  }
@@ -10737,7 +11345,7 @@ var HookOverview = (props) => {
10737
11345
  return unseenCount() > 0;
10738
11346
  },
10739
11347
  get children() {
10740
- var _el$24 = _tmpl$76(), _el$25 = _el$24.firstChild;
11348
+ var _el$24 = _tmpl$77(), _el$25 = _el$24.firstChild;
10741
11349
  insert(_el$24, unseenCount, _el$25);
10742
11350
  effect(() => className(_el$24, styles().hookDetails.kind));
10743
11351
  return _el$24;
@@ -10808,7 +11416,7 @@ var HookOverview = (props) => {
10808
11416
  var OverviewMetric = (props) => {
10809
11417
  const styles = useStyles();
10810
11418
  return (() => {
10811
- var _el$26 = _tmpl$96(), _el$27 = _el$26.firstChild, _el$28 = _el$27.nextSibling;
11419
+ var _el$26 = _tmpl$97(), _el$27 = _el$26.firstChild, _el$28 = _el$27.nextSibling;
10812
11420
  insert(_el$27, () => props.value);
10813
11421
  insert(_el$28, () => props.label);
10814
11422
  effect((_p$) => {
@@ -10828,7 +11436,7 @@ var OverviewMetric = (props) => {
10828
11436
  var HookHeader = (props) => {
10829
11437
  const styles = useStyles();
10830
11438
  return (() => {
10831
- var _el$29 = _tmpl$115(), _el$30 = _el$29.firstChild, _el$31 = _el$30.firstChild, _el$32 = _el$31.firstChild, _el$33 = _el$32.nextSibling, _el$35 = _el$31.nextSibling, _el$37 = _el$35.firstChild, _el$41 = _el$30.nextSibling;
11439
+ var _el$29 = _tmpl$117(), _el$30 = _el$29.firstChild, _el$31 = _el$30.firstChild, _el$32 = _el$31.firstChild, _el$33 = _el$32.nextSibling, _el$35 = _el$31.nextSibling, _el$37 = _el$35.firstChild, _el$41 = _el$30.nextSibling;
10832
11440
  insert(_el$32, () => getHookDisplayName(props.hook));
10833
11441
  insert(_el$33, () => props.hook.lifecycle);
10834
11442
  insert(_el$31, createComponent(Show, {
@@ -10836,7 +11444,7 @@ var HookHeader = (props) => {
10836
11444
  return props.hook.outputKind;
10837
11445
  },
10838
11446
  get children() {
10839
- var _el$34 = _tmpl$05();
11447
+ var _el$34 = _tmpl$06();
10840
11448
  insert(_el$34, () => props.hook.outputKind);
10841
11449
  effect(() => className(_el$34, styles().hookDetails.kind));
10842
11450
  return _el$34;
@@ -10847,19 +11455,22 @@ var HookHeader = (props) => {
10847
11455
  return props.hook.displayName;
10848
11456
  },
10849
11457
  get children() {
10850
- var _el$36 = _tmpl$114();
11458
+ var _el$36 = _tmpl$116();
10851
11459
  insert(_el$36, () => props.hook.hookName);
10852
11460
  return _el$36;
10853
11461
  }
10854
11462
  }), _el$37);
10855
- insert(_el$37, () => props.hook.id);
11463
+ insert(_el$37, (() => {
11464
+ var _c$ = memo(() => !!props.hook.threadId);
11465
+ return () => _c$() ? `thread ${props.hook.threadId}` : getHookIdentityLabel(props.hook);
11466
+ })());
10856
11467
  insert(_el$35, createComponent(Show, {
10857
11468
  get when() {
10858
- return props.hook.threadId;
11469
+ return memo(() => !!props.hook.threadId)() && props.hook.threadId !== props.hook.id;
10859
11470
  },
10860
11471
  get children() {
10861
- var _el$38 = _tmpl$105(); _el$38.firstChild;
10862
- insert(_el$38, () => props.hook.threadId, null);
11472
+ var _el$38 = _tmpl$106(); _el$38.firstChild;
11473
+ insert(_el$38, () => props.hook.id, null);
10863
11474
  return _el$38;
10864
11475
  }
10865
11476
  }), null);
@@ -10868,7 +11479,7 @@ var HookHeader = (props) => {
10868
11479
  return props.hook.framework;
10869
11480
  },
10870
11481
  get children() {
10871
- var _el$40 = _tmpl$05();
11482
+ var _el$40 = _tmpl$06();
10872
11483
  insert(_el$40, () => props.hook.framework);
10873
11484
  return _el$40;
10874
11485
  }
@@ -10937,7 +11548,7 @@ var HookHeader = (props) => {
10937
11548
  var Metric = (props) => {
10938
11549
  const styles = useStyles();
10939
11550
  return (() => {
10940
- var _el$42 = _tmpl$96(), _el$43 = _el$42.firstChild, _el$44 = _el$43.nextSibling;
11551
+ var _el$42 = _tmpl$97(), _el$43 = _el$42.firstChild, _el$44 = _el$43.nextSibling;
10941
11552
  insert(_el$43, () => props.value);
10942
11553
  insert(_el$44, () => props.label);
10943
11554
  effect((_p$) => {
@@ -10964,7 +11575,7 @@ function formatMetricValue(value) {
10964
11575
  var TabButton = (props) => {
10965
11576
  const styles = useStyles();
10966
11577
  return (() => {
10967
- var _el$45 = _tmpl$123();
11578
+ var _el$45 = _tmpl$124();
10968
11579
  _el$45.$$click = () => props.onSelect(props.tab);
10969
11580
  insert(_el$45, () => props.label);
10970
11581
  effect((_p$) => {
@@ -10992,7 +11603,7 @@ var ConversationPanel = (props) => {
10992
11603
  },
10993
11604
  get fallback() {
10994
11605
  return (() => {
10995
- var _el$46 = _tmpl$133(), _el$47 = _el$46.firstChild, _el$48 = _el$47.firstChild;
11606
+ var _el$46 = _tmpl$134(), _el$47 = _el$46.firstChild, _el$48 = _el$47.firstChild;
10996
11607
  insert(_el$47, createComponent(JsonPanel, {
10997
11608
  get value() {
10998
11609
  return props.hook.state;
@@ -11105,13 +11716,13 @@ var MessagesPreview = (props) => {
11105
11716
  },
11106
11717
  get fallback() {
11107
11718
  return (() => {
11108
- var _el$50 = _tmpl$153();
11719
+ var _el$50 = _tmpl$154();
11109
11720
  effect(() => className(_el$50, styles().hookDetails.emptySmall));
11110
11721
  return _el$50;
11111
11722
  })();
11112
11723
  },
11113
11724
  get children() {
11114
- var _el$49 = _tmpl$143();
11725
+ var _el$49 = _tmpl$144();
11115
11726
  insert(_el$49, createComponent(Show, {
11116
11727
  get when() {
11117
11728
  return pendingFixture();
@@ -11131,7 +11742,7 @@ var MessagesPreview = (props) => {
11131
11742
  children: (message) => {
11132
11743
  const visibleParts = () => visiblePreviewPartsForMessage(message);
11133
11744
  return (() => {
11134
- var _el$51 = _tmpl$163(), _el$52 = _el$51.firstChild;
11745
+ var _el$51 = _tmpl$164(), _el$52 = _el$51.firstChild;
11135
11746
  spread(_el$51, mergeProps(() => getHoverDataAttributes({
11136
11747
  messageIds: [message.id],
11137
11748
  partIds: visibleParts().map((part) => part.id)
@@ -11158,7 +11769,7 @@ var MessagesPreview = (props) => {
11158
11769
  return message.content;
11159
11770
  },
11160
11771
  get children() {
11161
- var _el$53 = _tmpl$143();
11772
+ var _el$53 = _tmpl$144();
11162
11773
  insert(_el$53, () => message.content);
11163
11774
  effect(() => className(_el$53, styles().hookDetails.messageContent));
11164
11775
  return _el$53;
@@ -11229,14 +11840,14 @@ var MessagesPreview = (props) => {
11229
11840
  },
11230
11841
  get fallback() {
11231
11842
  return (() => {
11232
- var _el$60 = _tmpl$05();
11843
+ var _el$60 = _tmpl$06();
11233
11844
  insert(_el$60, () => part.content);
11234
11845
  effect(() => className(_el$60, styles().hookDetails.previewPartContent));
11235
11846
  return _el$60;
11236
11847
  })();
11237
11848
  },
11238
11849
  get children() {
11239
- var _el$59 = _tmpl$143();
11850
+ var _el$59 = _tmpl$144();
11240
11851
  insert(_el$59, createComponent(For, {
11241
11852
  get each() {
11242
11853
  return part.jsonItems;
@@ -11297,13 +11908,13 @@ var HookMessageTimeline = (props) => {
11297
11908
  })();
11298
11909
  },
11299
11910
  get children() {
11300
- var _el$64 = _tmpl$143();
11911
+ var _el$64 = _tmpl$144();
11301
11912
  insert(_el$64, createComponent(For, {
11302
11913
  get each() {
11303
11914
  return props.messages;
11304
11915
  },
11305
11916
  children: (message) => (() => {
11306
- var _el$66 = _tmpl$163(), _el$67 = _el$66.firstChild;
11917
+ var _el$66 = _tmpl$164(), _el$67 = _el$66.firstChild;
11307
11918
  spread(_el$66, mergeProps(() => getHoverDataAttributes({
11308
11919
  messageIds: [message.id]
11309
11920
  }), {
@@ -11329,7 +11940,7 @@ var HookMessageTimeline = (props) => {
11329
11940
  return message.content;
11330
11941
  },
11331
11942
  get children() {
11332
- var _el$68 = _tmpl$143();
11943
+ var _el$68 = _tmpl$144();
11333
11944
  insert(_el$68, () => message.content);
11334
11945
  effect(() => className(_el$68, styles().hookDetails.messageContent));
11335
11946
  return _el$68;
@@ -11363,14 +11974,14 @@ var HookMessageTimeline = (props) => {
11363
11974
  },
11364
11975
  get fallback() {
11365
11976
  return (() => {
11366
- var _el$72 = _tmpl$05();
11977
+ var _el$72 = _tmpl$06();
11367
11978
  insert(_el$72, () => part.content);
11368
11979
  effect(() => className(_el$72, styles().hookDetails.previewPartContent));
11369
11980
  return _el$72;
11370
11981
  })();
11371
11982
  },
11372
11983
  get children() {
11373
- var _el$71 = _tmpl$143();
11984
+ var _el$71 = _tmpl$144();
11374
11985
  insert(_el$71, createComponent(For, {
11375
11986
  get each() {
11376
11987
  return part.jsonItems;
@@ -11427,7 +12038,7 @@ var ToolsView = (props) => {
11427
12038
  const selectedTool = createMemo(() => props.hook.tools.find((tool) => tool.name === selectedToolName()));
11428
12039
  const savedFixtures = createMemo(() => state.hooks.fixtures.filter((fixture) => fixture.hookId === props.hook.id || !!props.hook.threadId && fixture.threadId === props.hook.threadId).sort((a, b) => b.createdAt - a.createdAt));
11429
12040
  return (() => {
11430
- var _el$76 = _tmpl$214(), _el$77 = _el$76.firstChild, _el$78 = _el$77.nextSibling;
12041
+ var _el$76 = _tmpl$215(), _el$77 = _el$76.firstChild, _el$78 = _el$77.nextSibling;
11431
12042
  insert(_el$77, createComponent(Show, {
11432
12043
  get when() {
11433
12044
  return props.hook.tools.length > 0;
@@ -11509,7 +12120,7 @@ var ToolsView = (props) => {
11509
12120
  })();
11510
12121
  },
11511
12122
  get children() {
11512
- var _el$85 = _tmpl$143();
12123
+ var _el$85 = _tmpl$144();
11513
12124
  insert(_el$85, createComponent(For, {
11514
12125
  get each() {
11515
12126
  return savedFixtures();
@@ -11518,7 +12129,7 @@ var ToolsView = (props) => {
11518
12129
  var _el$87 = _tmpl$282(), _el$88 = _el$87.firstChild, _el$89 = _el$88.firstChild, _el$90 = _el$89.nextSibling, _el$91 = _el$90.firstChild, _el$92 = _el$88.nextSibling, _el$93 = _el$92.firstChild, _el$94 = _el$93.nextSibling;
11519
12130
  insert(_el$89, () => fixture.name ?? fixture.toolName);
11520
12131
  insert(_el$90, () => fixture.toolName, _el$91);
11521
- insert(_el$90, () => formatTime2(fixture.createdAt), null);
12132
+ insert(_el$90, () => formatTime3(fixture.createdAt), null);
11522
12133
  _el$93.$$click = () => applyToolFixture(fixture);
11523
12134
  _el$94.$$click = () => deleteToolFixture(fixture.id);
11524
12135
  effect((_p$) => {
@@ -11569,7 +12180,7 @@ var ToolsView = (props) => {
11569
12180
  var JsonPanel = (props) => {
11570
12181
  const styles = useStyles();
11571
12182
  return (() => {
11572
- var _el$95 = _tmpl$143();
12183
+ var _el$95 = _tmpl$144();
11573
12184
  insert(_el$95, createComponent(JsonTree, {
11574
12185
  get value() {
11575
12186
  return props.value;
@@ -12012,13 +12623,13 @@ function jsonSafeValue(value) {
12012
12623
  return `[ai-devtools] unserializable value: ${error instanceof Error ? error.message : String(error)}`;
12013
12624
  }
12014
12625
  }
12015
- function formatTime2(timestamp) {
12626
+ function formatTime3(timestamp) {
12016
12627
  return new Date(timestamp).toLocaleTimeString();
12017
12628
  }
12018
12629
  delegateEvents(["mouseover", "click"]);
12019
12630
 
12020
12631
  // src/components/Shell.tsx
12021
- var _tmpl$40 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-panel><div><div data-testid=ai-devtools-left-panel style=min-width:150px;max-width:800px><div>AI Hooks</div></div><div></div><div data-testid=ai-devtools-right-panel style=flex:1>`);
12632
+ var _tmpl$41 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-panel><div><div data-testid=ai-devtools-left-panel style=min-width:150px;max-width:800px><div>AI Hooks</div></div><div></div><div data-testid=ai-devtools-right-panel style=flex:1>`);
12022
12633
  function Devtools(props) {
12023
12634
  return createComponent(ThemeContextProvider, {
12024
12635
  get theme() {
@@ -12100,7 +12711,7 @@ function DevtoolsContent() {
12100
12711
  });
12101
12712
  return createComponent(MainPanel, {
12102
12713
  get children() {
12103
- var _el$ = _tmpl$40(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$3.nextSibling, _el$6 = _el$5.nextSibling;
12714
+ var _el$ = _tmpl$41(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$3.nextSibling, _el$6 = _el$5.nextSibling;
12104
12715
  insert(_el$, createComponent(Header, {
12105
12716
  get children() {
12106
12717
  return createComponent(HeaderLogo, {