@tanstack/ai-devtools-core 0.5.8 → 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]};
@@ -4775,6 +4773,24 @@ function clearMemoryRegistry(state) {
4775
4773
  state.scopes = {};
4776
4774
  }
4777
4775
 
4776
+ // src/store/skills-registry.ts
4777
+ function createSkillsRegistryState() {
4778
+ return { snapshots: {} };
4779
+ }
4780
+ function clearSkillsRegistry(state) {
4781
+ state.snapshots = {};
4782
+ }
4783
+ function applySkillsSnapshot(state, payload) {
4784
+ const key = payload.hookId && payload.hookId.length > 0 ? payload.hookId : "_default";
4785
+ const catalog = Array.isArray(payload.catalog) ? payload.catalog : [];
4786
+ const activated = Array.isArray(payload.activated) ? payload.activated : [];
4787
+ state.snapshots[key] = {
4788
+ catalog,
4789
+ activated,
4790
+ updatedAt: payload.timestamp ?? Date.now()
4791
+ };
4792
+ }
4793
+
4778
4794
  // src/store/ai-context.tsx
4779
4795
  var AIContext = createContext();
4780
4796
  function useAIStore() {
@@ -4789,7 +4805,8 @@ var AIProvider = (props) => {
4789
4805
  conversations: {},
4790
4806
  activeConversationId: null,
4791
4807
  hooks: createHookRegistryState(),
4792
- memory: createMemoryRegistryState()
4808
+ memory: createMemoryRegistryState(),
4809
+ skills: createSkillsRegistryState()
4793
4810
  });
4794
4811
  const streamToConversation = /* @__PURE__ */ new Map();
4795
4812
  const requestToConversation = /* @__PURE__ */ new Map();
@@ -5046,6 +5063,11 @@ var AIProvider = (props) => {
5046
5063
  clearMemoryRegistry(memory);
5047
5064
  }));
5048
5065
  }
5066
+ function clearSkills() {
5067
+ setState("skills", produce((skills) => {
5068
+ clearSkillsRegistry(skills);
5069
+ }));
5070
+ }
5049
5071
  function selectHook(id) {
5050
5072
  setState("hooks", produce((hooks) => {
5051
5073
  setActiveHook(hooks, id);
@@ -5376,6 +5398,10 @@ var AIProvider = (props) => {
5376
5398
  setState("memory", produce((memory) => {
5377
5399
  applyMemorySnapshot(memory, e.payload);
5378
5400
  }));
5401
+ }), aiEventClient.on("skills:snapshot", (e) => {
5402
+ setState("skills", produce((skills) => {
5403
+ applySkillsSnapshot(skills, e.payload);
5404
+ }));
5379
5405
  }));
5380
5406
  const recordRunEvent = (eventName, payload) => {
5381
5407
  setState("hooks", produce((hooks) => {
@@ -6952,6 +6978,7 @@ var AIProvider = (props) => {
6952
6978
  selectConversation,
6953
6979
  clearHooks,
6954
6980
  clearMemory,
6981
+ clearSkills,
6955
6982
  selectHook,
6956
6983
  saveToolFixture,
6957
6984
  deleteToolFixture,
@@ -10935,15 +10962,161 @@ var MemoryPanel = () => {
10935
10962
  })();
10936
10963
  };
10937
10964
  delegateEvents(["click"]);
10965
+ var _tmpl$40 = /* @__PURE__ */ template(`<ul>`);
10966
+ var _tmpl$214 = /* @__PURE__ */ template(`<div><div>Catalog`);
10967
+ var _tmpl$310 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-skills-panel>`);
10968
+ var _tmpl$47 = /* @__PURE__ */ template(`<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\`.`);
10969
+ var _tmpl$57 = /* @__PURE__ */ template(`<div>Loaded via \`load_skill\`, but the catalog snapshot has not arrived yet.`);
10970
+ var _tmpl$67 = /* @__PURE__ */ template(`<span>loaded`);
10971
+ var _tmpl$77 = /* @__PURE__ */ template(`<li><span></span><span>`);
10972
+ function parseSkillName(argumentsJson) {
10973
+ if (!argumentsJson) return void 0;
10974
+ try {
10975
+ const parsed = JSON.parse(argumentsJson);
10976
+ if (parsed && typeof parsed === "object" && "name" in parsed && typeof parsed.name === "string") {
10977
+ return parsed.name;
10978
+ }
10979
+ } catch {
10980
+ return void 0;
10981
+ }
10982
+ return void 0;
10983
+ }
10984
+ function loadedFromMessages(messages) {
10985
+ const names = /* @__PURE__ */ new Set();
10986
+ for (const message of messages) {
10987
+ for (const toolCall of message.toolCalls ?? []) {
10988
+ if (toolCall.name === "load_skill") {
10989
+ const name = parseSkillName(toolCall.arguments);
10990
+ if (name) names.add(name);
10991
+ }
10992
+ }
10993
+ for (const part of message.parts ?? []) {
10994
+ if (part.type === "tool-call" && part.toolName === "load_skill") {
10995
+ const name = parseSkillName(part.arguments);
10996
+ if (name) names.add(name);
10997
+ }
10998
+ }
10999
+ }
11000
+ return [...names];
11001
+ }
11002
+ var SkillsPanel = () => {
11003
+ const {
11004
+ state
11005
+ } = useAIStore();
11006
+ const styles = useStyles();
11007
+ const snapshot = createMemo(() => {
11008
+ const hookId = state.hooks.activeHookId;
11009
+ if (hookId && state.skills.snapshots[hookId]) {
11010
+ return state.skills.snapshots[hookId];
11011
+ }
11012
+ const first = Object.values(state.skills.snapshots)[0];
11013
+ return first;
11014
+ });
11015
+ const conversation = createMemo(() => {
11016
+ const hookId = state.hooks.activeHookId;
11017
+ if (!hookId) return void 0;
11018
+ return state.conversations[hookId];
11019
+ });
11020
+ const loaded = createMemo(() => {
11021
+ const fromSnap = new Set(snapshot()?.activated ?? []);
11022
+ for (const name of loadedFromMessages(conversation()?.messages ?? [])) {
11023
+ fromSnap.add(name);
11024
+ }
11025
+ return fromSnap;
11026
+ });
11027
+ const catalog = createMemo(() => snapshot()?.catalog ?? []);
11028
+ return (() => {
11029
+ var _el$ = _tmpl$310();
11030
+ insert(_el$, createComponent(Show, {
11031
+ get when() {
11032
+ return catalog().length > 0 || loaded().size > 0;
11033
+ },
11034
+ get fallback() {
11035
+ return (() => {
11036
+ var _el$5 = _tmpl$47();
11037
+ effect(() => className(_el$5, styles().memoryPanel.empty));
11038
+ return _el$5;
11039
+ })();
11040
+ },
11041
+ get children() {
11042
+ var _el$2 = _tmpl$214(), _el$3 = _el$2.firstChild;
11043
+ insert(_el$2, createComponent(Show, {
11044
+ get when() {
11045
+ return catalog().length > 0;
11046
+ },
11047
+ get fallback() {
11048
+ return (() => {
11049
+ var _el$6 = _tmpl$57();
11050
+ effect(() => className(_el$6, styles().memoryPanel.sectionEmpty));
11051
+ return _el$6;
11052
+ })();
11053
+ },
11054
+ get children() {
11055
+ var _el$4 = _tmpl$40();
11056
+ insert(_el$4, createComponent(For, {
11057
+ get each() {
11058
+ return catalog();
11059
+ },
11060
+ children: (skill) => {
11061
+ const isLoaded = () => loaded().has(skill.name);
11062
+ return (() => {
11063
+ var _el$7 = _tmpl$77(), _el$8 = _el$7.firstChild, _el$0 = _el$8.nextSibling;
11064
+ insert(_el$8, () => skill.name);
11065
+ insert(_el$7, createComponent(Show, {
11066
+ get when() {
11067
+ return isLoaded();
11068
+ },
11069
+ get children() {
11070
+ var _el$9 = _tmpl$67();
11071
+ effect(() => className(_el$9, styles().memoryPanel.badge));
11072
+ return _el$9;
11073
+ }
11074
+ }), _el$0);
11075
+ insert(_el$0, () => skill.description);
11076
+ effect((_p$) => {
11077
+ var _v$3 = styles().memoryPanel.row, _v$4 = styles().memoryPanel.badge, _v$5 = styles().memoryPanel.sectionEmpty;
11078
+ _v$3 !== _p$.e && className(_el$7, _p$.e = _v$3);
11079
+ _v$4 !== _p$.t && className(_el$8, _p$.t = _v$4);
11080
+ _v$5 !== _p$.a && className(_el$0, _p$.a = _v$5);
11081
+ return _p$;
11082
+ }, {
11083
+ e: void 0,
11084
+ t: void 0,
11085
+ a: void 0
11086
+ });
11087
+ return _el$7;
11088
+ })();
11089
+ }
11090
+ }));
11091
+ effect(() => className(_el$4, styles().memoryPanel.list));
11092
+ return _el$4;
11093
+ }
11094
+ }), null);
11095
+ effect((_p$) => {
11096
+ var _v$ = styles().memoryPanel.section, _v$2 = styles().memoryPanel.sectionTitle;
11097
+ _v$ !== _p$.e && className(_el$2, _p$.e = _v$);
11098
+ _v$2 !== _p$.t && className(_el$3, _p$.t = _v$2);
11099
+ return _p$;
11100
+ }, {
11101
+ e: void 0,
11102
+ t: void 0
11103
+ });
11104
+ return _el$2;
11105
+ }
11106
+ }));
11107
+ effect(() => className(_el$, styles().memoryPanel.container));
11108
+ return _el$;
11109
+ })();
11110
+ };
10938
11111
 
10939
11112
  // src/components/hooks/HookDetails.tsx
10940
- var _tmpl$40 = /* @__PURE__ */ template(`<aside data-testid=ai-devtools-preview-pane><div>`);
10941
- var _tmpl$214 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-hook-detail><nav data-testid=ai-devtools-hook-tabs></nav><div><main data-testid=ai-devtools-primary-pane>`);
10942
- var _tmpl$310 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-dashboard-overview><header><div><div>Hooks Dashboard</div><div>Select a hook from the left or open one of the active hooks below.</div></div></header><div></div><div>`);
10943
- var _tmpl$47 = /* @__PURE__ */ template(`<div>Open a page with TanStack AI hooks to inspect live state.`);
10944
- var _tmpl$57 = /* @__PURE__ */ template(`<section data-testid=ai-devtools-overview-category><div><span></span><span>`);
10945
- var _tmpl$67 = /* @__PURE__ */ template(`<span>running`);
10946
- var _tmpl$77 = /* @__PURE__ */ template(`<span> new`);
11113
+ var _tmpl$41 = /* @__PURE__ */ template(`<aside data-testid=ai-devtools-preview-pane><div>`);
11114
+ var _tmpl$215 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-hook-detail><nav data-testid=ai-devtools-hook-tabs></nav><div><main data-testid=ai-devtools-primary-pane>`);
11115
+ var _tmpl$311 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-dashboard-overview><header><div><div>Hooks Dashboard</div><div>Select a hook from the left or open one of the active hooks below.</div></div></header><div></div><div>`);
11116
+ var _tmpl$48 = /* @__PURE__ */ template(`<div>Open a page with TanStack AI hooks to inspect live state.`);
11117
+ var _tmpl$58 = /* @__PURE__ */ template(`<section data-testid=ai-devtools-overview-category><div><span></span><span>`);
11118
+ var _tmpl$68 = /* @__PURE__ */ template(`<span>running`);
11119
+ var _tmpl$78 = /* @__PURE__ */ template(`<span> new`);
10947
11120
  var _tmpl$87 = /* @__PURE__ */ template(`<button type=button data-testid=ai-devtools-overview-hook><div><span></span><span></span></div><div><span>`);
10948
11121
  var _tmpl$97 = /* @__PURE__ */ template(`<div><span></span><span>`);
10949
11122
  var _tmpl$06 = /* @__PURE__ */ template(`<span>`);
@@ -10959,7 +11132,7 @@ var _tmpl$173 = /* @__PURE__ */ template(`<div><button type=button data-testid=a
10959
11132
  var _tmpl$182 = /* @__PURE__ */ template(`<div><span>`);
10960
11133
  var _tmpl$192 = /* @__PURE__ */ template(`<div><span></span><div>`);
10961
11134
  var _tmpl$202 = /* @__PURE__ */ template(`<div>No messages yet. Start a conversation to see messages here.`);
10962
- var _tmpl$215 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-tools><div></div><div>`);
11135
+ var _tmpl$216 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-tools><div></div><div>`);
10963
11136
  var _tmpl$223 = /* @__PURE__ */ template(`<div>No tools.`);
10964
11137
  var _tmpl$232 = /* @__PURE__ */ template(`<span>approval`);
10965
11138
  var _tmpl$242 = /* @__PURE__ */ template(`<button type=button data-testid=ai-devtools-tool-row><span>`);
@@ -10981,7 +11154,8 @@ var HookDetails = () => {
10981
11154
  let previewPane;
10982
11155
  const hook = createMemo(() => {
10983
11156
  const id = state.hooks.activeHookId;
10984
- return id ? state.hooks.hooks[id] : void 0;
11157
+ if (id === null) return void 0;
11158
+ return state.hooks.hooks[id];
10985
11159
  });
10986
11160
  const conversation = createMemo(() => {
10987
11161
  const activeHook = hook();
@@ -10998,7 +11172,7 @@ var HookDetails = () => {
10998
11172
  return Boolean(outputKind && outputKind !== "chat" && outputKind !== "structured");
10999
11173
  });
11000
11174
  createEffect(() => {
11001
- if (isGenerationHook() && (activeTab() === "tools" || activeTab() === "memory")) {
11175
+ if (isGenerationHook() && (activeTab() === "tools" || activeTab() === "memory" || activeTab() === "skills")) {
11002
11176
  setActiveTab("conversation");
11003
11177
  }
11004
11178
  });
@@ -11014,7 +11188,7 @@ var HookDetails = () => {
11014
11188
  return [];
11015
11189
  });
11016
11190
  const showSecondaryPane = createMemo(() => {
11017
- if (activeTab() === "tools" && !isGenerationHook()) return false;
11191
+ if ((activeTab() === "tools" || activeTab() === "skills") && !isGenerationHook()) return false;
11018
11192
  return isGenerationHook() || !hasStructuredOutputPreview(previewMessages());
11019
11193
  });
11020
11194
  createEffect(() => {
@@ -11043,7 +11217,7 @@ var HookDetails = () => {
11043
11217
  });
11044
11218
  },
11045
11219
  children: (activeHook) => (() => {
11046
- var _el$ = _tmpl$214(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.firstChild;
11220
+ var _el$ = _tmpl$215(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.firstChild;
11047
11221
  insert(_el$, createComponent(HookHeader, {
11048
11222
  get hook() {
11049
11223
  return activeHook();
@@ -11099,14 +11273,21 @@ var HookDetails = () => {
11099
11273
  return !isGenerationHook();
11100
11274
  },
11101
11275
  get children() {
11102
- return createComponent(TabButton, {
11276
+ return [createComponent(TabButton, {
11103
11277
  label: "Memory",
11104
11278
  tab: "memory",
11105
11279
  get activeTab() {
11106
11280
  return activeTab();
11107
11281
  },
11108
11282
  onSelect: setActiveTab
11109
- });
11283
+ }), createComponent(TabButton, {
11284
+ label: "Skills",
11285
+ tab: "skills",
11286
+ get activeTab() {
11287
+ return activeTab();
11288
+ },
11289
+ onSelect: setActiveTab
11290
+ })];
11110
11291
  }
11111
11292
  }), null);
11112
11293
  _el$4.addEventListener("mouseleave", () => setHoverTarget(null));
@@ -11185,12 +11366,20 @@ var HookDetails = () => {
11185
11366
  return createComponent(MemoryPanel, {});
11186
11367
  }
11187
11368
  }), null);
11369
+ insert(_el$4, createComponent(Show, {
11370
+ get when() {
11371
+ return activeTab() === "skills";
11372
+ },
11373
+ get children() {
11374
+ return createComponent(SkillsPanel, {});
11375
+ }
11376
+ }), null);
11188
11377
  insert(_el$3, createComponent(Show, {
11189
11378
  get when() {
11190
11379
  return showSecondaryPane();
11191
11380
  },
11192
11381
  get children() {
11193
- var _el$5 = _tmpl$40(), _el$6 = _el$5.firstChild;
11382
+ var _el$5 = _tmpl$41(), _el$6 = _el$5.firstChild;
11194
11383
  _el$5.addEventListener("mouseleave", () => setHoverTarget(null));
11195
11384
  _el$5.$$mouseover = (event) => setHoverTargetFromEvent(event, "preview", setHoverTarget);
11196
11385
  use((el) => {
@@ -11271,13 +11460,13 @@ var HookOverview = (props) => {
11271
11460
  },
11272
11461
  get fallback() {
11273
11462
  return (() => {
11274
- var _el$12 = _tmpl$47();
11463
+ var _el$12 = _tmpl$48();
11275
11464
  effect(() => className(_el$12, styles().hookDetails.empty));
11276
11465
  return _el$12;
11277
11466
  })();
11278
11467
  },
11279
11468
  get children() {
11280
- var _el$7 = _tmpl$310(), _el$8 = _el$7.firstChild, _el$9 = _el$8.firstChild, _el$0 = _el$9.firstChild, _el$1 = _el$0.nextSibling, _el$10 = _el$8.nextSibling, _el$11 = _el$10.nextSibling;
11469
+ var _el$7 = _tmpl$311(), _el$8 = _el$7.firstChild, _el$9 = _el$8.firstChild, _el$0 = _el$9.firstChild, _el$1 = _el$0.nextSibling, _el$10 = _el$8.nextSibling, _el$11 = _el$10.nextSibling;
11281
11470
  insert(_el$10, createComponent(OverviewMetric, {
11282
11471
  label: "active hooks",
11283
11472
  get value() {
@@ -11331,7 +11520,7 @@ var HookOverview = (props) => {
11331
11520
  return groups();
11332
11521
  },
11333
11522
  children: (group) => (() => {
11334
- var _el$13 = _tmpl$57(), _el$14 = _el$13.firstChild, _el$15 = _el$14.firstChild, _el$16 = _el$15.nextSibling;
11523
+ var _el$13 = _tmpl$58(), _el$14 = _el$13.firstChild, _el$15 = _el$14.firstChild, _el$16 = _el$15.nextSibling;
11335
11524
  insert(_el$15, () => group.label);
11336
11525
  insert(_el$16, () => group.hooks.length);
11337
11526
  insert(_el$13, createComponent(For, {
@@ -11352,7 +11541,7 @@ var HookOverview = (props) => {
11352
11541
  return running();
11353
11542
  },
11354
11543
  get children() {
11355
- var _el$23 = _tmpl$67();
11544
+ var _el$23 = _tmpl$68();
11356
11545
  effect(() => className(_el$23, styles().hookDetails.lifecycle));
11357
11546
  return _el$23;
11358
11547
  }
@@ -11362,7 +11551,7 @@ var HookOverview = (props) => {
11362
11551
  return unseenCount() > 0;
11363
11552
  },
11364
11553
  get children() {
11365
- var _el$24 = _tmpl$77(), _el$25 = _el$24.firstChild;
11554
+ var _el$24 = _tmpl$78(), _el$25 = _el$24.firstChild;
11366
11555
  insert(_el$24, unseenCount, _el$25);
11367
11556
  effect(() => className(_el$24, styles().hookDetails.kind));
11368
11557
  return _el$24;
@@ -12055,7 +12244,7 @@ var ToolsView = (props) => {
12055
12244
  const selectedTool = createMemo(() => props.hook.tools.find((tool) => tool.name === selectedToolName()));
12056
12245
  const savedFixtures = createMemo(() => state.hooks.fixtures.filter((fixture) => fixture.hookId === props.hook.id || !!props.hook.threadId && fixture.threadId === props.hook.threadId).sort((a, b) => b.createdAt - a.createdAt));
12057
12246
  return (() => {
12058
- var _el$76 = _tmpl$215(), _el$77 = _el$76.firstChild, _el$78 = _el$77.nextSibling;
12247
+ var _el$76 = _tmpl$216(), _el$77 = _el$76.firstChild, _el$78 = _el$77.nextSibling;
12059
12248
  insert(_el$77, createComponent(Show, {
12060
12249
  get when() {
12061
12250
  return props.hook.tools.length > 0;
@@ -12652,7 +12841,7 @@ function formatTime3(timestamp) {
12652
12841
  delegateEvents(["mouseover", "click"]);
12653
12842
 
12654
12843
  // src/components/Shell.tsx
12655
- var _tmpl$41 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-panel><div><div data-testid=ai-devtools-left-panel style=min-width:150px;max-width:800px><div>AI Hooks</div></div><div></div><div data-testid=ai-devtools-right-panel style=flex:1>`);
12844
+ var _tmpl$49 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-panel><div><div data-testid=ai-devtools-left-panel style=min-width:150px;max-width:800px><div>AI Hooks</div></div><div></div><div data-testid=ai-devtools-right-panel style=flex:1>`);
12656
12845
  function Devtools(props) {
12657
12846
  return createComponent(ThemeContextProvider, {
12658
12847
  get theme() {
@@ -12734,7 +12923,7 @@ function DevtoolsContent() {
12734
12923
  });
12735
12924
  return createComponent(MainPanel, {
12736
12925
  get children() {
12737
- var _el$ = _tmpl$41(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$3.nextSibling, _el$6 = _el$5.nextSibling;
12926
+ var _el$ = _tmpl$49(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$3.nextSibling, _el$6 = _el$5.nextSibling;
12738
12927
  insert(_el$, createComponent(Header, {
12739
12928
  get children() {
12740
12929
  return createComponent(HeaderLogo, {