@athenaintel/react 0.11.0 → 0.11.1

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.js CHANGED
@@ -33,7 +33,7 @@ import { runsMaterialize, StatewireThread, useStatewireSendCommand, useStatewire
33
33
  import { useAuiState } from "@assistant-ui/store";
34
34
  import * as ReactDOM from "react-dom";
35
35
  import ReactDOM__default, { flushSync } from "react-dom";
36
- const version$1 = "0.11.0";
36
+ const version$1 = "0.11.1";
37
37
  const packageJson = {
38
38
  version: version$1
39
39
  };
@@ -12031,6 +12031,9 @@ function useDeepAgentThread({
12031
12031
  return statewireTransport(
12032
12032
  {
12033
12033
  url: `${baseUrl.replace(/\/+$/, "")}/${encodeURIComponent(threadId)}`,
12034
+ // A never-started chat has no server session yet: the transport
12035
+ // makes no network calls until the first command send.
12036
+ ...preloadRef.current.preload && { isNew: true },
12034
12037
  headers: (ctx) => headersRef.current(ctx),
12035
12038
  ...sessionStore && { sessionStore }
12036
12039
  },
@@ -55999,13 +56002,13 @@ const TiptapComposer = ({ tools = [], rootCategories }) => {
55999
56002
  });
56000
56003
  if (fullMessage) {
56001
56004
  aui.composer.setText(fullMessage);
56002
- aui.composer.send();
56005
+ aui.composer.send({ steer: false });
56003
56006
  clearAttachments();
56004
56007
  clearQuote();
56005
56008
  }
56006
56009
  } else {
56007
56010
  aui.composer.setText(markdown);
56008
- aui.composer.send();
56011
+ aui.composer.send({ steer: false });
56009
56012
  }
56010
56013
  editor2.commands.clearContent();
56011
56014
  }, [aui, clearAttachments, clearQuote, appUrl]);
@@ -56642,6 +56645,10 @@ const TOOL_META = {
56642
56645
  // Presentations
56643
56646
  create_powerpoint_deck: { displayName: "Building presentation", icon: Monitor },
56644
56647
  execute_presentation_code: { displayName: "Generating slides", icon: Monitor },
56648
+ execute_word_document_code: { displayName: "Editing Word document", icon: FileText },
56649
+ execute_spreadsheet_code: { displayName: "Editing spreadsheet", icon: ChartColumn },
56650
+ execute_spreadsheet_commands: { displayName: "Editing spreadsheet", icon: ChartColumn },
56651
+ unified_email_list_accounts: { displayName: "Checking email accounts", icon: Mail },
56645
56652
  // Code & Data
56646
56653
  run_python_code: { displayName: "Running analysis", icon: Code },
56647
56654
  run_sql_query_tool: { displayName: "Running SQL query", icon: Database, describer: (a) => a.sql_query ?? a.query ?? a.sql ? `"${truncateLine(a.sql_query ?? a.query ?? a.sql)}"` : "" },
@@ -56689,14 +56696,14 @@ function extractResultMessage(result) {
56689
56696
  return null;
56690
56697
  }
56691
56698
  function isResultSuccess(result) {
56692
- if (typeof result === "string") {
56693
- const parsed = tryParseJson$1(result);
56694
- if (parsed) return parsed.success === true;
56695
- }
56696
- if (typeof result === "object" && result !== null) {
56697
- return result.success === true;
56699
+ const obj = typeof result === "string" ? tryParseJson$1(result) : typeof result === "object" && result !== null ? result : null;
56700
+ if (obj) {
56701
+ if (obj.success === false || obj.ok === false) return false;
56702
+ if (typeof obj.error === "string" && obj.error.length > 0) return false;
56703
+ return true;
56698
56704
  }
56699
- return false;
56705
+ if (typeof result === "string") return !/^\s*error\b/i.test(result);
56706
+ return true;
56700
56707
  }
56701
56708
  function extractAssetId$1(result) {
56702
56709
  if (!result) return null;
@@ -56861,7 +56868,7 @@ function ToolFallbackTrigger({
56861
56868
  "span",
56862
56869
  {
56863
56870
  className: cn(
56864
- "relative inline-block leading-tight",
56871
+ "relative inline-block text-[13px] font-medium leading-tight",
56865
56872
  isCancelled && "text-muted-foreground line-through"
56866
56873
  ),
56867
56874
  children: [
@@ -57846,17 +57853,103 @@ BrowseToolUI.displayName = "BrowseToolUI";
57846
57853
  function parseEmailResults(data) {
57847
57854
  const results = data.limited_results ?? data.results ?? data.emails ?? data.messages;
57848
57855
  if (!Array.isArray(results)) return [];
57849
- return results.slice(0, 10).map((r2) => {
57850
- const item = r2;
57851
- return {
57852
- subject: item.subject ?? item.title,
57853
- from: item.from ?? item.sender ?? item.from_email,
57854
- date: item.date ?? item.received_at ?? item.sent_at,
57855
- snippet: item.snippet ?? item.preview ?? item.body_preview,
57856
- isDraft: Boolean(item.is_draft)
57857
- };
57856
+ return results.slice(0, 50).flatMap((r2) => {
57857
+ const item = asRecord(r2);
57858
+ if (!item) return [];
57859
+ return [
57860
+ {
57861
+ subject: asString(item.subject) ?? asString(item.title),
57862
+ from: asString(item.from) ?? asString(item.sender) ?? asString(item.from_email),
57863
+ date: asString(item.date) ?? asString(item.received_at) ?? asString(item.sent_at),
57864
+ snippet: asString(item.snippet) ?? asString(item.preview) ?? asString(item.body_preview),
57865
+ isDraft: item.is_draft === true
57866
+ }
57867
+ ];
57858
57868
  });
57859
57869
  }
57870
+ function formatEmailDate(raw) {
57871
+ if (!raw) return void 0;
57872
+ const dateOnly = /^(\d{4})-(\d{2})-(\d{2})$/.exec(raw.trim());
57873
+ const date2 = dateOnly ? new Date(Number(dateOnly[1]), Number(dateOnly[2]) - 1, Number(dateOnly[3])) : new Date(raw);
57874
+ if (Number.isNaN(date2.getTime())) return raw;
57875
+ const now = /* @__PURE__ */ new Date();
57876
+ if (!dateOnly && date2.toDateString() === now.toDateString()) {
57877
+ return date2.toLocaleTimeString(void 0, {
57878
+ hour: "numeric",
57879
+ minute: "2-digit"
57880
+ });
57881
+ }
57882
+ const sameYear = date2.getFullYear() === now.getFullYear();
57883
+ return date2.toLocaleDateString(void 0, {
57884
+ month: "short",
57885
+ day: "numeric",
57886
+ ...sameYear ? {} : { year: "numeric" }
57887
+ });
57888
+ }
57889
+ const EMAIL_QUERY_OPERATOR = /(?:^|\s)(received|after|before|from|to|subject|has|in|is):(?:"([^"]+)"|(\S+))/gi;
57890
+ function humanEmailDate(raw) {
57891
+ return formatEmailDate(raw.replace(/\//g, "-")) ?? raw;
57892
+ }
57893
+ function humanizeEmailQuery(query) {
57894
+ if (!query.trim()) return "";
57895
+ const phrases = [];
57896
+ let freeText = query;
57897
+ for (const match2 of query.matchAll(EMAIL_QUERY_OPERATOR)) {
57898
+ const [token, op, quoted, bare] = match2;
57899
+ const value = quoted ?? bare ?? "";
57900
+ freeText = freeText.replace(token, " ");
57901
+ switch (op.toLowerCase()) {
57902
+ case "received": {
57903
+ const [start, end] = value.split("..");
57904
+ phrases.push(
57905
+ end ? `${humanEmailDate(start)} – ${humanEmailDate(end)}` : humanEmailDate(start)
57906
+ );
57907
+ break;
57908
+ }
57909
+ case "after":
57910
+ phrases.push(`after ${humanEmailDate(value)}`);
57911
+ break;
57912
+ case "before":
57913
+ phrases.push(`before ${humanEmailDate(value)}`);
57914
+ break;
57915
+ case "from":
57916
+ phrases.push(`from ${value}`);
57917
+ break;
57918
+ case "to":
57919
+ phrases.push(`to ${value}`);
57920
+ break;
57921
+ case "subject":
57922
+ phrases.push(`subject “${value}”`);
57923
+ break;
57924
+ case "has":
57925
+ phrases.push(value === "attachment" ? "with attachments" : `has ${value}`);
57926
+ break;
57927
+ case "in":
57928
+ phrases.push(value === "drafts" ? "drafts only" : `in ${value}`);
57929
+ break;
57930
+ case "is":
57931
+ phrases.push(value);
57932
+ break;
57933
+ }
57934
+ }
57935
+ const remainder = freeText.trim().replace(/\s+/g, " ");
57936
+ if (remainder) phrases.push(`“${remainder}”`);
57937
+ return phrases.join(" · ");
57938
+ }
57939
+ const INLINE_EMAIL_ROWS = 3;
57940
+ function EmailResultRow({ email: email2 }) {
57941
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5 py-2 first:pt-0 last:pb-0", children: [
57942
+ /* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between gap-2", children: [
57943
+ /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-baseline gap-1.5 text-[12px] font-medium text-foreground", children: [
57944
+ email2.isDraft && /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded bg-amber-100 px-1 py-px text-[9px] font-semibold uppercase tracking-wide text-amber-700", children: "Draft" }),
57945
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: email2.subject || "No subject" })
57946
+ ] }),
57947
+ email2.date && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: formatEmailDate(email2.date) })
57948
+ ] }),
57949
+ email2.from && /* @__PURE__ */ jsx("span", { className: "truncate text-[11px] text-muted-foreground", children: email2.from }),
57950
+ email2.snippet && /* @__PURE__ */ jsx("p", { className: "text-[11px] leading-relaxed text-muted-foreground/80", children: truncate(email2.snippet, 150) })
57951
+ ] });
57952
+ }
57860
57953
  const EmailSearchToolUIImpl = ({
57861
57954
  toolName,
57862
57955
  args,
@@ -57867,35 +57960,96 @@ const EmailSearchToolUIImpl = ({
57867
57960
  const query = (typedArgs == null ? void 0 : typedArgs.query) ?? (typedArgs == null ? void 0 : typedArgs.search_query) ?? "";
57868
57961
  const data = useMemo(() => normalizeResult(result), [result]);
57869
57962
  const emails = useMemo(() => data ? parseEmailResults(data) : [], [data]);
57963
+ const provider = typeof (data == null ? void 0 : data.provider) === "string" ? data.provider : void 0;
57964
+ const totalCount = typeof (data == null ? void 0 : data.count) === "number" ? data.count : emails.length;
57870
57965
  const isRunning = (status == null ? void 0 : status.type) === "running";
57871
57966
  const isComplete = (status == null ? void 0 : status.type) === "complete";
57872
57967
  const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
57968
+ const readableQuery = useMemo(() => humanizeEmailQuery(query), [query]);
57969
+ const inlineEmails = emails.slice(0, INLINE_EMAIL_ROWS);
57970
+ const overflowEmails = emails.slice(INLINE_EMAIL_ROWS);
57971
+ const countLabel = emails.length > 0 && totalCount > emails.length ? `${emails.length} of ${totalCount}` : `${totalCount}`;
57873
57972
  return /* @__PURE__ */ jsx(
57874
57973
  ToolCard,
57875
57974
  {
57876
57975
  icon: Mail,
57877
57976
  status: (status == null ? void 0 : status.type) ?? "complete",
57878
- title: isRunning ? "Searching emails..." : "Email search",
57879
- subtitle: query ? truncate(query, 80) : void 0,
57977
+ title: isRunning ? "Searching email…" : "Email search",
57978
+ subtitle: readableQuery ? truncate(readableQuery, 90) : void 0,
57880
57979
  toolName,
57881
57980
  args: typedArgs,
57882
57981
  result,
57883
- badge: isComplete && emails.length > 0 ? `${emails.length} emails` : void 0,
57982
+ badge: isComplete ? totalCount > 0 ? `${countLabel} email${totalCount === 1 ? "" : "s"}${provider ? ` · ${provider}` : ""}` : "No matches" : void 0,
57884
57983
  error: errorMsg,
57885
- 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((email2, i) => /* @__PURE__ */ jsxs(
57984
+ children: isComplete && emails.length > 0 && /* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 px-4 py-2.5", children: [
57985
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col divide-y divide-border/30", children: inlineEmails.map((email2, i) => /* @__PURE__ */ jsx(EmailResultRow, { email: email2 }, i)) }),
57986
+ overflowEmails.length > 0 && /* @__PURE__ */ jsx(
57987
+ ExpandableSection,
57988
+ {
57989
+ label: `Show ${overflowEmails.length} more`,
57990
+ children: /* @__PURE__ */ jsx("div", { className: "flex flex-col divide-y divide-border/30", children: overflowEmails.map((email2, i) => /* @__PURE__ */ jsx(EmailResultRow, { email: email2 }, i)) })
57991
+ }
57992
+ )
57993
+ ] })
57994
+ }
57995
+ );
57996
+ };
57997
+ const EmailSearchToolUI = memo(
57998
+ EmailSearchToolUIImpl
57999
+ );
58000
+ EmailSearchToolUI.displayName = "EmailSearchToolUI";
58001
+ function parseEmailAccounts(data) {
58002
+ const accounts = data.accounts ?? data.results;
58003
+ if (!Array.isArray(accounts)) return [];
58004
+ return accounts.slice(0, 10).flatMap((raw) => {
58005
+ const item = asRecord(raw);
58006
+ if (!item) return [];
58007
+ const defaultFlag = typeof item.is_default === "boolean" ? item.is_default : item.default;
58008
+ return [
58009
+ {
58010
+ address: asString(item.email_address) ?? asString(item.email) ?? asString(item.address),
58011
+ provider: asString(item.provider) ?? asString(item.provider_name),
58012
+ name: asString(item.account_name) ?? asString(item.name),
58013
+ isDefault: defaultFlag === true
58014
+ }
58015
+ ];
58016
+ });
58017
+ }
58018
+ const EmailAccountsToolUIImpl = ({
58019
+ toolName,
58020
+ args,
58021
+ result,
58022
+ status
58023
+ }) => {
58024
+ const data = useMemo(() => normalizeResult(result), [result]);
58025
+ const accounts = useMemo(
58026
+ () => data ? parseEmailAccounts(data) : [],
58027
+ [data]
58028
+ );
58029
+ const isRunning = (status == null ? void 0 : status.type) === "running";
58030
+ const isComplete = (status == null ? void 0 : status.type) === "complete";
58031
+ const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
58032
+ return /* @__PURE__ */ jsx(
58033
+ ToolCard,
58034
+ {
58035
+ icon: Mail,
58036
+ status: (status == null ? void 0 : status.type) ?? "complete",
58037
+ title: isRunning ? "Checking connected email accounts…" : "Email accounts",
58038
+ toolName,
58039
+ args,
58040
+ result,
58041
+ badge: isComplete && accounts.length > 0 ? `${accounts.length} connected` : void 0,
58042
+ error: errorMsg,
58043
+ children: isComplete && accounts.length > 0 && /* @__PURE__ */ jsx("div", { className: "border-t border-border/40 px-4 py-2.5", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col divide-y divide-border/30", children: accounts.map((account, i) => /* @__PURE__ */ jsxs(
57886
58044
  "div",
57887
58045
  {
57888
- className: cn("flex flex-col gap-0.5 py-2", i === 0 && "pt-0"),
58046
+ className: "flex items-center justify-between gap-2 py-1.5 first:pt-0 last:pb-0",
57889
58047
  children: [
57890
- /* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between gap-2", children: [
57891
- /* @__PURE__ */ jsxs("span", { className: "flex items-baseline gap-1.5 text-[12px] font-medium text-foreground", children: [
57892
- email2.isDraft && /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded bg-amber-100 px-1 py-px text-[9px] font-semibold uppercase tracking-wide text-amber-700", children: "Draft" }),
57893
- email2.subject || "No subject"
57894
- ] }),
57895
- email2.date && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: email2.date })
57896
- ] }),
57897
- email2.from && /* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground", children: email2.from }),
57898
- email2.snippet && /* @__PURE__ */ jsx("p", { className: "text-[11px] leading-relaxed text-muted-foreground/80", children: truncate(email2.snippet, 150) })
58048
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-[12px] text-foreground", children: account.address || account.name || "Unknown account" }),
58049
+ /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1.5", children: [
58050
+ account.isDefault && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-emerald-50 px-1.5 py-px text-[9px] font-semibold uppercase tracking-wide text-emerald-700", children: "Default" }),
58051
+ account.provider && /* @__PURE__ */ jsx("span", { className: "rounded-md bg-muted/60 px-1.5 py-0.5 text-[10px] text-muted-foreground", children: account.provider })
58052
+ ] })
57899
58053
  ]
57900
58054
  },
57901
58055
  i
@@ -57903,10 +58057,10 @@ const EmailSearchToolUIImpl = ({
57903
58057
  }
57904
58058
  );
57905
58059
  };
57906
- const EmailSearchToolUI = memo(
57907
- EmailSearchToolUIImpl
58060
+ const EmailAccountsToolUI = memo(
58061
+ EmailAccountsToolUIImpl
57908
58062
  );
57909
- EmailSearchToolUI.displayName = "EmailSearchToolUI";
58063
+ EmailAccountsToolUI.displayName = "EmailAccountsToolUI";
57910
58064
  function extractAssetId(result) {
57911
58065
  const data = normalizeResult(result);
57912
58066
  if (!data) return null;
@@ -57943,6 +58097,9 @@ function asRecord(value) {
57943
58097
  }
57944
58098
  return value;
57945
58099
  }
58100
+ function asString(value) {
58101
+ return typeof value === "string" ? value : void 0;
58102
+ }
57946
58103
  const PRESENTATION_CODE_SLIDE_NUMBER_KEYS = [
57947
58104
  "slideNumber",
57948
58105
  "slide_number",
@@ -58039,22 +58196,51 @@ function CreateAssetToolUIImpl({
58039
58196
  args: typedArgs,
58040
58197
  result,
58041
58198
  error: errorMsg,
58042
- children: assetId && isComplete && !isCancelled && /* @__PURE__ */ jsx("div", { className: "border-t border-border/40 px-4 py-2", children: /* @__PURE__ */ jsxs(
58199
+ children: assetId && isComplete && !isCancelled && /* @__PURE__ */ jsx("div", { className: "border-t border-border/40 px-4 py-2.5", children: /* @__PURE__ */ jsxs(
58043
58200
  "button",
58044
58201
  {
58045
58202
  type: "button",
58046
58203
  onClick: handleOpen,
58047
- className: "flex items-center gap-1.5 rounded-md border border-border/60 px-3 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground",
58204
+ className: "group flex w-full items-center gap-3 rounded-lg border border-border/60 bg-muted/20 px-3 py-2.5 text-left transition-colors hover:border-border hover:bg-muted/40",
58048
58205
  children: [
58049
- /* @__PURE__ */ jsx(ExternalLink, { className: "size-3" }),
58050
- "Open ",
58051
- assetType === "unknown" ? "asset" : assetType
58206
+ /* @__PURE__ */ jsx(
58207
+ "div",
58208
+ {
58209
+ className: cn(
58210
+ "flex size-10 shrink-0 items-center justify-center rounded-lg",
58211
+ ASSET_TILE_STYLE[assetType] ?? ASSET_TILE_STYLE.unknown
58212
+ ),
58213
+ children: /* @__PURE__ */ jsx(Icon2, { className: "size-5" })
58214
+ }
58215
+ ),
58216
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
58217
+ /* @__PURE__ */ jsx("div", { className: "truncate text-[13px] font-medium text-foreground", children: createdName || name || "Untitled" }),
58218
+ /* @__PURE__ */ jsxs("div", { className: "text-[11px] text-muted-foreground", children: [
58219
+ ASSET_TILE_LABEL[assetType] ?? "Asset",
58220
+ " · Click to open"
58221
+ ] })
58222
+ ] }),
58223
+ /* @__PURE__ */ jsx(ExternalLink, { className: "size-3.5 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100" })
58052
58224
  ]
58053
58225
  }
58054
58226
  ) })
58055
58227
  }
58056
58228
  );
58057
58229
  }
58230
+ const ASSET_TILE_STYLE = {
58231
+ document: "bg-blue-500/10 text-blue-600",
58232
+ spreadsheet: "bg-emerald-500/10 text-emerald-600",
58233
+ presentation: "bg-orange-500/10 text-orange-600",
58234
+ notebook: "bg-violet-500/10 text-violet-600",
58235
+ unknown: "bg-muted text-muted-foreground"
58236
+ };
58237
+ const ASSET_TILE_LABEL = {
58238
+ document: "Document",
58239
+ spreadsheet: "Spreadsheet",
58240
+ presentation: "Presentation",
58241
+ notebook: "Notebook",
58242
+ unknown: "Asset"
58243
+ };
58058
58244
  const CreateDocumentToolUIImpl = (props) => /* @__PURE__ */ jsx(
58059
58245
  CreateAssetToolUIImpl,
58060
58246
  {
@@ -60477,6 +60663,8 @@ const TOOL_UI_REGISTRY = {
60477
60663
  open_browser: OpenBrowserToolUI,
60478
60664
  search_email: EmailSearchToolUI,
60479
60665
  unified_email_search: EmailSearchToolUI,
60666
+ unified_email_list_accounts: EmailAccountsToolUI,
60667
+ email_list_accounts: EmailAccountsToolUI,
60480
60668
  create_email_draft: CreateEmailDraftToolUI,
60481
60669
  unified_email_create_draft: CreateEmailDraftToolUI,
60482
60670
  create_new_document: CreateDocumentToolUI,
@@ -61235,7 +61423,7 @@ function useSendMessage() {
61235
61423
  shouldReplace || !currentText ? text2 : `${currentText}
61236
61424
  ${text2}`
61237
61425
  );
61238
- await aui.composer.send();
61426
+ await aui.composer.send({ steer: false });
61239
61427
  },
61240
61428
  [aui]
61241
61429
  );
@@ -61835,13 +62023,13 @@ const ComposerSendWithQuote = () => {
61835
62023
  });
61836
62024
  if (!fullMessage) return;
61837
62025
  aui.composer.setText(fullMessage);
61838
- aui.composer.send();
62026
+ aui.composer.send({ steer: false });
61839
62027
  clearQuote();
61840
62028
  clearAttachments();
61841
62029
  } else {
61842
62030
  if (!userText) return;
61843
62031
  aui.composer.setText(userText);
61844
- aui.composer.send();
62032
+ aui.composer.send({ steer: false });
61845
62033
  }
61846
62034
  editor == null ? void 0 : editor.clear();
61847
62035
  }, [aui, quote, attachments, hasExtras, isUploading, isThreadRunning, clearQuote, clearAttachments, editorRef, appUrl]);