@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.
@@ -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`
@@ -4370,8 +4482,8 @@ function removeHookRecord(state, hookId) {
4370
4482
  delete state.runs[runId];
4371
4483
  }
4372
4484
  }
4373
- for (const eventId of hookEventIds) {
4374
- delete state.events[eventId];
4485
+ for (const eventId2 of hookEventIds) {
4486
+ delete state.events[eventId2];
4375
4487
  }
4376
4488
  delete state.hooks[hookId];
4377
4489
  delete state.seenHookActivityCounts[hookId];
@@ -4379,7 +4491,7 @@ function removeHookRecord(state, hookId) {
4379
4491
  state.activeHookId = null;
4380
4492
  }
4381
4493
  }
4382
- function upsertRun(state, event, eventId) {
4494
+ function upsertRun(state, event, eventId2) {
4383
4495
  const existing = state.runs[event.runId];
4384
4496
  if (!existing) {
4385
4497
  state.runs[event.runId] = {
@@ -4393,7 +4505,7 @@ function upsertRun(state, event, eventId) {
4393
4505
  updatedAt: event.timestamp,
4394
4506
  ...isTerminalRunStatus(event.status) ? { completedAt: event.timestamp } : {},
4395
4507
  ...event.error ? { error: event.error } : {},
4396
- eventIds: [eventId]
4508
+ eventIds: [eventId2]
4397
4509
  };
4398
4510
  return;
4399
4511
  }
@@ -4409,8 +4521,8 @@ function upsertRun(state, event, eventId) {
4409
4521
  if (event.error) {
4410
4522
  existing.error = event.error;
4411
4523
  }
4412
- if (!existing.eventIds.includes(eventId)) {
4413
- existing.eventIds.push(eventId);
4524
+ if (!existing.eventIds.includes(eventId2)) {
4525
+ existing.eventIds.push(eventId2);
4414
4526
  }
4415
4527
  }
4416
4528
  function attachRunToHook(state, hookId, runId) {
@@ -4418,7 +4530,7 @@ function attachRunToHook(state, hookId, runId) {
4418
4530
  if (!hook || hook.runIds.includes(runId)) return;
4419
4531
  hook.runIds.push(runId);
4420
4532
  }
4421
- function syncRunsFromSnapshot(state, snapshot, eventId) {
4533
+ function syncRunsFromSnapshot(state, snapshot, eventId2) {
4422
4534
  const rawRuns = snapshot.state.runs;
4423
4535
  if (!Array.isArray(rawRuns)) return;
4424
4536
  for (const candidate of rawRuns) {
@@ -4441,7 +4553,7 @@ function syncRunsFromSnapshot(state, snapshot, eventId) {
4441
4553
  updatedAt,
4442
4554
  ...typeof run.completedAt === "number" ? { completedAt: run.completedAt } : isTerminalRunStatus(status) ? { completedAt: updatedAt } : {},
4443
4555
  ...typeof run.error === "string" ? { error: run.error } : {},
4444
- eventIds: [eventId]
4556
+ eventIds: [eventId2]
4445
4557
  };
4446
4558
  } else {
4447
4559
  existing.hookId = snapshot.hookId;
@@ -4453,8 +4565,8 @@ function syncRunsFromSnapshot(state, snapshot, eventId) {
4453
4565
  existing.completedAt = updatedAt;
4454
4566
  }
4455
4567
  if (typeof run.error === "string") existing.error = run.error;
4456
- if (!existing.eventIds.includes(eventId)) {
4457
- existing.eventIds.push(eventId);
4568
+ if (!existing.eventIds.includes(eventId2)) {
4569
+ existing.eventIds.push(eventId2);
4458
4570
  }
4459
4571
  }
4460
4572
  attachRunToHook(state, snapshot.hookId, run.id);
@@ -4484,11 +4596,11 @@ function attachActivityRunToHook(state, hookId, runId) {
4484
4596
  if (!hook || hook.activityRunIds.includes(runId)) return;
4485
4597
  hook.activityRunIds.push(runId);
4486
4598
  }
4487
- function attachEventToHook(state, hookId, eventId) {
4599
+ function attachEventToHook(state, hookId, eventId2) {
4488
4600
  if (!hookId) return;
4489
4601
  const hook = state.hooks[hookId];
4490
- if (!hook || hook.eventIds.includes(eventId)) return;
4491
- hook.eventIds.push(eventId);
4602
+ if (!hook || hook.eventIds.includes(eventId2)) return;
4603
+ hook.eventIds.push(eventId2);
4492
4604
  }
4493
4605
  function inferLifecycleFromSnapshot(state) {
4494
4606
  if (state.status === "error" || state.error) {
@@ -4530,6 +4642,107 @@ function shouldSkipClientAssistantPlaceholder(message) {
4530
4642
  return message.role === "assistant" && message.source === "client" && !message.content && (!message.toolCalls || message.toolCalls.length === 0) && (!message.parts || message.parts.length === 0);
4531
4643
  }
4532
4644
 
4645
+ // src/store/memory-registry.ts
4646
+ function createMemoryRegistryState() {
4647
+ return { scopes: {} };
4648
+ }
4649
+ function escapeScopeDim(value) {
4650
+ return value.replace(/[\\:_]/g, "\\$&");
4651
+ }
4652
+ function scopeDim(value) {
4653
+ return value != null && value.length > 0 ? escapeScopeDim(value) : "_";
4654
+ }
4655
+ function memoryScopeKey(scope) {
4656
+ if (!scope) return "(unknown)";
4657
+ return `${scopeDim(scope.tenantId)}:${scopeDim(scope.userId)}:${escapeScopeDim(scope.threadId)}:${scopeDim(scope.namespace)}`;
4658
+ }
4659
+ function memoryScopeLabel(entry) {
4660
+ if (entry.key === "(unknown)" || !entry.threadId) return "(unknown)";
4661
+ const parts = [
4662
+ entry.tenantId,
4663
+ entry.userId,
4664
+ entry.threadId,
4665
+ entry.namespace
4666
+ ].filter((p) => p != null && p.length > 0);
4667
+ return parts.join(" \xB7 ");
4668
+ }
4669
+ var MAX_EVENTS_PER_SCOPE = 200;
4670
+ function ensureScope(state, scope) {
4671
+ const key = memoryScopeKey(scope);
4672
+ let entry = state.scopes[key];
4673
+ if (!entry) {
4674
+ entry = {
4675
+ key,
4676
+ threadId: scope?.threadId ?? "",
4677
+ userId: scope?.userId,
4678
+ tenantId: scope?.tenantId,
4679
+ namespace: scope?.namespace,
4680
+ events: [],
4681
+ lastActivity: 0
4682
+ };
4683
+ state.scopes[key] = entry;
4684
+ }
4685
+ if (scope) {
4686
+ if (scope.userId) entry.userId = scope.userId;
4687
+ if (scope.tenantId) entry.tenantId = scope.tenantId;
4688
+ if (scope.namespace) entry.namespace = scope.namespace;
4689
+ }
4690
+ return entry;
4691
+ }
4692
+ var fallbackCounter = 0;
4693
+ function eventId(payload, type, ts) {
4694
+ if (payload.eventId && payload.eventId.length > 0) return payload.eventId;
4695
+ return `${type}:${ts}:${fallbackCounter++}`;
4696
+ }
4697
+ function applyMemoryEvent(state, event) {
4698
+ const entry = ensureScope(state, event.scope);
4699
+ entry.adapter = event.adapter;
4700
+ entry.lastActivity = Math.max(entry.lastActivity, event.timestamp);
4701
+ const record = {
4702
+ id: eventId(event, event.type, event.timestamp),
4703
+ type: event.type,
4704
+ timestamp: event.timestamp,
4705
+ adapter: event.adapter
4706
+ };
4707
+ switch (event.type) {
4708
+ case "retrieve:started":
4709
+ record.query = event.query;
4710
+ break;
4711
+ case "retrieve:completed":
4712
+ record.fragmentCount = event.fragmentCount;
4713
+ record.hasTools = event.hasTools;
4714
+ record.systemPromptChars = event.systemPromptChars;
4715
+ record.durationMs = event.durationMs;
4716
+ break;
4717
+ case "persist:completed":
4718
+ record.receiptCount = event.receiptCount;
4719
+ record.okCount = event.okCount;
4720
+ record.durationMs = event.durationMs;
4721
+ break;
4722
+ case "error":
4723
+ record.phase = event.phase;
4724
+ record.error = event.error;
4725
+ break;
4726
+ }
4727
+ entry.events.push(record);
4728
+ if (entry.events.length > MAX_EVENTS_PER_SCOPE) {
4729
+ entry.events.splice(0, entry.events.length - MAX_EVENTS_PER_SCOPE);
4730
+ }
4731
+ }
4732
+ function applyMemorySnapshot(state, event) {
4733
+ const entry = ensureScope(state, event.scope);
4734
+ entry.adapter = event.adapter;
4735
+ entry.lastActivity = Math.max(entry.lastActivity, event.timestamp);
4736
+ entry.snapshot = {
4737
+ takenAt: event.takenAt,
4738
+ data: event.data,
4739
+ facts: event.facts
4740
+ };
4741
+ }
4742
+ function clearMemoryRegistry(state) {
4743
+ state.scopes = {};
4744
+ }
4745
+
4533
4746
  // src/store/ai-context.tsx
4534
4747
  var AIContext = createContext();
4535
4748
  function useAIStore() {
@@ -4543,7 +4756,8 @@ var AIProvider = (props) => {
4543
4756
  const [state, setState] = createStore({
4544
4757
  conversations: {},
4545
4758
  activeConversationId: null,
4546
- hooks: createHookRegistryState()
4759
+ hooks: createHookRegistryState(),
4760
+ memory: createMemoryRegistryState()
4547
4761
  });
4548
4762
  const streamToConversation = /* @__PURE__ */ new Map();
4549
4763
  const requestToConversation = /* @__PURE__ */ new Map();
@@ -4795,6 +5009,11 @@ var AIProvider = (props) => {
4795
5009
  clearHookRegistry(hooks);
4796
5010
  }));
4797
5011
  }
5012
+ function clearMemory() {
5013
+ setState("memory", produce((memory) => {
5014
+ clearMemoryRegistry(memory);
5015
+ }));
5016
+ }
4798
5017
  function selectHook(id) {
4799
5018
  setState("hooks", produce((hooks) => {
4800
5019
  setActiveHook(hooks, id);
@@ -5097,6 +5316,29 @@ var AIProvider = (props) => {
5097
5316
  applyHookEvent(hooks, "hook:state-snapshot", e.payload);
5098
5317
  }));
5099
5318
  }));
5319
+ const recordMemoryEvent = (type, payload) => {
5320
+ setState("memory", produce((memory) => {
5321
+ applyMemoryEvent(memory, {
5322
+ ...payload,
5323
+ type
5324
+ });
5325
+ }));
5326
+ };
5327
+ cleanupFns.push(aiEventClient.on("memory:retrieve:started", (e) => {
5328
+ recordMemoryEvent("retrieve:started", e.payload);
5329
+ }), aiEventClient.on("memory:retrieve:completed", (e) => {
5330
+ recordMemoryEvent("retrieve:completed", e.payload);
5331
+ }), aiEventClient.on("memory:persist:started", (e) => {
5332
+ recordMemoryEvent("persist:started", e.payload);
5333
+ }), aiEventClient.on("memory:persist:completed", (e) => {
5334
+ recordMemoryEvent("persist:completed", e.payload);
5335
+ }), aiEventClient.on("memory:error", (e) => {
5336
+ recordMemoryEvent("error", e.payload);
5337
+ }), aiEventClient.on("memory:snapshot", (e) => {
5338
+ setState("memory", produce((memory) => {
5339
+ applyMemorySnapshot(memory, e.payload);
5340
+ }));
5341
+ }));
5100
5342
  const recordRunEvent = (eventName, payload) => {
5101
5343
  setState("hooks", produce((hooks) => {
5102
5344
  applyHookEvent(hooks, eventName, payload);
@@ -6671,6 +6913,7 @@ var AIProvider = (props) => {
6671
6913
  clearAllConversations,
6672
6914
  selectConversation,
6673
6915
  clearHooks,
6916
+ clearMemory,
6674
6917
  selectHook,
6675
6918
  saveToolFixture,
6676
6919
  deleteToolFixture,
@@ -6715,6 +6958,16 @@ function visibleHooks(hooks) {
6715
6958
  function getHookDisplayName(hook) {
6716
6959
  return hook.displayName ?? hook.hookName;
6717
6960
  }
6961
+ function getHookIdentityLabel(hook) {
6962
+ return hook.threadId ?? hook.id;
6963
+ }
6964
+ function getHookIdentitySubtitle(hook) {
6965
+ const identity = getHookIdentityLabel(hook);
6966
+ if (hook.displayName) {
6967
+ return `${hook.hookName} - ${identity}`;
6968
+ }
6969
+ return identity;
6970
+ }
6718
6971
  function groupHooksByCategory(hooks) {
6719
6972
  const groups = /* @__PURE__ */ new Map();
6720
6973
  for (const hook of hooks) {
@@ -6829,17 +7082,7 @@ var HookDashboard = () => {
6829
7082
  get children() {
6830
7083
  return ssr(_tmpl$6, ssrAttribute("class", escape(styles().hookDashboard.updateBadge, true), false), escape(unseenCount()));
6831
7084
  }
6832
- })), ssrAttribute("class", escape(styles().hookDashboard.rowId, true), false), escape(createComponent(Show, {
6833
- get when() {
6834
- return hook.displayName;
6835
- },
6836
- get fallback() {
6837
- return hook.id;
6838
- },
6839
- get children() {
6840
- return [hook.hookName, " - ", hook.id];
6841
- }
6842
- })), ssrAttribute("class", escape(styles().hookDashboard.rowMeta, true), false), `${escape(styles().hookDashboard.lifecycleBadge, true)} ${hook.lifecycle === "streaming" ? escape(styles().hookDashboard.lifecycleStreaming, true) : hook.lifecycle === "errored" ? escape(styles().hookDashboard.lifecycleErrored, true) : ""}`, escape(hook.lifecycle), escape(createComponent(Show, {
7085
+ })), ssrAttribute("class", escape(styles().hookDashboard.rowId, true), false), escape(getHookIdentitySubtitle(hook)), ssrAttribute("class", escape(styles().hookDashboard.rowMeta, true), false), `${escape(styles().hookDashboard.lifecycleBadge, true)} ${hook.lifecycle === "streaming" ? escape(styles().hookDashboard.lifecycleStreaming, true) : hook.lifecycle === "errored" ? escape(styles().hookDashboard.lifecycleErrored, true) : ""}`, escape(hook.lifecycle), escape(createComponent(Show, {
6843
7086
  get when() {
6844
7087
  return hook.outputKind;
6845
7088
  },
@@ -8981,31 +9224,198 @@ function formatTime(timestamp) {
8981
9224
  function isRecord3(value) {
8982
9225
  return typeof value === "object" && value !== null && !Array.isArray(value);
8983
9226
  }
9227
+ var _tmpl$40 = ["<div", ' data-testid="ai-devtools-memory-panel">', "</div>"];
9228
+ var _tmpl$213 = ["<div", ">No memory activity yet. Send a message through a chat wired with<code> memoryMiddleware</code> and recall/save events will appear here.</div>"];
9229
+ var _tmpl$311 = ["<select", ' data-testid="ai-devtools-memory-scope-select">', "</select>"];
9230
+ var _tmpl$46 = ["<div", "><div", ">", '</div><button type="button"', ">Clear</button></div>"];
9231
+ var _tmpl$56 = ["<div", ">", "</div>"];
9232
+ var _tmpl$66 = ["<section", "><div", ">Stored records (", ")", "</div>", "</section>"];
9233
+ var _tmpl$76 = ["<section", "><div", ">listFacts() (", ")</div>", "</section>"];
9234
+ var _tmpl$86 = ["<section", "><div", ">Operations (", ")</div>", "</section>"];
9235
+ var _tmpl$96 = ["<span", ">", "</span>"];
9236
+ var _tmpl$05 = ["<option", ">", "", "</option>"];
9237
+ var _tmpl$114 = ["<span", ">snapshot ", "</span>"];
9238
+ var _tmpl$105 = ["<span>", "</span>"];
9239
+ var _tmpl$115 = ["<span>importance ", "</span>"];
9240
+ var _tmpl$124 = ["<div", ' data-testid="ai-devtools-memory-record"><div', "><span", ">", "</span>", "", "<span", ">", "</span></div><div", ">", "</div></div>"];
9241
+ var _tmpl$134 = ["<div", ">No facts.</div>"];
9242
+ var _tmpl$143 = ["<span", ">", ": </span>"];
9243
+ var _tmpl$153 = ["<div", "><div", ">", "", "</div></div>"];
9244
+ var _tmpl$163 = ["<div", ">No operations recorded.</div>"];
9245
+ var _tmpl$173 = ['<div class="', '" data-testid="ai-devtools-memory-event"><div', "><span", ">", "</span><span", ">", "</span></div><div", ">", "</div></div>"];
9246
+ function extractRecords(data) {
9247
+ if (!data || typeof data !== "object") return [];
9248
+ const records = data.records;
9249
+ if (!Array.isArray(records)) return [];
9250
+ return records.filter((r) => Boolean(r) && typeof r === "object" && typeof r.id === "string" && typeof r.text === "string");
9251
+ }
9252
+ function formatTime2(value) {
9253
+ if (value === void 0) return "";
9254
+ const date = new Date(value);
9255
+ if (Number.isNaN(date.getTime())) return "";
9256
+ return date.toLocaleTimeString();
9257
+ }
9258
+ function eventSummary(event) {
9259
+ switch (event.type) {
9260
+ case "retrieve:started":
9261
+ return `recall "${event.query ?? ""}"`;
9262
+ case "retrieve:completed":
9263
+ return `recalled ${event.fragmentCount ?? 0} fragment(s), ${event.systemPromptChars ?? 0} prompt chars${event.hasTools ? ", +tools" : ""} (${event.durationMs ?? 0}ms)`;
9264
+ case "persist:started":
9265
+ return "save started";
9266
+ case "persist:completed":
9267
+ return `saved ${event.okCount ?? 0}/${event.receiptCount ?? 0} receipt(s) (${event.durationMs ?? 0}ms)`;
9268
+ case "error":
9269
+ return `${event.phase ?? ""} error: ${event.error?.message ?? "unknown"}`;
9270
+ default:
9271
+ return event.type;
9272
+ }
9273
+ }
9274
+ var MemoryPanel = () => {
9275
+ const {
9276
+ state,
9277
+ clearMemory
9278
+ } = useAIStore();
9279
+ const styles = useStyles();
9280
+ const [override, setOverride] = createSignal(null);
9281
+ const scopeKeys = createMemo(() => Object.values(state.memory.scopes).slice().sort((a, b) => b.lastActivity - a.lastActivity).map((s) => s.key));
9282
+ const selectedKey = createMemo(() => {
9283
+ const chosen = override();
9284
+ if (chosen && state.memory.scopes[chosen]) return chosen;
9285
+ return scopeKeys()[0] ?? null;
9286
+ });
9287
+ const scope = createMemo(() => {
9288
+ const key = selectedKey();
9289
+ return key ? state.memory.scopes[key] : void 0;
9290
+ });
9291
+ const records = createMemo(() => extractRecords(scope()?.snapshot?.data));
9292
+ const facts = createMemo(() => scope()?.snapshot?.facts ?? []);
9293
+ const events = createMemo(() => (scope()?.events ?? []).slice().sort((a, b) => b.timestamp - a.timestamp));
9294
+ return ssr(_tmpl$40, ssrAttribute("class", escape(styles().memoryPanel.container, true), false), escape(createComponent(Show, {
9295
+ get when() {
9296
+ return scope();
9297
+ },
9298
+ get fallback() {
9299
+ return ssr(_tmpl$213, ssrAttribute("class", escape(styles().memoryPanel.empty, true), false));
9300
+ },
9301
+ children: (activeScope) => [ssr(_tmpl$46, ssrAttribute("class", escape(styles().memoryPanel.toolbar, true), false), ssrAttribute("class", escape(styles().memoryPanel.scopeControls, true), false), escape(createComponent(Show, {
9302
+ get when() {
9303
+ return scopeKeys().length > 1;
9304
+ },
9305
+ get fallback() {
9306
+ return ssr(_tmpl$96, ssrAttribute("class", escape(styles().memoryPanel.badge, true), false), escape(activeScope().adapter) ?? "memory");
9307
+ },
9308
+ get children() {
9309
+ return ssr(_tmpl$311, ssrAttribute("class", escape(styles().memoryPanel.scopeSelect, true), false) + ssrAttribute("value", escape(selectedKey(), true) ?? "", false), escape(createComponent(For, {
9310
+ get each() {
9311
+ return scopeKeys();
9312
+ },
9313
+ children: (key) => {
9314
+ const entry = state.memory.scopes[key];
9315
+ const label = entry ? memoryScopeLabel(entry) : key;
9316
+ return ssr(_tmpl$05, ssrAttribute("value", escape(key, true), false), entry?.adapter ? `${escape(entry.adapter)} \xB7 ` : "", label.length > 40 ? `${escape(label.slice(0, 40))}\u2026` : escape(label));
9317
+ }
9318
+ })));
9319
+ }
9320
+ })), ssrAttribute("class", escape(styles().memoryPanel.clearButton, true), false)), ssr(_tmpl$66, ssrAttribute("class", escape(styles().memoryPanel.section, true), false), ssrAttribute("class", escape(styles().memoryPanel.sectionTitle, true), false), escape(records().length), escape(createComponent(Show, {
9321
+ get when() {
9322
+ return activeScope().snapshot;
9323
+ },
9324
+ children: (snap) => ssr(_tmpl$114, ssrAttribute("class", escape(styles().memoryPanel.time, true), false), escape(formatTime2(snap().takenAt)))
9325
+ })), escape(createComponent(Show, {
9326
+ get when() {
9327
+ return records().length > 0;
9328
+ },
9329
+ get fallback() {
9330
+ return ssr(_tmpl$56, ssrAttribute("class", escape(styles().memoryPanel.sectionEmpty, true), false), activeScope().snapshot ? "Snapshot is empty." : "This adapter does not expose inspect() \u2014 see the timeline below for activity.");
9331
+ },
9332
+ get children() {
9333
+ return ssr(_tmpl$56, ssrAttribute("class", escape(styles().memoryPanel.list, true), false), escape(createComponent(For, {
9334
+ get each() {
9335
+ return records();
9336
+ },
9337
+ children: (rec) => ssr(_tmpl$124, ssrAttribute("class", escape(styles().memoryPanel.row, true), false), ssrAttribute("class", escape(styles().memoryPanel.rowHeader, true), false), ssrAttribute("class", escape(styles().memoryPanel.badge, true), false), escape(rec.kind), escape(createComponent(Show, {
9338
+ get when() {
9339
+ return rec.role;
9340
+ },
9341
+ get children() {
9342
+ return ssr(_tmpl$105, escape(rec.role));
9343
+ }
9344
+ })), escape(createComponent(Show, {
9345
+ get when() {
9346
+ return rec.importance !== void 0;
9347
+ },
9348
+ get children() {
9349
+ return ssr(_tmpl$115, escape(rec.importance?.toFixed(2)));
9350
+ }
9351
+ })), ssrAttribute("class", escape(styles().memoryPanel.time, true), false), escape(formatTime2(rec.createdAt)), ssrAttribute("class", escape(styles().memoryPanel.rowText, true), false), escape(rec.text))
9352
+ })));
9353
+ }
9354
+ }))), ssr(_tmpl$76, ssrAttribute("class", escape(styles().memoryPanel.section, true), false), ssrAttribute("class", escape(styles().memoryPanel.sectionTitle, true), false), escape(facts().length), escape(createComponent(Show, {
9355
+ get when() {
9356
+ return facts().length > 0;
9357
+ },
9358
+ get fallback() {
9359
+ return ssr(_tmpl$134, ssrAttribute("class", escape(styles().memoryPanel.sectionEmpty, true), false));
9360
+ },
9361
+ get children() {
9362
+ return ssr(_tmpl$56, ssrAttribute("class", escape(styles().memoryPanel.list, true), false), escape(createComponent(For, {
9363
+ get each() {
9364
+ return facts();
9365
+ },
9366
+ children: (fact) => ssr(_tmpl$153, ssrAttribute("class", escape(styles().memoryPanel.row, true), false), ssrAttribute("class", escape(styles().memoryPanel.rowText, true), false), escape(createComponent(Show, {
9367
+ get when() {
9368
+ return fact.source;
9369
+ },
9370
+ get children() {
9371
+ return ssr(_tmpl$143, ssrAttribute("class", escape(styles().memoryPanel.rowHeader, true), false), escape(fact.source));
9372
+ }
9373
+ })), escape(fact.text))
9374
+ })));
9375
+ }
9376
+ }))), ssr(_tmpl$86, ssrAttribute("class", escape(styles().memoryPanel.section, true), false), ssrAttribute("class", escape(styles().memoryPanel.sectionTitle, true), false), escape(events().length), escape(createComponent(Show, {
9377
+ get when() {
9378
+ return events().length > 0;
9379
+ },
9380
+ get fallback() {
9381
+ return ssr(_tmpl$163, ssrAttribute("class", escape(styles().memoryPanel.sectionEmpty, true), false));
9382
+ },
9383
+ get children() {
9384
+ return ssr(_tmpl$56, ssrAttribute("class", escape(styles().memoryPanel.list, true), false), escape(createComponent(For, {
9385
+ get each() {
9386
+ return events();
9387
+ },
9388
+ children: (event) => ssr(_tmpl$173, `${escape(styles().memoryPanel.row, true)} ${event.type === "error" ? escape(styles().memoryPanel.rowError, true) : ""}`, ssrAttribute("class", escape(styles().memoryPanel.rowHeader, true), false), ssrAttribute("class", escape(styles().memoryPanel.badge, true), false), escape(event.type), ssrAttribute("class", escape(styles().memoryPanel.time, true), false), escape(formatTime2(event.timestamp)), ssrAttribute("class", escape(styles().memoryPanel.rowText, true), false), escape(eventSummary(event)))
9389
+ })));
9390
+ }
9391
+ })))]
9392
+ })));
9393
+ };
8984
9394
 
8985
9395
  // src/components/hooks/HookDetails.tsx
8986
- var _tmpl$40 = ["<aside", ' data-testid="ai-devtools-preview-pane"><div', ">", "</div>", "</aside>"];
8987
- var _tmpl$213 = ["<div", ' data-testid="ai-devtools-hook-detail">', "<nav", ' data-testid="ai-devtools-hook-tabs">', "", "", '</nav><div class="', '"><main', ' data-testid="ai-devtools-primary-pane">', "", "", "</main>", "</div></div>"];
8988
- var _tmpl$311 = ["<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", ">", "</div></div>"];
8989
- var _tmpl$46 = ["<div", ">Open a page with TanStack AI hooks to inspect live state.</div>"];
8990
- var _tmpl$56 = ["<section", ' data-testid="ai-devtools-overview-category"', "><div", "><span>", "</span><span>", "</span></div>", "</section>"];
8991
- var _tmpl$66 = ["<span", ">running</span>"];
8992
- var _tmpl$76 = ["<span", ">", " new</span>"];
8993
- var _tmpl$86 = ['<button type="button" data-testid="ai-devtools-overview-hook"', "><div", "><span", ">", "</span><span", ">", "</span></div><div", "><span", ">", "</span>", "", "</div></button>"];
8994
- var _tmpl$96 = ["<div", "><span", ">", "</span><span", ">", "</span></div>"];
8995
- var _tmpl$05 = ["<span", ">", "</span>"];
8996
- var _tmpl$114 = ['<span data-testid="ai-devtools-hook-technical-name">', "</span>"];
8997
- var _tmpl$105 = ["<span>thread ", "</span>"];
8998
- var _tmpl$115 = ["<span>", "</span>"];
8999
- var _tmpl$124 = ["<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", ">", "", "</div></header>"];
9000
- var _tmpl$134 = ['<button type="button" data-testid="ai-devtools-hook-tab"', ' class="', '">', "</button>"];
9001
- var _tmpl$143 = ["<div", "><section", "><div", ">Current State</div>", "</section></div>"];
9002
- var _tmpl$153 = ["<div", ">", "", "</div>"];
9003
- var _tmpl$163 = ["<div", ">No messages.</div>"];
9004
- var _tmpl$173 = ["<div", ">", "</div>"];
9396
+ var _tmpl$41 = ["<aside", ' data-testid="ai-devtools-preview-pane"><div', ">", "</div>", "</aside>"];
9397
+ var _tmpl$214 = ["<div", ' data-testid="ai-devtools-hook-detail">', "<nav", ' data-testid="ai-devtools-hook-tabs">', "", "", "", '</nav><div class="', '"><main', ' data-testid="ai-devtools-primary-pane">', "", "", "", "</main>", "</div></div>"];
9398
+ var _tmpl$312 = ["<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", ">", "</div></div>"];
9399
+ var _tmpl$47 = ["<div", ">Open a page with TanStack AI hooks to inspect live state.</div>"];
9400
+ var _tmpl$57 = ["<section", ' data-testid="ai-devtools-overview-category"', "><div", "><span>", "</span><span>", "</span></div>", "</section>"];
9401
+ var _tmpl$67 = ["<span", ">running</span>"];
9402
+ var _tmpl$77 = ["<span", ">", " new</span>"];
9403
+ var _tmpl$87 = ['<button type="button" data-testid="ai-devtools-overview-hook"', "><div", "><span", ">", "</span><span", ">", "</span></div><div", "><span", ">", "</span>", "", "</div></button>"];
9404
+ var _tmpl$97 = ["<div", "><span", ">", "</span><span", ">", "</span></div>"];
9405
+ var _tmpl$06 = ["<span", ">", "</span>"];
9406
+ var _tmpl$116 = ['<span data-testid="ai-devtools-hook-technical-name">', "</span>"];
9407
+ var _tmpl$106 = ['<span data-testid="ai-devtools-hook-registry-id">id ', "</span>"];
9408
+ var _tmpl$117 = ["<span>", "</span>"];
9409
+ var _tmpl$125 = ["<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", ">", "", "</div></header>"];
9410
+ var _tmpl$135 = ['<button type="button" data-testid="ai-devtools-hook-tab"', ' class="', '">', "</button>"];
9411
+ var _tmpl$144 = ["<div", "><section", "><div", ">Current State</div>", "</section></div>"];
9412
+ var _tmpl$154 = ["<div", ">", "", "</div>"];
9413
+ var _tmpl$164 = ["<div", ">No messages.</div>"];
9414
+ var _tmpl$174 = ["<div", ">", "</div>"];
9005
9415
  var _tmpl$183 = ["<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</button></div>'];
9006
9416
  var _tmpl$193 = ['<div class="', '">', "</div>"];
9007
9417
  var _tmpl$202 = ["<div", "><span", ">", "</span><div", ">", "</div></div>"];
9008
- var _tmpl$214 = ["<div", ">No messages yet. Start a conversation to see messages here.</div>"];
9418
+ var _tmpl$215 = ["<div", ">No messages yet. Start a conversation to see messages here.</div>"];
9009
9419
  var _tmpl$223 = ["<div", ' data-testid="ai-devtools-tools"><div', ">", "</div><div", ">", "</div></div>"];
9010
9420
  var _tmpl$232 = ["<div", ">No tools.</div>"];
9011
9421
  var _tmpl$242 = ["<span", ">approval</span>"];
@@ -9044,7 +9454,7 @@ var HookDetails = () => {
9044
9454
  return Boolean(outputKind && outputKind !== "chat" && outputKind !== "structured");
9045
9455
  });
9046
9456
  createEffect(() => {
9047
- if (isGenerationHook() && activeTab() === "tools") {
9457
+ if (isGenerationHook() && (activeTab() === "tools" || activeTab() === "memory")) {
9048
9458
  setActiveTab("conversation");
9049
9459
  }
9050
9460
  });
@@ -9083,7 +9493,7 @@ var HookDetails = () => {
9083
9493
  }
9084
9494
  });
9085
9495
  },
9086
- children: (activeHook) => ssr(_tmpl$213, ssrAttribute("class", escape(styles().hookDetails.container, true), false), escape(createComponent(HookHeader, {
9496
+ children: (activeHook) => ssr(_tmpl$214, ssrAttribute("class", escape(styles().hookDetails.container, true), false), escape(createComponent(HookHeader, {
9087
9497
  get hook() {
9088
9498
  return activeHook();
9089
9499
  },
@@ -9129,6 +9539,20 @@ var HookDetails = () => {
9129
9539
  return activeTab();
9130
9540
  },
9131
9541
  onSelect: setActiveTab
9542
+ })), escape(createComponent(Show, {
9543
+ get when() {
9544
+ return !isGenerationHook();
9545
+ },
9546
+ get children() {
9547
+ return createComponent(TabButton, {
9548
+ label: "Memory",
9549
+ tab: "memory",
9550
+ get activeTab() {
9551
+ return activeTab();
9552
+ },
9553
+ onSelect: setActiveTab
9554
+ });
9555
+ }
9132
9556
  })), `${escape(styles().hookDetails.body, true)} ${showSecondaryPane() ? "" : escape(styles().hookDetails.bodySinglePane, true)}`, ssrAttribute("class", escape(styles().hookDetails.primary, true), false), escape(createComponent(Show, {
9133
9557
  get when() {
9134
9558
  return activeTab() === "conversation";
@@ -9189,12 +9613,19 @@ var HookDetails = () => {
9189
9613
  }
9190
9614
  });
9191
9615
  }
9616
+ })), escape(createComponent(Show, {
9617
+ get when() {
9618
+ return activeTab() === "memory";
9619
+ },
9620
+ get children() {
9621
+ return createComponent(MemoryPanel, {});
9622
+ }
9192
9623
  })), escape(createComponent(Show, {
9193
9624
  get when() {
9194
9625
  return showSecondaryPane();
9195
9626
  },
9196
9627
  get children() {
9197
- return ssr(_tmpl$40, ssrAttribute("class", escape(styles().hookDetails.previewPane, true), false), ssrAttribute("class", escape(styles().hookDetails.previewHeader, true), false), isGenerationHook() ? "Generated Output" : "User View", escape(createComponent(Show, {
9628
+ return ssr(_tmpl$41, ssrAttribute("class", escape(styles().hookDetails.previewPane, true), false), ssrAttribute("class", escape(styles().hookDetails.previewHeader, true), false), isGenerationHook() ? "Generated Output" : "User View", escape(createComponent(Show, {
9198
9629
  get when() {
9199
9630
  return isGenerationHook();
9200
9631
  },
@@ -9242,10 +9673,10 @@ var HookOverview = (props) => {
9242
9673
  return hooks().length > 0;
9243
9674
  },
9244
9675
  get fallback() {
9245
- return ssr(_tmpl$46, ssrAttribute("class", escape(styles().hookDetails.empty, true), false));
9676
+ return ssr(_tmpl$47, ssrAttribute("class", escape(styles().hookDetails.empty, true), false));
9246
9677
  },
9247
9678
  get children() {
9248
- return ssr(_tmpl$311, ssrAttribute("class", escape(styles().hookDetails.overview, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewHeader, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewTitle, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewSubtitle, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewMetricGrid, true), false), escape(createComponent(OverviewMetric, {
9679
+ return ssr(_tmpl$312, ssrAttribute("class", escape(styles().hookDetails.overview, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewHeader, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewTitle, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewSubtitle, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewMetricGrid, true), false), escape(createComponent(OverviewMetric, {
9249
9680
  label: "active hooks",
9250
9681
  get value() {
9251
9682
  return summary().active;
@@ -9289,36 +9720,26 @@ var HookOverview = (props) => {
9289
9720
  get each() {
9290
9721
  return groups();
9291
9722
  },
9292
- children: (group) => ssr(_tmpl$56, ssrAttribute("class", escape(styles().hookDetails.overviewGroupCard, true), false), ssrAttribute("data-category", escape(group.id, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewGroupHeader, true), false), escape(group.label), escape(group.hooks.length), escape(createComponent(For, {
9723
+ children: (group) => ssr(_tmpl$57, ssrAttribute("class", escape(styles().hookDetails.overviewGroupCard, true), false), ssrAttribute("data-category", escape(group.id, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewGroupHeader, true), false), escape(group.label), escape(group.hooks.length), escape(createComponent(For, {
9293
9724
  get each() {
9294
9725
  return group.hooks;
9295
9726
  },
9296
9727
  children: (hook) => {
9297
9728
  const running = createMemo(() => isHookRunning(hook, state.hooks.runs));
9298
9729
  const unseenCount = createMemo(() => getHookUnseenEventCount(state.hooks, hook.id));
9299
- return ssr(_tmpl$86, ssrAttribute("data-hook-id", escape(hook.id, true), false) + ssrAttribute("data-hook-name", escape(hook.hookName, true), false) + ssrAttribute("data-display-name", escape(getHookDisplayName(hook), true), false) + ssrAttribute("class", escape(styles().hookDetails.overviewHookButton, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewHookMain, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewHookTitle, true), false), escape(getHookDisplayName(hook)), ssrAttribute("class", escape(styles().hookDetails.overviewHookId, true), false), escape(createComponent(Show, {
9300
- get when() {
9301
- return hook.displayName;
9302
- },
9303
- get fallback() {
9304
- return hook.id;
9305
- },
9306
- get children() {
9307
- return [hook.hookName, " - ", hook.id];
9308
- }
9309
- })), ssrAttribute("class", escape(styles().hookDetails.overviewHookMeta, true), false), ssrAttribute("class", escape(styles().hookDetails.kind, true), false), escape(hook.outputKind) ?? "hook", escape(createComponent(Show, {
9730
+ return ssr(_tmpl$87, ssrAttribute("data-hook-id", escape(hook.id, true), false) + ssrAttribute("data-hook-name", escape(hook.hookName, true), false) + ssrAttribute("data-display-name", escape(getHookDisplayName(hook), true), false) + ssrAttribute("class", escape(styles().hookDetails.overviewHookButton, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewHookMain, true), false), ssrAttribute("class", escape(styles().hookDetails.overviewHookTitle, true), false), escape(getHookDisplayName(hook)), ssrAttribute("class", escape(styles().hookDetails.overviewHookId, true), false), escape(getHookIdentitySubtitle(hook)), ssrAttribute("class", escape(styles().hookDetails.overviewHookMeta, true), false), ssrAttribute("class", escape(styles().hookDetails.kind, true), false), escape(hook.outputKind) ?? "hook", escape(createComponent(Show, {
9310
9731
  get when() {
9311
9732
  return running();
9312
9733
  },
9313
9734
  get children() {
9314
- return ssr(_tmpl$66, ssrAttribute("class", escape(styles().hookDetails.lifecycle, true), false));
9735
+ return ssr(_tmpl$67, ssrAttribute("class", escape(styles().hookDetails.lifecycle, true), false));
9315
9736
  }
9316
9737
  })), escape(createComponent(Show, {
9317
9738
  get when() {
9318
9739
  return unseenCount() > 0;
9319
9740
  },
9320
9741
  get children() {
9321
- return ssr(_tmpl$76, ssrAttribute("class", escape(styles().hookDetails.kind, true), false), escape(unseenCount()));
9742
+ return ssr(_tmpl$77, ssrAttribute("class", escape(styles().hookDetails.kind, true), false), escape(unseenCount()));
9322
9743
  }
9323
9744
  })));
9324
9745
  }
@@ -9329,37 +9750,37 @@ var HookOverview = (props) => {
9329
9750
  };
9330
9751
  var OverviewMetric = (props) => {
9331
9752
  const styles = useStyles();
9332
- return ssr(_tmpl$96, ssrAttribute("class", escape(styles().hookDetails.overviewMetricCard, true), false), ssrAttribute("class", escape(styles().hookDetails.metricValue, true), false), escape(props.value), ssrAttribute("class", escape(styles().hookDetails.metricLabel, true), false), escape(props.label));
9753
+ return ssr(_tmpl$97, ssrAttribute("class", escape(styles().hookDetails.overviewMetricCard, true), false), ssrAttribute("class", escape(styles().hookDetails.metricValue, true), false), escape(props.value), ssrAttribute("class", escape(styles().hookDetails.metricLabel, true), false), escape(props.label));
9333
9754
  };
9334
9755
  var HookHeader = (props) => {
9335
9756
  const styles = useStyles();
9336
- return ssr(_tmpl$124, ssrAttribute("class", escape(styles().hookDetails.header, true), false), ssrAttribute("data-hook-id", escape(props.hook.id, true), false) + ssrAttribute("data-hook-name", escape(props.hook.hookName, true), false) + ssrAttribute("data-display-name", escape(getHookDisplayName(props.hook), true), false), ssrAttribute("class", escape(styles().hookDetails.headerMain, true), false), ssrAttribute("class", escape(styles().hookDetails.titleRow, true), false), ssrAttribute("class", escape(styles().hookDetails.title, true), false), escape(getHookDisplayName(props.hook)), ssrAttribute("class", escape(styles().hookDetails.lifecycle, true), false), escape(props.hook.lifecycle), escape(createComponent(Show, {
9757
+ return ssr(_tmpl$125, ssrAttribute("class", escape(styles().hookDetails.header, true), false), ssrAttribute("data-hook-id", escape(props.hook.id, true), false) + ssrAttribute("data-hook-name", escape(props.hook.hookName, true), false) + ssrAttribute("data-display-name", escape(getHookDisplayName(props.hook), true), false), ssrAttribute("class", escape(styles().hookDetails.headerMain, true), false), ssrAttribute("class", escape(styles().hookDetails.titleRow, true), false), ssrAttribute("class", escape(styles().hookDetails.title, true), false), escape(getHookDisplayName(props.hook)), ssrAttribute("class", escape(styles().hookDetails.lifecycle, true), false), escape(props.hook.lifecycle), escape(createComponent(Show, {
9337
9758
  get when() {
9338
9759
  return props.hook.outputKind;
9339
9760
  },
9340
9761
  get children() {
9341
- return ssr(_tmpl$05, ssrAttribute("class", escape(styles().hookDetails.kind, true), false), escape(props.hook.outputKind));
9762
+ return ssr(_tmpl$06, ssrAttribute("class", escape(styles().hookDetails.kind, true), false), escape(props.hook.outputKind));
9342
9763
  }
9343
9764
  })), ssrAttribute("class", escape(styles().hookDetails.identity, true), false), escape(createComponent(Show, {
9344
9765
  get when() {
9345
9766
  return props.hook.displayName;
9346
9767
  },
9347
9768
  get children() {
9348
- return ssr(_tmpl$114, escape(props.hook.hookName));
9769
+ return ssr(_tmpl$116, escape(props.hook.hookName));
9349
9770
  }
9350
- })), escape(props.hook.id), escape(createComponent(Show, {
9771
+ })), props.hook.threadId ? `thread ${escape(props.hook.threadId)}` : escape(getHookIdentityLabel(props.hook)), escape(createComponent(Show, {
9351
9772
  get when() {
9352
- return props.hook.threadId;
9773
+ return props.hook.threadId && props.hook.threadId !== props.hook.id;
9353
9774
  },
9354
9775
  get children() {
9355
- return ssr(_tmpl$105, escape(props.hook.threadId));
9776
+ return ssr(_tmpl$106, escape(props.hook.id));
9356
9777
  }
9357
9778
  })), escape(createComponent(Show, {
9358
9779
  get when() {
9359
9780
  return props.hook.framework;
9360
9781
  },
9361
9782
  get children() {
9362
- return ssr(_tmpl$115, escape(props.hook.framework));
9783
+ return ssr(_tmpl$117, escape(props.hook.framework));
9363
9784
  }
9364
9785
  })), ssrAttribute("class", escape(styles().hookDetails.metrics, true), false), escape(createComponent(Metric, {
9365
9786
  label: "runs",
@@ -9396,7 +9817,7 @@ var HookHeader = (props) => {
9396
9817
  };
9397
9818
  var Metric = (props) => {
9398
9819
  const styles = useStyles();
9399
- return ssr(_tmpl$96, ssrAttribute("class", escape(styles().hookDetails.metric, true), false) + ssrAttribute("data-testid", props.testId ? `ai-devtools-hook-metric-${escape(props.testId, true)}` : escape(void 0, true), false), ssrAttribute("class", escape(styles().hookDetails.metricValue, true), false), escape(props.value), ssrAttribute("class", escape(styles().hookDetails.metricLabel, true), false), escape(props.label));
9820
+ return ssr(_tmpl$97, ssrAttribute("class", escape(styles().hookDetails.metric, true), false) + ssrAttribute("data-testid", props.testId ? `ai-devtools-hook-metric-${escape(props.testId, true)}` : escape(void 0, true), false), ssrAttribute("class", escape(styles().hookDetails.metricValue, true), false), escape(props.value), ssrAttribute("class", escape(styles().hookDetails.metricLabel, true), false), escape(props.label));
9400
9821
  };
9401
9822
  function formatMetricValue(value) {
9402
9823
  return Intl.NumberFormat(void 0, {
@@ -9405,7 +9826,7 @@ function formatMetricValue(value) {
9405
9826
  }
9406
9827
  var TabButton = (props) => {
9407
9828
  const styles = useStyles();
9408
- return ssr(_tmpl$134, ssrAttribute("data-tab", escape(props.label, true), false), `${escape(styles().hookDetails.tab, true)} ${props.activeTab === props.tab ? escape(styles().hookDetails.tabActive, true) : ""}`, escape(props.label));
9829
+ return ssr(_tmpl$135, ssrAttribute("data-tab", escape(props.label, true), false), `${escape(styles().hookDetails.tab, true)} ${props.activeTab === props.tab ? escape(styles().hookDetails.tabActive, true) : ""}`, escape(props.label));
9409
9830
  };
9410
9831
  var ConversationPanel = (props) => {
9411
9832
  const styles = useStyles();
@@ -9419,7 +9840,7 @@ var ConversationPanel = (props) => {
9419
9840
  return props.messages.length > 0;
9420
9841
  },
9421
9842
  get fallback() {
9422
- return ssr(_tmpl$143, ssrAttribute("class", escape(styles().hookDetails.stack, true), false), ssrAttribute("class", escape(styles().hookDetails.section, true), false), ssrAttribute("class", escape(styles().hookDetails.sectionTitle, true), false), escape(createComponent(JsonPanel, {
9843
+ return ssr(_tmpl$144, ssrAttribute("class", escape(styles().hookDetails.stack, true), false), ssrAttribute("class", escape(styles().hookDetails.section, true), false), ssrAttribute("class", escape(styles().hookDetails.sectionTitle, true), false), escape(createComponent(JsonPanel, {
9423
9844
  get value() {
9424
9845
  return props.hook.state;
9425
9846
  },
@@ -9507,10 +9928,10 @@ var MessagesPreview = (props) => {
9507
9928
  return props.messages.length > 0;
9508
9929
  },
9509
9930
  get fallback() {
9510
- return ssr(_tmpl$163, ssrAttribute("class", escape(styles().hookDetails.emptySmall, true), false));
9931
+ return ssr(_tmpl$164, ssrAttribute("class", escape(styles().hookDetails.emptySmall, true), false));
9511
9932
  },
9512
9933
  get children() {
9513
- return ssr(_tmpl$153, ssrAttribute("class", escape(styles().hookDetails.messages, true), false), escape(createComponent(Show, {
9934
+ return ssr(_tmpl$154, ssrAttribute("class", escape(styles().hookDetails.messages, true), false), escape(createComponent(Show, {
9514
9935
  get when() {
9515
9936
  return pendingFixture();
9516
9937
  },
@@ -9541,12 +9962,12 @@ var MessagesPreview = (props) => {
9541
9962
  get ["data-role"]() {
9542
9963
  return message.role;
9543
9964
  }
9544
- }), [ssr(_tmpl$173, ssrAttribute("class", escape(styles().hookDetails.messageRole, true), false), escape(message.role)), escape(createComponent(Show, {
9965
+ }), [ssr(_tmpl$174, ssrAttribute("class", escape(styles().hookDetails.messageRole, true), false), escape(message.role)), escape(createComponent(Show, {
9545
9966
  get when() {
9546
9967
  return message.content;
9547
9968
  },
9548
9969
  get children() {
9549
- return ssr(_tmpl$173, ssrAttribute("class", escape(styles().hookDetails.messageContent, true), false), escape(message.content));
9970
+ return ssr(_tmpl$174, ssrAttribute("class", escape(styles().hookDetails.messageContent, true), false), escape(message.content));
9550
9971
  }
9551
9972
  })), escape(createComponent(For, {
9552
9973
  get each() {
@@ -9566,7 +9987,7 @@ var MessagesPreview = (props) => {
9566
9987
  get ["data-part-kind"]() {
9567
9988
  return part.kind;
9568
9989
  }
9569
- }), [ssr(_tmpl$05, ssrAttribute("class", escape(styles().hookDetails.previewPartLabel, true), false), escape(part.label)), escape(createComponent(Show, {
9990
+ }), [ssr(_tmpl$06, ssrAttribute("class", escape(styles().hookDetails.previewPartLabel, true), false), escape(part.label)), escape(createComponent(Show, {
9570
9991
  get when() {
9571
9992
  return part.fixture;
9572
9993
  },
@@ -9578,7 +9999,7 @@ var MessagesPreview = (props) => {
9578
9999
  return part.jsonItems?.length;
9579
10000
  },
9580
10001
  get fallback() {
9581
- return ssr(_tmpl$05, ssrAttribute("class", escape(styles().hookDetails.previewPartContent, true), false), escape(part.content));
10002
+ return ssr(_tmpl$06, ssrAttribute("class", escape(styles().hookDetails.previewPartContent, true), false), escape(part.content));
9582
10003
  },
9583
10004
  get children() {
9584
10005
  return ssr(_tmpl$193, `${escape(styles().hookDetails.previewJsonItems, true)} ${part.kind === "structured-output" ? escape(styles().hookDetails.previewJsonItemsCompare, true) : ""}`, escape(createComponent(For, {
@@ -9608,10 +10029,10 @@ var HookMessageTimeline = (props) => {
9608
10029
  return props.messages.length > 0;
9609
10030
  },
9610
10031
  get fallback() {
9611
- return ssr(_tmpl$214, ssrAttribute("class", escape(styles().hookDetails.emptySmall, true), false));
10032
+ return ssr(_tmpl$215, ssrAttribute("class", escape(styles().hookDetails.emptySmall, true), false));
9612
10033
  },
9613
10034
  get children() {
9614
- return ssr(_tmpl$173, ssrAttribute("class", escape(styles().hookDetails.messageTimeline, true), false), escape(createComponent(For, {
10035
+ return ssr(_tmpl$174, ssrAttribute("class", escape(styles().hookDetails.messageTimeline, true), false), escape(createComponent(For, {
9615
10036
  get each() {
9616
10037
  return props.messages;
9617
10038
  },
@@ -9628,12 +10049,12 @@ var HookMessageTimeline = (props) => {
9628
10049
  get ["class"]() {
9629
10050
  return `${styles().hookDetails.timelineMessage} ${isMessageHighlighted(message.id, props.hoverTarget) ? styles().hookDetails.timelineMessageHighlighted : ""}`;
9630
10051
  }
9631
- }), [ssr(_tmpl$173, ssrAttribute("class", escape(styles().hookDetails.messageRole, true), false), escape(message.role)), escape(createComponent(Show, {
10052
+ }), [ssr(_tmpl$174, ssrAttribute("class", escape(styles().hookDetails.messageRole, true), false), escape(message.role)), escape(createComponent(Show, {
9632
10053
  get when() {
9633
10054
  return message.content;
9634
10055
  },
9635
10056
  get children() {
9636
- return ssr(_tmpl$173, ssrAttribute("class", escape(styles().hookDetails.messageContent, true), false), escape(message.content));
10057
+ return ssr(_tmpl$174, ssrAttribute("class", escape(styles().hookDetails.messageContent, true), false), escape(message.content));
9637
10058
  }
9638
10059
  })), escape(createComponent(For, {
9639
10060
  get each() {
@@ -9653,12 +10074,12 @@ var HookMessageTimeline = (props) => {
9653
10074
  get ["data-part-kind"]() {
9654
10075
  return part.kind;
9655
10076
  }
9656
- }), [ssr(_tmpl$05, ssrAttribute("class", escape(styles().hookDetails.previewPartLabel, true), false), escape(part.label)), escape(createComponent(Show, {
10077
+ }), [ssr(_tmpl$06, ssrAttribute("class", escape(styles().hookDetails.previewPartLabel, true), false), escape(part.label)), escape(createComponent(Show, {
9657
10078
  get when() {
9658
10079
  return part.jsonItems?.length;
9659
10080
  },
9660
10081
  get fallback() {
9661
- return ssr(_tmpl$05, ssrAttribute("class", escape(styles().hookDetails.previewPartContent, true), false), escape(part.content));
10082
+ return ssr(_tmpl$06, ssrAttribute("class", escape(styles().hookDetails.previewPartContent, true), false), escape(part.content));
9662
10083
  },
9663
10084
  get children() {
9664
10085
  return ssr(_tmpl$193, `${escape(styles().hookDetails.previewJsonItems, true)} ${part.kind === "structured-output" ? escape(styles().hookDetails.previewJsonItemsCompare, true) : ""}`, escape(createComponent(For, {
@@ -9735,11 +10156,11 @@ var ToolsView = (props) => {
9735
10156
  return ssr(_tmpl$282, ssrAttribute("class", escape(styles().hookDetails.emptySmall, true), false));
9736
10157
  },
9737
10158
  get children() {
9738
- return ssr(_tmpl$173, ssrAttribute("class", escape(styles().hookDetails.eventList, true), false), escape(createComponent(For, {
10159
+ return ssr(_tmpl$174, ssrAttribute("class", escape(styles().hookDetails.eventList, true), false), escape(createComponent(For, {
9739
10160
  get each() {
9740
10161
  return savedFixtures();
9741
10162
  },
9742
- children: (fixture) => ssr(_tmpl$292, ssrAttribute("class", escape(styles().hookDetails.fixtureRow, true), false), ssrAttribute("data-fixture-name", escape(fixture.name, true) ?? escape(fixture.toolName, true), false) + ssrAttribute("data-tool-name", escape(fixture.toolName, true), false), ssrAttribute("class", escape(styles().hookDetails.fixtureInfo, true), false), ssrAttribute("class", escape(styles().hookDetails.fixtureName, true), false), escape(fixture.name) ?? escape(fixture.toolName), ssrAttribute("class", escape(styles().hookDetails.fixtureMeta, true), false), escape(fixture.toolName), escape(formatTime2(fixture.createdAt)), ssrAttribute("class", escape(styles().hookDetails.fixtureRowActions, true), false), ssrAttribute("class", escape(styles().hookDetails.fixtureRowButton, true), false), `${escape(styles().hookDetails.fixtureRowButton, true)} ${escape(styles().hookDetails.fixtureDangerButton, true)}`)
10163
+ children: (fixture) => ssr(_tmpl$292, ssrAttribute("class", escape(styles().hookDetails.fixtureRow, true), false), ssrAttribute("data-fixture-name", escape(fixture.name, true) ?? escape(fixture.toolName, true), false) + ssrAttribute("data-tool-name", escape(fixture.toolName, true), false), ssrAttribute("class", escape(styles().hookDetails.fixtureInfo, true), false), ssrAttribute("class", escape(styles().hookDetails.fixtureName, true), false), escape(fixture.name) ?? escape(fixture.toolName), ssrAttribute("class", escape(styles().hookDetails.fixtureMeta, true), false), escape(fixture.toolName), escape(formatTime3(fixture.createdAt)), ssrAttribute("class", escape(styles().hookDetails.fixtureRowActions, true), false), ssrAttribute("class", escape(styles().hookDetails.fixtureRowButton, true), false), `${escape(styles().hookDetails.fixtureRowButton, true)} ${escape(styles().hookDetails.fixtureDangerButton, true)}`)
9743
10164
  })));
9744
10165
  }
9745
10166
  })]
@@ -10086,12 +10507,12 @@ function jsonSafeValue(value) {
10086
10507
  return `[ai-devtools] unserializable value: ${error instanceof Error ? error.message : String(error)}`;
10087
10508
  }
10088
10509
  }
10089
- function formatTime2(timestamp) {
10510
+ function formatTime3(timestamp) {
10090
10511
  return new Date(timestamp).toLocaleTimeString();
10091
10512
  }
10092
10513
 
10093
10514
  // src/components/Shell.tsx
10094
- var _tmpl$41 = ["<div", ' data-testid="ai-devtools-panel">', "<div", "><div", ' data-testid="ai-devtools-left-panel" style="', '"><div', ">AI Hooks</div>", '</div><div class="', '"></div><div', ' data-testid="ai-devtools-right-panel" style="', '">', "</div></div></div>"];
10515
+ var _tmpl$48 = ["<div", ' data-testid="ai-devtools-panel">', "<div", "><div", ' data-testid="ai-devtools-left-panel" style="', '"><div', ">AI Hooks</div>", '</div><div class="', '"></div><div', ' data-testid="ai-devtools-right-panel" style="', '">', "</div></div></div>"];
10095
10516
  function Devtools(props) {
10096
10517
  return createComponent(ThemeContextProvider, {
10097
10518
  get theme() {
@@ -10164,7 +10585,7 @@ function DevtoolsContent() {
10164
10585
  });
10165
10586
  return createComponent(MainPanel, {
10166
10587
  get children() {
10167
- return ssr(_tmpl$41, ssrAttribute("class", escape(styles().shellRoot, true), false), escape(createComponent(Header, {
10588
+ return ssr(_tmpl$48, ssrAttribute("class", escape(styles().shellRoot, true), false), escape(createComponent(Header, {
10168
10589
  get children() {
10169
10590
  return createComponent(HeaderLogo, {
10170
10591
  flavor: {