@tanstack/ai-devtools-core 0.5.9 → 0.5.11

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 { createComponent, ssr, ssrAttribute, escape, ssrStyleProperty, ssrElement, mergeProps, Portal } from 'solid-js/web';
1
+ import { createComponent, ssr, ssrAttribute, escape, ssrStyleProperty, ssrElement, mergeProps, Portal, ssrStyle } 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';
@@ -1999,7 +1999,6 @@ var stylesFactory = (theme) => {
1999
1999
  border: 1px solid ${t(colors.gray[200], colors.darkGray[600])};
2000
2000
  border-radius: ${border.radius.sm};
2001
2001
  background: ${t(colors.white, colors.darkGray[900])};
2002
- min-height: 260px;
2003
2002
  max-height: 420px;
2004
2003
  overflow: auto;
2005
2004
  padding: ${size[2]} ${size[2]} ${size[2]} ${size[5]};
@@ -2874,7 +2873,7 @@ var stylesFactory = (theme) => {
2874
2873
  gap: ${size[3]};
2875
2874
  align-items: start;
2876
2875
  & > * {
2877
- min-height: 280px;
2876
+ max-height: 420px;
2878
2877
  border: 1px solid oklch(0.28 0.03 260);
2879
2878
  border-radius: 6px;
2880
2879
  background: oklch(0.18 0.02 260);
@@ -3935,7 +3934,6 @@ var stylesFactory = (theme) => {
3935
3934
  `,
3936
3935
  stepJsonPanel: css2`
3937
3936
  margin: ${size[1.5]} ${size[3]};
3938
- min-height: 280px;
3939
3937
  max-height: 520px;
3940
3938
  overflow: auto;
3941
3939
  padding: ${size[2]} ${size[2]} ${size[2]} ${size[5]};
@@ -3953,6 +3951,7 @@ var stylesFactory = (theme) => {
3953
3951
  grid-template-columns: repeat(2, minmax(320px, 1fr));
3954
3952
  gap: ${size[3]};
3955
3953
  align-items: start;
3954
+ padding-left: ${size[3]};
3956
3955
  padding-right: ${size[3]};
3957
3956
  @media (max-width: 760px) {
3958
3957
  grid-template-columns: 1fr;
@@ -4346,12 +4345,6 @@ function applyHookEvent(state, eventName, event) {
4346
4345
  markHookViewed(state, state.activeHookId);
4347
4346
  }
4348
4347
  }
4349
- function setActiveHook(state, hookId) {
4350
- state.activeHookId = hookId;
4351
- if (hookId) {
4352
- markHookViewed(state, hookId);
4353
- }
4354
- }
4355
4348
  function clearHookRegistry(state) {
4356
4349
  state.hooks = {};
4357
4350
  state.runs = {};
@@ -4482,8 +4475,8 @@ function removeHookRecord(state, hookId) {
4482
4475
  delete state.runs[runId];
4483
4476
  }
4484
4477
  }
4485
- for (const eventId2 of hookEventIds) {
4486
- delete state.events[eventId2];
4478
+ for (const eventId3 of hookEventIds) {
4479
+ delete state.events[eventId3];
4487
4480
  }
4488
4481
  delete state.hooks[hookId];
4489
4482
  delete state.seenHookActivityCounts[hookId];
@@ -4491,7 +4484,7 @@ function removeHookRecord(state, hookId) {
4491
4484
  state.activeHookId = null;
4492
4485
  }
4493
4486
  }
4494
- function upsertRun(state, event, eventId2) {
4487
+ function upsertRun(state, event, eventId3) {
4495
4488
  const existing = state.runs[event.runId];
4496
4489
  if (!existing) {
4497
4490
  state.runs[event.runId] = {
@@ -4505,7 +4498,7 @@ function upsertRun(state, event, eventId2) {
4505
4498
  updatedAt: event.timestamp,
4506
4499
  ...isTerminalRunStatus(event.status) ? { completedAt: event.timestamp } : {},
4507
4500
  ...event.error ? { error: event.error } : {},
4508
- eventIds: [eventId2]
4501
+ eventIds: [eventId3]
4509
4502
  };
4510
4503
  return;
4511
4504
  }
@@ -4521,8 +4514,8 @@ function upsertRun(state, event, eventId2) {
4521
4514
  if (event.error) {
4522
4515
  existing.error = event.error;
4523
4516
  }
4524
- if (!existing.eventIds.includes(eventId2)) {
4525
- existing.eventIds.push(eventId2);
4517
+ if (!existing.eventIds.includes(eventId3)) {
4518
+ existing.eventIds.push(eventId3);
4526
4519
  }
4527
4520
  }
4528
4521
  function attachRunToHook(state, hookId, runId) {
@@ -4530,7 +4523,7 @@ function attachRunToHook(state, hookId, runId) {
4530
4523
  if (!hook || hook.runIds.includes(runId)) return;
4531
4524
  hook.runIds.push(runId);
4532
4525
  }
4533
- function syncRunsFromSnapshot(state, snapshot, eventId2) {
4526
+ function syncRunsFromSnapshot(state, snapshot, eventId3) {
4534
4527
  const rawRuns = snapshot.state.runs;
4535
4528
  if (!Array.isArray(rawRuns)) return;
4536
4529
  for (const candidate of rawRuns) {
@@ -4553,7 +4546,7 @@ function syncRunsFromSnapshot(state, snapshot, eventId2) {
4553
4546
  updatedAt,
4554
4547
  ...typeof run.completedAt === "number" ? { completedAt: run.completedAt } : isTerminalRunStatus(status) ? { completedAt: updatedAt } : {},
4555
4548
  ...typeof run.error === "string" ? { error: run.error } : {},
4556
- eventIds: [eventId2]
4549
+ eventIds: [eventId3]
4557
4550
  };
4558
4551
  } else {
4559
4552
  existing.hookId = snapshot.hookId;
@@ -4565,8 +4558,8 @@ function syncRunsFromSnapshot(state, snapshot, eventId2) {
4565
4558
  existing.completedAt = updatedAt;
4566
4559
  }
4567
4560
  if (typeof run.error === "string") existing.error = run.error;
4568
- if (!existing.eventIds.includes(eventId2)) {
4569
- existing.eventIds.push(eventId2);
4561
+ if (!existing.eventIds.includes(eventId3)) {
4562
+ existing.eventIds.push(eventId3);
4570
4563
  }
4571
4564
  }
4572
4565
  attachRunToHook(state, snapshot.hookId, run.id);
@@ -4596,11 +4589,11 @@ function attachActivityRunToHook(state, hookId, runId) {
4596
4589
  if (!hook || hook.activityRunIds.includes(runId)) return;
4597
4590
  hook.activityRunIds.push(runId);
4598
4591
  }
4599
- function attachEventToHook(state, hookId, eventId2) {
4592
+ function attachEventToHook(state, hookId, eventId3) {
4600
4593
  if (!hookId) return;
4601
4594
  const hook = state.hooks[hookId];
4602
- if (!hook || hook.eventIds.includes(eventId2)) return;
4603
- hook.eventIds.push(eventId2);
4595
+ if (!hook || hook.eventIds.includes(eventId3)) return;
4596
+ hook.eventIds.push(eventId3);
4604
4597
  }
4605
4598
  function inferLifecycleFromSnapshot(state) {
4606
4599
  if (state.status === "error" || state.error) {
@@ -4743,6 +4736,80 @@ function clearMemoryRegistry(state) {
4743
4736
  state.scopes = {};
4744
4737
  }
4745
4738
 
4739
+ // src/store/compaction-registry.ts
4740
+ var MAX_EVENTS = 50;
4741
+ function createCompactionRegistryState() {
4742
+ return { events: [] };
4743
+ }
4744
+ function eventId2(kind, event) {
4745
+ return [
4746
+ "cmp",
4747
+ kind,
4748
+ String(event.timestamp),
4749
+ event.hookId ?? event.clientId ?? event.threadId ?? "unknown",
4750
+ String(event.before ?? event.after ?? "")
4751
+ ].join("-");
4752
+ }
4753
+ function applyCompactionEvent(state, kind, event) {
4754
+ state.events.push({
4755
+ id: event.eventId ?? eventId2(kind, event),
4756
+ kind,
4757
+ timestamp: event.timestamp,
4758
+ hookId: event.hookId,
4759
+ clientId: event.clientId,
4760
+ threadId: event.threadId,
4761
+ runId: event.runId,
4762
+ before: event.before,
4763
+ after: event.after,
4764
+ messagesBefore: event.messagesBefore,
4765
+ messagesAfter: event.messagesAfter,
4766
+ reusedCheckpoint: event.reusedCheckpoint,
4767
+ maxTokens: event.maxTokens,
4768
+ strategyKey: event.strategyKey,
4769
+ durationMs: event.durationMs,
4770
+ dropped: event.dropped,
4771
+ result: event.result
4772
+ });
4773
+ if (state.events.length > MAX_EVENTS) {
4774
+ state.events.splice(0, state.events.length - MAX_EVENTS);
4775
+ }
4776
+ }
4777
+ function clearCompactionRegistry(state) {
4778
+ state.events = [];
4779
+ }
4780
+ function compactionEventsForHook(state, hook) {
4781
+ const matched = state.events.filter((event) => {
4782
+ if (event.hookId && event.hookId === hook.id) return true;
4783
+ if (event.clientId && hook.clientId && event.clientId === hook.clientId) {
4784
+ return true;
4785
+ }
4786
+ if (event.threadId && hook.threadId && event.threadId === hook.threadId) {
4787
+ return true;
4788
+ }
4789
+ return false;
4790
+ });
4791
+ if (matched.length > 0) return matched;
4792
+ return state.events;
4793
+ }
4794
+
4795
+ // src/store/skills-registry.ts
4796
+ function createSkillsRegistryState() {
4797
+ return { snapshots: {} };
4798
+ }
4799
+ function clearSkillsRegistry(state) {
4800
+ state.snapshots = {};
4801
+ }
4802
+ function applySkillsSnapshot(state, payload) {
4803
+ const key = payload.hookId && payload.hookId.length > 0 ? payload.hookId : "_default";
4804
+ const catalog = Array.isArray(payload.catalog) ? payload.catalog : [];
4805
+ const activated = Array.isArray(payload.activated) ? payload.activated : [];
4806
+ state.snapshots[key] = {
4807
+ catalog,
4808
+ activated,
4809
+ updatedAt: payload.timestamp ?? Date.now()
4810
+ };
4811
+ }
4812
+
4746
4813
  // src/store/ai-context.tsx
4747
4814
  var AIContext = createContext();
4748
4815
  function useAIStore() {
@@ -4757,7 +4824,9 @@ var AIProvider = (props) => {
4757
4824
  conversations: {},
4758
4825
  activeConversationId: null,
4759
4826
  hooks: createHookRegistryState(),
4760
- memory: createMemoryRegistryState()
4827
+ memory: createMemoryRegistryState(),
4828
+ compaction: createCompactionRegistryState(),
4829
+ skills: createSkillsRegistryState()
4761
4830
  });
4762
4831
  const streamToConversation = /* @__PURE__ */ new Map();
4763
4832
  const requestToConversation = /* @__PURE__ */ new Map();
@@ -5014,11 +5083,24 @@ var AIProvider = (props) => {
5014
5083
  clearMemoryRegistry(memory);
5015
5084
  }));
5016
5085
  }
5017
- function selectHook(id) {
5018
- setState("hooks", produce((hooks) => {
5019
- setActiveHook(hooks, id);
5086
+ function clearCompaction() {
5087
+ setState("compaction", produce((compaction) => {
5088
+ clearCompactionRegistry(compaction);
5089
+ }));
5090
+ }
5091
+ function clearSkills() {
5092
+ setState("skills", produce((skills) => {
5093
+ clearSkillsRegistry(skills);
5020
5094
  }));
5021
5095
  }
5096
+ function selectHook(id) {
5097
+ setState("hooks", "activeHookId", id);
5098
+ if (id) {
5099
+ setState("hooks", produce((hooks) => {
5100
+ markHookViewed(hooks, id);
5101
+ }));
5102
+ }
5103
+ }
5022
5104
  function saveToolFixture(fixture) {
5023
5105
  const fixtures = mergeFixtures(fixture, state.hooks.fixtures);
5024
5106
  setState("hooks", produce((hooks) => {
@@ -5338,6 +5420,10 @@ var AIProvider = (props) => {
5338
5420
  setState("memory", produce((memory) => {
5339
5421
  applyMemorySnapshot(memory, e.payload);
5340
5422
  }));
5423
+ }), aiEventClient.on("skills:snapshot", (e) => {
5424
+ setState("skills", produce((skills) => {
5425
+ applySkillsSnapshot(skills, e.payload);
5426
+ }));
5341
5427
  }));
5342
5428
  const recordRunEvent = (eventName, payload) => {
5343
5429
  setState("hooks", produce((hooks) => {
@@ -6521,6 +6607,48 @@ var AIProvider = (props) => {
6521
6607
  arr.push(mwEvent);
6522
6608
  }));
6523
6609
  }));
6610
+ const recordCompactionLifecycle = (kind, hookName, payload) => {
6611
+ setState("compaction", produce((compaction) => {
6612
+ applyCompactionEvent(compaction, kind, payload);
6613
+ }));
6614
+ const {
6615
+ requestId,
6616
+ streamId,
6617
+ clientId
6618
+ } = payload;
6619
+ const conversationId = (clientId && state.conversations[clientId] ? clientId : void 0) || (streamId ? streamToConversation.get(streamId) : void 0) || (requestId ? requestToConversation.get(requestId) : void 0);
6620
+ if (!conversationId || !state.conversations[conversationId]) return;
6621
+ const conv = state.conversations[conversationId];
6622
+ const iterIndex = findLatestIterationIndex(conv, requestId);
6623
+ if (iterIndex < 0) return;
6624
+ const mwEvent = {
6625
+ id: `mw-cmp-${kind}-${Date.now()}-${Math.random()}`,
6626
+ middlewareName: "compaction",
6627
+ hookName,
6628
+ timestamp: payload.timestamp,
6629
+ hasTransform: kind === "state",
6630
+ configChanges: {
6631
+ before: payload.before,
6632
+ after: payload.after,
6633
+ messagesBefore: payload.messagesBefore,
6634
+ messagesAfter: payload.messagesAfter,
6635
+ reusedCheckpoint: payload.reusedCheckpoint,
6636
+ maxTokens: payload.maxTokens,
6637
+ strategyKey: payload.strategyKey,
6638
+ durationMs: payload.durationMs
6639
+ }
6640
+ };
6641
+ setState("conversations", conversationId, "iterations", iterIndex, "middlewareEvents", produce((arr) => {
6642
+ arr.push(mwEvent);
6643
+ }));
6644
+ };
6645
+ cleanupFns.push(aiEventClient.on("compaction:started", (e) => {
6646
+ recordCompactionLifecycle("started", "onCompactStart", e.payload);
6647
+ }), aiEventClient.on("compaction:state", (e) => {
6648
+ recordCompactionLifecycle("state", "onCompact", e.payload);
6649
+ }), aiEventClient.on("compaction:ended", (e) => {
6650
+ recordCompactionLifecycle("ended", "onCompactEnd", e.payload);
6651
+ }));
6524
6652
  cleanupFns.push(aiEventClient.on("summarize:request:started", (e) => {
6525
6653
  const {
6526
6654
  requestId,
@@ -6914,6 +7042,8 @@ var AIProvider = (props) => {
6914
7042
  selectConversation,
6915
7043
  clearHooks,
6916
7044
  clearMemory,
7045
+ clearCompaction,
7046
+ clearSkills,
6917
7047
  selectHook,
6918
7048
  saveToolFixture,
6919
7049
  deleteToolFixture,
@@ -7182,7 +7312,7 @@ var formatDuration = (ms) => {
7182
7312
  };
7183
7313
  var _tmpl$10 = ["<span", ">", "ms</span>"];
7184
7314
  var _tmpl$22 = ["<span", ">", "</span>"];
7185
- var _tmpl$32 = ["<div", '><span class="', '">Middleware</span><span class="', '">', "</span><span", ">", "</span>", "", "", "</div>"];
7315
+ var _tmpl$32 = ["<div", ' style="', '"><span class="', '">Middleware</span><span class="', '">', "</span><span", ">", "</span>", "", "", "</div>"];
7186
7316
  var _tmpl$42 = ["<div", ">", "</div>"];
7187
7317
  var _tmpl$52 = ['<span class="', '">Thinking</span>'];
7188
7318
  var _tmpl$62 = ['<span class="', '">Structured</span>'];
@@ -7310,6 +7440,9 @@ var MiddlewareStep = (props) => {
7310
7440
  if (ev().wasDropped) return "DROP";
7311
7441
  if (ev().hookName === "onChunk" && ev().hasTransform) return "TRANSFORM";
7312
7442
  if (ev().hookName === "onConfig" && ev().hasTransform) return "TRANSFORM";
7443
+ if (ev().hookName === "onCompactStart") return "START";
7444
+ if (ev().hookName === "onCompact") return "COMPACT";
7445
+ if (ev().hookName === "onCompactEnd") return "END";
7313
7446
  if (ev().hookName === "onBeforeToolCall" && ev().hasTransform) return "DECISION";
7314
7447
  return null;
7315
7448
  };
@@ -7317,7 +7450,9 @@ var MiddlewareStep = (props) => {
7317
7450
  const changes = ev().configChanges;
7318
7451
  return changes && Object.keys(changes).length > 0;
7319
7452
  };
7320
- return [ssr(_tmpl$32, ssrAttribute("class", escape(s().step, true), false), `${escape(s().stepPrefix, true)} ${escape(s().stepPrefixMiddleware, true)}`, `${escape(s().mwBadge, true)} ${escape(badgeClass(), true)}`, escape(ev().middlewareName), ssrAttribute("class", escape(s().mwHook, true), false), escape(ev().hookName), escape(createComponent(Show, {
7453
+ return [ssr(_tmpl$32, ssrAttribute("class", escape(s().step, true), false), ssrStyle(hasChanges() ? {
7454
+ cursor: "pointer"
7455
+ } : void 0), `${escape(s().stepPrefix, true)} ${escape(s().stepPrefixMiddleware, true)}`, `${escape(s().mwBadge, true)} ${escape(badgeClass(), true)}`, escape(ev().middlewareName), ssrAttribute("class", escape(s().mwHook, true), false), escape(ev().hookName), escape(createComponent(Show, {
7321
7456
  get when() {
7322
7457
  return ev().duration !== void 0;
7323
7458
  },
@@ -9391,21 +9526,299 @@ var MemoryPanel = () => {
9391
9526
  })))]
9392
9527
  })));
9393
9528
  };
9529
+ var _tmpl$41 = ["<div", "><div", ">", "", "</div><div", ">", "</div></div>"];
9530
+ var _tmpl$214 = ["<div", ">", "</div>"];
9531
+ var _tmpl$312 = ["<div", "><div", ">", " (", ")</div>", "</div>"];
9532
+ var _tmpl$47 = ["<span", ">", " \u2192 ", " tok</span>"];
9533
+ var _tmpl$57 = ["<span", ">", "ms</span>"];
9534
+ var _tmpl$67 = ["<span", ">checkpoint</span>"];
9535
+ var _tmpl$77 = ["<div", ' data-testid="ai-devtools-compaction-event"', ' style="', '"><span class="', '">', '</span><span class="', '">', "</span><span", ">", "</span>", "", "", "<span", ">", '</span><span class="', '">\u25B6</span></div>'];
9536
+ var _tmpl$87 = ["<div", ">", "", "</div>"];
9537
+ var _tmpl$97 = ["<div", "><span", ">", " event", '</span><button type="button"', ">Clear</button></div>"];
9538
+ var _tmpl$06 = ["<div", ' data-testid="ai-devtools-compaction-panel">', "</div>"];
9539
+ var _tmpl$116 = ["<div", ">No compaction yet. When the transcript passes maxTokens, each compact appears here.</div>"];
9540
+ function formatTime3(value) {
9541
+ const date = new Date(value);
9542
+ if (Number.isNaN(date.getTime())) return "";
9543
+ return date.toLocaleTimeString();
9544
+ }
9545
+ function shortStrategy(event) {
9546
+ const key = event.strategyKey;
9547
+ if (!key) return event.reusedCheckpoint ? "checkpoint" : "compaction";
9548
+ const cut = key.indexOf(":maxTokens=");
9549
+ return cut === -1 ? key : key.slice(0, cut);
9550
+ }
9551
+ var PreviewMessage = (props) => {
9552
+ const styles = useStyles();
9553
+ return ssr(_tmpl$41, ssrAttribute("class", escape(styles().hookDetails.message, true), false), ssrAttribute("class", escape(styles().hookDetails.messageRole, true), false), escape(props.preview.role), escape(createComponent(Show, {
9554
+ get when() {
9555
+ return props.preview.tokens > 0;
9556
+ },
9557
+ get children() {
9558
+ return ` \xB7 ${props.preview.tokens} tok`;
9559
+ }
9560
+ })), ssrAttribute("class", escape(styles().hookDetails.messageContent, true), false), escape(props.preview.text));
9561
+ };
9562
+ var PreviewColumn = (props) => {
9563
+ const styles = useStyles();
9564
+ const s = () => styles().iterationTimeline;
9565
+ return ssr(_tmpl$312, ssrAttribute("class", escape(s().stepJsonItem, true), false), ssrAttribute("class", escape(s().stepJsonItemLabel, true), false), escape(props.title), escape(props.previews.length), escape(createComponent(Show, {
9566
+ get when() {
9567
+ return props.previews.length > 0;
9568
+ },
9569
+ get fallback() {
9570
+ return ssr(_tmpl$214, ssrAttribute("class", escape(styles().hookDetails.emptySmall, true), false), escape(props.empty));
9571
+ },
9572
+ get children() {
9573
+ return ssr(_tmpl$214, ssrAttribute("class", escape(styles().memoryPanel.list, true), false), escape(createComponent(For, {
9574
+ get each() {
9575
+ return props.previews;
9576
+ },
9577
+ children: (preview) => createComponent(PreviewMessage, {
9578
+ preview
9579
+ })
9580
+ })));
9581
+ }
9582
+ })));
9583
+ };
9584
+ function kindLabel(kind) {
9585
+ if (kind === "started") return "Started";
9586
+ if (kind === "ended") return "Ended";
9587
+ return "State";
9588
+ }
9589
+ var CompactEvent = (props) => {
9590
+ const styles = useStyles();
9591
+ const s = () => styles().iterationTimeline;
9592
+ const [expanded, setExpanded] = createSignal(props.defaultOpen === true);
9593
+ const event = () => props.event;
9594
+ const isState = () => event().kind === "state";
9595
+ const stats = () => ({
9596
+ kind: event().kind,
9597
+ before: event().before,
9598
+ after: event().after,
9599
+ messagesBefore: event().messagesBefore,
9600
+ messagesAfter: event().messagesAfter,
9601
+ maxTokens: event().maxTokens,
9602
+ strategyKey: event().strategyKey,
9603
+ reusedCheckpoint: event().reusedCheckpoint,
9604
+ durationMs: event().durationMs
9605
+ });
9606
+ const countLabel = () => {
9607
+ if (event().kind === "started") {
9608
+ return `${event().messagesBefore ?? 0} msgs \xB7 ${event().before ?? 0} tok`;
9609
+ }
9610
+ if (event().kind === "ended") {
9611
+ return `${event().messagesAfter ?? 0} msgs \xB7 ${event().after ?? 0} tok`;
9612
+ }
9613
+ return `${event().messagesBefore ?? 0} \u2192 ${event().messagesAfter ?? 0} msgs`;
9614
+ };
9615
+ return [ssr(_tmpl$77, ssrAttribute("class", escape(s().step, true), false), ssrAttribute("data-kind", escape(event().kind, true), false), ssrStyleProperty("cursor:", "pointer"), `${escape(s().stepPrefix, true)} ${escape(s().stepPrefixMiddleware, true)}`, escape(kindLabel(event().kind)), `${escape(s().mwBadge, true)} ${escape(s().mwBadgeTransform, true)}`, escape(shortStrategy(event())), ssrAttribute("class", escape(s().mwHook, true), false), escape(countLabel()), escape(createComponent(Show, {
9616
+ get when() {
9617
+ return event().kind === "state";
9618
+ },
9619
+ get children() {
9620
+ return ssr(_tmpl$47, ssrAttribute("class", escape(s().stepDuration, true), false), escape(event().before), escape(event().after));
9621
+ }
9622
+ })), escape(createComponent(Show, {
9623
+ get when() {
9624
+ return event().durationMs !== void 0;
9625
+ },
9626
+ get children() {
9627
+ return ssr(_tmpl$57, ssrAttribute("class", escape(s().stepDuration, true), false), escape(event().durationMs));
9628
+ }
9629
+ })), escape(createComponent(Show, {
9630
+ get when() {
9631
+ return event().reusedCheckpoint;
9632
+ },
9633
+ get children() {
9634
+ return ssr(_tmpl$67, ssrAttribute("class", escape(s().mwSuffix, true), false));
9635
+ }
9636
+ })), ssrAttribute("class", escape(s().stepDuration, true), false), escape(formatTime3(event().timestamp)), `${escape(s().chevron, true)} ${expanded() ? escape(s().chevronOpen, true) : ""}`), createComponent(Show, {
9637
+ get when() {
9638
+ return expanded();
9639
+ },
9640
+ get children() {
9641
+ return [ssr(_tmpl$214, ssrAttribute("class", escape(s().mwChangesContainer, true), false), escape(createComponent(JsonTree, {
9642
+ get value() {
9643
+ return stats();
9644
+ },
9645
+ defaultExpansionDepth: 1,
9646
+ copyable: true
9647
+ }))), createComponent(Show, {
9648
+ get when() {
9649
+ return isState();
9650
+ },
9651
+ get children() {
9652
+ return ssr(_tmpl$87, ssrAttribute("class", escape(s().stepJsonItemsCompare, true), false), escape(createComponent(PreviewColumn, {
9653
+ title: "Dropped",
9654
+ get previews() {
9655
+ return event().dropped ?? [];
9656
+ },
9657
+ empty: "Nothing was dropped."
9658
+ })), escape(createComponent(PreviewColumn, {
9659
+ title: "Sent to model",
9660
+ get previews() {
9661
+ return event().result ?? [];
9662
+ },
9663
+ empty: "No compacted transcript on this event."
9664
+ })));
9665
+ }
9666
+ })];
9667
+ }
9668
+ })];
9669
+ };
9670
+ var CompactionPanel = (props) => {
9671
+ const {
9672
+ state,
9673
+ clearCompaction
9674
+ } = useAIStore();
9675
+ const styles = useStyles();
9676
+ const s = () => styles().iterationTimeline;
9677
+ const events = createMemo(() => compactionEventsForHook(state.compaction, props.hook));
9678
+ const lastStateIndex = createMemo(() => {
9679
+ const list = events();
9680
+ for (let i = list.length - 1; i >= 0; i--) {
9681
+ if (list[i]?.kind === "state") return i;
9682
+ }
9683
+ return -1;
9684
+ });
9685
+ return ssr(_tmpl$06, ssrAttribute("class", escape(styles().memoryPanel.container, true), false), escape(createComponent(Show, {
9686
+ get when() {
9687
+ return events().length > 0;
9688
+ },
9689
+ get fallback() {
9690
+ return ssr(_tmpl$116, ssrAttribute("class", escape(styles().hookDetails.emptySmall, true), false));
9691
+ },
9692
+ get children() {
9693
+ return [ssr(_tmpl$97, ssrAttribute("class", escape(styles().memoryPanel.toolbar, true), false), ssrAttribute("class", escape(styles().memoryPanel.badge, true), false), escape(events().length), events().length === 1 ? "" : "s", ssrAttribute("class", escape(styles().memoryPanel.clearButton, true), false)), ssr(_tmpl$214, ssrAttribute("class", escape(s().iterCard, true), false), escape(createComponent(For, {
9694
+ get each() {
9695
+ return events();
9696
+ },
9697
+ children: (event, index) => createComponent(CompactEvent, {
9698
+ event,
9699
+ get defaultOpen() {
9700
+ return event.kind === "state" && index() === lastStateIndex();
9701
+ }
9702
+ })
9703
+ })))];
9704
+ }
9705
+ })));
9706
+ };
9707
+ var _tmpl$48 = ["<ul", ">", "</ul>"];
9708
+ var _tmpl$215 = ["<div", "><div", ">Catalog</div>", "</div>"];
9709
+ var _tmpl$313 = ["<div", ' data-testid="ai-devtools-skills-panel">', "</div>"];
9710
+ var _tmpl$49 = ["<div", ">No skills on this run. Add `withSkills(...)` to `chat()` and the catalog will appear here. A skill lights up when the model calls `load_skill`.</div>"];
9711
+ var _tmpl$58 = ["<div", ">Loaded via `load_skill`, but the catalog snapshot has not arrived yet.</div>"];
9712
+ var _tmpl$68 = ["<span", ">loaded</span>"];
9713
+ var _tmpl$78 = ["<li", "><span", ">", "</span>", "<span", ">", "</span></li>"];
9714
+ function parseSkillName(argumentsJson) {
9715
+ if (!argumentsJson) return void 0;
9716
+ try {
9717
+ const parsed = JSON.parse(argumentsJson);
9718
+ if (parsed && typeof parsed === "object" && "name" in parsed && typeof parsed.name === "string") {
9719
+ return parsed.name;
9720
+ }
9721
+ } catch {
9722
+ return void 0;
9723
+ }
9724
+ return void 0;
9725
+ }
9726
+ function loadedFromMessages(messages) {
9727
+ const names = /* @__PURE__ */ new Set();
9728
+ for (const message of messages) {
9729
+ for (const toolCall of message.toolCalls ?? []) {
9730
+ if (toolCall.name === "load_skill") {
9731
+ const name = parseSkillName(toolCall.arguments);
9732
+ if (name) names.add(name);
9733
+ }
9734
+ }
9735
+ for (const part of message.parts ?? []) {
9736
+ if (part.type === "tool-call" && part.toolName === "load_skill") {
9737
+ const name = parseSkillName(part.arguments);
9738
+ if (name) names.add(name);
9739
+ }
9740
+ }
9741
+ }
9742
+ return [...names];
9743
+ }
9744
+ var SkillsPanel = () => {
9745
+ const {
9746
+ state
9747
+ } = useAIStore();
9748
+ const styles = useStyles();
9749
+ const snapshot = createMemo(() => {
9750
+ const hookId = state.hooks.activeHookId;
9751
+ if (hookId && state.skills.snapshots[hookId]) {
9752
+ return state.skills.snapshots[hookId];
9753
+ }
9754
+ const first = Object.values(state.skills.snapshots)[0];
9755
+ return first;
9756
+ });
9757
+ const conversation = createMemo(() => {
9758
+ const hookId = state.hooks.activeHookId;
9759
+ if (!hookId) return void 0;
9760
+ return state.conversations[hookId];
9761
+ });
9762
+ const loaded = createMemo(() => {
9763
+ const fromSnap = new Set(snapshot()?.activated ?? []);
9764
+ for (const name of loadedFromMessages(conversation()?.messages ?? [])) {
9765
+ fromSnap.add(name);
9766
+ }
9767
+ return fromSnap;
9768
+ });
9769
+ const catalog = createMemo(() => snapshot()?.catalog ?? []);
9770
+ return ssr(_tmpl$313, ssrAttribute("class", escape(styles().memoryPanel.container, true), false), escape(createComponent(Show, {
9771
+ get when() {
9772
+ return catalog().length > 0 || loaded().size > 0;
9773
+ },
9774
+ get fallback() {
9775
+ return ssr(_tmpl$49, ssrAttribute("class", escape(styles().memoryPanel.empty, true), false));
9776
+ },
9777
+ get children() {
9778
+ return ssr(_tmpl$215, ssrAttribute("class", escape(styles().memoryPanel.section, true), false), ssrAttribute("class", escape(styles().memoryPanel.sectionTitle, true), false), escape(createComponent(Show, {
9779
+ get when() {
9780
+ return catalog().length > 0;
9781
+ },
9782
+ get fallback() {
9783
+ return ssr(_tmpl$58, ssrAttribute("class", escape(styles().memoryPanel.sectionEmpty, true), false));
9784
+ },
9785
+ get children() {
9786
+ return ssr(_tmpl$48, ssrAttribute("class", escape(styles().memoryPanel.list, true), false), escape(createComponent(For, {
9787
+ get each() {
9788
+ return catalog();
9789
+ },
9790
+ children: (skill) => {
9791
+ const isLoaded = () => loaded().has(skill.name);
9792
+ return ssr(_tmpl$78, ssrAttribute("class", escape(styles().memoryPanel.row, true), false), ssrAttribute("class", escape(styles().memoryPanel.badge, true), false), escape(skill.name), escape(createComponent(Show, {
9793
+ get when() {
9794
+ return isLoaded();
9795
+ },
9796
+ get children() {
9797
+ return ssr(_tmpl$68, ssrAttribute("class", escape(styles().memoryPanel.badge, true), false));
9798
+ }
9799
+ })), ssrAttribute("class", escape(styles().memoryPanel.sectionEmpty, true), false), escape(skill.description));
9800
+ }
9801
+ })));
9802
+ }
9803
+ })));
9804
+ }
9805
+ })));
9806
+ };
9394
9807
 
9395
9808
  // src/components/hooks/HookDetails.tsx
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>"];
9809
+ var _tmpl$50 = ["<aside", ' data-testid="ai-devtools-preview-pane"><div', ">", "</div>", "</aside>"];
9810
+ var _tmpl$216 = ["<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>"];
9811
+ var _tmpl$314 = ["<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>"];
9812
+ var _tmpl$410 = ["<div", ">Open a page with TanStack AI hooks to inspect live state.</div>"];
9813
+ var _tmpl$59 = ["<section", ' data-testid="ai-devtools-overview-category"', "><div", "><span>", "</span><span>", "</span></div>", "</section>"];
9814
+ var _tmpl$69 = ["<span", ">running</span>"];
9815
+ var _tmpl$79 = ["<span", ">", " new</span>"];
9816
+ var _tmpl$88 = ['<button type="button" data-testid="ai-devtools-overview-hook"', "><div", "><span", ">", "</span><span", ">", "</span></div><div", "><span", ">", "</span>", "", "</div></button>"];
9817
+ var _tmpl$98 = ["<div", "><span", ">", "</span><span", ">", "</span></div>"];
9818
+ var _tmpl$07 = ["<span", ">", "</span>"];
9819
+ var _tmpl$117 = ['<span data-testid="ai-devtools-hook-technical-name">', "</span>"];
9407
9820
  var _tmpl$106 = ['<span data-testid="ai-devtools-hook-registry-id">id ', "</span>"];
9408
- var _tmpl$117 = ["<span>", "</span>"];
9821
+ var _tmpl$118 = ["<span>", "</span>"];
9409
9822
  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
9823
  var _tmpl$135 = ['<button type="button" data-testid="ai-devtools-hook-tab"', ' class="', '">', "</button>"];
9411
9824
  var _tmpl$144 = ["<div", "><section", "><div", ">Current State</div>", "</section></div>"];
@@ -9415,7 +9828,7 @@ var _tmpl$174 = ["<div", ">", "</div>"];
9415
9828
  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>'];
9416
9829
  var _tmpl$193 = ['<div class="', '">', "</div>"];
9417
9830
  var _tmpl$202 = ["<div", "><span", ">", "</span><div", ">", "</div></div>"];
9418
- var _tmpl$215 = ["<div", ">No messages yet. Start a conversation to see messages here.</div>"];
9831
+ var _tmpl$217 = ["<div", ">No messages yet. Start a conversation to see messages here.</div>"];
9419
9832
  var _tmpl$223 = ["<div", ' data-testid="ai-devtools-tools"><div', ">", "</div><div", ">", "</div></div>"];
9420
9833
  var _tmpl$232 = ["<div", ">No tools.</div>"];
9421
9834
  var _tmpl$242 = ["<span", ">approval</span>"];
@@ -9437,7 +9850,8 @@ var HookDetails = () => {
9437
9850
  let previewPane;
9438
9851
  const hook = createMemo(() => {
9439
9852
  const id = state.hooks.activeHookId;
9440
- return id ? state.hooks.hooks[id] : void 0;
9853
+ if (id === null) return void 0;
9854
+ return state.hooks.hooks[id];
9441
9855
  });
9442
9856
  const conversation = createMemo(() => {
9443
9857
  const activeHook = hook();
@@ -9454,7 +9868,7 @@ var HookDetails = () => {
9454
9868
  return Boolean(outputKind && outputKind !== "chat" && outputKind !== "structured");
9455
9869
  });
9456
9870
  createEffect(() => {
9457
- if (isGenerationHook() && (activeTab() === "tools" || activeTab() === "memory")) {
9871
+ if (isGenerationHook() && (activeTab() === "tools" || activeTab() === "memory" || activeTab() === "compaction" || activeTab() === "skills")) {
9458
9872
  setActiveTab("conversation");
9459
9873
  }
9460
9874
  });
@@ -9470,7 +9884,7 @@ var HookDetails = () => {
9470
9884
  return [];
9471
9885
  });
9472
9886
  const showSecondaryPane = createMemo(() => {
9473
- if (activeTab() === "tools" && !isGenerationHook()) return false;
9887
+ if ((activeTab() === "tools" || activeTab() === "skills") && !isGenerationHook()) return false;
9474
9888
  return isGenerationHook() || !hasStructuredOutputPreview(previewMessages());
9475
9889
  });
9476
9890
  createEffect(() => {
@@ -9487,13 +9901,14 @@ var HookDetails = () => {
9487
9901
  return createComponent(HookOverview, {
9488
9902
  onSelectHook: (selectedHook) => {
9489
9903
  selectHook(selectedHook.id);
9490
- if (state.conversations[selectedHook.id]) {
9491
- selectConversation(selectedHook.id);
9904
+ const conversationId = selectedHook.id || selectedHook.clientId || selectedHook.threadId;
9905
+ if (conversationId && state.conversations[conversationId]) {
9906
+ selectConversation(conversationId);
9492
9907
  }
9493
9908
  }
9494
9909
  });
9495
9910
  },
9496
- children: (activeHook) => ssr(_tmpl$214, ssrAttribute("class", escape(styles().hookDetails.container, true), false), escape(createComponent(HookHeader, {
9911
+ children: (activeHook) => ssr(_tmpl$216, ssrAttribute("class", escape(styles().hookDetails.container, true), false), escape(createComponent(HookHeader, {
9497
9912
  get hook() {
9498
9913
  return activeHook();
9499
9914
  },
@@ -9544,14 +9959,28 @@ var HookDetails = () => {
9544
9959
  return !isGenerationHook();
9545
9960
  },
9546
9961
  get children() {
9547
- return createComponent(TabButton, {
9962
+ return [createComponent(TabButton, {
9548
9963
  label: "Memory",
9549
9964
  tab: "memory",
9550
9965
  get activeTab() {
9551
9966
  return activeTab();
9552
9967
  },
9553
9968
  onSelect: setActiveTab
9554
- });
9969
+ }), createComponent(TabButton, {
9970
+ label: "Compaction",
9971
+ tab: "compaction",
9972
+ get activeTab() {
9973
+ return activeTab();
9974
+ },
9975
+ onSelect: setActiveTab
9976
+ }), createComponent(TabButton, {
9977
+ label: "Skills",
9978
+ tab: "skills",
9979
+ get activeTab() {
9980
+ return activeTab();
9981
+ },
9982
+ onSelect: setActiveTab
9983
+ })];
9555
9984
  }
9556
9985
  })), `${escape(styles().hookDetails.body, true)} ${showSecondaryPane() ? "" : escape(styles().hookDetails.bodySinglePane, true)}`, ssrAttribute("class", escape(styles().hookDetails.primary, true), false), escape(createComponent(Show, {
9557
9986
  get when() {
@@ -9620,12 +10049,30 @@ var HookDetails = () => {
9620
10049
  get children() {
9621
10050
  return createComponent(MemoryPanel, {});
9622
10051
  }
10052
+ })), escape(createComponent(Show, {
10053
+ get when() {
10054
+ return activeTab() === "compaction";
10055
+ },
10056
+ get children() {
10057
+ return createComponent(CompactionPanel, {
10058
+ get hook() {
10059
+ return activeHook();
10060
+ }
10061
+ });
10062
+ }
10063
+ })), escape(createComponent(Show, {
10064
+ get when() {
10065
+ return activeTab() === "skills";
10066
+ },
10067
+ get children() {
10068
+ return createComponent(SkillsPanel, {});
10069
+ }
9623
10070
  })), escape(createComponent(Show, {
9624
10071
  get when() {
9625
10072
  return showSecondaryPane();
9626
10073
  },
9627
10074
  get children() {
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, {
10075
+ return ssr(_tmpl$50, ssrAttribute("class", escape(styles().hookDetails.previewPane, true), false), ssrAttribute("class", escape(styles().hookDetails.previewHeader, true), false), isGenerationHook() ? "Generated Output" : "User View", escape(createComponent(Show, {
9629
10076
  get when() {
9630
10077
  return isGenerationHook();
9631
10078
  },
@@ -9673,10 +10120,10 @@ var HookOverview = (props) => {
9673
10120
  return hooks().length > 0;
9674
10121
  },
9675
10122
  get fallback() {
9676
- return ssr(_tmpl$47, ssrAttribute("class", escape(styles().hookDetails.empty, true), false));
10123
+ return ssr(_tmpl$410, ssrAttribute("class", escape(styles().hookDetails.empty, true), false));
9677
10124
  },
9678
10125
  get children() {
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, {
10126
+ return ssr(_tmpl$314, 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, {
9680
10127
  label: "active hooks",
9681
10128
  get value() {
9682
10129
  return summary().active;
@@ -9720,26 +10167,26 @@ var HookOverview = (props) => {
9720
10167
  get each() {
9721
10168
  return groups();
9722
10169
  },
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, {
10170
+ children: (group) => ssr(_tmpl$59, 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, {
9724
10171
  get each() {
9725
10172
  return group.hooks;
9726
10173
  },
9727
10174
  children: (hook) => {
9728
10175
  const running = createMemo(() => isHookRunning(hook, state.hooks.runs));
9729
10176
  const unseenCount = createMemo(() => getHookUnseenEventCount(state.hooks, hook.id));
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, {
10177
+ return ssr(_tmpl$88, 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, {
9731
10178
  get when() {
9732
10179
  return running();
9733
10180
  },
9734
10181
  get children() {
9735
- return ssr(_tmpl$67, ssrAttribute("class", escape(styles().hookDetails.lifecycle, true), false));
10182
+ return ssr(_tmpl$69, ssrAttribute("class", escape(styles().hookDetails.lifecycle, true), false));
9736
10183
  }
9737
10184
  })), escape(createComponent(Show, {
9738
10185
  get when() {
9739
10186
  return unseenCount() > 0;
9740
10187
  },
9741
10188
  get children() {
9742
- return ssr(_tmpl$77, ssrAttribute("class", escape(styles().hookDetails.kind, true), false), escape(unseenCount()));
10189
+ return ssr(_tmpl$79, ssrAttribute("class", escape(styles().hookDetails.kind, true), false), escape(unseenCount()));
9743
10190
  }
9744
10191
  })));
9745
10192
  }
@@ -9750,7 +10197,7 @@ var HookOverview = (props) => {
9750
10197
  };
9751
10198
  var OverviewMetric = (props) => {
9752
10199
  const styles = useStyles();
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));
10200
+ return ssr(_tmpl$98, 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));
9754
10201
  };
9755
10202
  var HookHeader = (props) => {
9756
10203
  const styles = useStyles();
@@ -9759,14 +10206,14 @@ var HookHeader = (props) => {
9759
10206
  return props.hook.outputKind;
9760
10207
  },
9761
10208
  get children() {
9762
- return ssr(_tmpl$06, ssrAttribute("class", escape(styles().hookDetails.kind, true), false), escape(props.hook.outputKind));
10209
+ return ssr(_tmpl$07, ssrAttribute("class", escape(styles().hookDetails.kind, true), false), escape(props.hook.outputKind));
9763
10210
  }
9764
10211
  })), ssrAttribute("class", escape(styles().hookDetails.identity, true), false), escape(createComponent(Show, {
9765
10212
  get when() {
9766
10213
  return props.hook.displayName;
9767
10214
  },
9768
10215
  get children() {
9769
- return ssr(_tmpl$116, escape(props.hook.hookName));
10216
+ return ssr(_tmpl$117, escape(props.hook.hookName));
9770
10217
  }
9771
10218
  })), props.hook.threadId ? `thread ${escape(props.hook.threadId)}` : escape(getHookIdentityLabel(props.hook)), escape(createComponent(Show, {
9772
10219
  get when() {
@@ -9780,7 +10227,7 @@ var HookHeader = (props) => {
9780
10227
  return props.hook.framework;
9781
10228
  },
9782
10229
  get children() {
9783
- return ssr(_tmpl$117, escape(props.hook.framework));
10230
+ return ssr(_tmpl$118, escape(props.hook.framework));
9784
10231
  }
9785
10232
  })), ssrAttribute("class", escape(styles().hookDetails.metrics, true), false), escape(createComponent(Metric, {
9786
10233
  label: "runs",
@@ -9817,7 +10264,7 @@ var HookHeader = (props) => {
9817
10264
  };
9818
10265
  var Metric = (props) => {
9819
10266
  const styles = useStyles();
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));
10267
+ return ssr(_tmpl$98, 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));
9821
10268
  };
9822
10269
  function formatMetricValue(value) {
9823
10270
  return Intl.NumberFormat(void 0, {
@@ -9987,7 +10434,7 @@ var MessagesPreview = (props) => {
9987
10434
  get ["data-part-kind"]() {
9988
10435
  return part.kind;
9989
10436
  }
9990
- }), [ssr(_tmpl$06, ssrAttribute("class", escape(styles().hookDetails.previewPartLabel, true), false), escape(part.label)), escape(createComponent(Show, {
10437
+ }), [ssr(_tmpl$07, ssrAttribute("class", escape(styles().hookDetails.previewPartLabel, true), false), escape(part.label)), escape(createComponent(Show, {
9991
10438
  get when() {
9992
10439
  return part.fixture;
9993
10440
  },
@@ -9999,7 +10446,7 @@ var MessagesPreview = (props) => {
9999
10446
  return part.jsonItems?.length;
10000
10447
  },
10001
10448
  get fallback() {
10002
- return ssr(_tmpl$06, ssrAttribute("class", escape(styles().hookDetails.previewPartContent, true), false), escape(part.content));
10449
+ return ssr(_tmpl$07, ssrAttribute("class", escape(styles().hookDetails.previewPartContent, true), false), escape(part.content));
10003
10450
  },
10004
10451
  get children() {
10005
10452
  return ssr(_tmpl$193, `${escape(styles().hookDetails.previewJsonItems, true)} ${part.kind === "structured-output" ? escape(styles().hookDetails.previewJsonItemsCompare, true) : ""}`, escape(createComponent(For, {
@@ -10029,7 +10476,7 @@ var HookMessageTimeline = (props) => {
10029
10476
  return props.messages.length > 0;
10030
10477
  },
10031
10478
  get fallback() {
10032
- return ssr(_tmpl$215, ssrAttribute("class", escape(styles().hookDetails.emptySmall, true), false));
10479
+ return ssr(_tmpl$217, ssrAttribute("class", escape(styles().hookDetails.emptySmall, true), false));
10033
10480
  },
10034
10481
  get children() {
10035
10482
  return ssr(_tmpl$174, ssrAttribute("class", escape(styles().hookDetails.messageTimeline, true), false), escape(createComponent(For, {
@@ -10074,12 +10521,12 @@ var HookMessageTimeline = (props) => {
10074
10521
  get ["data-part-kind"]() {
10075
10522
  return part.kind;
10076
10523
  }
10077
- }), [ssr(_tmpl$06, ssrAttribute("class", escape(styles().hookDetails.previewPartLabel, true), false), escape(part.label)), escape(createComponent(Show, {
10524
+ }), [ssr(_tmpl$07, ssrAttribute("class", escape(styles().hookDetails.previewPartLabel, true), false), escape(part.label)), escape(createComponent(Show, {
10078
10525
  get when() {
10079
10526
  return part.jsonItems?.length;
10080
10527
  },
10081
10528
  get fallback() {
10082
- return ssr(_tmpl$06, ssrAttribute("class", escape(styles().hookDetails.previewPartContent, true), false), escape(part.content));
10529
+ return ssr(_tmpl$07, ssrAttribute("class", escape(styles().hookDetails.previewPartContent, true), false), escape(part.content));
10083
10530
  },
10084
10531
  get children() {
10085
10532
  return ssr(_tmpl$193, `${escape(styles().hookDetails.previewJsonItems, true)} ${part.kind === "structured-output" ? escape(styles().hookDetails.previewJsonItemsCompare, true) : ""}`, escape(createComponent(For, {
@@ -10160,7 +10607,7 @@ var ToolsView = (props) => {
10160
10607
  get each() {
10161
10608
  return savedFixtures();
10162
10609
  },
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)}`)
10610
+ 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(formatTime4(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)}`)
10164
10611
  })));
10165
10612
  }
10166
10613
  })]
@@ -10507,12 +10954,12 @@ function jsonSafeValue(value) {
10507
10954
  return `[ai-devtools] unserializable value: ${error instanceof Error ? error.message : String(error)}`;
10508
10955
  }
10509
10956
  }
10510
- function formatTime3(timestamp) {
10957
+ function formatTime4(timestamp) {
10511
10958
  return new Date(timestamp).toLocaleTimeString();
10512
10959
  }
10513
10960
 
10514
10961
  // src/components/Shell.tsx
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>"];
10962
+ var _tmpl$51 = ["<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>"];
10516
10963
  function Devtools(props) {
10517
10964
  return createComponent(ThemeContextProvider, {
10518
10965
  get theme() {
@@ -10585,7 +11032,7 @@ function DevtoolsContent() {
10585
11032
  });
10586
11033
  return createComponent(MainPanel, {
10587
11034
  get children() {
10588
- return ssr(_tmpl$48, ssrAttribute("class", escape(styles().shellRoot, true), false), escape(createComponent(Header, {
11035
+ return ssr(_tmpl$51, ssrAttribute("class", escape(styles().shellRoot, true), false), escape(createComponent(Header, {
10589
11036
  get children() {
10590
11037
  return createComponent(HeaderLogo, {
10591
11038
  flavor: {