@arbidocs/react 0.4.3 → 0.4.4
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 +22 -0
- package/dist/index.cjs +384 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1522 -82
- package/dist/index.d.ts +1522 -82
- package/dist/index.js +363 -21
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { formatRelativeTime } from './chunk-EJ2BMHYK.js';
|
|
2
2
|
export { DEFAULT_NOTIFY_TONE, NotificationBell, Toaster, formatRelativeTime, notify, seedNotifications, selectUnread, toast, useNotify } from './chunk-EJ2BMHYK.js';
|
|
3
|
-
import { normalizeCitationMarkup, MarkMenu, AiMarkdown, Card, Button, Badge, TagEntity, MarkdownRenderer, Input, FILE_TYPE_COLORS, getEntityIcon, UserEntity, getEntityColorStyles, AgentBadge, Textarea, Slider, Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DocumentEntity, DocumentCard, useAudioRecorder, MicWaveformIndicator, IconToggle, classifyMediaError, formatElapsed, PassageCard } from './chunk-MIJRORQL.js';
|
|
3
|
+
import { normalizeCitationMarkup, MarkMenu, AiMarkdown, Card, Button, Badge, TagEntity, MarkdownRenderer, Input, FILE_TYPE_COLORS, getEntityIcon, UserEntity, getEntityColorStyles, AgentBadge, Textarea, Label, Slider, Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DocumentEntity, DocumentCard, useAudioRecorder, MicWaveformIndicator, IconToggle, classifyMediaError, formatElapsed, PassageCard } from './chunk-MIJRORQL.js';
|
|
4
4
|
export { AgentBadge, AiMarkdown, ArbiBotHeadIcon, AudIcon, Avatar, AvatarFallback, AvatarImage, BASE_COLORS, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DictateProvider, DocumentCard, DocumentEntity, ENTITY_MAPPINGS, EmlIcon, EntityIcon, EntityPill, FILE_TYPE_COLORS, HoverCard, HoverCardContent, HoverCardTrigger, IconToggle, ImgIcon, InlineMicButton, Input, Label, MarkMenu, MarkdownRenderer, MarkdownStreamingContext, MicRecordingOverlay, MicWaveformIndicator, NEUTRAL_GRAY, PLACEHOLDER_COLOR, PassageCard, PdfIcon, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PresenceLabel, Progress, ProjectEntity, RadioGroup, RadioGroupItem, RagDot, RelevanceDot, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Slider, StatusPill, Switch, TAG_TYPE_ICONS, TAG_TYPE_LABELS, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TagEntity, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserEntity, UserMenu, VISIBILITY_ICONS, VidIcon, VisibilityIcon, badgeVariants, buttonVariants, cardVariants, configureEntityRegistry, configureRagLabels, configureStatusRegistry, formatElapsed, getDocIcon, getEntityColor, getEntityColorStyles, getEntityIcon, getEntityLabel, getStatusVariant, getTagTypeIcon, getTagTypeLabel, getWorkspaceColor, markdownBaseComponents, normalizeCitationMarkup, splitMarkdownBlocks, toggleVariants, useAudioRecorder } from './chunk-MIJRORQL.js';
|
|
5
5
|
import { cn, ScrollArea, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator } from './chunk-6ALMBER7.js';
|
|
6
6
|
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, ScrollArea, ScrollBar, cn } from './chunk-6ALMBER7.js';
|
|
@@ -23,6 +23,23 @@ import Cropper from 'react-easy-crop';
|
|
|
23
23
|
import { AgGridReact } from 'ag-grid-react';
|
|
24
24
|
import { ModuleRegistry, AllCommunityModule } from 'ag-grid-community';
|
|
25
25
|
|
|
26
|
+
// src/credits.ts
|
|
27
|
+
var DEFAULT_USD_PER_CREDIT = 0.01;
|
|
28
|
+
function formatCredits(credits, options = {}) {
|
|
29
|
+
const { unit = true, locale = "en-US" } = options;
|
|
30
|
+
const whole = Math.round(Number.isFinite(credits) ? credits : 0);
|
|
31
|
+
const digits = whole.toLocaleString(locale);
|
|
32
|
+
return unit ? `${digits} ${whole === 1 ? "credit" : "credits"}` : digits;
|
|
33
|
+
}
|
|
34
|
+
function creditsToUsd(credits, usdPerCredit = DEFAULT_USD_PER_CREDIT) {
|
|
35
|
+
return credits * usdPerCredit;
|
|
36
|
+
}
|
|
37
|
+
function isUsageMetered(usage, subscription) {
|
|
38
|
+
const empty = usage.total_spend === 0 && usage.total_tokens === 0 && usage.total_requests === 0;
|
|
39
|
+
return !(empty && subscription === "dev");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/hooks.ts
|
|
26
43
|
var arbiQueryKeys = {
|
|
27
44
|
workspaces: () => ["arbi", "workspaces"],
|
|
28
45
|
documents: (workspaceId) => ["arbi", "documents", workspaceId],
|
|
@@ -40,7 +57,14 @@ var arbiQueryKeys = {
|
|
|
40
57
|
projects: () => ["arbi", "projects"],
|
|
41
58
|
projectUsage: (projectExtId, monthsBack) => ["arbi", "projectUsage", projectExtId, monthsBack],
|
|
42
59
|
projectInvoices: (projectExtId) => ["arbi", "projectInvoices", projectExtId],
|
|
43
|
-
userUsageToday: () => ["arbi", "userUsageToday"]
|
|
60
|
+
userUsageToday: () => ["arbi", "userUsageToday"],
|
|
61
|
+
contacts: () => ["arbi", "contacts"],
|
|
62
|
+
skills: () => ["arbi", "skills"],
|
|
63
|
+
taskRuns: (taskId) => ["arbi", "taskRuns", taskId],
|
|
64
|
+
/** An agent's pinned config; `undefined` = the library default config. */
|
|
65
|
+
agentConfig: (agentExtId) => ["arbi", "agentConfig", agentExtId ?? "default"],
|
|
66
|
+
agentWorkspaces: (agentExtId) => ["arbi", "agentWorkspaces", agentExtId],
|
|
67
|
+
models: () => ["arbi", "models"]
|
|
44
68
|
};
|
|
45
69
|
function useWorkspaces(options) {
|
|
46
70
|
const arbi = useArbi();
|
|
@@ -169,15 +193,20 @@ function useProjects(options) {
|
|
|
169
193
|
}
|
|
170
194
|
function useProjectUsage(projectExtId, monthsBack = 0, options) {
|
|
171
195
|
const arbi = useArbi();
|
|
172
|
-
|
|
196
|
+
const usage = useQuery({
|
|
173
197
|
queryKey: arbiQueryKeys.projectUsage(projectExtId ?? "", monthsBack),
|
|
174
198
|
queryFn: () => arbi.projects.usage(projectExtId, monthsBack),
|
|
175
199
|
enabled: (options?.enabled ?? true) && !!projectExtId && arbi.isLoggedIn
|
|
176
200
|
});
|
|
201
|
+
const projects = useProjects({ enabled: !!projectExtId && (options?.enabled ?? true) });
|
|
202
|
+
const subscription = projects.data?.find((p) => p.external_id === projectExtId)?.subscription;
|
|
203
|
+
const metered = usage.data ? isUsageMetered(usage.data, subscription) : void 0;
|
|
204
|
+
return { ...usage, metered };
|
|
177
205
|
}
|
|
178
206
|
function useProjectsUsage(projectExtIds, monthsBack = 0, options) {
|
|
179
207
|
const arbi = useArbi();
|
|
180
208
|
const enabled = (options?.enabled ?? true) && arbi.isLoggedIn;
|
|
209
|
+
const projects = useProjects({ enabled: enabled && projectExtIds.length > 0 });
|
|
181
210
|
const results = useQueries({
|
|
182
211
|
queries: projectExtIds.map((id) => ({
|
|
183
212
|
queryKey: arbiQueryKeys.projectUsage(id, monthsBack),
|
|
@@ -185,27 +214,34 @@ function useProjectsUsage(projectExtIds, monthsBack = 0, options) {
|
|
|
185
214
|
enabled: enabled && !!id
|
|
186
215
|
}))
|
|
187
216
|
});
|
|
188
|
-
const signature = results.map((r) => `${r.status}:${r.dataUpdatedAt ?? 0}`).join("|")
|
|
217
|
+
const signature = results.map((r) => `${r.status}:${r.dataUpdatedAt ?? 0}`).join("|") + `#${projects.dataUpdatedAt}`;
|
|
189
218
|
return useMemo(() => {
|
|
190
219
|
const dailyMap = /* @__PURE__ */ new Map();
|
|
191
220
|
const modelMap = /* @__PURE__ */ new Map();
|
|
192
|
-
let
|
|
221
|
+
let totalCredits = 0;
|
|
222
|
+
let anyData = false;
|
|
223
|
+
let anyMetered = false;
|
|
193
224
|
let totalTokens = 0;
|
|
194
225
|
let totalRequests = 0;
|
|
195
|
-
|
|
226
|
+
results.forEach((r, i) => {
|
|
196
227
|
const d = r.data;
|
|
197
|
-
if (!d)
|
|
198
|
-
|
|
228
|
+
if (!d) return;
|
|
229
|
+
anyData = true;
|
|
230
|
+
const subscription = projects.data?.find(
|
|
231
|
+
(p) => p.external_id === projectExtIds[i]
|
|
232
|
+
)?.subscription;
|
|
233
|
+
if (isUsageMetered(d, subscription)) anyMetered = true;
|
|
234
|
+
totalCredits += d.total_spend ?? 0;
|
|
199
235
|
totalTokens += d.total_tokens ?? 0;
|
|
200
236
|
totalRequests += d.total_requests ?? 0;
|
|
201
237
|
for (const day of d.daily ?? []) {
|
|
202
238
|
const cur = dailyMap.get(day.date) ?? {
|
|
203
239
|
date: day.date,
|
|
204
|
-
|
|
240
|
+
credits: 0,
|
|
205
241
|
totalTokens: 0,
|
|
206
242
|
apiRequests: 0
|
|
207
243
|
};
|
|
208
|
-
cur.
|
|
244
|
+
cur.credits += day.spend ?? 0;
|
|
209
245
|
cur.totalTokens += day.total_tokens ?? 0;
|
|
210
246
|
cur.apiRequests += day.api_requests ?? 0;
|
|
211
247
|
dailyMap.set(day.date, cur);
|
|
@@ -213,28 +249,29 @@ function useProjectsUsage(projectExtIds, monthsBack = 0, options) {
|
|
|
213
249
|
for (const [model, mg] of Object.entries(d.model_groups ?? {})) {
|
|
214
250
|
const cur = modelMap.get(model) ?? {
|
|
215
251
|
model,
|
|
216
|
-
|
|
252
|
+
credits: 0,
|
|
217
253
|
totalTokens: 0,
|
|
218
254
|
promptTokens: 0,
|
|
219
255
|
completionTokens: 0,
|
|
220
256
|
successfulRequests: 0
|
|
221
257
|
};
|
|
222
|
-
cur.
|
|
258
|
+
cur.credits += mg.spend ?? 0;
|
|
223
259
|
cur.totalTokens += mg.total_tokens ?? 0;
|
|
224
260
|
cur.promptTokens += mg.prompt_tokens ?? 0;
|
|
225
261
|
cur.completionTokens += mg.completion_tokens ?? 0;
|
|
226
262
|
cur.successfulRequests += mg.successful_requests ?? 0;
|
|
227
263
|
modelMap.set(model, cur);
|
|
228
264
|
}
|
|
229
|
-
}
|
|
265
|
+
});
|
|
230
266
|
return {
|
|
231
|
-
|
|
267
|
+
totalCredits,
|
|
232
268
|
totalTokens,
|
|
233
269
|
totalRequests,
|
|
234
270
|
daily: [...dailyMap.values()].sort((a, b) => a.date.localeCompare(b.date)),
|
|
235
271
|
modelGroups: [...modelMap.values()].sort(
|
|
236
|
-
(a, b) => b.
|
|
272
|
+
(a, b) => b.credits - a.credits || b.totalTokens - a.totalTokens
|
|
237
273
|
),
|
|
274
|
+
metered: !anyData || anyMetered,
|
|
238
275
|
isLoading: results.some((r) => r.isLoading),
|
|
239
276
|
isError: results.some((r) => r.isError)
|
|
240
277
|
};
|
|
@@ -890,6 +927,186 @@ function useArbiShellWorkspaces(options = {}) {
|
|
|
890
927
|
select: select ?? defaultSelect
|
|
891
928
|
});
|
|
892
929
|
}
|
|
930
|
+
function useCreateTask() {
|
|
931
|
+
const arbi = useArbi();
|
|
932
|
+
const qc = useQueryClient();
|
|
933
|
+
return useMutation({
|
|
934
|
+
mutationFn: (body) => arbi.tasks.create(body),
|
|
935
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.tasks() })
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
function useUpdateTask() {
|
|
939
|
+
const arbi = useArbi();
|
|
940
|
+
const qc = useQueryClient();
|
|
941
|
+
return useMutation({
|
|
942
|
+
mutationFn: ({ taskId, patch }) => arbi.tasks.update(taskId, patch),
|
|
943
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.tasks() })
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
function useRunTask() {
|
|
947
|
+
const arbi = useArbi();
|
|
948
|
+
const qc = useQueryClient();
|
|
949
|
+
return useMutation({
|
|
950
|
+
mutationFn: (taskId) => arbi.tasks.runWithAuth(taskId),
|
|
951
|
+
onSuccess: (_task, taskId) => Promise.all([
|
|
952
|
+
qc.invalidateQueries({ queryKey: arbiQueryKeys.tasks() }),
|
|
953
|
+
qc.invalidateQueries({ queryKey: arbiQueryKeys.taskRuns(taskId) })
|
|
954
|
+
])
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
function useDeleteTask() {
|
|
958
|
+
const arbi = useArbi();
|
|
959
|
+
const qc = useQueryClient();
|
|
960
|
+
return useMutation({
|
|
961
|
+
mutationFn: (taskId) => arbi.tasks.delete(taskId),
|
|
962
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.tasks() })
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
function useTaskRuns(taskId, options) {
|
|
966
|
+
const arbi = useArbi();
|
|
967
|
+
return useQuery({
|
|
968
|
+
queryKey: arbiQueryKeys.taskRuns(taskId ?? ""),
|
|
969
|
+
queryFn: () => arbi.tasks.listRuns(taskId),
|
|
970
|
+
enabled: (options?.enabled ?? true) && !!taskId && arbi.isLoggedIn,
|
|
971
|
+
refetchInterval: (q) => q.state.data?.some((r) => r.status === "running") ? 3e3 : false
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
function useCreateAgent() {
|
|
975
|
+
const arbi = useArbi();
|
|
976
|
+
const qc = useQueryClient();
|
|
977
|
+
return useMutation({
|
|
978
|
+
mutationFn: (name) => arbi.agents.create(name),
|
|
979
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.agents() })
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
function useAgentConfig(agentExtId, options) {
|
|
983
|
+
const arbi = useArbi();
|
|
984
|
+
return useQuery({
|
|
985
|
+
queryKey: arbiQueryKeys.agentConfig(agentExtId),
|
|
986
|
+
queryFn: async () => agentExtId ? await arbi.agents.getConfig(agentExtId) : await arbi.agentConfig.get("default"),
|
|
987
|
+
enabled: (options?.enabled ?? true) && arbi.isLoggedIn
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
function useAgentModels(options) {
|
|
991
|
+
const arbi = useArbi();
|
|
992
|
+
return useQuery({
|
|
993
|
+
queryKey: arbiQueryKeys.models(),
|
|
994
|
+
queryFn: async () => (await arbi.agentConfig.getModels()).models.map((m) => m.model_name),
|
|
995
|
+
enabled: (options?.enabled ?? true) && arbi.isLoggedIn
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
function useSaveAgentConfig() {
|
|
999
|
+
const arbi = useArbi();
|
|
1000
|
+
const qc = useQueryClient();
|
|
1001
|
+
return useMutation({
|
|
1002
|
+
mutationFn: async ({ agentExtId, title, sections }) => {
|
|
1003
|
+
const pinned = await arbi.agents.getConfig(agentExtId);
|
|
1004
|
+
const base = pinned ?? await arbi.agentConfig.get("default");
|
|
1005
|
+
const merged = structuredClone(base);
|
|
1006
|
+
for (const [section, params] of Object.entries(sections)) {
|
|
1007
|
+
merged[section] = { ...merged[section] ?? {}, ...params };
|
|
1008
|
+
}
|
|
1009
|
+
return arbi.agentConfig.save({
|
|
1010
|
+
...merged,
|
|
1011
|
+
agent_ext_id: agentExtId,
|
|
1012
|
+
title: title ?? `agent-${agentExtId}`
|
|
1013
|
+
});
|
|
1014
|
+
},
|
|
1015
|
+
onSuccess: (_saved, { agentExtId }) => Promise.all([
|
|
1016
|
+
qc.invalidateQueries({ queryKey: arbiQueryKeys.configs() }),
|
|
1017
|
+
qc.invalidateQueries({ queryKey: arbiQueryKeys.agentConfig(agentExtId) })
|
|
1018
|
+
])
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
function useAgentWorkspaces(agentExtId, options) {
|
|
1022
|
+
const arbi = useArbi();
|
|
1023
|
+
return useQuery({
|
|
1024
|
+
queryKey: arbiQueryKeys.agentWorkspaces(agentExtId ?? ""),
|
|
1025
|
+
queryFn: () => arbi.agents.listWorkspaces(agentExtId),
|
|
1026
|
+
enabled: (options?.enabled ?? true) && !!agentExtId && arbi.isLoggedIn
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
1029
|
+
function useGrantAgentAccess() {
|
|
1030
|
+
const arbi = useArbi();
|
|
1031
|
+
const qc = useQueryClient();
|
|
1032
|
+
return useMutation({
|
|
1033
|
+
mutationFn: async ({
|
|
1034
|
+
agentExtId,
|
|
1035
|
+
workspaceId,
|
|
1036
|
+
mode = { kind: "standing" }
|
|
1037
|
+
}) => {
|
|
1038
|
+
if (mode.kind === "temporary") {
|
|
1039
|
+
return arbi.agents.grantTemporaryAccess(agentExtId, workspaceId, mode.ttlSeconds);
|
|
1040
|
+
}
|
|
1041
|
+
const agent = (await arbi.agents.list()).find((a) => a.external_id === agentExtId);
|
|
1042
|
+
if (!agent?.email) throw new Error("The agent's address is unknown.");
|
|
1043
|
+
return arbi.workspaces.grantAccess({ workspaceId, emails: [agent.email] });
|
|
1044
|
+
},
|
|
1045
|
+
onSuccess: (_res, { agentExtId }) => qc.invalidateQueries({ queryKey: arbiQueryKeys.agentWorkspaces(agentExtId) })
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
function useRevokeAgentAccess() {
|
|
1049
|
+
const arbi = useArbi();
|
|
1050
|
+
const qc = useQueryClient();
|
|
1051
|
+
return useMutation({
|
|
1052
|
+
mutationFn: async ({
|
|
1053
|
+
agentExtId,
|
|
1054
|
+
workspaceId
|
|
1055
|
+
}) => {
|
|
1056
|
+
const previous = arbi.hasWorkspace ? arbi.getWorkspaceId() : null;
|
|
1057
|
+
await arbi.selectWorkspace(workspaceId);
|
|
1058
|
+
try {
|
|
1059
|
+
await arbi.workspaces.removeUsers([agentExtId]);
|
|
1060
|
+
} finally {
|
|
1061
|
+
if (previous && previous !== workspaceId) await arbi.selectWorkspace(previous);
|
|
1062
|
+
}
|
|
1063
|
+
},
|
|
1064
|
+
onSuccess: (_res, { agentExtId }) => qc.invalidateQueries({ queryKey: arbiQueryKeys.agentWorkspaces(agentExtId) })
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
function useSkills(options) {
|
|
1068
|
+
const arbi = useArbi();
|
|
1069
|
+
return useQuery({
|
|
1070
|
+
queryKey: [...arbiQueryKeys.skills(), options?.includeHidden ?? false],
|
|
1071
|
+
queryFn: () => arbi.assistant.listSkills({ includeHidden: options?.includeHidden }),
|
|
1072
|
+
enabled: (options?.enabled ?? true) && arbi.isLoggedIn,
|
|
1073
|
+
staleTime: 3e4
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
function useContacts(options) {
|
|
1077
|
+
const arbi = useArbi();
|
|
1078
|
+
return useQuery({
|
|
1079
|
+
queryKey: arbiQueryKeys.contacts(),
|
|
1080
|
+
queryFn: () => arbi.contacts.list(),
|
|
1081
|
+
enabled: (options?.enabled ?? true) && arbi.isLoggedIn
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
function usePendingContacts(options) {
|
|
1085
|
+
const contacts = useContacts(options);
|
|
1086
|
+
const pending = useMemo(
|
|
1087
|
+
() => (contacts.data ?? []).filter(
|
|
1088
|
+
(c) => c.status === "invitation_pending" || c.status === "invitation_expired"
|
|
1089
|
+
),
|
|
1090
|
+
[contacts.data]
|
|
1091
|
+
);
|
|
1092
|
+
return { ...contacts, pending };
|
|
1093
|
+
}
|
|
1094
|
+
function useAddContacts() {
|
|
1095
|
+
const arbi = useArbi();
|
|
1096
|
+
const qc = useQueryClient();
|
|
1097
|
+
return useMutation({
|
|
1098
|
+
mutationFn: (emails) => arbi.contacts.add(emails),
|
|
1099
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.contacts() })
|
|
1100
|
+
});
|
|
1101
|
+
}
|
|
1102
|
+
function useRemoveContacts() {
|
|
1103
|
+
const arbi = useArbi();
|
|
1104
|
+
const qc = useQueryClient();
|
|
1105
|
+
return useMutation({
|
|
1106
|
+
mutationFn: (contactIds) => arbi.contacts.remove(contactIds),
|
|
1107
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.contacts() })
|
|
1108
|
+
});
|
|
1109
|
+
}
|
|
893
1110
|
function useWorkspaceDocs(workspaceId) {
|
|
894
1111
|
const { data: docs = [], isLoading, isError } = useDocuments(workspaceId);
|
|
895
1112
|
const docIds = useMemo(
|
|
@@ -3065,7 +3282,6 @@ function isAgentUser(user) {
|
|
|
3065
3282
|
return user.external_id.startsWith("agt-");
|
|
3066
3283
|
}
|
|
3067
3284
|
var DM_QUERY_KEY = ["arbi", "directMessages"];
|
|
3068
|
-
var CONTACTS_QUERY_KEY = ["arbi", "contacts"];
|
|
3069
3285
|
function mergeContacts(threads, contacts) {
|
|
3070
3286
|
const byPeer = /* @__PURE__ */ new Map();
|
|
3071
3287
|
for (const t of threads) byPeer.set(t.peer.external_id, t);
|
|
@@ -3131,7 +3347,7 @@ function useDirectMessages(options) {
|
|
|
3131
3347
|
enabled
|
|
3132
3348
|
});
|
|
3133
3349
|
const contactsQuery = useQuery({
|
|
3134
|
-
queryKey:
|
|
3350
|
+
queryKey: arbiQueryKeys.contacts(),
|
|
3135
3351
|
queryFn: () => arbi.contacts.list(),
|
|
3136
3352
|
enabled
|
|
3137
3353
|
});
|
|
@@ -3216,6 +3432,7 @@ function ConversationList({
|
|
|
3216
3432
|
classNames,
|
|
3217
3433
|
emptyState,
|
|
3218
3434
|
header,
|
|
3435
|
+
lead,
|
|
3219
3436
|
className
|
|
3220
3437
|
}) {
|
|
3221
3438
|
return /* @__PURE__ */ jsxs(
|
|
@@ -3235,6 +3452,7 @@ function ConversationList({
|
|
|
3235
3452
|
conversations.length === 1 ? "colleague" : "colleagues"
|
|
3236
3453
|
] })
|
|
3237
3454
|
] }) : header,
|
|
3455
|
+
lead,
|
|
3238
3456
|
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", children: conversations.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-6 text-xs text-muted-foreground", children: emptyState ?? "No conversations yet." }) : /* @__PURE__ */ jsx("ul", { className: "w-full", children: conversations.map((c, i) => {
|
|
3239
3457
|
const { peer, lastMessage, unreadCount } = c;
|
|
3240
3458
|
const newSection = c.sectionLabel && c.sectionLabel !== conversations[i - 1]?.sectionLabel;
|
|
@@ -3521,14 +3739,117 @@ function DmComposer({
|
|
|
3521
3739
|
error && /* @__PURE__ */ jsx("p", { className: "mt-2 text-xs text-destructive", "data-testid": "arbi-dm-error", children: error })
|
|
3522
3740
|
] });
|
|
3523
3741
|
}
|
|
3742
|
+
var DEFAULT_START_BY_EMAIL_LABELS = {
|
|
3743
|
+
email: "Email address",
|
|
3744
|
+
emailPlaceholder: "name@example.com",
|
|
3745
|
+
message: "Message",
|
|
3746
|
+
messagePlaceholder: "Write the first message\u2026",
|
|
3747
|
+
send: "Send",
|
|
3748
|
+
sending: "Sending\u2026",
|
|
3749
|
+
invalidEmail: "Enter a valid email address."
|
|
3750
|
+
};
|
|
3751
|
+
var EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
3752
|
+
function StartByEmail({
|
|
3753
|
+
onStart,
|
|
3754
|
+
onStarted,
|
|
3755
|
+
classNames,
|
|
3756
|
+
labels,
|
|
3757
|
+
className
|
|
3758
|
+
}) {
|
|
3759
|
+
const l = { ...DEFAULT_START_BY_EMAIL_LABELS, ...labels };
|
|
3760
|
+
const uid = useId();
|
|
3761
|
+
const [email, setEmail] = useState("");
|
|
3762
|
+
const [text, setText] = useState("");
|
|
3763
|
+
const [busy, setBusy] = useState(false);
|
|
3764
|
+
const [error, setError] = useState(null);
|
|
3765
|
+
const address = email.trim().toLowerCase();
|
|
3766
|
+
const valid = EMAIL.test(address);
|
|
3767
|
+
const submit = async () => {
|
|
3768
|
+
if (!valid || !text.trim() || busy) return;
|
|
3769
|
+
setBusy(true);
|
|
3770
|
+
setError(null);
|
|
3771
|
+
try {
|
|
3772
|
+
const result = await onStart(address, text.trim());
|
|
3773
|
+
setEmail("");
|
|
3774
|
+
setText("");
|
|
3775
|
+
onStarted?.(result);
|
|
3776
|
+
} catch (e) {
|
|
3777
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
3778
|
+
} finally {
|
|
3779
|
+
setBusy(false);
|
|
3780
|
+
}
|
|
3781
|
+
};
|
|
3782
|
+
return /* @__PURE__ */ jsxs(
|
|
3783
|
+
"form",
|
|
3784
|
+
{
|
|
3785
|
+
"data-testid": "arbi-dm-start",
|
|
3786
|
+
className: cn("flex flex-col gap-2 border-b border-border px-4 py-3", className),
|
|
3787
|
+
onSubmit: (e) => {
|
|
3788
|
+
e.preventDefault();
|
|
3789
|
+
void submit();
|
|
3790
|
+
},
|
|
3791
|
+
children: [
|
|
3792
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: `${uid}-email`, children: l.email }),
|
|
3793
|
+
/* @__PURE__ */ jsx(
|
|
3794
|
+
Input,
|
|
3795
|
+
{
|
|
3796
|
+
id: `${uid}-email`,
|
|
3797
|
+
type: "email",
|
|
3798
|
+
value: email,
|
|
3799
|
+
onChange: (e) => setEmail(e.target.value),
|
|
3800
|
+
placeholder: l.emailPlaceholder,
|
|
3801
|
+
"aria-invalid": email !== "" && !valid,
|
|
3802
|
+
"aria-describedby": email !== "" && !valid ? `${uid}-bad` : void 0,
|
|
3803
|
+
disabled: busy,
|
|
3804
|
+
"data-testid": "arbi-dm-start-email"
|
|
3805
|
+
}
|
|
3806
|
+
),
|
|
3807
|
+
email !== "" && !valid && /* @__PURE__ */ jsx("p", { id: `${uid}-bad`, className: "text-xs text-destructive", children: l.invalidEmail }),
|
|
3808
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: `${uid}-text`, children: l.message }),
|
|
3809
|
+
/* @__PURE__ */ jsx(
|
|
3810
|
+
Textarea,
|
|
3811
|
+
{
|
|
3812
|
+
id: `${uid}-text`,
|
|
3813
|
+
value: text,
|
|
3814
|
+
onChange: (e) => setText(e.target.value),
|
|
3815
|
+
placeholder: l.messagePlaceholder,
|
|
3816
|
+
rows: 2,
|
|
3817
|
+
disabled: busy,
|
|
3818
|
+
"data-testid": "arbi-dm-start-message"
|
|
3819
|
+
}
|
|
3820
|
+
),
|
|
3821
|
+
error && /* @__PURE__ */ jsx("p", { role: "alert", className: "text-xs text-destructive", "data-testid": "arbi-dm-start-error", children: error }),
|
|
3822
|
+
/* @__PURE__ */ jsxs(
|
|
3823
|
+
Button,
|
|
3824
|
+
{
|
|
3825
|
+
type: "submit",
|
|
3826
|
+
size: "sm",
|
|
3827
|
+
disabled: !valid || !text.trim() || busy,
|
|
3828
|
+
className: cn("self-end", classNames?.sendButton),
|
|
3829
|
+
"data-testid": "arbi-dm-start-send",
|
|
3830
|
+
children: [
|
|
3831
|
+
busy ? /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin", "aria-hidden": true }) : /* @__PURE__ */ jsx(Send, { className: "size-4", "aria-hidden": true }),
|
|
3832
|
+
busy ? l.sending : l.send
|
|
3833
|
+
]
|
|
3834
|
+
}
|
|
3835
|
+
)
|
|
3836
|
+
]
|
|
3837
|
+
}
|
|
3838
|
+
);
|
|
3839
|
+
}
|
|
3524
3840
|
function DirectMessages({
|
|
3525
3841
|
className,
|
|
3526
3842
|
classNames,
|
|
3527
3843
|
emptyThread: emptyThread2,
|
|
3528
|
-
emptyList
|
|
3844
|
+
emptyList,
|
|
3845
|
+
listHeader,
|
|
3846
|
+
listLead,
|
|
3847
|
+
startByEmail,
|
|
3848
|
+
hideOwnContact
|
|
3529
3849
|
}) {
|
|
3530
3850
|
const {
|
|
3531
|
-
conversations,
|
|
3851
|
+
conversations: allConversations,
|
|
3852
|
+
myExtId,
|
|
3532
3853
|
isLoading,
|
|
3533
3854
|
isError,
|
|
3534
3855
|
error,
|
|
@@ -3538,6 +3859,14 @@ function DirectMessages({
|
|
|
3538
3859
|
markRead
|
|
3539
3860
|
} = useDirectMessages();
|
|
3540
3861
|
const [selectedPeerId, setSelectedPeerId] = useState(null);
|
|
3862
|
+
const conversations = useMemo(
|
|
3863
|
+
() => hideOwnContact && myExtId ? allConversations.filter((c) => c.peer.external_id !== myExtId) : allConversations,
|
|
3864
|
+
[allConversations, hideOwnContact, myExtId]
|
|
3865
|
+
);
|
|
3866
|
+
const openStarted = (created) => {
|
|
3867
|
+
const peer = Array.isArray(created) ? created[0]?.recipient?.external_id : void 0;
|
|
3868
|
+
if (peer) setSelectedPeerId(peer);
|
|
3869
|
+
};
|
|
3541
3870
|
const loadError = isError ? error instanceof Error ? error.message : "Couldn\u2019t load messages." : null;
|
|
3542
3871
|
const selected = useMemo(
|
|
3543
3872
|
() => conversations.find((c) => c.peer.external_id === selectedPeerId) ?? null,
|
|
@@ -3581,7 +3910,20 @@ function DirectMessages({
|
|
|
3581
3910
|
selectedPeerId: selected?.peer.external_id ?? null,
|
|
3582
3911
|
onSelect: setSelectedPeerId,
|
|
3583
3912
|
classNames,
|
|
3584
|
-
emptyState: isLoading ? "Loading messages\u2026" : emptyList
|
|
3913
|
+
emptyState: isLoading ? "Loading messages\u2026" : emptyList,
|
|
3914
|
+
header: listHeader,
|
|
3915
|
+
lead: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3916
|
+
listLead,
|
|
3917
|
+
startByEmail && /* @__PURE__ */ jsx(
|
|
3918
|
+
StartByEmail,
|
|
3919
|
+
{
|
|
3920
|
+
onStart: sendMessageTo,
|
|
3921
|
+
onStarted: openStarted,
|
|
3922
|
+
classNames,
|
|
3923
|
+
labels: typeof startByEmail === "object" ? startByEmail.labels : void 0
|
|
3924
|
+
}
|
|
3925
|
+
)
|
|
3926
|
+
] })
|
|
3585
3927
|
}
|
|
3586
3928
|
),
|
|
3587
3929
|
/* @__PURE__ */ jsxs("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: [
|
|
@@ -4990,6 +5332,6 @@ function hasVideoTrack(blob) {
|
|
|
4990
5332
|
});
|
|
4991
5333
|
}
|
|
4992
5334
|
|
|
4993
|
-
export { ActivityFeed, AiActionCard, AiAnswer, AppleIcon, ArbiBotIcon, ArbiIcon, ArbiWebSocketProvider, ArtifactCanvas, ChatBubble, CitationRenderer, ClaudeIcon, CommandPalette, CommandPaletteProvider, ConversationList, DEFAULT_ASPECT_OPTIONS, DateSeparator, DirectMessages, DmAvatar, DmComposer, DocIcon, DocQaPanel, DocSearch, DocumentCardMenu, DocumentGallery, DocumentReview, DocumentTable, DraftTitleControls, FileIcon, FireworksIcon, GeminiIcon, GitHubIcon, GoogleIcon, HtmlIcon, ImageCropModal, ImageCropper, LinkedInIcon, MessageArtifactCard, MessageBubble, MessageThread, OpenAIIcon, PhotoCapture, ProviderIcon, RUN_WINDOW_MS, SemanticSearch, TxtIcon, TypingIndicator, VideoCapture, VoiceNoteRecorder, XlsIcon, annotateThread, arbiQueryKeys, captureFrameAsBlob, cropImage, dayKey, describeActivity, getNotificationTypeMeta, getWorkspaceActionText, getWorkspaceKind, getWorkspaceSentPhrase, hasVideoTrack, isWorkspaceNotificationType, parseActivityContent, pickRecentWorkspaces, redlineStats, resolveActiveWorkspace, textToArtifact, titleFromQuestion, toRedlineMarkdown, toShellWorkspace, useActivity, useAgents, useAiTask, useArbiChat, useArbiConnected, useArbiDocumentSync, useArbiShellWorkspaces, useArbiUiStore, useArbiWebSocket, useArbiWsContext, useArbiWsMessage, useArbiWsStatus, useArbiWsStore, useArbiWsTask, useArbiWsTasks, useAssistantQuery, useCameraStream, useCommandPalette, useConfigs, useConversations, useDeleteAgents, useDirectMessages, useDocuments, useFacts, useHealth, useParsedDocument, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useSemanticSearch, useSessions, useShellWorkspaces, useTags, useTasks, useThumbnails, useUserUsageToday, useVideoRecorder, useWorkspaceDocs, useWorkspaces, userDisplayName, userInitials };
|
|
5335
|
+
export { ActivityFeed, AiActionCard, AiAnswer, AppleIcon, ArbiBotIcon, ArbiIcon, ArbiWebSocketProvider, ArtifactCanvas, ChatBubble, CitationRenderer, ClaudeIcon, CommandPalette, CommandPaletteProvider, ConversationList, DEFAULT_ASPECT_OPTIONS, DEFAULT_START_BY_EMAIL_LABELS, DEFAULT_USD_PER_CREDIT, DateSeparator, DirectMessages, DmAvatar, DmComposer, DocIcon, DocQaPanel, DocSearch, DocumentCardMenu, DocumentGallery, DocumentReview, DocumentTable, DraftTitleControls, FileIcon, FireworksIcon, GeminiIcon, GitHubIcon, GoogleIcon, HtmlIcon, ImageCropModal, ImageCropper, LinkedInIcon, MessageArtifactCard, MessageBubble, MessageThread, OpenAIIcon, PhotoCapture, ProviderIcon, RUN_WINDOW_MS, SemanticSearch, StartByEmail, TxtIcon, TypingIndicator, VideoCapture, VoiceNoteRecorder, XlsIcon, annotateThread, arbiQueryKeys, captureFrameAsBlob, creditsToUsd, cropImage, dayKey, describeActivity, formatCredits, getNotificationTypeMeta, getWorkspaceActionText, getWorkspaceKind, getWorkspaceSentPhrase, hasVideoTrack, isUsageMetered, isWorkspaceNotificationType, parseActivityContent, pickRecentWorkspaces, redlineStats, resolveActiveWorkspace, textToArtifact, titleFromQuestion, toRedlineMarkdown, toShellWorkspace, useActivity, useAddContacts, useAgentConfig, useAgentModels, useAgentWorkspaces, useAgents, useAiTask, useArbiChat, useArbiConnected, useArbiDocumentSync, useArbiShellWorkspaces, useArbiUiStore, useArbiWebSocket, useArbiWsContext, useArbiWsMessage, useArbiWsStatus, useArbiWsStore, useArbiWsTask, useArbiWsTasks, useAssistantQuery, useCameraStream, useCommandPalette, useConfigs, useContacts, useConversations, useCreateAgent, useCreateTask, useDeleteAgents, useDeleteTask, useDirectMessages, useDocuments, useFacts, useGrantAgentAccess, useHealth, useParsedDocument, usePendingContacts, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useRemoveContacts, useRevokeAgentAccess, useRunTask, useSaveAgentConfig, useSemanticSearch, useSessions, useShellWorkspaces, useSkills, useTags, useTaskRuns, useTasks, useThumbnails, useUpdateTask, useUserUsageToday, useVideoRecorder, useWorkspaceDocs, useWorkspaces, userDisplayName, userInitials };
|
|
4994
5336
|
//# sourceMappingURL=index.js.map
|
|
4995
5337
|
//# sourceMappingURL=index.js.map
|