@athenaintel/react 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -30,6 +30,10 @@ export declare interface AssetPanelState {
30
30
  activeTabId: string | null;
31
31
  viewMode: ViewMode;
32
32
  isFullscreen: boolean;
33
+ /** Generation counter for auto-open tracking — incremented on reset */
34
+ autoOpenGeneration: number;
35
+ /** Tracks which assets have been auto-opened in the current generation */
36
+ autoOpenedAssets: Map<string, number>;
33
37
  openAsset: (assetId: string, meta?: {
34
38
  name?: string;
35
39
  type?: AssetType;
@@ -39,6 +43,10 @@ export declare interface AssetPanelState {
39
43
  setViewMode: (mode: ViewMode) => void;
40
44
  closePanel: () => void;
41
45
  toggleFullscreen: () => void;
46
+ /** Reset auto-open tracking (increments generation so new assets can auto-open) */
47
+ resetAutoOpen: () => void;
48
+ /** Check if an asset should auto-open, and mark it as opened if so */
49
+ markAutoOpened: (assetId: string) => boolean;
42
50
  }
43
51
 
44
52
  export declare interface AssetTab {
package/dist/index.js CHANGED
@@ -1360,7 +1360,7 @@ const createStoreImpl = (createState) => {
1360
1360
  };
1361
1361
  const createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);
1362
1362
  const identity = (arg) => arg;
1363
- function useStore(api, selector = identity) {
1363
+ function useStore$1(api, selector = identity) {
1364
1364
  const slice2 = React__default.useSyncExternalStore(
1365
1365
  api.subscribe,
1366
1366
  React__default.useCallback(() => selector(api.getState()), [api, selector]),
@@ -1371,7 +1371,7 @@ function useStore(api, selector = identity) {
1371
1371
  }
1372
1372
  const createImpl = (createState) => {
1373
1373
  const api = createStore(createState);
1374
- const useBoundStore = (selector) => useStore(api, selector);
1374
+ const useBoundStore = (selector) => useStore$1(api, selector);
1375
1375
  Object.assign(useBoundStore, api);
1376
1376
  return useBoundStore;
1377
1377
  };
@@ -20731,7 +20731,11 @@ const useAthenaRuntime = (config2) => {
20731
20731
  systemPrompt,
20732
20732
  threadId: threadIdProp
20733
20733
  } = config2;
20734
- const threadId = useMemo(() => threadIdProp ?? crypto.randomUUID(), [threadIdProp]);
20734
+ const generatedIdRef = useRef(null);
20735
+ if (generatedIdRef.current === null) {
20736
+ generatedIdRef.current = crypto.randomUUID();
20737
+ }
20738
+ const threadId = threadIdProp ?? generatedIdRef.current;
20735
20739
  const enabledTools = useMemo(
20736
20740
  () => Array.from(/* @__PURE__ */ new Set([...tools, ...frontendToolIds])),
20737
20741
  [tools, frontendToolIds]
@@ -24100,8 +24104,9 @@ function AthenaProvider({
24100
24104
  threadId
24101
24105
  }) {
24102
24106
  const frontendToolNames = useMemo(() => Object.keys(frontendTools), [frontendTools]);
24107
+ const auiTools = useMemo(() => Tools({ toolkit: frontendTools }), [frontendTools]);
24103
24108
  const aui = useAui({
24104
- tools: Tools({ toolkit: frontendTools })
24109
+ tools: auiTools
24105
24110
  });
24106
24111
  const parentAuthToken = useParentAuth();
24107
24112
  const effectiveToken = tokenProp ?? parentAuthToken;
@@ -59508,6 +59513,31 @@ class Store {
59508
59513
  return this.atom.subscribe(toObserver(observerOrFn));
59509
59514
  }
59510
59515
  }
59516
+ function defaultCompare(a, b) {
59517
+ return a === b;
59518
+ }
59519
+ function useStore(atom, selector, compare = defaultCompare) {
59520
+ const subscribe = useCallback(
59521
+ (handleStoreChange) => {
59522
+ if (!atom) {
59523
+ return () => {
59524
+ };
59525
+ }
59526
+ const { unsubscribe } = atom.subscribe(handleStoreChange);
59527
+ return unsubscribe;
59528
+ },
59529
+ [atom]
59530
+ );
59531
+ const boundGetSnapshot = useCallback(() => atom == null ? void 0 : atom.get(), [atom]);
59532
+ const selectedSnapshot = withSelectorExports.useSyncExternalStoreWithSelector(
59533
+ subscribe,
59534
+ boundGetSnapshot,
59535
+ boundGetSnapshot,
59536
+ selector,
59537
+ compare
59538
+ );
59539
+ return selectedSnapshot;
59540
+ }
59511
59541
  function createScopeRegistry() {
59512
59542
  return { entries: /* @__PURE__ */ new Map() };
59513
59543
  }
@@ -59543,52 +59573,13 @@ function getFilteredItems(cache, scope, query) {
59543
59573
  }
59544
59574
  return results;
59545
59575
  }
59546
- function toolsToMenuItems(tools) {
59547
- return tools.map((t) => ({
59548
- id: t.id,
59549
- name: t.name,
59550
- type: t.type,
59551
- fallbackIcon: t.icon ?? (t.type === "toolkit" ? "🧰" : "🔧"),
59552
- description: t.description,
59553
- visibleInScopes: /* @__PURE__ */ new Set(["root"])
59554
- }));
59555
- }
59556
- function useMentionSuggestions(tools) {
59557
- const store = useMemo(() => {
59558
- const registry = createScopeRegistry();
59559
- const cache = createItemCache();
59560
- registerSource(registry, "root", async () => ({
59561
- items: [],
59562
- pagination: { hasMore: false }
59563
- }));
59564
- const items = toolsToMenuItems(tools);
59565
- addItems(cache, items, "root");
59566
- return new Store({ registry, cache });
59567
- }, []);
59568
- useEffect(() => {
59569
- const { cache } = store.state;
59570
- for (const item of cache.items.values()) {
59571
- item.visibleInScopes.delete("root");
59572
- }
59573
- for (const [id, item] of cache.items) {
59574
- if (item.visibleInScopes.size === 0) {
59575
- cache.items.delete(id);
59576
- }
59577
- }
59578
- const items = toolsToMenuItems(tools);
59579
- addItems(cache, items, "root");
59580
- }, [tools, store]);
59581
- return store;
59582
- }
59583
- function selectItems(store, scope, query) {
59584
- const { cache } = store.state;
59585
- const items = getFilteredItems(cache, scope, query);
59586
- return { items, isFetching: false, hasMore: false };
59587
- }
59588
59576
  const MentionSuggestionList = forwardRef(({ store, query, command: command2, closeMenu }, ref) => {
59589
59577
  const [selectedIndex, setSelectedIndex] = useState(0);
59590
59578
  const scrollContainerRef = useRef(null);
59591
- const { items, isFetching } = selectItems(store, "root", query);
59579
+ const { items, isFetching } = useStore(store, (state) => ({
59580
+ items: getFilteredItems(state.cache, "root", query),
59581
+ isFetching: false
59582
+ }));
59592
59583
  useEffect(() => {
59593
59584
  setSelectedIndex(0);
59594
59585
  }, [query]);
@@ -59651,7 +59642,10 @@ const MentionSuggestionList = forwardRef(({ store, query, command: command2, clo
59651
59642
  },
59652
59643
  item.id
59653
59644
  )),
59654
- isFetching
59645
+ isFetching && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-2 py-1.5 text-sm text-muted-foreground", children: [
59646
+ /* @__PURE__ */ jsx("span", { className: "h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent" }),
59647
+ "Loading..."
59648
+ ] })
59655
59649
  ] }) });
59656
59650
  });
59657
59651
  MentionSuggestionList.displayName = "MentionSuggestionList";
@@ -59841,6 +59835,45 @@ const MentionSuggestionsExtension = Extension.create({
59841
59835
  ];
59842
59836
  }
59843
59837
  });
59838
+ function toolsToMenuItems(tools) {
59839
+ return tools.map((t) => ({
59840
+ id: t.id,
59841
+ name: t.name,
59842
+ type: t.type,
59843
+ fallbackIcon: t.icon ?? (t.type === "toolkit" ? "🧰" : "🔧"),
59844
+ description: t.description,
59845
+ visibleInScopes: /* @__PURE__ */ new Set(["root"])
59846
+ }));
59847
+ }
59848
+ function useMentionSuggestions(tools) {
59849
+ const storeRef = useRef(null);
59850
+ if (!storeRef.current) {
59851
+ const registry = createScopeRegistry();
59852
+ const cache = createItemCache();
59853
+ registerSource(registry, "root", async () => ({
59854
+ items: [],
59855
+ pagination: { hasMore: false }
59856
+ }));
59857
+ const items = toolsToMenuItems(tools);
59858
+ addItems(cache, items, "root");
59859
+ storeRef.current = new Store({ registry, cache });
59860
+ }
59861
+ const store = storeRef.current;
59862
+ useEffect(() => {
59863
+ store.setState((prev) => {
59864
+ const newCache = createItemCache();
59865
+ for (const [id, item] of prev.cache.items) {
59866
+ if (item.visibleInScopes.size > 0 && !item.visibleInScopes.has("root")) {
59867
+ newCache.items.set(id, { ...item, visibleInScopes: new Set(item.visibleInScopes) });
59868
+ }
59869
+ }
59870
+ const items = toolsToMenuItems(tools);
59871
+ addItems(newCache, items, "root");
59872
+ return { ...prev, cache: newCache };
59873
+ });
59874
+ }, [tools, store]);
59875
+ return store;
59876
+ }
59844
59877
  const TiptapComposer = ({ tools = [] }) => {
59845
59878
  const composerRuntime = useComposerRuntime();
59846
59879
  const editorRef = useRef(null);
@@ -60556,12 +60589,14 @@ function CollapsibleTrigger({ ...props }) {
60556
60589
  function CollapsibleContent({ ...props }) {
60557
60590
  return /* @__PURE__ */ jsx(CollapsibleContent$1, { "data-slot": "collapsible-content", ...props });
60558
60591
  }
60559
- const useAssetPanelStore = create((set2) => ({
60592
+ const useAssetPanelStore = create((set2, get2) => ({
60560
60593
  isOpen: false,
60561
60594
  tabs: [],
60562
60595
  activeTabId: null,
60563
60596
  viewMode: "tabs",
60564
60597
  isFullscreen: false,
60598
+ autoOpenGeneration: 0,
60599
+ autoOpenedAssets: /* @__PURE__ */ new Map(),
60565
60600
  openAsset: (assetId, meta) => set2((s) => {
60566
60601
  const existing = s.tabs.find((t) => t.id === assetId);
60567
60602
  if (existing) {
@@ -60589,39 +60624,59 @@ const useAssetPanelStore = create((set2) => ({
60589
60624
  setActiveTab: (assetId) => set2({ activeTabId: assetId, viewMode: "tabs" }),
60590
60625
  setViewMode: (mode) => set2({ viewMode: mode }),
60591
60626
  closePanel: () => set2({ isOpen: false, tabs: [], activeTabId: null, viewMode: "tabs", isFullscreen: false }),
60592
- toggleFullscreen: () => set2((s) => ({ isFullscreen: !s.isFullscreen }))
60627
+ toggleFullscreen: () => set2((s) => ({ isFullscreen: !s.isFullscreen })),
60628
+ resetAutoOpen: () => set2((s) => ({ autoOpenGeneration: s.autoOpenGeneration + 1 })),
60629
+ markAutoOpened: (assetId) => {
60630
+ const state = get2();
60631
+ if (state.autoOpenedAssets.get(assetId) === state.autoOpenGeneration) {
60632
+ return false;
60633
+ }
60634
+ state.autoOpenedAssets.set(assetId, state.autoOpenGeneration);
60635
+ return true;
60636
+ }
60593
60637
  }));
60594
60638
  const ANIMATION_DURATION = 200;
60595
60639
  const TOOL_META = {
60596
- search: { displayName: "Web Search", icon: Search, describer: (a) => a.query ? `"${a.query}"` : "" },
60597
- browse: { displayName: "Browse Page", icon: Globe, describer: (a) => a.url ?? "" },
60598
- search_email: { displayName: "Email Search", icon: Mail, describer: (a) => a.query ? `"${a.query}"` : "" },
60599
- unified_email_search: { displayName: "Email Search", icon: Mail, describer: (a) => a.query ? `"${a.query}"` : "" },
60600
- create_email_draft: { displayName: "Create Email Draft", icon: Mail },
60601
- unified_email_create_draft: { displayName: "Create Email Draft", icon: Mail },
60602
- edit_email_draft: { displayName: "Edit Email Draft", icon: Mail },
60603
- unified_edit_email_draft: { displayName: "Edit Email Draft", icon: Mail },
60604
- search_contacts: { displayName: "Search Contacts", icon: Search },
60605
- search_calendar_events: { displayName: "Search Calendar", icon: Search },
60606
- read_full_asset: { displayName: "Read Asset", icon: BookOpen },
60607
- create_new_document: { displayName: "Create Document", icon: FileText },
60608
- create_document_from_markdown: { displayName: "Create Document", icon: FileText },
60609
- append_markdown_to_athena_document: { displayName: "Write to Document", icon: PenLine },
60610
- replace_markdown_in_athena_document: { displayName: "Update Document", icon: PenLine },
60611
- create_new_sheet: { displayName: "Create Spreadsheet", icon: ChartColumn },
60612
- update_sheet_range: { displayName: "Update Spreadsheet", icon: ChartColumn },
60613
- run_python_code: { displayName: "Run Python", icon: Code },
60614
- run_sql_query_tool: { displayName: "Run SQL Query", icon: Database },
60615
- create_database: { displayName: "Create Database", icon: Database },
60616
- run_database_sql: { displayName: "Run Database Query", icon: Database },
60617
- computer_asset_exec: { displayName: "Run Command", icon: Monitor },
60618
- create_new_notebook: { displayName: "Create Notebook", icon: BookOpen },
60619
- execute_cell: { displayName: "Execute Cell", icon: Code },
60620
- create_new_aop: { displayName: "Create AOP", icon: Brain },
60621
- execute_aop: { displayName: "Execute AOP", icon: Brain },
60622
- list_contents: { displayName: "List Files", icon: Search },
60623
- search_assets: { displayName: "Search Assets", icon: Search },
60624
- save_preference_as_memory: { displayName: "Save Preference", icon: Settings }
60640
+ // Search & Browse
60641
+ search: { displayName: "Searching the web", icon: Search, describer: (a) => a.query ? `"${a.query}"` : "" },
60642
+ browse: { displayName: "Reading webpage", icon: Globe, describer: (a) => a.url ?? "" },
60643
+ search_email: { displayName: "Searching emails", icon: Mail, describer: (a) => a.query ? `"${a.query}"` : "" },
60644
+ unified_email_search: { displayName: "Searching emails", icon: Mail, describer: (a) => a.query ? `"${a.query}"` : "" },
60645
+ search_contacts: { displayName: "Looking up contacts", icon: Search },
60646
+ search_calendar_events: { displayName: "Checking calendar", icon: Search },
60647
+ search_assets: { displayName: "Searching files", icon: Search },
60648
+ list_contents: { displayName: "Browsing files", icon: Search },
60649
+ // Email
60650
+ create_email_draft: { displayName: "Drafting email", icon: Mail },
60651
+ unified_email_create_draft: { displayName: "Drafting email", icon: Mail },
60652
+ edit_email_draft: { displayName: "Editing email draft", icon: Mail },
60653
+ unified_edit_email_draft: { displayName: "Editing email draft", icon: Mail },
60654
+ // Documents
60655
+ read_full_asset: { displayName: "Reading document", icon: BookOpen },
60656
+ create_new_document: { displayName: "Creating document", icon: FileText },
60657
+ create_document_from_markdown: { displayName: "Creating document", icon: FileText },
60658
+ append_markdown_to_athena_document: { displayName: "Updating document", icon: PenLine },
60659
+ replace_markdown_in_athena_document: { displayName: "Updating document", icon: PenLine },
60660
+ // Spreadsheets
60661
+ create_new_sheet: { displayName: "Creating spreadsheet", icon: ChartColumn },
60662
+ update_sheet_range: { displayName: "Updating spreadsheet", icon: ChartColumn },
60663
+ // Presentations
60664
+ create_powerpoint_deck: { displayName: "Building presentation", icon: Monitor },
60665
+ execute_presentation_code: { displayName: "Generating slides", icon: Monitor },
60666
+ // Code & Data
60667
+ run_python_code: { displayName: "Running analysis", icon: Code },
60668
+ run_sql_query_tool: { displayName: "Querying data", icon: Database },
60669
+ create_database: { displayName: "Setting up database", icon: Database },
60670
+ run_database_sql: { displayName: "Querying database", icon: Database },
60671
+ computer_asset_exec: { displayName: "Running command", icon: Monitor },
60672
+ // Notebooks
60673
+ create_new_notebook: { displayName: "Creating notebook", icon: BookOpen },
60674
+ execute_cell: { displayName: "Running notebook cell", icon: Code },
60675
+ // Workflows
60676
+ create_new_aop: { displayName: "Creating workflow", icon: Brain },
60677
+ execute_aop: { displayName: "Running workflow", icon: Brain },
60678
+ // Preferences
60679
+ save_preference_as_memory: { displayName: "Saving preference", icon: Settings }
60625
60680
  };
60626
60681
  function getToolMeta(toolName) {
60627
60682
  if (TOOL_META[toolName]) return TOOL_META[toolName];
@@ -60708,10 +60763,8 @@ function extractTitle(argsText, result) {
60708
60763
  }
60709
60764
  return null;
60710
60765
  }
60711
- let assetGeneration$1 = 0;
60712
- const autoOpenedAssets$1 = /* @__PURE__ */ new Map();
60713
60766
  function clearAutoOpenedAssets() {
60714
- assetGeneration$1++;
60767
+ useAssetPanelStore.getState().resetAutoOpen();
60715
60768
  }
60716
60769
  function ToolFallbackRoot({
60717
60770
  className,
@@ -60746,7 +60799,7 @@ function ToolFallbackRoot({
60746
60799
  open: isOpen,
60747
60800
  onOpenChange: handleOpenChange,
60748
60801
  className: cn(
60749
- "aui-tool-fallback-root group/tool-fallback-root w-full rounded-xl border border-border/60 bg-background py-2.5 shadow-sm",
60802
+ "aui-tool-fallback-root group/tool-fallback-root my-3 w-full rounded-xl border border-border/60 bg-background py-2.5 shadow-sm",
60750
60803
  className
60751
60804
  ),
60752
60805
  style: {
@@ -60817,16 +60870,16 @@ function ToolFallbackTrigger({
60817
60870
  ),
60818
60871
  children: [
60819
60872
  /* @__PURE__ */ jsx("span", { children: isRunning ? /* @__PURE__ */ jsxs(Fragment$2, { children: [
60820
- /* @__PURE__ */ jsx("b", { children: meta.displayName }),
60873
+ meta.displayName,
60821
60874
  "..."
60822
- ] }) : /* @__PURE__ */ jsx("b", { children: meta.displayName }) }),
60875
+ ] }) : meta.displayName }),
60823
60876
  isRunning && /* @__PURE__ */ jsxs(
60824
60877
  "span",
60825
60878
  {
60826
60879
  "aria-hidden": true,
60827
60880
  className: "shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none",
60828
60881
  children: [
60829
- /* @__PURE__ */ jsx("b", { children: meta.displayName }),
60882
+ meta.displayName,
60830
60883
  "..."
60831
60884
  ]
60832
60885
  }
@@ -60960,17 +61013,19 @@ function AssetToolCard({
60960
61013
  const assetType = toolMetaToAssetType(toolName);
60961
61014
  const wasCompleteAtMount = useRef(isComplete);
60962
61015
  useEffect(() => {
60963
- if (isComplete && !isCancelled && assetId && !wasCompleteAtMount.current && autoOpenedAssets$1.get(assetId) !== assetGeneration$1) {
60964
- autoOpenedAssets$1.set(assetId, assetGeneration$1);
60965
- useAssetPanelStore.getState().openAsset(assetId, {
60966
- name: title ?? void 0,
60967
- type: assetType
60968
- });
61016
+ if (isComplete && !isCancelled && assetId && !wasCompleteAtMount.current) {
61017
+ const store = useAssetPanelStore.getState();
61018
+ if (store.markAutoOpened(assetId)) {
61019
+ store.openAsset(assetId, {
61020
+ name: title ?? void 0,
61021
+ type: assetType
61022
+ });
61023
+ }
60969
61024
  }
60970
61025
  }, [isComplete, isCancelled, assetId, title, assetType]);
60971
61026
  const success = isComplete && isResultSuccess(result);
60972
61027
  return /* @__PURE__ */ jsxs("div", { className: cn(
60973
- "aui-tool-fallback-root w-full rounded-xl border border-border/60 bg-background py-2.5 shadow-sm",
61028
+ "aui-tool-fallback-root my-3 w-full rounded-xl border border-border/60 bg-background py-2.5 shadow-sm",
60974
61029
  isCancelled && "border-muted-foreground/30 bg-muted/30"
60975
61030
  ), children: [
60976
61031
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 px-3 text-sm", children: [
@@ -60987,13 +61042,13 @@ function AssetToolCard({
60987
61042
  }
60988
61043
  ),
60989
61044
  /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 grow flex-col items-start gap-0.5 text-left", children: [
60990
- /* @__PURE__ */ jsxs("span", { className: "leading-tight", children: [
60991
- /* @__PURE__ */ jsx("b", { children: meta.displayName }),
61045
+ /* @__PURE__ */ jsxs("span", { className: "leading-tight font-medium", children: [
61046
+ meta.displayName,
60992
61047
  isRunning && "..."
60993
61048
  ] }),
60994
61049
  !isRunning && title && /* @__PURE__ */ jsx("span", { className: "max-w-full truncate text-xs leading-snug text-muted-foreground", children: title })
60995
61050
  ] }),
60996
- assetId && isComplete && !isCancelled && /* @__PURE__ */ jsxs(
61051
+ assetId && isComplete && !isCancelled && CREATE_ASSET_TOOLS.includes(toolName.toLowerCase()) && /* @__PURE__ */ jsxs(
60997
61052
  "button",
60998
61053
  {
60999
61054
  onClick: () => openAsset(assetId, { name: title ?? void 0, type: assetType }),
@@ -61415,11 +61470,15 @@ function normalizeResult(result) {
61415
61470
  function truncate(text2, max2) {
61416
61471
  return text2.length > max2 ? `${text2.slice(0, max2)}...` : text2;
61417
61472
  }
61473
+ function formatToolName(name) {
61474
+ return name.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
61475
+ }
61418
61476
  function ToolCard({
61419
61477
  icon: Icon2,
61420
61478
  status,
61421
61479
  title,
61422
61480
  subtitle,
61481
+ toolName,
61423
61482
  badge,
61424
61483
  error: error2,
61425
61484
  children
@@ -61427,7 +61486,7 @@ function ToolCard({
61427
61486
  const isRunning = status === "running";
61428
61487
  const isComplete = status === "complete";
61429
61488
  const isError = status === "incomplete";
61430
- return /* @__PURE__ */ jsxs("div", { className: "my-1.5 w-full overflow-hidden rounded-xl border border-border/60 bg-background shadow-sm", children: [
61489
+ return /* @__PURE__ */ jsxs("div", { className: "my-3 w-full overflow-hidden rounded-xl border border-border/60 bg-background shadow-sm", children: [
61431
61490
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 px-4 py-3", children: [
61432
61491
  /* @__PURE__ */ jsx(
61433
61492
  "div",
@@ -61443,11 +61502,12 @@ function ToolCard({
61443
61502
  ),
61444
61503
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
61445
61504
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
61446
- /* @__PURE__ */ jsx("span", { className: "text-[13px] font-semibold text-foreground", children: title }),
61505
+ /* @__PURE__ */ jsx("span", { className: "text-[13px] font-medium text-foreground", children: title }),
61447
61506
  isComplete && !error2 && /* @__PURE__ */ jsx(CircleCheck, { className: "size-3.5 text-emerald-500" })
61448
61507
  ] }),
61449
61508
  subtitle && /* @__PURE__ */ jsx("p", { className: "truncate text-[12px] text-muted-foreground", children: subtitle })
61450
61509
  ] }),
61510
+ toolName && /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded-md bg-muted/60 px-1.5 py-0.5 text-[10px] font-mono text-muted-foreground", children: formatToolName(toolName) }),
61451
61511
  badge && /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: badge }),
61452
61512
  isRunning && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
61453
61513
  /* @__PURE__ */ jsx("div", { className: "h-1.5 w-10 animate-pulse rounded-full bg-blue-100" }),
@@ -61501,6 +61561,7 @@ function parseSearchResults(data) {
61501
61561
  });
61502
61562
  }
61503
61563
  const WebSearchToolUIImpl = ({
61564
+ toolName,
61504
61565
  args,
61505
61566
  result,
61506
61567
  status
@@ -61519,11 +61580,12 @@ const WebSearchToolUIImpl = ({
61519
61580
  status: (status == null ? void 0 : status.type) ?? "complete",
61520
61581
  title: isRunning ? "Searching the web..." : "Web search",
61521
61582
  subtitle: query ? truncate(query, 80) : void 0,
61583
+ toolName,
61522
61584
  badge: isComplete && results.length > 0 ? `${results.length} results` : void 0,
61523
61585
  error: errorMsg,
61524
61586
  children: isComplete && results.length > 0 && /* @__PURE__ */ jsx(ExpandableSection, { label: "Show search results", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2.5", children: results.map((r2, i) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
61525
61587
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
61526
- r2.url ? /* @__PURE__ */ jsx(
61588
+ r2.url && /^https?:\/\//i.test(r2.url) ? /* @__PURE__ */ jsx(
61527
61589
  "a",
61528
61590
  {
61529
61591
  href: r2.url,
@@ -61532,7 +61594,7 @@ const WebSearchToolUIImpl = ({
61532
61594
  className: "text-[12px] font-medium text-blue-600 hover:underline",
61533
61595
  children: r2.title || r2.url
61534
61596
  }
61535
- ) : /* @__PURE__ */ jsx("span", { className: "text-[12px] font-medium text-foreground", children: r2.title || "Result" }),
61597
+ ) : /* @__PURE__ */ jsx("span", { className: "text-[12px] font-medium text-foreground", children: r2.title || r2.url || "Result" }),
61536
61598
  r2.url && /* @__PURE__ */ jsx(ExternalLink, { className: "size-3 shrink-0 text-muted-foreground" })
61537
61599
  ] }),
61538
61600
  r2.url && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: truncate(r2.url, 60) }),
@@ -61546,6 +61608,7 @@ const WebSearchToolUI = memo(
61546
61608
  );
61547
61609
  WebSearchToolUI.displayName = "WebSearchToolUI";
61548
61610
  const BrowseToolUIImpl = ({
61611
+ toolName,
61549
61612
  args,
61550
61613
  result,
61551
61614
  status
@@ -61574,6 +61637,7 @@ const BrowseToolUIImpl = ({
61574
61637
  status: (status == null ? void 0 : status.type) ?? "complete",
61575
61638
  title: isRunning ? "Browsing page..." : pageTitle ? truncate(pageTitle, 50) : "Browsed page",
61576
61639
  subtitle: displayUrl,
61640
+ toolName,
61577
61641
  error: errorMsg,
61578
61642
  children: isComplete && pageContent && /* @__PURE__ */ jsx(ExpandableSection, { label: "Show page content", children: /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap break-words text-[11px] leading-relaxed text-muted-foreground", children: truncate(pageContent, 3e3) }) })
61579
61643
  }
@@ -61597,6 +61661,7 @@ function parseEmailResults(data) {
61597
61661
  });
61598
61662
  }
61599
61663
  const EmailSearchToolUIImpl = ({
61664
+ toolName,
61600
61665
  args,
61601
61666
  result,
61602
61667
  status
@@ -61615,6 +61680,7 @@ const EmailSearchToolUIImpl = ({
61615
61680
  status: (status == null ? void 0 : status.type) ?? "complete",
61616
61681
  title: isRunning ? "Searching emails..." : "Email search",
61617
61682
  subtitle: query ? truncate(query, 80) : void 0,
61683
+ toolName,
61618
61684
  badge: isComplete && emails.length > 0 ? `${emails.length} emails` : void 0,
61619
61685
  error: errorMsg,
61620
61686
  children: isComplete && emails.length > 0 && /* @__PURE__ */ jsx(ExpandableSection, { label: "Show email results", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col divide-y divide-border/30", children: emails.map((email, i) => /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-0.5 py-2", i === 0 && "pt-0"), children: [
@@ -61639,16 +61705,15 @@ function extractAssetId(result) {
61639
61705
  if (typeof id === "string" && id.startsWith("asset_")) return id;
61640
61706
  return null;
61641
61707
  }
61642
- let assetGeneration = 0;
61643
- const autoOpenedAssets = /* @__PURE__ */ new Map();
61644
61708
  function resetAssetAutoOpen() {
61645
- assetGeneration++;
61709
+ useAssetPanelStore.getState().resetAutoOpen();
61646
61710
  }
61647
61711
  function CreateAssetToolUIImpl({
61648
61712
  icon: Icon2,
61649
61713
  assetType,
61650
61714
  runningLabel,
61651
61715
  doneLabel,
61716
+ toolName,
61652
61717
  args,
61653
61718
  result,
61654
61719
  status
@@ -61665,12 +61730,14 @@ function CreateAssetToolUIImpl({
61665
61730
  const openAsset = useAssetPanelStore((s) => s.openAsset);
61666
61731
  const wasCompleteAtMount = useRef(isComplete);
61667
61732
  useEffect(() => {
61668
- if (isComplete && !isCancelled && assetId && !wasCompleteAtMount.current && autoOpenedAssets.get(assetId) !== assetGeneration) {
61669
- autoOpenedAssets.set(assetId, assetGeneration);
61670
- useAssetPanelStore.getState().openAsset(assetId, {
61671
- name: createdName || name || void 0,
61672
- type: assetType
61673
- });
61733
+ if (isComplete && !isCancelled && assetId && !wasCompleteAtMount.current) {
61734
+ const store = useAssetPanelStore.getState();
61735
+ if (store.markAutoOpened(assetId)) {
61736
+ store.openAsset(assetId, {
61737
+ name: createdName || name || void 0,
61738
+ type: assetType
61739
+ });
61740
+ }
61674
61741
  }
61675
61742
  }, [isComplete, isCancelled, assetId, createdName, name, assetType]);
61676
61743
  const handleOpen = () => {
@@ -61688,6 +61755,7 @@ function CreateAssetToolUIImpl({
61688
61755
  status: (status == null ? void 0 : status.type) ?? "complete",
61689
61756
  title: isRunning ? runningLabel : doneLabel,
61690
61757
  subtitle: createdName || name || void 0,
61758
+ toolName,
61691
61759
  error: errorMsg,
61692
61760
  children: assetId && isComplete && !isCancelled && /* @__PURE__ */ jsx("div", { className: "border-t border-border/40 px-4 py-2", children: /* @__PURE__ */ jsxs(
61693
61761
  "button",
@@ -61747,6 +61815,7 @@ const CreatePresentationToolUI = memo(
61747
61815
  );
61748
61816
  CreatePresentationToolUI.displayName = "CreatePresentationToolUI";
61749
61817
  const CreateEmailDraftToolUIImpl = ({
61818
+ toolName,
61750
61819
  args,
61751
61820
  result,
61752
61821
  status
@@ -61762,6 +61831,7 @@ const CreateEmailDraftToolUIImpl = ({
61762
61831
  icon: Mail,
61763
61832
  status: (status == null ? void 0 : status.type) ?? "complete",
61764
61833
  title: isRunning ? "Creating email draft..." : "Email draft created",
61834
+ toolName,
61765
61835
  subtitle: subject ? truncate(subject, 60) : to ? `To: ${truncate(to, 40)}` : void 0,
61766
61836
  error: errorMsg
61767
61837
  }
@@ -61781,7 +61851,6 @@ const TOOL_UI_REGISTRY = {
61781
61851
  create_new_document: CreateDocumentToolUI,
61782
61852
  create_document_from_markdown: CreateDocumentToolUI,
61783
61853
  create_new_sheet: CreateSheetToolUI,
61784
- update_sheet_range: CreateSheetToolUI,
61785
61854
  create_powerpoint_deck: CreatePresentationToolUI
61786
61855
  };
61787
61856
  const falsyToString = (value) => typeof value === "boolean" ? `${value}` : value === 0 ? "0" : value;
@@ -62080,7 +62149,8 @@ function useAssetEmbed(assetId, options = {
62080
62149
  setError(null);
62081
62150
  return;
62082
62151
  }
62083
- const cached = embedCache.get(assetId);
62152
+ const cacheKey = `${assetId}:${readOnly}:${token ?? apiKey ?? "anon"}`;
62153
+ const cached = embedCache.get(cacheKey);
62084
62154
  if (cached && cached.expiresAt > Date.now() / 1e3) {
62085
62155
  setEmbedUrl(cached.url);
62086
62156
  setIsLoading(false);
@@ -62116,7 +62186,7 @@ function useAssetEmbed(assetId, options = {
62116
62186
  }
62117
62187
  return res.json();
62118
62188
  }).then((data) => {
62119
- embedCache.set(assetId, { url: data.embed_url, expiresAt: data.expires_at });
62189
+ embedCache.set(`${assetId}:${readOnly}:${token ?? apiKey ?? "anon"}`, { url: data.embed_url, expiresAt: data.expires_at });
62120
62190
  setEmbedUrl(data.embed_url);
62121
62191
  setIsLoading(false);
62122
62192
  }).catch((err) => {