@arbidocs/blocks 0.4.136 → 0.4.138
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/agents/index.cjs +384 -353
- package/dist/agents/index.js +8 -9
- package/dist/agents/skills/SkillLibraryDetail.d.ts +26 -0
- package/dist/agents/skills/index.d.ts +2 -0
- package/dist/agents/skills/skillLibrary.d.ts +46 -0
- package/dist/agents/workflows/WorkflowDocumentsField.d.ts +42 -5
- package/dist/agents/workflows/index.d.ts +2 -2
- package/dist/agents/workflows/workspaceScope.d.ts +12 -0
- package/dist/calls/index.cjs +3 -3
- package/dist/calls/index.js +2 -2
- package/dist/chunk-2KUCVSFF.js +51 -0
- package/dist/chunk-2KUCVSFF.js.map +1 -0
- package/dist/{chunk-LIHRGG4M.cjs → chunk-3BI6EWKP.cjs} +2022 -89
- package/dist/chunk-3BI6EWKP.cjs.map +1 -0
- package/dist/{chunk-3FFRYZKV.js → chunk-3RJN2VTL.js} +36 -6
- package/dist/chunk-3RJN2VTL.js.map +1 -0
- package/dist/{chunk-OR4CO743.cjs → chunk-AAFX64WD.cjs} +3 -3
- package/dist/{chunk-OR4CO743.cjs.map → chunk-AAFX64WD.cjs.map} +1 -1
- package/dist/chunk-CQCC7LE7.js +210 -0
- package/dist/chunk-CQCC7LE7.js.map +1 -0
- package/dist/{chunk-ZAVEMQ37.cjs → chunk-DWZXSPMB.cjs} +3 -3
- package/dist/{chunk-ZAVEMQ37.cjs.map → chunk-DWZXSPMB.cjs.map} +1 -1
- package/dist/{chunk-VIU7AMHF.js → chunk-E5OYHJMU.js} +3 -3
- package/dist/{chunk-VIU7AMHF.js.map → chunk-E5OYHJMU.js.map} +1 -1
- package/dist/{chunk-RUB62J2X.js → chunk-ED4HHTIA.js} +3 -3
- package/dist/{chunk-RUB62J2X.js.map → chunk-ED4HHTIA.js.map} +1 -1
- package/dist/{chunk-5HFPRI3W.js → chunk-FUTMU4FR.js} +3 -3
- package/dist/{chunk-5HFPRI3W.js.map → chunk-FUTMU4FR.js.map} +1 -1
- package/dist/{chunk-C44D4WFG.cjs → chunk-HLB4DIYV.cjs} +3 -3
- package/dist/{chunk-C44D4WFG.cjs.map → chunk-HLB4DIYV.cjs.map} +1 -1
- package/dist/{chunk-N55UIXVT.cjs → chunk-JVL7HUIQ.cjs} +5 -5
- package/dist/{chunk-N55UIXVT.cjs.map → chunk-JVL7HUIQ.cjs.map} +1 -1
- package/dist/{chunk-6S5FLMWG.js → chunk-KSHKTOY2.js} +203 -7
- package/dist/chunk-KSHKTOY2.js.map +1 -0
- package/dist/{chunk-OZLWSNUC.cjs → chunk-MJKBVIV3.cjs} +83 -1650
- package/dist/chunk-MJKBVIV3.cjs.map +1 -0
- package/dist/{chunk-DJM7DLCT.cjs → chunk-OPTBQSCV.cjs} +3 -3
- package/dist/{chunk-DJM7DLCT.cjs.map → chunk-OPTBQSCV.cjs.map} +1 -1
- package/dist/{chunk-GFYGYME3.js → chunk-OQ7RUNOC.js} +3 -3
- package/dist/{chunk-GFYGYME3.js.map → chunk-OQ7RUNOC.js.map} +1 -1
- package/dist/chunk-RFIBUWLF.cjs +232 -0
- package/dist/chunk-RFIBUWLF.cjs.map +1 -0
- package/dist/{chunk-N26CXGXC.cjs → chunk-RQ2Y7USX.cjs} +201 -3
- package/dist/chunk-RQ2Y7USX.cjs.map +1 -0
- package/dist/{chunk-LT2X5N37.js → chunk-UBEI6WFJ.js} +58 -1592
- package/dist/chunk-UBEI6WFJ.js.map +1 -0
- package/dist/chunk-UUHUQHXR.cjs +56 -0
- package/dist/chunk-UUHUQHXR.cjs.map +1 -0
- package/dist/{chunk-ECERC6TI.js → chunk-VHJHY7TT.js} +3 -3
- package/dist/{chunk-ECERC6TI.js.map → chunk-VHJHY7TT.js.map} +1 -1
- package/dist/{chunk-44R3CCZT.cjs → chunk-WS5EX7DN.cjs} +37 -6
- package/dist/chunk-WS5EX7DN.cjs.map +1 -0
- package/dist/{chunk-IQU2GI6V.js → chunk-XVME4XYD.js} +1982 -93
- package/dist/chunk-XVME4XYD.js.map +1 -0
- package/dist/collaboration/index.cjs +42 -42
- package/dist/collaboration/index.js +2 -2
- package/dist/connect/docx.cjs +5 -5
- package/dist/connect/docx.js +4 -4
- package/dist/connect/index.cjs +710 -51
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.d.ts +4 -0
- package/dist/connect/index.js +655 -20
- package/dist/connect/index.js.map +1 -1
- package/dist/connection/ConnectedSkillsLibrary.d.ts +26 -0
- package/dist/connection/ConnectedWorkflowBuilder.d.ts +1 -1
- package/dist/connection/ConnectedWorkflowLauncher.d.ts +35 -0
- package/dist/connection/ConnectedWorkflowsTable.d.ts +62 -0
- package/dist/connection/workspaceData.d.ts +45 -0
- package/dist/facts/index.cjs +2 -2
- package/dist/facts/index.js +2 -2
- package/dist/files/index.cjs +3 -3
- package/dist/files/index.js +3 -3
- package/dist/home/index.cjs +22 -23
- package/dist/home/index.cjs.map +1 -1
- package/dist/home/index.js +4 -5
- package/dist/home/index.js.map +1 -1
- package/dist/index.cjs +503 -472
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +12 -13
- package/dist/index.js.map +1 -1
- package/dist/retrieval/index.cjs +1 -1
- package/dist/retrieval/index.js +1 -1
- package/dist/settings/index.cjs +49 -49
- package/dist/settings/index.js +6 -6
- package/dist/shell/index.cjs +2 -2
- package/dist/shell/index.js +2 -2
- package/dist/studio/index.cjs +2 -2
- package/dist/studio/index.js +2 -2
- package/dist/workflow-canvas/index.cjs +32 -30
- package/dist/workflow-canvas/index.cjs.map +1 -1
- package/dist/workflow-canvas/index.js +20 -18
- package/dist/workflow-canvas/index.js.map +1 -1
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +4 -4
- package/dist/chunk-3FFRYZKV.js.map +0 -1
- package/dist/chunk-44R3CCZT.cjs.map +0 -1
- package/dist/chunk-4XJZ6AAY.js +0 -407
- package/dist/chunk-4XJZ6AAY.js.map +0 -1
- package/dist/chunk-6S5FLMWG.js.map +0 -1
- package/dist/chunk-7D737FLE.cjs +0 -43
- package/dist/chunk-7D737FLE.cjs.map +0 -1
- package/dist/chunk-IQU2GI6V.js.map +0 -1
- package/dist/chunk-LIHRGG4M.cjs.map +0 -1
- package/dist/chunk-LT2X5N37.js.map +0 -1
- package/dist/chunk-N26CXGXC.cjs.map +0 -1
- package/dist/chunk-OZLWSNUC.cjs.map +0 -1
- package/dist/chunk-S5HZBXZA.cjs +0 -430
- package/dist/chunk-S5HZBXZA.cjs.map +0 -1
- package/dist/chunk-XD2M6LIG.js +0 -41
- package/dist/chunk-XD2M6LIG.js.map +0 -1
package/dist/connect/index.js
CHANGED
|
@@ -1,31 +1,34 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { SettingsSection, ProfileCard, AvatarPicker, IdentityVerificationCard, IdentityVerificationDialog, RequireVerified, PasswordChangeDialog, SettingsCard, SettingsActionRow, EMAIL_NOTIFICATION_KEYS, EMAIL_NOTIFICATION_CATEGORIES, NotificationCategoryList, toNotificationCategories, toActiveSessionViews, SettingsRow, ActiveSessionsDialog, LogoutDialog, toLogoutSessionViews, SettingsDangerZone, DeleteAccountDialog, toDeleteBlockerViews } from '../chunk-
|
|
2
|
+
import { SettingsSection, ProfileCard, AvatarPicker, IdentityVerificationCard, IdentityVerificationDialog, RequireVerified, PasswordChangeDialog, SettingsCard, SettingsActionRow, EMAIL_NOTIFICATION_KEYS, EMAIL_NOTIFICATION_CATEGORIES, NotificationCategoryList, toNotificationCategories, toActiveSessionViews, SettingsRow, ActiveSessionsDialog, LogoutDialog, toLogoutSessionViews, SettingsDangerZone, DeleteAccountDialog, toDeleteBlockerViews } from '../chunk-OQ7RUNOC.js';
|
|
3
3
|
import { useWorkspaceDocs } from '../chunk-ZNI4SW2G.js';
|
|
4
4
|
export { ConnectedAssistantDock, redlineStats, textToArtifact, toRedlineMarkdown, useConnectedAiTask, useConnectedChat, useSemanticSearch, useWorkspaceDocs } from '../chunk-ZNI4SW2G.js';
|
|
5
|
-
import {
|
|
6
|
-
|
|
5
|
+
import { useConnectedConversations, useConnectedDocuments, useConnectedTags } from '../chunk-2KUCVSFF.js';
|
|
6
|
+
export { ConnectedWorkspaceDataProvider, useConnectedConversations, useConnectedDocuments, useConnectedTags } from '../chunk-2KUCVSFF.js';
|
|
7
|
+
import { ConnectedNativeDocxEditor } from '../chunk-E5OYHJMU.js';
|
|
8
|
+
import { ConnectionProvider, useConnection, useConnectedWorkspace } from '../chunk-L2PAPOZ5.js';
|
|
7
9
|
export { ConnectionProvider, SESSION_EXPIRED_MESSAGE, isAuthenticated, useConnectedWorkspace, useConnection } from '../chunk-L2PAPOZ5.js';
|
|
8
10
|
import { SignDocumentDialog } from '../chunk-2YOVK524.js';
|
|
9
11
|
import '../chunk-GYAUJ4KT.js';
|
|
10
12
|
import '../chunk-2FL7QJKJ.js';
|
|
11
13
|
import '../chunk-HFZ45FD3.js';
|
|
12
14
|
import { FilesFilterBar, FolderFilterButton, FolderPickerRow } from '../chunk-7RJTEWYM.js';
|
|
13
|
-
import { WorkspaceActivityList, WorkspaceNotificationMenu, ThreadFollowMenuItem, ThreadFollowButton, TagTable, tagTableDocx } from '../chunk-
|
|
15
|
+
import { WorkspaceActivityList, WorkspaceNotificationMenu, ThreadFollowMenuItem, ThreadFollowButton, TagTable, tagTableDocx } from '../chunk-ED4HHTIA.js';
|
|
14
16
|
import { PlainMailBodyEditor, draftMailCompose, replyMailCompose, emptyMailCompose, MailGrid, MailMessageView, MailDocumentPicker, parseMailRecipients } from '../chunk-6HCJ3ZEU.js';
|
|
15
17
|
import { DOCX_MIME_TYPE } from '../chunk-QXMR5YHC.js';
|
|
16
18
|
import '../chunk-AF6RDAJF.js';
|
|
17
|
-
import { WorkflowStepBar, importSkillFile, importSkillFromUrl, WorkflowRunner, fromPlanSteps, toPlanSteps, useWorkflowView } from '../chunk-
|
|
18
|
-
import '../chunk-
|
|
19
|
-
import { TriStateFilterMenu } from '../chunk-
|
|
19
|
+
import { WorkflowsTable, workflowTriggerType, buildWorkflowScopeSource, documentScopeLabels, WorkflowDocumentsField, WorkflowLauncher, buildLibrarySkills, filterLibrarySkills, SKILL_SOURCE_LABELS, SKILL_TYPE_LABELS, SkillViewToggle, SkillFilterChips, SkillTile, SkillGenerateForm, SkillLibraryDetail, parseSkillFrontmatter, SKILL_MAIN_FILENAME, SkillEditForm, WorkflowStepBar, importSkillFile, importSkillFromUrl, WorkflowRunner, skillSlug, serializeSkill, fromPlanSteps, toPlanSteps, useWorkflowView, workflowToSkillMarkdown } from '../chunk-XVME4XYD.js';
|
|
20
|
+
import '../chunk-3RJN2VTL.js';
|
|
21
|
+
import { TriStateFilterMenu } from '../chunk-KSHKTOY2.js';
|
|
22
|
+
import '../chunk-P6GHJSLR.js';
|
|
20
23
|
import '../chunk-EVUEIBNU.js';
|
|
24
|
+
import '../chunk-444XKG46.js';
|
|
25
|
+
import '../chunk-NUNKSZKU.js';
|
|
21
26
|
import { FilterInput } from '../chunk-YU2KUMGE.js';
|
|
22
27
|
import '../chunk-N5YEF3LC.js';
|
|
23
28
|
import { StreamedArtifactFrame } from '../chunk-LOJVUGBJ.js';
|
|
24
29
|
import '../chunk-VILAPTCB.js';
|
|
25
|
-
import { ConfirmDialog } from '../chunk-
|
|
30
|
+
import { ConfirmDialog } from '../chunk-VHJHY7TT.js';
|
|
26
31
|
import { TabHeader } from '../chunk-4WWM3GQ5.js';
|
|
27
|
-
import { useBlocksEnvironment } from '../chunk-YNIBUKV5.js';
|
|
28
|
-
import { ModalScaffold } from '../chunk-TX2ZICS7.js';
|
|
29
32
|
import { ChatPage } from '../chunk-JO3EMZ4X.js';
|
|
30
33
|
import '../chunk-7XF5SFJ2.js';
|
|
31
34
|
import { takeOpenDocumentForTurn, useRegisterOpenDocument } from '../chunk-YBLIKTJK.js';
|
|
@@ -35,16 +38,18 @@ import '../chunk-AUS3KBHJ.js';
|
|
|
35
38
|
import '../chunk-SLSBJRWW.js';
|
|
36
39
|
import '../chunk-NPLYHR2E.js';
|
|
37
40
|
import '../chunk-7F6CBP3Z.js';
|
|
38
|
-
import {
|
|
41
|
+
import { useBlocksEnvironment } from '../chunk-YNIBUKV5.js';
|
|
42
|
+
import { ModalScaffold } from '../chunk-TX2ZICS7.js';
|
|
43
|
+
import { fmtDate, initials } from '../chunk-OXF2IFXG.js';
|
|
39
44
|
import '../chunk-VUNV25KB.js';
|
|
40
|
-
import { lazy, useState, useMemo,
|
|
45
|
+
import { lazy, useState, useMemo, useEffect, useRef, useCallback, Suspense, useLayoutEffect } from 'react';
|
|
41
46
|
import { QueryClient, QueryClientProvider, useQueryClient, useQuery } from '@tanstack/react-query';
|
|
42
|
-
import { ArbiProvider, useConversations, useRunConversation, useWorkspaceActivity, useWorkspaceUsers, useWorkspaceNotificationLevel, useFollowThread, useUploadSkillFiles, ArtifactCanvas, useArbiChat,
|
|
47
|
+
import { ArbiProvider, useConversations, useRunConversation, useWorkspaceActivity, useWorkspaceUsers, useWorkspaceNotificationLevel, useFollowThread, useWorkflows, useAgents, useUpdateWorkflow, useDeleteWorkflow, useRunWorkflow, useArbi, useThumbnails, useUploadSkillFiles, useSkills, useSetSkillVisibility, useDeleteSkill, useSkillSource, ArtifactCanvas, useArbiChat, useDocuments, useTagKindSchema, useTags, useSetTagValues, useUpdateTagKindSchema, useInvalidateTagData, useWorkspaces, useShellWorkspaces, useProfile, useUpdateProfile, useRequestEmailChange, useConfirmEmailChange, useNameEditor, useAvatarCrop, useEmailChange, ImageCropModal, useIdentityVerification, usePasswordChange, usePasswordChangeForm, useNotificationPreferences, useSessions, useCurrentSessionId, useTerminateSession, useSignOut, useDeleteAccount, useDeleteAccountFlow, useArbiWebSocket, useWorkNotifications, mailDraftIdFromContent, useMailClient, defaultMailAlias, useClaimNativeAlias, useMailOnline, useConnectMailAccount, useDisconnectMailAccount, useMailPolicy, useMailAccounts, useMailUnlock, useMailFolders, useMailMessages, useMailDraftCompose, useMailMessage, useMailCache, MailOfflineUnavailableError, accountPath, useAgentSession, useStartAgentSession, useCloseAgentSession, isAliasTakenError, nextAliasSuggestion, aliasTakenMessage, mailJson, ArbiWebSocketProvider, useCreateWork, useActOnStep, useConversationActivity, useConversationThreads, fileAttachment, useMailProjects, useSaveMailDraft, useSendMail, useMailDraftReplaced, AiAnswer, useMailDraftEditor } from '@arbidocs/react';
|
|
43
48
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
44
|
-
import { Button, Label, Input, cn, Dialog, DialogContent, DialogTitle, DialogDescription, Tooltip, TooltipTrigger, TooltipContent } from '@arbidocs/react/ui';
|
|
45
|
-
import {
|
|
49
|
+
import { Button, Label, Input, cn, Textarea, Dialog, DialogContent, DialogTitle, DialogDescription, EntityIcon, Tooltip, TooltipTrigger, TooltipContent } from '@arbidocs/react/ui';
|
|
50
|
+
import { useIsOnline, downloadBlob, useOptionalDocumentTools, fetchDocumentPdf, DocumentToolsProvider } from '@arbidocs/react/document-tools';
|
|
51
|
+
import { Upload, Link2, Search, Plus, ArrowLeft, ExternalLink, UserCircle, KeyRound, Radio, Mail, Settings, Loader2, X, Paperclip, Send, MessageSquare } from 'lucide-react';
|
|
46
52
|
import { useStreamedArtifact } from '@arbidocs/react/artifacts';
|
|
47
|
-
import { useIsOnline, useOptionalDocumentTools, fetchDocumentPdf, DocumentToolsProvider } from '@arbidocs/react/document-tools';
|
|
48
53
|
import { useNotify } from '@arbidocs/react/shell';
|
|
49
54
|
import { bytesToBase64 } from '@arbidocs/client';
|
|
50
55
|
import { createPortal } from 'react-dom';
|
|
@@ -181,6 +186,255 @@ function ConnectedThreadFollow({
|
|
|
181
186
|
}
|
|
182
187
|
);
|
|
183
188
|
}
|
|
189
|
+
function useConnectedWorkspaceRole() {
|
|
190
|
+
const { workspaceId, live, userId, ensureWorkspaceOpen } = useConnectedWorkspace();
|
|
191
|
+
const { data: members = [] } = useWorkspaceUsers(workspaceId ?? void 0, {
|
|
192
|
+
enabled: live && !!workspaceId,
|
|
193
|
+
beforeFetch: ensureWorkspaceOpen
|
|
194
|
+
});
|
|
195
|
+
const role = members.find((m) => m.user.external_id === userId)?.role;
|
|
196
|
+
return {
|
|
197
|
+
members,
|
|
198
|
+
role,
|
|
199
|
+
/** An owner or a collaborator edits, pauses, resumes and runs what is shared with the workspace. */
|
|
200
|
+
canEditShared: role === "owner" || role === "collaborator",
|
|
201
|
+
/** With an item's creator, the only one who deletes it. */
|
|
202
|
+
isWorkspaceOwner: role === "owner"
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
var DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS = {
|
|
206
|
+
updateFailed: "Could not update the workflow",
|
|
207
|
+
deleteTitle: "Delete workflow",
|
|
208
|
+
deleteOne: (name) => `Delete \u201C${name}\u201D? Threads it already created stay.`,
|
|
209
|
+
deleteMany: (count) => `Delete ${count} workflows? Threads they already created stay.`,
|
|
210
|
+
runFailed: "The workflow failed. You can send an error report from its history.",
|
|
211
|
+
noThread: "The workflow did not create a thread.",
|
|
212
|
+
documentAction: (workflow) => workflow.action?.type === "email_documents" ? "Preparing your document email" : "Reviewing documents",
|
|
213
|
+
untitledTask: "Untitled thread"
|
|
214
|
+
};
|
|
215
|
+
var messageOf = (error) => error instanceof Error ? error.message : "";
|
|
216
|
+
function ConnectedWorkflowsTable({
|
|
217
|
+
filter,
|
|
218
|
+
describeTrigger = (w) => workflowTriggerType(w).replaceAll("_", " "),
|
|
219
|
+
formatDate = fmtDate,
|
|
220
|
+
onViewRuns,
|
|
221
|
+
connectedLabels,
|
|
222
|
+
...tableProps
|
|
223
|
+
}) {
|
|
224
|
+
const l = { ...DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS, ...connectedLabels };
|
|
225
|
+
const { notify, confirm, openConversation } = useBlocksEnvironment();
|
|
226
|
+
const { canEditShared, isWorkspaceOwner } = useConnectedWorkspaceRole();
|
|
227
|
+
const { data: saved = [], isLoading } = useWorkflows({ live: true });
|
|
228
|
+
const { data: conversations, refetch } = useConnectedConversations({ live: true });
|
|
229
|
+
const { data: agents = [] } = useAgents();
|
|
230
|
+
const update = useUpdateWorkflow();
|
|
231
|
+
const remove = useDeleteWorkflow();
|
|
232
|
+
const run = useRunWorkflow();
|
|
233
|
+
const [busyId, setBusyId] = useState(null);
|
|
234
|
+
const workflows = useMemo(() => filter ? saved.filter(filter) : saved, [saved, filter]);
|
|
235
|
+
const firingStamp = saved.map((w) => `${w.external_id}:${w.last_fired_at ?? ""}`).join("|");
|
|
236
|
+
useEffect(() => {
|
|
237
|
+
void refetch?.();
|
|
238
|
+
}, [firingStamp, refetch]);
|
|
239
|
+
const lastRuns = useMemo(() => {
|
|
240
|
+
const out = {};
|
|
241
|
+
for (const c of conversations) {
|
|
242
|
+
const id = c.workflow_ext_id;
|
|
243
|
+
if (id && (!out[id] || Date.parse(c.created_at) > Date.parse(out[id].at)))
|
|
244
|
+
out[id] = { conversationId: c.external_id, at: c.created_at, threadStatus: c.status };
|
|
245
|
+
}
|
|
246
|
+
return out;
|
|
247
|
+
}, [conversations]);
|
|
248
|
+
const agentNames = useMemo(
|
|
249
|
+
() => Object.fromEntries(agents.map((a) => [a.external_id, a.given_name || a.email])),
|
|
250
|
+
[agents]
|
|
251
|
+
);
|
|
252
|
+
const taskNames = useMemo(
|
|
253
|
+
() => Object.fromEntries(
|
|
254
|
+
conversations.filter((c) => c.status != null).map((c) => [c.external_id, c.title || l.untitledTask])
|
|
255
|
+
),
|
|
256
|
+
[conversations, l.untitledTask]
|
|
257
|
+
);
|
|
258
|
+
const act = async (workflow, action) => {
|
|
259
|
+
setBusyId(workflow.external_id);
|
|
260
|
+
try {
|
|
261
|
+
await action();
|
|
262
|
+
} catch (error) {
|
|
263
|
+
notify(messageOf(error) || l.updateFailed, "error");
|
|
264
|
+
} finally {
|
|
265
|
+
setBusyId(null);
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
const setActive = (workflow, active) => act(workflow, () => update.mutateAsync({ workflowId: workflow.external_id, patch: { active } }));
|
|
269
|
+
const deleteAll = async (items) => {
|
|
270
|
+
if (!items.length) return;
|
|
271
|
+
const ok = await confirm({
|
|
272
|
+
title: l.deleteTitle,
|
|
273
|
+
message: items.length === 1 ? l.deleteOne(items[0].name) : l.deleteMany(items.length)
|
|
274
|
+
});
|
|
275
|
+
if (!ok) return;
|
|
276
|
+
for (const workflow of items)
|
|
277
|
+
await act(workflow, () => remove.mutateAsync(workflow.external_id));
|
|
278
|
+
};
|
|
279
|
+
return /* @__PURE__ */ jsx(
|
|
280
|
+
WorkflowsTable,
|
|
281
|
+
{
|
|
282
|
+
...tableProps,
|
|
283
|
+
workflows,
|
|
284
|
+
isLoading,
|
|
285
|
+
busyId,
|
|
286
|
+
describeTrigger,
|
|
287
|
+
formatDate,
|
|
288
|
+
agentNames,
|
|
289
|
+
taskNames,
|
|
290
|
+
lastRuns,
|
|
291
|
+
canEditShared,
|
|
292
|
+
isWorkspaceOwner,
|
|
293
|
+
onOpenThread: (conversationId) => openConversation(conversationId),
|
|
294
|
+
onViewRuns,
|
|
295
|
+
onToggleActive: (workflow, active) => void setActive(workflow, active),
|
|
296
|
+
onToggleActiveMany: (items, active) => {
|
|
297
|
+
void (async () => {
|
|
298
|
+
for (const workflow of items) await setActive(workflow, active);
|
|
299
|
+
})();
|
|
300
|
+
},
|
|
301
|
+
onToggleShared: (workflow, shared) => void act(
|
|
302
|
+
workflow,
|
|
303
|
+
() => update.mutateAsync({ workflowId: workflow.external_id, patch: { shared } })
|
|
304
|
+
),
|
|
305
|
+
onDelete: (workflow) => void deleteAll([workflow]),
|
|
306
|
+
onDeleteMany: (items) => void deleteAll(items),
|
|
307
|
+
onRun: (workflow) => void act(workflow, async () => {
|
|
308
|
+
const result = await run.mutateAsync(workflow.external_id);
|
|
309
|
+
if (result.conversation_ext_id) openConversation(result.conversation_ext_id);
|
|
310
|
+
if (result.error) {
|
|
311
|
+
onViewRuns?.(workflow);
|
|
312
|
+
notify(l.runFailed, "error");
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
if (result.execution_id && !result.conversation_ext_id) {
|
|
316
|
+
onViewRuns?.(workflow);
|
|
317
|
+
notify(l.documentAction(workflow), "success");
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
if (!result.conversation_ext_id) throw new Error(l.noThread);
|
|
321
|
+
})
|
|
322
|
+
}
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
var IMAGE_FILE_TYPES = /* @__PURE__ */ new Set(["png", "jpg", "jpeg", "gif", "bmp", "tiff", "webp"]);
|
|
326
|
+
function toWorkflowFieldDocument(doc) {
|
|
327
|
+
const isImage = IMAGE_FILE_TYPES.has((doc.file_type ?? "").toLowerCase());
|
|
328
|
+
return {
|
|
329
|
+
id: doc.external_id,
|
|
330
|
+
title: doc.doc_metadata?.title || doc.file_name || doc.external_id,
|
|
331
|
+
fileName: doc.file_name,
|
|
332
|
+
pages: isImage ? null : doc.n_pages ?? null,
|
|
333
|
+
tokens: isImage ? null : doc.tokens ?? null,
|
|
334
|
+
status: doc.status,
|
|
335
|
+
isImage
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function useConnectedWorkflowScopeSource() {
|
|
339
|
+
const { data: docs } = useConnectedDocuments();
|
|
340
|
+
const { data: tags } = useConnectedTags();
|
|
341
|
+
return useMemo(() => buildWorkflowScopeSource(docs, documentScopeLabels(tags)), [docs, tags]);
|
|
342
|
+
}
|
|
343
|
+
function useConnectedAgentOptions() {
|
|
344
|
+
const { data: agents } = useAgents();
|
|
345
|
+
return useMemo(
|
|
346
|
+
() => (agents ?? []).map((a) => ({ id: a.external_id, label: a.given_name || a.email })),
|
|
347
|
+
[agents]
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
function ConnectedWorkflowDocumentsField({
|
|
351
|
+
field,
|
|
352
|
+
value,
|
|
353
|
+
onChange,
|
|
354
|
+
onAddFiles,
|
|
355
|
+
labels
|
|
356
|
+
}) {
|
|
357
|
+
const arbi = useArbi();
|
|
358
|
+
const { notify } = useBlocksEnvironment();
|
|
359
|
+
const { ensureWorkspaceOpen } = useConnectedWorkspace();
|
|
360
|
+
const { data: docs, loaded, refetch } = useConnectedDocuments();
|
|
361
|
+
const documents = useMemo(() => docs.map(toWorkflowFieldDocument), [docs]);
|
|
362
|
+
const chosen = value.documents ?? [];
|
|
363
|
+
const { data: thumbnails } = useThumbnails(chosen, { enabled: (field.max ?? 1) > 1 });
|
|
364
|
+
const input = useRef(null);
|
|
365
|
+
const [adding, setAdding] = useState(false);
|
|
366
|
+
const upload = useCallback(
|
|
367
|
+
async (files) => {
|
|
368
|
+
setAdding(true);
|
|
369
|
+
try {
|
|
370
|
+
await ensureWorkspaceOpen();
|
|
371
|
+
for (const file of files) await arbi.documents.uploadFile(file, file.name);
|
|
372
|
+
} catch (error) {
|
|
373
|
+
notify(error instanceof Error && error.message ? error.message : String(error), "error");
|
|
374
|
+
} finally {
|
|
375
|
+
setAdding(false);
|
|
376
|
+
await refetch?.();
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
[arbi, ensureWorkspaceOpen, notify, refetch]
|
|
380
|
+
);
|
|
381
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
382
|
+
!onAddFiles && /* @__PURE__ */ jsx(
|
|
383
|
+
"input",
|
|
384
|
+
{
|
|
385
|
+
ref: input,
|
|
386
|
+
type: "file",
|
|
387
|
+
multiple: true,
|
|
388
|
+
className: "hidden",
|
|
389
|
+
"aria-label": "Add files",
|
|
390
|
+
"data-testid": "workflow-add-files-input",
|
|
391
|
+
onChange: (e) => {
|
|
392
|
+
const files = Array.from(e.target.files ?? []);
|
|
393
|
+
e.target.value = "";
|
|
394
|
+
if (files.length) void upload(files);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
),
|
|
398
|
+
/* @__PURE__ */ jsx(
|
|
399
|
+
WorkflowDocumentsField,
|
|
400
|
+
{
|
|
401
|
+
field,
|
|
402
|
+
value,
|
|
403
|
+
onChange,
|
|
404
|
+
documents,
|
|
405
|
+
loaded,
|
|
406
|
+
thumbnailOf: (id) => thumbnails?.[id],
|
|
407
|
+
onAddFiles: onAddFiles ?? ((files) => files?.length ? void upload(files) : input.current?.click()),
|
|
408
|
+
adding,
|
|
409
|
+
labels
|
|
410
|
+
}
|
|
411
|
+
)
|
|
412
|
+
] });
|
|
413
|
+
}
|
|
414
|
+
function ConnectedWorkflowLauncher({
|
|
415
|
+
onAddFiles,
|
|
416
|
+
...props
|
|
417
|
+
}) {
|
|
418
|
+
const scopeSource = useConnectedWorkflowScopeSource();
|
|
419
|
+
const agents = useConnectedAgentOptions();
|
|
420
|
+
return /* @__PURE__ */ jsx(
|
|
421
|
+
WorkflowLauncher,
|
|
422
|
+
{
|
|
423
|
+
...props,
|
|
424
|
+
scopeSource,
|
|
425
|
+
agents,
|
|
426
|
+
renderDocuments: (field, value, onChange) => /* @__PURE__ */ jsx(
|
|
427
|
+
ConnectedWorkflowDocumentsField,
|
|
428
|
+
{
|
|
429
|
+
field,
|
|
430
|
+
value,
|
|
431
|
+
onChange,
|
|
432
|
+
onAddFiles
|
|
433
|
+
}
|
|
434
|
+
)
|
|
435
|
+
}
|
|
436
|
+
);
|
|
437
|
+
}
|
|
184
438
|
var DEFAULT_CONNECTED_SKILL_UPLOAD_LABELS = {
|
|
185
439
|
title: "Add a skill",
|
|
186
440
|
description: "Bring in a skill someone sent you, from a file or a link.",
|
|
@@ -307,6 +561,387 @@ function ConnectedSkillUpload({ onDone, labels, className }) {
|
|
|
307
561
|
}
|
|
308
562
|
);
|
|
309
563
|
}
|
|
564
|
+
var SKILL_FOLDER = "skills/";
|
|
565
|
+
var NAME_PATTERN = /^[a-z0-9-]{1,64}$/;
|
|
566
|
+
var icon = /* @__PURE__ */ jsx(EntityIcon, { entityType: "SKILL" });
|
|
567
|
+
var errorText = (error, fallback) => error instanceof Error && error.message ? error.message : fallback;
|
|
568
|
+
var statusOf = (error) => error && typeof error === "object" && "status" in error ? error.status : void 0;
|
|
569
|
+
function ConnectedSkillsLibrary({
|
|
570
|
+
builtins = [],
|
|
571
|
+
initialSlug,
|
|
572
|
+
onRun,
|
|
573
|
+
onDraft,
|
|
574
|
+
renderEditor
|
|
575
|
+
}) {
|
|
576
|
+
const arbi = useArbi();
|
|
577
|
+
const { confirm, notify } = useBlocksEnvironment();
|
|
578
|
+
const { data: listings } = useSkills();
|
|
579
|
+
const upload = useUploadSkillFiles();
|
|
580
|
+
const setVisibility = useSetSkillVisibility();
|
|
581
|
+
const deleteSkill = useDeleteSkill();
|
|
582
|
+
const [mode, setMode] = useState("detail");
|
|
583
|
+
const [selected, setSelected] = useState(initialSlug ?? null);
|
|
584
|
+
const [query, setQuery] = useState("");
|
|
585
|
+
const [source, setSource] = useState("all");
|
|
586
|
+
const [type, setType] = useState("all");
|
|
587
|
+
const [view, setView] = useState("gallery");
|
|
588
|
+
const [isBusy, setIsBusy] = useState(false);
|
|
589
|
+
const all = useMemo(() => buildLibrarySkills(builtins, listings ?? []), [builtins, listings]);
|
|
590
|
+
const shown = useMemo(
|
|
591
|
+
() => filterLibrarySkills(all, { query, source, type }),
|
|
592
|
+
[all, query, source, type]
|
|
593
|
+
);
|
|
594
|
+
const current = all.find((s) => s.slug === selected) ?? null;
|
|
595
|
+
const { data: currentText, isLoading: textLoading } = useSkillSource(current?.docExtId);
|
|
596
|
+
useEffect(() => {
|
|
597
|
+
if (selected && !current && all.length > 0) setSelected(null);
|
|
598
|
+
}, [selected, current, all.length]);
|
|
599
|
+
const count = (s) => all.filter((x) => x.source === s).length;
|
|
600
|
+
const sourceOptions = [
|
|
601
|
+
{ id: "all", label: "All", count: all.length },
|
|
602
|
+
{ id: "builtin", label: SKILL_SOURCE_LABELS.builtin, count: count("builtin") },
|
|
603
|
+
{ id: "mine", label: SKILL_SOURCE_LABELS.mine, count: count("mine") },
|
|
604
|
+
{ id: "shared", label: SKILL_SOURCE_LABELS.shared, count: count("shared") }
|
|
605
|
+
];
|
|
606
|
+
const types = [...new Set(all.map((s) => s.type))];
|
|
607
|
+
const typeOptions = [
|
|
608
|
+
{ id: "all", label: "Any kind" },
|
|
609
|
+
...types.map((t) => ({ id: t, label: SKILL_TYPE_LABELS[t] ?? t }))
|
|
610
|
+
];
|
|
611
|
+
const pick = (slug) => {
|
|
612
|
+
setSelected(slug);
|
|
613
|
+
setMode("detail");
|
|
614
|
+
};
|
|
615
|
+
const markdownOf = async (skill) => {
|
|
616
|
+
if (!skill.docExtId) return workflowToSkillMarkdown(skill.workflow);
|
|
617
|
+
const response = await arbi.documents.download(skill.docExtId);
|
|
618
|
+
if (!response.ok) throw new Error(`Could not read the skill (${response.status})`);
|
|
619
|
+
return response.text();
|
|
620
|
+
};
|
|
621
|
+
const saveAs = (slug, markdown, shared = false) => upload.mutateAsync([
|
|
622
|
+
{
|
|
623
|
+
folder: `${SKILL_FOLDER}${slug}`,
|
|
624
|
+
fileName: SKILL_MAIN_FILENAME,
|
|
625
|
+
content: new Blob([markdown], { type: "text/markdown" }),
|
|
626
|
+
shared
|
|
627
|
+
}
|
|
628
|
+
]);
|
|
629
|
+
const busy = async (work) => {
|
|
630
|
+
setIsBusy(true);
|
|
631
|
+
try {
|
|
632
|
+
await work();
|
|
633
|
+
} finally {
|
|
634
|
+
setIsBusy(false);
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
const makeCopy = (skill) => busy(async () => {
|
|
638
|
+
try {
|
|
639
|
+
await saveAs(skill.slug, await markdownOf(skill));
|
|
640
|
+
notify(
|
|
641
|
+
"Your copy is ready. It is used instead of the original; delete it to go back.",
|
|
642
|
+
"success"
|
|
643
|
+
);
|
|
644
|
+
setSelected(skill.slug);
|
|
645
|
+
} catch (error) {
|
|
646
|
+
notify(errorText(error, "Could not make a copy"), "error");
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
const toggleShare = (skill) => {
|
|
650
|
+
if (!skill.docExtId) return;
|
|
651
|
+
const docExtId = skill.docExtId;
|
|
652
|
+
const next = skill.isShared ? "mine" : "global";
|
|
653
|
+
return busy(async () => {
|
|
654
|
+
try {
|
|
655
|
+
await setVisibility.mutateAsync({ docExtId, visibility: next });
|
|
656
|
+
notify(next === "global" ? "Shared with everyone" : "Made private", "success");
|
|
657
|
+
} catch (error) {
|
|
658
|
+
notify(
|
|
659
|
+
statusOf(error) === 409 || errorText(error, "").includes("409") ? "Someone has already shared a skill with this name. Rename yours first." : "Could not change who can see this skill",
|
|
660
|
+
"error"
|
|
661
|
+
);
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
};
|
|
665
|
+
const remove = async (skill) => {
|
|
666
|
+
if (!skill.docExtId) return;
|
|
667
|
+
const docExtId = skill.docExtId;
|
|
668
|
+
const ok = await confirm({
|
|
669
|
+
message: skill.replacesBuiltin ? `Delete your copy of "${skill.title}"? The original will be used again.` : `Delete "${skill.title}"? This cannot be undone.`,
|
|
670
|
+
title: "Delete skill"
|
|
671
|
+
});
|
|
672
|
+
if (!ok) return;
|
|
673
|
+
await busy(async () => {
|
|
674
|
+
try {
|
|
675
|
+
await deleteSkill.mutateAsync(docExtId);
|
|
676
|
+
notify(`${skill.title} deleted`, "success");
|
|
677
|
+
setSelected(null);
|
|
678
|
+
} catch {
|
|
679
|
+
notify("Could not delete the skill", "error");
|
|
680
|
+
}
|
|
681
|
+
});
|
|
682
|
+
};
|
|
683
|
+
const exportFile = async (skill) => {
|
|
684
|
+
try {
|
|
685
|
+
downloadBlob(
|
|
686
|
+
new Blob([await markdownOf(skill)], { type: "text/markdown" }),
|
|
687
|
+
SKILL_MAIN_FILENAME
|
|
688
|
+
);
|
|
689
|
+
} catch (error) {
|
|
690
|
+
notify(errorText(error, "Could not export the skill"), "error");
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
const rightVisible = mode !== "detail" || current !== null;
|
|
694
|
+
const backToList = () => {
|
|
695
|
+
setMode("detail");
|
|
696
|
+
setSelected(null);
|
|
697
|
+
};
|
|
698
|
+
const done = (slug) => {
|
|
699
|
+
if (slug) setSelected(slug);
|
|
700
|
+
setMode("detail");
|
|
701
|
+
};
|
|
702
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 border-t border-border", children: [
|
|
703
|
+
/* @__PURE__ */ jsxs(
|
|
704
|
+
"div",
|
|
705
|
+
{
|
|
706
|
+
className: cn(
|
|
707
|
+
"flex min-h-0 w-full flex-col md:w-[26rem] md:shrink-0 md:border-r md:border-border",
|
|
708
|
+
rightVisible && "max-md:hidden"
|
|
709
|
+
),
|
|
710
|
+
"data-testid": "skills-list-pane",
|
|
711
|
+
children: [
|
|
712
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 p-3", children: [
|
|
713
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
714
|
+
/* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
|
|
715
|
+
/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
|
|
716
|
+
/* @__PURE__ */ jsx(
|
|
717
|
+
Input,
|
|
718
|
+
{
|
|
719
|
+
value: query,
|
|
720
|
+
onChange: (e) => setQuery(e.target.value),
|
|
721
|
+
placeholder: "Search skills",
|
|
722
|
+
"aria-label": "Search skills",
|
|
723
|
+
className: "pl-9 pointer-coarse:min-h-11",
|
|
724
|
+
"data-testid": "skills-browser-search"
|
|
725
|
+
}
|
|
726
|
+
)
|
|
727
|
+
] }),
|
|
728
|
+
/* @__PURE__ */ jsx(SkillViewToggle, { value: view, onChange: setView })
|
|
729
|
+
] }),
|
|
730
|
+
/* @__PURE__ */ jsx(
|
|
731
|
+
SkillFilterChips,
|
|
732
|
+
{
|
|
733
|
+
label: "Show",
|
|
734
|
+
value: source,
|
|
735
|
+
onChange: (id) => setSource(id),
|
|
736
|
+
options: sourceOptions
|
|
737
|
+
}
|
|
738
|
+
),
|
|
739
|
+
types.length > 1 && /* @__PURE__ */ jsx(
|
|
740
|
+
SkillFilterChips,
|
|
741
|
+
{
|
|
742
|
+
label: "Kind",
|
|
743
|
+
value: type,
|
|
744
|
+
onChange: setType,
|
|
745
|
+
options: typeOptions,
|
|
746
|
+
testIdPrefix: "skills-type"
|
|
747
|
+
}
|
|
748
|
+
),
|
|
749
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
750
|
+
/* @__PURE__ */ jsxs(
|
|
751
|
+
Button,
|
|
752
|
+
{
|
|
753
|
+
size: "sm",
|
|
754
|
+
onClick: () => setMode("new"),
|
|
755
|
+
className: "pointer-coarse:min-h-11",
|
|
756
|
+
"data-testid": "skills-new",
|
|
757
|
+
children: [
|
|
758
|
+
/* @__PURE__ */ jsx(Plus, { className: "mr-1 size-4" }),
|
|
759
|
+
"New skill"
|
|
760
|
+
]
|
|
761
|
+
}
|
|
762
|
+
),
|
|
763
|
+
/* @__PURE__ */ jsxs(
|
|
764
|
+
Button,
|
|
765
|
+
{
|
|
766
|
+
size: "sm",
|
|
767
|
+
variant: "outline",
|
|
768
|
+
onClick: () => setMode("add"),
|
|
769
|
+
className: "pointer-coarse:min-h-11",
|
|
770
|
+
"data-testid": "skills-add",
|
|
771
|
+
children: [
|
|
772
|
+
/* @__PURE__ */ jsx(Upload, { className: "mr-1 size-4" }),
|
|
773
|
+
"Add a skill"
|
|
774
|
+
]
|
|
775
|
+
}
|
|
776
|
+
)
|
|
777
|
+
] })
|
|
778
|
+
] }),
|
|
779
|
+
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-3 pb-3", "data-testid": "skills-list", children: shown.length === 0 ? /* @__PURE__ */ jsx("p", { className: "py-10 text-center text-sm text-muted-foreground", children: "No skills match. Try another word or filter." }) : /* @__PURE__ */ jsx(
|
|
780
|
+
"div",
|
|
781
|
+
{
|
|
782
|
+
className: cn(
|
|
783
|
+
"gap-2",
|
|
784
|
+
view === "gallery" ? "grid grid-cols-[repeat(auto-fill,minmax(9.5rem,1fr))]" : "flex flex-col"
|
|
785
|
+
),
|
|
786
|
+
children: shown.map((skill) => /* @__PURE__ */ jsx(
|
|
787
|
+
SkillTile,
|
|
788
|
+
{
|
|
789
|
+
name: skill.title,
|
|
790
|
+
testId: `skill-tile-${skill.slug}`,
|
|
791
|
+
description: skill.description,
|
|
792
|
+
sourceLabel: skill.isShared ? `${SKILL_SOURCE_LABELS.mine}, shared` : SKILL_SOURCE_LABELS[skill.source],
|
|
793
|
+
type: skill.type,
|
|
794
|
+
icon,
|
|
795
|
+
layout: view,
|
|
796
|
+
selected: skill.slug === selected,
|
|
797
|
+
onSelect: () => pick(skill.slug)
|
|
798
|
+
},
|
|
799
|
+
skill.slug
|
|
800
|
+
))
|
|
801
|
+
}
|
|
802
|
+
) })
|
|
803
|
+
]
|
|
804
|
+
}
|
|
805
|
+
),
|
|
806
|
+
/* @__PURE__ */ jsxs(
|
|
807
|
+
"div",
|
|
808
|
+
{
|
|
809
|
+
className: cn("flex min-h-0 min-w-0 flex-1 flex-col", !rightVisible && "max-md:hidden"),
|
|
810
|
+
"data-testid": "skills-detail-pane",
|
|
811
|
+
children: [
|
|
812
|
+
rightVisible && /* @__PURE__ */ jsxs(
|
|
813
|
+
Button,
|
|
814
|
+
{
|
|
815
|
+
variant: "ghost",
|
|
816
|
+
size: "sm",
|
|
817
|
+
onClick: backToList,
|
|
818
|
+
className: "m-2 self-start pointer-coarse:min-h-11 md:hidden",
|
|
819
|
+
"data-testid": "skills-back",
|
|
820
|
+
children: [
|
|
821
|
+
/* @__PURE__ */ jsx(ArrowLeft, { className: "mr-1 size-4" }),
|
|
822
|
+
"All skills"
|
|
823
|
+
]
|
|
824
|
+
}
|
|
825
|
+
),
|
|
826
|
+
mode === "new" && /* @__PURE__ */ jsx(
|
|
827
|
+
SkillGenerateForm,
|
|
828
|
+
{
|
|
829
|
+
icon,
|
|
830
|
+
onGenerate: (desc) => {
|
|
831
|
+
onDraft(`/create-skill ${desc}`.trim() + " ");
|
|
832
|
+
notify("Sent to the chat: the assistant will draft your skill.", "info");
|
|
833
|
+
},
|
|
834
|
+
onManual: () => setMode("edit")
|
|
835
|
+
}
|
|
836
|
+
),
|
|
837
|
+
mode === "edit" && /* @__PURE__ */ jsx(
|
|
838
|
+
SkillEditor,
|
|
839
|
+
{
|
|
840
|
+
skill: current?.source === "mine" ? current : null,
|
|
841
|
+
text: current?.source === "mine" ? currentText : void 0,
|
|
842
|
+
renderEditor,
|
|
843
|
+
onSave: async (slug, markdown, isEditing) => {
|
|
844
|
+
await saveAs(slug, markdown, isEditing && !!current?.isShared);
|
|
845
|
+
notify(isEditing ? `${slug} saved` : `${slug} added`, "success");
|
|
846
|
+
done(slug);
|
|
847
|
+
},
|
|
848
|
+
onCancel: () => done(),
|
|
849
|
+
isSaving: upload.isPending
|
|
850
|
+
}
|
|
851
|
+
),
|
|
852
|
+
mode === "add" && /* @__PURE__ */ jsx(ConnectedSkillUpload, { onDone: done }),
|
|
853
|
+
mode === "detail" && current && /* @__PURE__ */ jsx(
|
|
854
|
+
SkillLibraryDetail,
|
|
855
|
+
{
|
|
856
|
+
skill: current,
|
|
857
|
+
icon,
|
|
858
|
+
instructions: current.docExtId ? currentText ? parseSkillFrontmatter(currentText, SKILL_MAIN_FILENAME).content : "" : current.workflow.run.kind === "prompt" ? current.workflow.run.promptTemplate : "",
|
|
859
|
+
isLoading: !!current.docExtId && textLoading,
|
|
860
|
+
actions: {
|
|
861
|
+
onRun: () => onRun(current.slug),
|
|
862
|
+
onCopy: () => void makeCopy(current),
|
|
863
|
+
onEdit: () => setMode("edit"),
|
|
864
|
+
onToggleShare: () => void toggleShare(current),
|
|
865
|
+
onExport: () => void exportFile(current),
|
|
866
|
+
onDelete: () => void remove(current),
|
|
867
|
+
isBusy
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
),
|
|
871
|
+
mode === "detail" && !current && /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-center p-8 text-center text-sm text-muted-foreground max-md:hidden", children: "Pick a skill to read it, run it or make a copy." })
|
|
872
|
+
]
|
|
873
|
+
}
|
|
874
|
+
)
|
|
875
|
+
] });
|
|
876
|
+
}
|
|
877
|
+
function SkillEditor({
|
|
878
|
+
skill,
|
|
879
|
+
text,
|
|
880
|
+
renderEditor,
|
|
881
|
+
onSave,
|
|
882
|
+
onCancel,
|
|
883
|
+
isSaving
|
|
884
|
+
}) {
|
|
885
|
+
const { notify } = useBlocksEnvironment();
|
|
886
|
+
const isEditing = !!skill;
|
|
887
|
+
const [name, setName] = useState(skill?.slug ?? "");
|
|
888
|
+
const [description, setDescription] = useState("");
|
|
889
|
+
const [body, setBody] = useState("");
|
|
890
|
+
const [seeded, setSeeded] = useState(!isEditing);
|
|
891
|
+
const [nameError, setNameError] = useState(null);
|
|
892
|
+
if (isEditing && !seeded && text !== void 0) {
|
|
893
|
+
const parsed = parseSkillFrontmatter(text, SKILL_MAIN_FILENAME);
|
|
894
|
+
setDescription(parsed.description ?? "");
|
|
895
|
+
setBody(parsed.content ?? "");
|
|
896
|
+
setSeeded(true);
|
|
897
|
+
}
|
|
898
|
+
const save = async () => {
|
|
899
|
+
if (!NAME_PATTERN.test(name)) {
|
|
900
|
+
setNameError("Use 1\u201364 lowercase letters, numbers or hyphens.");
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
if (description.trim().length < 1) {
|
|
904
|
+
notify("Add a short description.", "error");
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
const slug = skillSlug(name);
|
|
908
|
+
try {
|
|
909
|
+
await onSave(slug, serializeSkill({ name: slug, description, body }), isEditing);
|
|
910
|
+
} catch (err) {
|
|
911
|
+
notify(errorText(err, "Could not save the skill"), "error");
|
|
912
|
+
}
|
|
913
|
+
};
|
|
914
|
+
return /* @__PURE__ */ jsx(
|
|
915
|
+
SkillEditForm,
|
|
916
|
+
{
|
|
917
|
+
name,
|
|
918
|
+
onNameChange: setName,
|
|
919
|
+
isNameLocked: isEditing,
|
|
920
|
+
nameError,
|
|
921
|
+
description,
|
|
922
|
+
onDescriptionChange: setDescription,
|
|
923
|
+
editor: renderEditor ? renderEditor(body, setBody) : /* @__PURE__ */ jsx(
|
|
924
|
+
Textarea,
|
|
925
|
+
{
|
|
926
|
+
value: body,
|
|
927
|
+
onChange: (e) => setBody(e.target.value),
|
|
928
|
+
className: "min-h-64 flex-1 font-mono text-sm",
|
|
929
|
+
"aria-label": "Instructions"
|
|
930
|
+
}
|
|
931
|
+
),
|
|
932
|
+
isSaving,
|
|
933
|
+
isEditing,
|
|
934
|
+
onSave: save,
|
|
935
|
+
onCancel,
|
|
936
|
+
labels: { create: "Add skill" },
|
|
937
|
+
testIds: {
|
|
938
|
+
name: "skill-edit-name",
|
|
939
|
+
description: "skill-edit-description",
|
|
940
|
+
save: "skill-edit-save"
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
);
|
|
944
|
+
}
|
|
310
945
|
var StreamedArtifactEditor = lazy(() => import('../StreamedArtifactEditor-XQNANTWM.js'));
|
|
311
946
|
function StreamedArtifact({
|
|
312
947
|
artifacts,
|
|
@@ -1396,7 +2031,7 @@ function useConnectedShellWorkspaces(options = {}) {
|
|
|
1396
2031
|
select: (workspace) => setWorkspace(workspace.id)
|
|
1397
2032
|
});
|
|
1398
2033
|
}
|
|
1399
|
-
function
|
|
2034
|
+
function errorText2(error, fallback) {
|
|
1400
2035
|
const body = error?.apiError;
|
|
1401
2036
|
return typeof body?.detail === "string" ? body.detail : fallback;
|
|
1402
2037
|
}
|
|
@@ -1446,7 +2081,7 @@ function ConnectedProfileCard({
|
|
|
1446
2081
|
await requestEmailChange.mutateAsync(address);
|
|
1447
2082
|
notify("Verification code sent to your new email", "success");
|
|
1448
2083
|
} catch (e) {
|
|
1449
|
-
notify(
|
|
2084
|
+
notify(errorText2(e, "Failed to send verification code"), "error");
|
|
1450
2085
|
throw e;
|
|
1451
2086
|
}
|
|
1452
2087
|
},
|
|
@@ -1455,7 +2090,7 @@ function ConnectedProfileCard({
|
|
|
1455
2090
|
await confirmEmailChange.mutateAsync(args);
|
|
1456
2091
|
notify("Email address updated", "success");
|
|
1457
2092
|
} catch (e) {
|
|
1458
|
-
notify(
|
|
2093
|
+
notify(errorText2(e, "Invalid or expired verification code"), "error");
|
|
1459
2094
|
throw e;
|
|
1460
2095
|
}
|
|
1461
2096
|
}
|
|
@@ -3909,6 +4544,6 @@ function ConnectedAgentChatPanel({
|
|
|
3909
4544
|
] });
|
|
3910
4545
|
}
|
|
3911
4546
|
|
|
3912
|
-
export { ArbiAppProvider, ConnectedAgentChatPanel, ConnectedDangerZone, ConnectedIdentityVerification, ConnectedLogoutDialog, ConnectedMailAccounts, ConnectedMailComposer, ConnectedMailMessage, ConnectedMailSetup, ConnectedMailbox, ConnectedNotificationPreferences, ConnectedPasswordChangeDialog, ConnectedProfileCard, ConnectedRequireVerified, ConnectedSecuritySection, ConnectedSessionsRow, ConnectedSkillUpload, ConnectedTagTable, ConnectedTaskAccessRequest, ConnectedThreadFollow, ConnectedWorkflowRunner, ConnectedWorkspaceActivity, ConnectedWorkspaceNotificationMenu, DEFAULT_CONNECTED_SKILL_UPLOAD_LABELS, DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS, StreamedArtifact, WorkflowRunThread, defaultUnmetPasswordRequirement, resolveMailbox, useConnectedDocxNotifications, useConnectedShellWorkspaces, useConnectedWorkNotifications };
|
|
4547
|
+
export { ArbiAppProvider, ConnectedAgentChatPanel, ConnectedDangerZone, ConnectedIdentityVerification, ConnectedLogoutDialog, ConnectedMailAccounts, ConnectedMailComposer, ConnectedMailMessage, ConnectedMailSetup, ConnectedMailbox, ConnectedNotificationPreferences, ConnectedPasswordChangeDialog, ConnectedProfileCard, ConnectedRequireVerified, ConnectedSecuritySection, ConnectedSessionsRow, ConnectedSkillUpload, ConnectedSkillsLibrary, ConnectedTagTable, ConnectedTaskAccessRequest, ConnectedThreadFollow, ConnectedWorkflowDocumentsField, ConnectedWorkflowLauncher, ConnectedWorkflowRunner, ConnectedWorkflowsTable, ConnectedWorkspaceActivity, ConnectedWorkspaceNotificationMenu, DEFAULT_CONNECTED_SKILL_UPLOAD_LABELS, DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS, DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS, StreamedArtifact, WorkflowRunThread, defaultUnmetPasswordRequirement, resolveMailbox, toWorkflowFieldDocument, useConnectedAgentOptions, useConnectedDocxNotifications, useConnectedShellWorkspaces, useConnectedWorkNotifications, useConnectedWorkflowScopeSource, useConnectedWorkspaceRole };
|
|
3913
4548
|
//# sourceMappingURL=index.js.map
|
|
3914
4549
|
//# sourceMappingURL=index.js.map
|