@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/README.md +123 -3
- package/dist/index.cjs +233 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +233 -45
- package/dist/index.js.map +1 -1
- package/dist/tools/tool-uis.d.ts +18 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -103,9 +103,83 @@ What the statewire transport wires up in `AthenaChat`:
|
|
|
103
103
|
statewire session to the selected thread. `ThreadList` and
|
|
104
104
|
`useAthenaThreadManager` work in both modes.
|
|
105
105
|
|
|
106
|
-
Remaining limitations: the `agent` prop
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
Remaining limitations: on statewire the `agent` prop only accepts
|
|
107
|
+
`collab_agent:<asset_id>` refs (see below) — any other value is ignored,
|
|
108
|
+
because the statewire host always runs the Athena deep agent. `model`
|
|
109
|
+
defaults to the deep-agent default model unless a collab agent supplies one.
|
|
110
|
+
|
|
111
|
+
## Collab Agents
|
|
112
|
+
|
|
113
|
+
A **collab agent** is an agent configuration authored in Athena (prompt,
|
|
114
|
+
model, toolkits, behavior) and addressed as `collab_agent:<asset_id>`. Point
|
|
115
|
+
the provider at one and the chat runs **as** that agent:
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
<AthenaProvider
|
|
119
|
+
transport="statewire"
|
|
120
|
+
agent="collab_agent:asset_432af46f-293d-480b-a518-30b1f42a9ef7"
|
|
121
|
+
channel="askbob_web"
|
|
122
|
+
>
|
|
123
|
+
<AthenaChat />
|
|
124
|
+
</AthenaProvider>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Copy the snippet with real ids from the agent's **Channels** tab in Athena.
|
|
128
|
+
|
|
129
|
+
`channel` is optional. It selects a **channel override layer** — a built-in
|
|
130
|
+
channel (`email`, `sms`, …) or a custom channel defined on that agent — so one
|
|
131
|
+
agent can present different prompts, models, and tools per surface. Omit it to
|
|
132
|
+
run the agent's base configuration.
|
|
133
|
+
|
|
134
|
+
### Requirements
|
|
135
|
+
|
|
136
|
+
- **`transport="statewire"`.** The legacy transport ignores `collab_agent:` refs.
|
|
137
|
+
- **Publish the agent.** Resolution reads the *published* snapshot, not the
|
|
138
|
+
live draft, so a channel that exists only in the editor is rejected with
|
|
139
|
+
`collab_agent_channel_unknown`.
|
|
140
|
+
- **The acting user needs VIEW access** to the agent asset (admins bypass).
|
|
141
|
+
Running as an agent exposes its prompt and tool policy, so the same gate that
|
|
142
|
+
governs opening the asset governs running it.
|
|
143
|
+
|
|
144
|
+
### Do not also pass `model`, `systemPrompt`, or `tools`
|
|
145
|
+
|
|
146
|
+
Request keys override the agent definition, so **anything you pass here
|
|
147
|
+
silently replaces what the agent's author configured** — the run succeeds and
|
|
148
|
+
returns a plausible answer using your config instead of theirs.
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
// ❌ the agent's prompt, model, and tools are all discarded
|
|
152
|
+
<AthenaProvider
|
|
153
|
+
transport="statewire"
|
|
154
|
+
agent="collab_agent:asset_1234"
|
|
155
|
+
model="claude-opus-4-6"
|
|
156
|
+
systemPrompt="You are a helpful assistant."
|
|
157
|
+
tools={['web_search_browse_toolkit']}
|
|
158
|
+
/>
|
|
159
|
+
|
|
160
|
+
// ✅ the agent's own configuration wins
|
|
161
|
+
<AthenaProvider transport="statewire" agent="collab_agent:asset_1234" />
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Pass them only when you deliberately want to override the agent — an explicit
|
|
165
|
+
`model` is honoured as a caller override, with the agent's model as the default
|
|
166
|
+
beneath it.
|
|
167
|
+
|
|
168
|
+
### Failure codes
|
|
169
|
+
|
|
170
|
+
A refused selection surfaces as an `AthenaSdkError` with
|
|
171
|
+
`code: 'collab_agent_rejected'`; the specific reason below rides in the error's
|
|
172
|
+
`detail`. Subscribe with `onError` (see
|
|
173
|
+
[Debugging](#debugging-and-diagnostics)) rather than guessing from messages:
|
|
174
|
+
|
|
175
|
+
| Code | Meaning |
|
|
176
|
+
|---|---|
|
|
177
|
+
| `collab_agent_not_found` | No such asset, or it is not a `collab_agent` |
|
|
178
|
+
| `collab_agent_forbidden` | The acting user lacks VIEW on the asset |
|
|
179
|
+
| `collab_agent_channel_unknown` | No such channel (the message lists the known ones) |
|
|
180
|
+
| `collab_agent_channel_disabled` | The channel exists but is toggled off |
|
|
181
|
+
| `collab_agent_channel_kind_mismatch` | A voice channel was selected for a text run |
|
|
182
|
+
| `collab_agent_runs_disabled` | The deployment has the SDK seam turned off |
|
|
109
183
|
|
|
110
184
|
## Authentication
|
|
111
185
|
|
|
@@ -323,6 +397,52 @@ function WorkflowButton() {
|
|
|
323
397
|
}
|
|
324
398
|
```
|
|
325
399
|
|
|
400
|
+
## Debugging and Diagnostics
|
|
401
|
+
|
|
402
|
+
The SDK emits structured diagnostic events — auth handshake, thread list,
|
|
403
|
+
statewire attach, sends, errors — with timings. Nothing is logged by default;
|
|
404
|
+
turn it on with the `debug` prop:
|
|
405
|
+
|
|
406
|
+
```tsx
|
|
407
|
+
<AthenaProvider
|
|
408
|
+
debug // or 'debug' | 'info' | { console: 'debug', posthog: true }
|
|
409
|
+
onDiagnostic={(event) => console.log(event.name, event.durationMs)}
|
|
410
|
+
onError={(error) => reportToSentry(error)}
|
|
411
|
+
>
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
`onError` receives an `AthenaSdkError` with a stable `code`, a human `hint`,
|
|
415
|
+
and the originating `status`/`detail` — match on `code`, never on message text:
|
|
416
|
+
|
|
417
|
+
```tsx
|
|
418
|
+
import { ATHENA_SDK_ERROR_CODES } from '@athenaintel/react';
|
|
419
|
+
|
|
420
|
+
onError={(error) => {
|
|
421
|
+
if (error.code === ATHENA_SDK_ERROR_CODES.collab_agent_rejected) {
|
|
422
|
+
// the backend's granular reason rides in `detail`, e.g.
|
|
423
|
+
// 'collab_agent_channel_unknown' — whose message lists the known channels
|
|
424
|
+
console.warn(error.detail, error.hint);
|
|
425
|
+
}
|
|
426
|
+
}}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Each provider registers its own consumer, so multiple mounted providers all
|
|
430
|
+
receive every event; a callback that throws is caught and cannot break the chat.
|
|
431
|
+
|
|
432
|
+
Without a rebuild, from the browser console:
|
|
433
|
+
|
|
434
|
+
```js
|
|
435
|
+
localStorage.setItem('athena:debug', 'debug'); // console echo on, survives reload
|
|
436
|
+
__ATHENA_SDK__.diagnostics.snapshot(); // recent events + timings
|
|
437
|
+
__ATHENA_SDK__.diagnostics.export(); // JSON, for attaching to a bug report
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
Credentials are redacted everywhere (buffer, console, PostHog): any key
|
|
441
|
+
matching `token`, `secret`, `api[-_]?key`, `authorization`, `cookie`, or
|
|
442
|
+
`password` is stripped before an event is recorded. Spans also emit
|
|
443
|
+
`performance.mark`/`measure` entries prefixed `athena-sdk:`, so they show up on
|
|
444
|
+
the browser Performance timeline.
|
|
445
|
+
|
|
326
446
|
## License
|
|
327
447
|
|
|
328
448
|
Proprietary. For licensed enterprise customers only.
|
package/dist/index.cjs
CHANGED
|
@@ -72,7 +72,7 @@ function _interopNamespaceDefault(e) {
|
|
|
72
72
|
}
|
|
73
73
|
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
|
|
74
74
|
const ReactDOM__namespace = /* @__PURE__ */ _interopNamespaceDefault(ReactDOM);
|
|
75
|
-
const version$1 = "0.11.
|
|
75
|
+
const version$1 = "0.11.1";
|
|
76
76
|
const packageJson = {
|
|
77
77
|
version: version$1
|
|
78
78
|
};
|
|
@@ -12070,6 +12070,9 @@ function useDeepAgentThread({
|
|
|
12070
12070
|
return statewireTransport(
|
|
12071
12071
|
{
|
|
12072
12072
|
url: `${baseUrl.replace(/\/+$/, "")}/${encodeURIComponent(threadId)}`,
|
|
12073
|
+
// A never-started chat has no server session yet: the transport
|
|
12074
|
+
// makes no network calls until the first command send.
|
|
12075
|
+
...preloadRef.current.preload && { isNew: true },
|
|
12073
12076
|
headers: (ctx) => headersRef.current(ctx),
|
|
12074
12077
|
...sessionStore && { sessionStore }
|
|
12075
12078
|
},
|
|
@@ -56038,13 +56041,13 @@ const TiptapComposer = ({ tools = [], rootCategories }) => {
|
|
|
56038
56041
|
});
|
|
56039
56042
|
if (fullMessage) {
|
|
56040
56043
|
aui.composer.setText(fullMessage);
|
|
56041
|
-
aui.composer.send();
|
|
56044
|
+
aui.composer.send({ steer: false });
|
|
56042
56045
|
clearAttachments();
|
|
56043
56046
|
clearQuote();
|
|
56044
56047
|
}
|
|
56045
56048
|
} else {
|
|
56046
56049
|
aui.composer.setText(markdown);
|
|
56047
|
-
aui.composer.send();
|
|
56050
|
+
aui.composer.send({ steer: false });
|
|
56048
56051
|
}
|
|
56049
56052
|
editor2.commands.clearContent();
|
|
56050
56053
|
}, [aui, clearAttachments, clearQuote, appUrl]);
|
|
@@ -56681,6 +56684,10 @@ const TOOL_META = {
|
|
|
56681
56684
|
// Presentations
|
|
56682
56685
|
create_powerpoint_deck: { displayName: "Building presentation", icon: Monitor },
|
|
56683
56686
|
execute_presentation_code: { displayName: "Generating slides", icon: Monitor },
|
|
56687
|
+
execute_word_document_code: { displayName: "Editing Word document", icon: FileText },
|
|
56688
|
+
execute_spreadsheet_code: { displayName: "Editing spreadsheet", icon: ChartColumn },
|
|
56689
|
+
execute_spreadsheet_commands: { displayName: "Editing spreadsheet", icon: ChartColumn },
|
|
56690
|
+
unified_email_list_accounts: { displayName: "Checking email accounts", icon: Mail },
|
|
56684
56691
|
// Code & Data
|
|
56685
56692
|
run_python_code: { displayName: "Running analysis", icon: Code },
|
|
56686
56693
|
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)}"` : "" },
|
|
@@ -56728,14 +56735,14 @@ function extractResultMessage(result) {
|
|
|
56728
56735
|
return null;
|
|
56729
56736
|
}
|
|
56730
56737
|
function isResultSuccess(result) {
|
|
56731
|
-
|
|
56732
|
-
|
|
56733
|
-
if (
|
|
56734
|
-
|
|
56735
|
-
|
|
56736
|
-
return result.success === true;
|
|
56738
|
+
const obj = typeof result === "string" ? tryParseJson$1(result) : typeof result === "object" && result !== null ? result : null;
|
|
56739
|
+
if (obj) {
|
|
56740
|
+
if (obj.success === false || obj.ok === false) return false;
|
|
56741
|
+
if (typeof obj.error === "string" && obj.error.length > 0) return false;
|
|
56742
|
+
return true;
|
|
56737
56743
|
}
|
|
56738
|
-
return
|
|
56744
|
+
if (typeof result === "string") return !/^\s*error\b/i.test(result);
|
|
56745
|
+
return true;
|
|
56739
56746
|
}
|
|
56740
56747
|
function extractAssetId$1(result) {
|
|
56741
56748
|
if (!result) return null;
|
|
@@ -56900,7 +56907,7 @@ function ToolFallbackTrigger({
|
|
|
56900
56907
|
"span",
|
|
56901
56908
|
{
|
|
56902
56909
|
className: cn(
|
|
56903
|
-
"relative inline-block leading-tight",
|
|
56910
|
+
"relative inline-block text-[13px] font-medium leading-tight",
|
|
56904
56911
|
isCancelled && "text-muted-foreground line-through"
|
|
56905
56912
|
),
|
|
56906
56913
|
children: [
|
|
@@ -57885,17 +57892,103 @@ BrowseToolUI.displayName = "BrowseToolUI";
|
|
|
57885
57892
|
function parseEmailResults(data) {
|
|
57886
57893
|
const results = data.limited_results ?? data.results ?? data.emails ?? data.messages;
|
|
57887
57894
|
if (!Array.isArray(results)) return [];
|
|
57888
|
-
return results.slice(0,
|
|
57889
|
-
const item = r2;
|
|
57890
|
-
return
|
|
57891
|
-
|
|
57892
|
-
|
|
57893
|
-
|
|
57894
|
-
|
|
57895
|
-
|
|
57896
|
-
|
|
57895
|
+
return results.slice(0, 50).flatMap((r2) => {
|
|
57896
|
+
const item = asRecord(r2);
|
|
57897
|
+
if (!item) return [];
|
|
57898
|
+
return [
|
|
57899
|
+
{
|
|
57900
|
+
subject: asString(item.subject) ?? asString(item.title),
|
|
57901
|
+
from: asString(item.from) ?? asString(item.sender) ?? asString(item.from_email),
|
|
57902
|
+
date: asString(item.date) ?? asString(item.received_at) ?? asString(item.sent_at),
|
|
57903
|
+
snippet: asString(item.snippet) ?? asString(item.preview) ?? asString(item.body_preview),
|
|
57904
|
+
isDraft: item.is_draft === true
|
|
57905
|
+
}
|
|
57906
|
+
];
|
|
57897
57907
|
});
|
|
57898
57908
|
}
|
|
57909
|
+
function formatEmailDate(raw) {
|
|
57910
|
+
if (!raw) return void 0;
|
|
57911
|
+
const dateOnly = /^(\d{4})-(\d{2})-(\d{2})$/.exec(raw.trim());
|
|
57912
|
+
const date2 = dateOnly ? new Date(Number(dateOnly[1]), Number(dateOnly[2]) - 1, Number(dateOnly[3])) : new Date(raw);
|
|
57913
|
+
if (Number.isNaN(date2.getTime())) return raw;
|
|
57914
|
+
const now = /* @__PURE__ */ new Date();
|
|
57915
|
+
if (!dateOnly && date2.toDateString() === now.toDateString()) {
|
|
57916
|
+
return date2.toLocaleTimeString(void 0, {
|
|
57917
|
+
hour: "numeric",
|
|
57918
|
+
minute: "2-digit"
|
|
57919
|
+
});
|
|
57920
|
+
}
|
|
57921
|
+
const sameYear = date2.getFullYear() === now.getFullYear();
|
|
57922
|
+
return date2.toLocaleDateString(void 0, {
|
|
57923
|
+
month: "short",
|
|
57924
|
+
day: "numeric",
|
|
57925
|
+
...sameYear ? {} : { year: "numeric" }
|
|
57926
|
+
});
|
|
57927
|
+
}
|
|
57928
|
+
const EMAIL_QUERY_OPERATOR = /(?:^|\s)(received|after|before|from|to|subject|has|in|is):(?:"([^"]+)"|(\S+))/gi;
|
|
57929
|
+
function humanEmailDate(raw) {
|
|
57930
|
+
return formatEmailDate(raw.replace(/\//g, "-")) ?? raw;
|
|
57931
|
+
}
|
|
57932
|
+
function humanizeEmailQuery(query) {
|
|
57933
|
+
if (!query.trim()) return "";
|
|
57934
|
+
const phrases = [];
|
|
57935
|
+
let freeText = query;
|
|
57936
|
+
for (const match2 of query.matchAll(EMAIL_QUERY_OPERATOR)) {
|
|
57937
|
+
const [token, op, quoted, bare] = match2;
|
|
57938
|
+
const value = quoted ?? bare ?? "";
|
|
57939
|
+
freeText = freeText.replace(token, " ");
|
|
57940
|
+
switch (op.toLowerCase()) {
|
|
57941
|
+
case "received": {
|
|
57942
|
+
const [start, end] = value.split("..");
|
|
57943
|
+
phrases.push(
|
|
57944
|
+
end ? `${humanEmailDate(start)} – ${humanEmailDate(end)}` : humanEmailDate(start)
|
|
57945
|
+
);
|
|
57946
|
+
break;
|
|
57947
|
+
}
|
|
57948
|
+
case "after":
|
|
57949
|
+
phrases.push(`after ${humanEmailDate(value)}`);
|
|
57950
|
+
break;
|
|
57951
|
+
case "before":
|
|
57952
|
+
phrases.push(`before ${humanEmailDate(value)}`);
|
|
57953
|
+
break;
|
|
57954
|
+
case "from":
|
|
57955
|
+
phrases.push(`from ${value}`);
|
|
57956
|
+
break;
|
|
57957
|
+
case "to":
|
|
57958
|
+
phrases.push(`to ${value}`);
|
|
57959
|
+
break;
|
|
57960
|
+
case "subject":
|
|
57961
|
+
phrases.push(`subject “${value}”`);
|
|
57962
|
+
break;
|
|
57963
|
+
case "has":
|
|
57964
|
+
phrases.push(value === "attachment" ? "with attachments" : `has ${value}`);
|
|
57965
|
+
break;
|
|
57966
|
+
case "in":
|
|
57967
|
+
phrases.push(value === "drafts" ? "drafts only" : `in ${value}`);
|
|
57968
|
+
break;
|
|
57969
|
+
case "is":
|
|
57970
|
+
phrases.push(value);
|
|
57971
|
+
break;
|
|
57972
|
+
}
|
|
57973
|
+
}
|
|
57974
|
+
const remainder = freeText.trim().replace(/\s+/g, " ");
|
|
57975
|
+
if (remainder) phrases.push(`“${remainder}”`);
|
|
57976
|
+
return phrases.join(" · ");
|
|
57977
|
+
}
|
|
57978
|
+
const INLINE_EMAIL_ROWS = 3;
|
|
57979
|
+
function EmailResultRow({ email: email2 }) {
|
|
57980
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5 py-2 first:pt-0 last:pb-0", children: [
|
|
57981
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
57982
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-baseline gap-1.5 text-[12px] font-medium text-foreground", children: [
|
|
57983
|
+
email2.isDraft && /* @__PURE__ */ jsxRuntime.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" }),
|
|
57984
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: email2.subject || "No subject" })
|
|
57985
|
+
] }),
|
|
57986
|
+
email2.date && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: formatEmailDate(email2.date) })
|
|
57987
|
+
] }),
|
|
57988
|
+
email2.from && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[11px] text-muted-foreground", children: email2.from }),
|
|
57989
|
+
email2.snippet && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] leading-relaxed text-muted-foreground/80", children: truncate(email2.snippet, 150) })
|
|
57990
|
+
] });
|
|
57991
|
+
}
|
|
57899
57992
|
const EmailSearchToolUIImpl = ({
|
|
57900
57993
|
toolName,
|
|
57901
57994
|
args,
|
|
@@ -57906,35 +57999,96 @@ const EmailSearchToolUIImpl = ({
|
|
|
57906
57999
|
const query = (typedArgs == null ? void 0 : typedArgs.query) ?? (typedArgs == null ? void 0 : typedArgs.search_query) ?? "";
|
|
57907
58000
|
const data = React.useMemo(() => normalizeResult(result), [result]);
|
|
57908
58001
|
const emails = React.useMemo(() => data ? parseEmailResults(data) : [], [data]);
|
|
58002
|
+
const provider = typeof (data == null ? void 0 : data.provider) === "string" ? data.provider : void 0;
|
|
58003
|
+
const totalCount = typeof (data == null ? void 0 : data.count) === "number" ? data.count : emails.length;
|
|
57909
58004
|
const isRunning = (status == null ? void 0 : status.type) === "running";
|
|
57910
58005
|
const isComplete = (status == null ? void 0 : status.type) === "complete";
|
|
57911
58006
|
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
|
|
58007
|
+
const readableQuery = React.useMemo(() => humanizeEmailQuery(query), [query]);
|
|
58008
|
+
const inlineEmails = emails.slice(0, INLINE_EMAIL_ROWS);
|
|
58009
|
+
const overflowEmails = emails.slice(INLINE_EMAIL_ROWS);
|
|
58010
|
+
const countLabel = emails.length > 0 && totalCount > emails.length ? `${emails.length} of ${totalCount}` : `${totalCount}`;
|
|
57912
58011
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
57913
58012
|
ToolCard,
|
|
57914
58013
|
{
|
|
57915
58014
|
icon: Mail,
|
|
57916
58015
|
status: (status == null ? void 0 : status.type) ?? "complete",
|
|
57917
|
-
title: isRunning ? "Searching
|
|
57918
|
-
subtitle:
|
|
58016
|
+
title: isRunning ? "Searching email…" : "Email search",
|
|
58017
|
+
subtitle: readableQuery ? truncate(readableQuery, 90) : void 0,
|
|
57919
58018
|
toolName,
|
|
57920
58019
|
args: typedArgs,
|
|
57921
58020
|
result,
|
|
57922
|
-
badge: isComplete
|
|
58021
|
+
badge: isComplete ? totalCount > 0 ? `${countLabel} email${totalCount === 1 ? "" : "s"}${provider ? ` · ${provider}` : ""}` : "No matches" : void 0,
|
|
57923
58022
|
error: errorMsg,
|
|
57924
|
-
children: isComplete && emails.length > 0 && /* @__PURE__ */ jsxRuntime.
|
|
58023
|
+
children: isComplete && emails.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-border/40 px-4 py-2.5", children: [
|
|
58024
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col divide-y divide-border/30", children: inlineEmails.map((email2, i) => /* @__PURE__ */ jsxRuntime.jsx(EmailResultRow, { email: email2 }, i)) }),
|
|
58025
|
+
overflowEmails.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
58026
|
+
ExpandableSection,
|
|
58027
|
+
{
|
|
58028
|
+
label: `Show ${overflowEmails.length} more`,
|
|
58029
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col divide-y divide-border/30", children: overflowEmails.map((email2, i) => /* @__PURE__ */ jsxRuntime.jsx(EmailResultRow, { email: email2 }, i)) })
|
|
58030
|
+
}
|
|
58031
|
+
)
|
|
58032
|
+
] })
|
|
58033
|
+
}
|
|
58034
|
+
);
|
|
58035
|
+
};
|
|
58036
|
+
const EmailSearchToolUI = React.memo(
|
|
58037
|
+
EmailSearchToolUIImpl
|
|
58038
|
+
);
|
|
58039
|
+
EmailSearchToolUI.displayName = "EmailSearchToolUI";
|
|
58040
|
+
function parseEmailAccounts(data) {
|
|
58041
|
+
const accounts = data.accounts ?? data.results;
|
|
58042
|
+
if (!Array.isArray(accounts)) return [];
|
|
58043
|
+
return accounts.slice(0, 10).flatMap((raw) => {
|
|
58044
|
+
const item = asRecord(raw);
|
|
58045
|
+
if (!item) return [];
|
|
58046
|
+
const defaultFlag = typeof item.is_default === "boolean" ? item.is_default : item.default;
|
|
58047
|
+
return [
|
|
58048
|
+
{
|
|
58049
|
+
address: asString(item.email_address) ?? asString(item.email) ?? asString(item.address),
|
|
58050
|
+
provider: asString(item.provider) ?? asString(item.provider_name),
|
|
58051
|
+
name: asString(item.account_name) ?? asString(item.name),
|
|
58052
|
+
isDefault: defaultFlag === true
|
|
58053
|
+
}
|
|
58054
|
+
];
|
|
58055
|
+
});
|
|
58056
|
+
}
|
|
58057
|
+
const EmailAccountsToolUIImpl = ({
|
|
58058
|
+
toolName,
|
|
58059
|
+
args,
|
|
58060
|
+
result,
|
|
58061
|
+
status
|
|
58062
|
+
}) => {
|
|
58063
|
+
const data = React.useMemo(() => normalizeResult(result), [result]);
|
|
58064
|
+
const accounts = React.useMemo(
|
|
58065
|
+
() => data ? parseEmailAccounts(data) : [],
|
|
58066
|
+
[data]
|
|
58067
|
+
);
|
|
58068
|
+
const isRunning = (status == null ? void 0 : status.type) === "running";
|
|
58069
|
+
const isComplete = (status == null ? void 0 : status.type) === "complete";
|
|
58070
|
+
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
|
|
58071
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
58072
|
+
ToolCard,
|
|
58073
|
+
{
|
|
58074
|
+
icon: Mail,
|
|
58075
|
+
status: (status == null ? void 0 : status.type) ?? "complete",
|
|
58076
|
+
title: isRunning ? "Checking connected email accounts…" : "Email accounts",
|
|
58077
|
+
toolName,
|
|
58078
|
+
args,
|
|
58079
|
+
result,
|
|
58080
|
+
badge: isComplete && accounts.length > 0 ? `${accounts.length} connected` : void 0,
|
|
58081
|
+
error: errorMsg,
|
|
58082
|
+
children: isComplete && accounts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border/40 px-4 py-2.5", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col divide-y divide-border/30", children: accounts.map((account, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
57925
58083
|
"div",
|
|
57926
58084
|
{
|
|
57927
|
-
className:
|
|
58085
|
+
className: "flex items-center justify-between gap-2 py-1.5 first:pt-0 last:pb-0",
|
|
57928
58086
|
children: [
|
|
57929
|
-
/* @__PURE__ */ jsxRuntime.
|
|
57930
|
-
|
|
57931
|
-
|
|
57932
|
-
|
|
57933
|
-
|
|
57934
|
-
email2.date && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: email2.date })
|
|
57935
|
-
] }),
|
|
57936
|
-
email2.from && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] text-muted-foreground", children: email2.from }),
|
|
57937
|
-
email2.snippet && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] leading-relaxed text-muted-foreground/80", children: truncate(email2.snippet, 150) })
|
|
58087
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate text-[12px] text-foreground", children: account.address || account.name || "Unknown account" }),
|
|
58088
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
58089
|
+
account.isDefault && /* @__PURE__ */ jsxRuntime.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" }),
|
|
58090
|
+
account.provider && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-md bg-muted/60 px-1.5 py-0.5 text-[10px] text-muted-foreground", children: account.provider })
|
|
58091
|
+
] })
|
|
57938
58092
|
]
|
|
57939
58093
|
},
|
|
57940
58094
|
i
|
|
@@ -57942,10 +58096,10 @@ const EmailSearchToolUIImpl = ({
|
|
|
57942
58096
|
}
|
|
57943
58097
|
);
|
|
57944
58098
|
};
|
|
57945
|
-
const
|
|
57946
|
-
|
|
58099
|
+
const EmailAccountsToolUI = React.memo(
|
|
58100
|
+
EmailAccountsToolUIImpl
|
|
57947
58101
|
);
|
|
57948
|
-
|
|
58102
|
+
EmailAccountsToolUI.displayName = "EmailAccountsToolUI";
|
|
57949
58103
|
function extractAssetId(result) {
|
|
57950
58104
|
const data = normalizeResult(result);
|
|
57951
58105
|
if (!data) return null;
|
|
@@ -57982,6 +58136,9 @@ function asRecord(value) {
|
|
|
57982
58136
|
}
|
|
57983
58137
|
return value;
|
|
57984
58138
|
}
|
|
58139
|
+
function asString(value) {
|
|
58140
|
+
return typeof value === "string" ? value : void 0;
|
|
58141
|
+
}
|
|
57985
58142
|
const PRESENTATION_CODE_SLIDE_NUMBER_KEYS = [
|
|
57986
58143
|
"slideNumber",
|
|
57987
58144
|
"slide_number",
|
|
@@ -58078,22 +58235,51 @@ function CreateAssetToolUIImpl({
|
|
|
58078
58235
|
args: typedArgs,
|
|
58079
58236
|
result,
|
|
58080
58237
|
error: errorMsg,
|
|
58081
|
-
children: assetId && isComplete && !isCancelled && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border/40 px-4 py-2", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
58238
|
+
children: assetId && isComplete && !isCancelled && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border/40 px-4 py-2.5", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
58082
58239
|
"button",
|
|
58083
58240
|
{
|
|
58084
58241
|
type: "button",
|
|
58085
58242
|
onClick: handleOpen,
|
|
58086
|
-
className: "flex items-center gap-
|
|
58243
|
+
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",
|
|
58087
58244
|
children: [
|
|
58088
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
58089
|
-
|
|
58090
|
-
|
|
58245
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
58246
|
+
"div",
|
|
58247
|
+
{
|
|
58248
|
+
className: cn(
|
|
58249
|
+
"flex size-10 shrink-0 items-center justify-center rounded-lg",
|
|
58250
|
+
ASSET_TILE_STYLE[assetType] ?? ASSET_TILE_STYLE.unknown
|
|
58251
|
+
),
|
|
58252
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "size-5" })
|
|
58253
|
+
}
|
|
58254
|
+
),
|
|
58255
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
58256
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-[13px] font-medium text-foreground", children: createdName || name || "Untitled" }),
|
|
58257
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[11px] text-muted-foreground", children: [
|
|
58258
|
+
ASSET_TILE_LABEL[assetType] ?? "Asset",
|
|
58259
|
+
" · Click to open"
|
|
58260
|
+
] })
|
|
58261
|
+
] }),
|
|
58262
|
+
/* @__PURE__ */ jsxRuntime.jsx(ExternalLink, { className: "size-3.5 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100" })
|
|
58091
58263
|
]
|
|
58092
58264
|
}
|
|
58093
58265
|
) })
|
|
58094
58266
|
}
|
|
58095
58267
|
);
|
|
58096
58268
|
}
|
|
58269
|
+
const ASSET_TILE_STYLE = {
|
|
58270
|
+
document: "bg-blue-500/10 text-blue-600",
|
|
58271
|
+
spreadsheet: "bg-emerald-500/10 text-emerald-600",
|
|
58272
|
+
presentation: "bg-orange-500/10 text-orange-600",
|
|
58273
|
+
notebook: "bg-violet-500/10 text-violet-600",
|
|
58274
|
+
unknown: "bg-muted text-muted-foreground"
|
|
58275
|
+
};
|
|
58276
|
+
const ASSET_TILE_LABEL = {
|
|
58277
|
+
document: "Document",
|
|
58278
|
+
spreadsheet: "Spreadsheet",
|
|
58279
|
+
presentation: "Presentation",
|
|
58280
|
+
notebook: "Notebook",
|
|
58281
|
+
unknown: "Asset"
|
|
58282
|
+
};
|
|
58097
58283
|
const CreateDocumentToolUIImpl = (props) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
58098
58284
|
CreateAssetToolUIImpl,
|
|
58099
58285
|
{
|
|
@@ -60516,6 +60702,8 @@ const TOOL_UI_REGISTRY = {
|
|
|
60516
60702
|
open_browser: OpenBrowserToolUI,
|
|
60517
60703
|
search_email: EmailSearchToolUI,
|
|
60518
60704
|
unified_email_search: EmailSearchToolUI,
|
|
60705
|
+
unified_email_list_accounts: EmailAccountsToolUI,
|
|
60706
|
+
email_list_accounts: EmailAccountsToolUI,
|
|
60519
60707
|
create_email_draft: CreateEmailDraftToolUI,
|
|
60520
60708
|
unified_email_create_draft: CreateEmailDraftToolUI,
|
|
60521
60709
|
create_new_document: CreateDocumentToolUI,
|
|
@@ -61274,7 +61462,7 @@ function useSendMessage() {
|
|
|
61274
61462
|
shouldReplace || !currentText ? text2 : `${currentText}
|
|
61275
61463
|
${text2}`
|
|
61276
61464
|
);
|
|
61277
|
-
await aui.composer.send();
|
|
61465
|
+
await aui.composer.send({ steer: false });
|
|
61278
61466
|
},
|
|
61279
61467
|
[aui]
|
|
61280
61468
|
);
|
|
@@ -61874,13 +62062,13 @@ const ComposerSendWithQuote = () => {
|
|
|
61874
62062
|
});
|
|
61875
62063
|
if (!fullMessage) return;
|
|
61876
62064
|
aui.composer.setText(fullMessage);
|
|
61877
|
-
aui.composer.send();
|
|
62065
|
+
aui.composer.send({ steer: false });
|
|
61878
62066
|
clearQuote();
|
|
61879
62067
|
clearAttachments();
|
|
61880
62068
|
} else {
|
|
61881
62069
|
if (!userText) return;
|
|
61882
62070
|
aui.composer.setText(userText);
|
|
61883
|
-
aui.composer.send();
|
|
62071
|
+
aui.composer.send({ steer: false });
|
|
61884
62072
|
}
|
|
61885
62073
|
editor == null ? void 0 : editor.clear();
|
|
61886
62074
|
}, [aui, quote, attachments, hasExtras, isUploading, isThreadRunning, clearQuote, clearAttachments, editorRef, appUrl]);
|