@tanstack/ai-devtools-core 0.5.9 → 0.5.10

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.
@@ -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]};
@@ -4743,6 +4741,24 @@ function clearMemoryRegistry(state) {
4743
4741
  state.scopes = {};
4744
4742
  }
4745
4743
 
4744
+ // src/store/skills-registry.ts
4745
+ function createSkillsRegistryState() {
4746
+ return { snapshots: {} };
4747
+ }
4748
+ function clearSkillsRegistry(state) {
4749
+ state.snapshots = {};
4750
+ }
4751
+ function applySkillsSnapshot(state, payload) {
4752
+ const key = payload.hookId && payload.hookId.length > 0 ? payload.hookId : "_default";
4753
+ const catalog = Array.isArray(payload.catalog) ? payload.catalog : [];
4754
+ const activated = Array.isArray(payload.activated) ? payload.activated : [];
4755
+ state.snapshots[key] = {
4756
+ catalog,
4757
+ activated,
4758
+ updatedAt: payload.timestamp ?? Date.now()
4759
+ };
4760
+ }
4761
+
4746
4762
  // src/store/ai-context.tsx
4747
4763
  var AIContext = createContext();
4748
4764
  function useAIStore() {
@@ -4757,7 +4773,8 @@ var AIProvider = (props) => {
4757
4773
  conversations: {},
4758
4774
  activeConversationId: null,
4759
4775
  hooks: createHookRegistryState(),
4760
- memory: createMemoryRegistryState()
4776
+ memory: createMemoryRegistryState(),
4777
+ skills: createSkillsRegistryState()
4761
4778
  });
4762
4779
  const streamToConversation = /* @__PURE__ */ new Map();
4763
4780
  const requestToConversation = /* @__PURE__ */ new Map();
@@ -5014,6 +5031,11 @@ var AIProvider = (props) => {
5014
5031
  clearMemoryRegistry(memory);
5015
5032
  }));
5016
5033
  }
5034
+ function clearSkills() {
5035
+ setState("skills", produce((skills) => {
5036
+ clearSkillsRegistry(skills);
5037
+ }));
5038
+ }
5017
5039
  function selectHook(id) {
5018
5040
  setState("hooks", produce((hooks) => {
5019
5041
  setActiveHook(hooks, id);
@@ -5338,6 +5360,10 @@ var AIProvider = (props) => {
5338
5360
  setState("memory", produce((memory) => {
5339
5361
  applyMemorySnapshot(memory, e.payload);
5340
5362
  }));
5363
+ }), aiEventClient.on("skills:snapshot", (e) => {
5364
+ setState("skills", produce((skills) => {
5365
+ applySkillsSnapshot(skills, e.payload);
5366
+ }));
5341
5367
  }));
5342
5368
  const recordRunEvent = (eventName, payload) => {
5343
5369
  setState("hooks", produce((hooks) => {
@@ -6914,6 +6940,7 @@ var AIProvider = (props) => {
6914
6940
  selectConversation,
6915
6941
  clearHooks,
6916
6942
  clearMemory,
6943
+ clearSkills,
6917
6944
  selectHook,
6918
6945
  saveToolFixture,
6919
6946
  deleteToolFixture,
@@ -9391,15 +9418,115 @@ var MemoryPanel = () => {
9391
9418
  })))]
9392
9419
  })));
9393
9420
  };
9421
+ var _tmpl$41 = ["<ul", ">", "</ul>"];
9422
+ var _tmpl$214 = ["<div", "><div", ">Catalog</div>", "</div>"];
9423
+ var _tmpl$312 = ["<div", ' data-testid="ai-devtools-skills-panel">', "</div>"];
9424
+ var _tmpl$47 = ["<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>"];
9425
+ var _tmpl$57 = ["<div", ">Loaded via `load_skill`, but the catalog snapshot has not arrived yet.</div>"];
9426
+ var _tmpl$67 = ["<span", ">loaded</span>"];
9427
+ var _tmpl$77 = ["<li", "><span", ">", "</span>", "<span", ">", "</span></li>"];
9428
+ function parseSkillName(argumentsJson) {
9429
+ if (!argumentsJson) return void 0;
9430
+ try {
9431
+ const parsed = JSON.parse(argumentsJson);
9432
+ if (parsed && typeof parsed === "object" && "name" in parsed && typeof parsed.name === "string") {
9433
+ return parsed.name;
9434
+ }
9435
+ } catch {
9436
+ return void 0;
9437
+ }
9438
+ return void 0;
9439
+ }
9440
+ function loadedFromMessages(messages) {
9441
+ const names = /* @__PURE__ */ new Set();
9442
+ for (const message of messages) {
9443
+ for (const toolCall of message.toolCalls ?? []) {
9444
+ if (toolCall.name === "load_skill") {
9445
+ const name = parseSkillName(toolCall.arguments);
9446
+ if (name) names.add(name);
9447
+ }
9448
+ }
9449
+ for (const part of message.parts ?? []) {
9450
+ if (part.type === "tool-call" && part.toolName === "load_skill") {
9451
+ const name = parseSkillName(part.arguments);
9452
+ if (name) names.add(name);
9453
+ }
9454
+ }
9455
+ }
9456
+ return [...names];
9457
+ }
9458
+ var SkillsPanel = () => {
9459
+ const {
9460
+ state
9461
+ } = useAIStore();
9462
+ const styles = useStyles();
9463
+ const snapshot = createMemo(() => {
9464
+ const hookId = state.hooks.activeHookId;
9465
+ if (hookId && state.skills.snapshots[hookId]) {
9466
+ return state.skills.snapshots[hookId];
9467
+ }
9468
+ const first = Object.values(state.skills.snapshots)[0];
9469
+ return first;
9470
+ });
9471
+ const conversation = createMemo(() => {
9472
+ const hookId = state.hooks.activeHookId;
9473
+ if (!hookId) return void 0;
9474
+ return state.conversations[hookId];
9475
+ });
9476
+ const loaded = createMemo(() => {
9477
+ const fromSnap = new Set(snapshot()?.activated ?? []);
9478
+ for (const name of loadedFromMessages(conversation()?.messages ?? [])) {
9479
+ fromSnap.add(name);
9480
+ }
9481
+ return fromSnap;
9482
+ });
9483
+ const catalog = createMemo(() => snapshot()?.catalog ?? []);
9484
+ return ssr(_tmpl$312, ssrAttribute("class", escape(styles().memoryPanel.container, true), false), escape(createComponent(Show, {
9485
+ get when() {
9486
+ return catalog().length > 0 || loaded().size > 0;
9487
+ },
9488
+ get fallback() {
9489
+ return ssr(_tmpl$47, ssrAttribute("class", escape(styles().memoryPanel.empty, true), false));
9490
+ },
9491
+ get children() {
9492
+ return ssr(_tmpl$214, ssrAttribute("class", escape(styles().memoryPanel.section, true), false), ssrAttribute("class", escape(styles().memoryPanel.sectionTitle, true), false), escape(createComponent(Show, {
9493
+ get when() {
9494
+ return catalog().length > 0;
9495
+ },
9496
+ get fallback() {
9497
+ return ssr(_tmpl$57, ssrAttribute("class", escape(styles().memoryPanel.sectionEmpty, true), false));
9498
+ },
9499
+ get children() {
9500
+ return ssr(_tmpl$41, ssrAttribute("class", escape(styles().memoryPanel.list, true), false), escape(createComponent(For, {
9501
+ get each() {
9502
+ return catalog();
9503
+ },
9504
+ children: (skill) => {
9505
+ const isLoaded = () => loaded().has(skill.name);
9506
+ return ssr(_tmpl$77, ssrAttribute("class", escape(styles().memoryPanel.row, true), false), ssrAttribute("class", escape(styles().memoryPanel.badge, true), false), escape(skill.name), escape(createComponent(Show, {
9507
+ get when() {
9508
+ return isLoaded();
9509
+ },
9510
+ get children() {
9511
+ return ssr(_tmpl$67, ssrAttribute("class", escape(styles().memoryPanel.badge, true), false));
9512
+ }
9513
+ })), ssrAttribute("class", escape(styles().memoryPanel.sectionEmpty, true), false), escape(skill.description));
9514
+ }
9515
+ })));
9516
+ }
9517
+ })));
9518
+ }
9519
+ })));
9520
+ };
9394
9521
 
9395
9522
  // 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>"];
9523
+ var _tmpl$48 = ["<aside", ' data-testid="ai-devtools-preview-pane"><div', ">", "</div>", "</aside>"];
9524
+ var _tmpl$215 = ["<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>"];
9525
+ var _tmpl$313 = ["<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>"];
9526
+ var _tmpl$49 = ["<div", ">Open a page with TanStack AI hooks to inspect live state.</div>"];
9527
+ var _tmpl$58 = ["<section", ' data-testid="ai-devtools-overview-category"', "><div", "><span>", "</span><span>", "</span></div>", "</section>"];
9528
+ var _tmpl$68 = ["<span", ">running</span>"];
9529
+ var _tmpl$78 = ["<span", ">", " new</span>"];
9403
9530
  var _tmpl$87 = ['<button type="button" data-testid="ai-devtools-overview-hook"', "><div", "><span", ">", "</span><span", ">", "</span></div><div", "><span", ">", "</span>", "", "</div></button>"];
9404
9531
  var _tmpl$97 = ["<div", "><span", ">", "</span><span", ">", "</span></div>"];
9405
9532
  var _tmpl$06 = ["<span", ">", "</span>"];
@@ -9415,7 +9542,7 @@ var _tmpl$174 = ["<div", ">", "</div>"];
9415
9542
  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
9543
  var _tmpl$193 = ['<div class="', '">', "</div>"];
9417
9544
  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>"];
9545
+ var _tmpl$216 = ["<div", ">No messages yet. Start a conversation to see messages here.</div>"];
9419
9546
  var _tmpl$223 = ["<div", ' data-testid="ai-devtools-tools"><div', ">", "</div><div", ">", "</div></div>"];
9420
9547
  var _tmpl$232 = ["<div", ">No tools.</div>"];
9421
9548
  var _tmpl$242 = ["<span", ">approval</span>"];
@@ -9437,7 +9564,8 @@ var HookDetails = () => {
9437
9564
  let previewPane;
9438
9565
  const hook = createMemo(() => {
9439
9566
  const id = state.hooks.activeHookId;
9440
- return id ? state.hooks.hooks[id] : void 0;
9567
+ if (id === null) return void 0;
9568
+ return state.hooks.hooks[id];
9441
9569
  });
9442
9570
  const conversation = createMemo(() => {
9443
9571
  const activeHook = hook();
@@ -9454,7 +9582,7 @@ var HookDetails = () => {
9454
9582
  return Boolean(outputKind && outputKind !== "chat" && outputKind !== "structured");
9455
9583
  });
9456
9584
  createEffect(() => {
9457
- if (isGenerationHook() && (activeTab() === "tools" || activeTab() === "memory")) {
9585
+ if (isGenerationHook() && (activeTab() === "tools" || activeTab() === "memory" || activeTab() === "skills")) {
9458
9586
  setActiveTab("conversation");
9459
9587
  }
9460
9588
  });
@@ -9470,7 +9598,7 @@ var HookDetails = () => {
9470
9598
  return [];
9471
9599
  });
9472
9600
  const showSecondaryPane = createMemo(() => {
9473
- if (activeTab() === "tools" && !isGenerationHook()) return false;
9601
+ if ((activeTab() === "tools" || activeTab() === "skills") && !isGenerationHook()) return false;
9474
9602
  return isGenerationHook() || !hasStructuredOutputPreview(previewMessages());
9475
9603
  });
9476
9604
  createEffect(() => {
@@ -9493,7 +9621,7 @@ var HookDetails = () => {
9493
9621
  }
9494
9622
  });
9495
9623
  },
9496
- children: (activeHook) => ssr(_tmpl$214, ssrAttribute("class", escape(styles().hookDetails.container, true), false), escape(createComponent(HookHeader, {
9624
+ children: (activeHook) => ssr(_tmpl$215, ssrAttribute("class", escape(styles().hookDetails.container, true), false), escape(createComponent(HookHeader, {
9497
9625
  get hook() {
9498
9626
  return activeHook();
9499
9627
  },
@@ -9544,14 +9672,21 @@ var HookDetails = () => {
9544
9672
  return !isGenerationHook();
9545
9673
  },
9546
9674
  get children() {
9547
- return createComponent(TabButton, {
9675
+ return [createComponent(TabButton, {
9548
9676
  label: "Memory",
9549
9677
  tab: "memory",
9550
9678
  get activeTab() {
9551
9679
  return activeTab();
9552
9680
  },
9553
9681
  onSelect: setActiveTab
9554
- });
9682
+ }), createComponent(TabButton, {
9683
+ label: "Skills",
9684
+ tab: "skills",
9685
+ get activeTab() {
9686
+ return activeTab();
9687
+ },
9688
+ onSelect: setActiveTab
9689
+ })];
9555
9690
  }
9556
9691
  })), `${escape(styles().hookDetails.body, true)} ${showSecondaryPane() ? "" : escape(styles().hookDetails.bodySinglePane, true)}`, ssrAttribute("class", escape(styles().hookDetails.primary, true), false), escape(createComponent(Show, {
9557
9692
  get when() {
@@ -9620,12 +9755,19 @@ var HookDetails = () => {
9620
9755
  get children() {
9621
9756
  return createComponent(MemoryPanel, {});
9622
9757
  }
9758
+ })), escape(createComponent(Show, {
9759
+ get when() {
9760
+ return activeTab() === "skills";
9761
+ },
9762
+ get children() {
9763
+ return createComponent(SkillsPanel, {});
9764
+ }
9623
9765
  })), escape(createComponent(Show, {
9624
9766
  get when() {
9625
9767
  return showSecondaryPane();
9626
9768
  },
9627
9769
  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, {
9770
+ return ssr(_tmpl$48, 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
9771
  get when() {
9630
9772
  return isGenerationHook();
9631
9773
  },
@@ -9673,10 +9815,10 @@ var HookOverview = (props) => {
9673
9815
  return hooks().length > 0;
9674
9816
  },
9675
9817
  get fallback() {
9676
- return ssr(_tmpl$47, ssrAttribute("class", escape(styles().hookDetails.empty, true), false));
9818
+ return ssr(_tmpl$49, ssrAttribute("class", escape(styles().hookDetails.empty, true), false));
9677
9819
  },
9678
9820
  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, {
9821
+ return ssr(_tmpl$313, 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
9822
  label: "active hooks",
9681
9823
  get value() {
9682
9824
  return summary().active;
@@ -9720,7 +9862,7 @@ var HookOverview = (props) => {
9720
9862
  get each() {
9721
9863
  return groups();
9722
9864
  },
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, {
9865
+ children: (group) => ssr(_tmpl$58, 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
9866
  get each() {
9725
9867
  return group.hooks;
9726
9868
  },
@@ -9732,14 +9874,14 @@ var HookOverview = (props) => {
9732
9874
  return running();
9733
9875
  },
9734
9876
  get children() {
9735
- return ssr(_tmpl$67, ssrAttribute("class", escape(styles().hookDetails.lifecycle, true), false));
9877
+ return ssr(_tmpl$68, ssrAttribute("class", escape(styles().hookDetails.lifecycle, true), false));
9736
9878
  }
9737
9879
  })), escape(createComponent(Show, {
9738
9880
  get when() {
9739
9881
  return unseenCount() > 0;
9740
9882
  },
9741
9883
  get children() {
9742
- return ssr(_tmpl$77, ssrAttribute("class", escape(styles().hookDetails.kind, true), false), escape(unseenCount()));
9884
+ return ssr(_tmpl$78, ssrAttribute("class", escape(styles().hookDetails.kind, true), false), escape(unseenCount()));
9743
9885
  }
9744
9886
  })));
9745
9887
  }
@@ -10029,7 +10171,7 @@ var HookMessageTimeline = (props) => {
10029
10171
  return props.messages.length > 0;
10030
10172
  },
10031
10173
  get fallback() {
10032
- return ssr(_tmpl$215, ssrAttribute("class", escape(styles().hookDetails.emptySmall, true), false));
10174
+ return ssr(_tmpl$216, ssrAttribute("class", escape(styles().hookDetails.emptySmall, true), false));
10033
10175
  },
10034
10176
  get children() {
10035
10177
  return ssr(_tmpl$174, ssrAttribute("class", escape(styles().hookDetails.messageTimeline, true), false), escape(createComponent(For, {
@@ -10512,7 +10654,7 @@ function formatTime3(timestamp) {
10512
10654
  }
10513
10655
 
10514
10656
  // 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>"];
10657
+ var _tmpl$50 = ["<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
10658
  function Devtools(props) {
10517
10659
  return createComponent(ThemeContextProvider, {
10518
10660
  get theme() {
@@ -10585,7 +10727,7 @@ function DevtoolsContent() {
10585
10727
  });
10586
10728
  return createComponent(MainPanel, {
10587
10729
  get children() {
10588
- return ssr(_tmpl$48, ssrAttribute("class", escape(styles().shellRoot, true), false), escape(createComponent(Header, {
10730
+ return ssr(_tmpl$50, ssrAttribute("class", escape(styles().shellRoot, true), false), escape(createComponent(Header, {
10589
10731
  get children() {
10590
10732
  return createComponent(HeaderLogo, {
10591
10733
  flavor: {