Skip to content

Commit

Permalink
[Ahuna] Users can create private assistants & change scope in builder (
Browse files Browse the repository at this point in the history
…#2870)

* [Ahuna] Users can create private assistants & change scope in builder

* fix flow

* Working personal assistants

* fix creation published

* fix home

---------

Co-authored-by: Stanislas Polu <[email protected]>
  • Loading branch information
philipperolet and spolu authored Dec 15, 2023
1 parent 7211f97 commit 3d71d28
Show file tree
Hide file tree
Showing 10 changed files with 590 additions and 125 deletions.
11 changes: 7 additions & 4 deletions front/components/assistant/AssistantActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ export function DeleteAssistantDialog({
show,
onClose,
onDelete,
isPrivateAssistant,
}: {
owner: WorkspaceType;
agentConfigurationId: string;
show: boolean;
onClose: () => void;
onDelete: () => void;
isPrivateAssistant?: boolean;
}) {
const sendNotification = useContext(SendNotificationsContext);

Expand All @@ -29,7 +31,7 @@ export function DeleteAssistantDialog({
isOpen={show}
title={`Deleting assistant`}
onCancel={onClose}
validateLabel="Delete for Everyone"
validateLabel={isPrivateAssistant ? "Delete" : "Delete for Everyone"}
validateVariant="primaryWarning"
onValidate={async () => {
try {
Expand Down Expand Up @@ -68,8 +70,9 @@ export function DeleteAssistantDialog({
<div className="font-bold">Are you sure you want to delete?</div>

<div>
This will be permanent and delete the&nbsp;assistant
for&nbsp;everyone.
{isPrivateAssistant
? "This will delete your personal assistant permanently."
: "This will be permanent and delete the assistant for everyone."}
</div>
</div>
</Dialog>
Expand All @@ -94,7 +97,7 @@ export function RemoveAssistantFromListDialog({
return (
<Dialog
isOpen={show}
title={`Remove @${agentConfiguration.name} from my list`}
title={`Remove from my list`}
onCancel={onClose}
validateLabel="Remove"
validateVariant="primaryWarning"
Expand Down
48 changes: 25 additions & 23 deletions front/components/assistant/AssistantPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,29 +208,31 @@ export function AssistantPreview({
];

let galleryChip = null;
switch (flow) {
case "personal":
galleryChip = agentConfiguration.userListStatus === "in-list" && (
<Chip
color="emerald"
size="xs"
label={agentConfiguration.scope === "global" ? "Active" : "Added"}
/>
);
break;
case "workspace":
galleryChip = ["workspace", "global"].includes(
agentConfiguration.scope
) && (
<Chip
color="emerald"
size="xs"
label={agentConfiguration.scope === "global" ? "Active" : "Added"}
/>
);
break;
default:
assertNever(flow);
if (variant === "gallery") {
switch (flow) {
case "personal":
galleryChip = agentConfiguration.userListStatus === "in-list" && (
<Chip
color="emerald"
size="xs"
label={agentConfiguration.scope === "global" ? "Active" : "Added"}
/>
);
break;
case "workspace":
galleryChip = ["workspace", "global"].includes(
agentConfiguration.scope
) && (
<Chip
color="emerald"
size="xs"
label={agentConfiguration.scope === "global" ? "Active" : "Added"}
/>
);
break;
default:
assertNever(flow);
}
}

// Define button groups with JSX elements, including default buttons
Expand Down
51 changes: 43 additions & 8 deletions front/components/assistant_builder/AssistantBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import {
SlackLogo,
TrashIcon,
} from "@dust-tt/sparkle";
import { ConnectorProvider, DataSourceType } from "@dust-tt/types";
import {
AgentConfigurationScope,
ConnectorProvider,
DataSourceType,
} from "@dust-tt/types";
import { UserType, WorkspaceType } from "@dust-tt/types";
import {
CLAUDE_DEFAULT_MODEL_CONFIG,
Expand Down Expand Up @@ -51,6 +55,7 @@ import {
SPIRIT_AVATARS_BASE_PATH,
TIME_FRAME_UNIT_TO_LABEL,
} from "@app/components/assistant_builder/shared";
import { TeamSharingSection } from "@app/components/assistant_builder/TeamSharingSection";
import DataSourceResourceSelectorTree from "@app/components/DataSourceResourceSelectorTree";
import AppLayout from "@app/components/sparkle/AppLayout";
import {
Expand Down Expand Up @@ -148,6 +153,7 @@ type AssistantBuilderState = {
databaseQueryConfiguration: AssistantBuilderDatabaseQueryConfiguration | null;
handle: string | null;
description: string | null;
scope: Exclude<AgentConfigurationScope, "global">;
instructions: string | null;
avatarUrl: string | null;
generationSettings: {
Expand All @@ -170,6 +176,7 @@ export type AssistantBuilderInitialState = {
databaseQueryConfiguration: AssistantBuilderState["databaseQueryConfiguration"];
handle: string;
description: string;
scope: Exclude<AgentConfigurationScope, "global">;
instructions: string;
avatarUrl: string;
generationSettings: {
Expand All @@ -178,6 +185,8 @@ export type AssistantBuilderInitialState = {
} | null;
};

export const BUILDER_FLOWS = ["workspace_assistants", "my_assistants"] as const;
export type BuilderFlow = (typeof BUILDER_FLOWS)[number];
type AssistantBuilderProps = {
user: UserType;
owner: WorkspaceType;
Expand All @@ -188,6 +197,7 @@ type AssistantBuilderProps = {
dustApps: AppType[];
initialBuilderState: AssistantBuilderInitialState | null;
agentConfigurationId: string | null;
flow: BuilderFlow;
};

const DEFAULT_ASSISTANT_STATE: AssistantBuilderState = {
Expand All @@ -200,6 +210,7 @@ const DEFAULT_ASSISTANT_STATE: AssistantBuilderState = {
dustAppConfiguration: null,
databaseQueryConfiguration: null,
handle: null,
scope: "private",
description: null,
instructions: null,
avatarUrl: null,
Expand Down Expand Up @@ -235,15 +246,19 @@ export default function AssistantBuilder({
dustApps,
initialBuilderState,
agentConfigurationId,
flow,
}: AssistantBuilderProps) {
const router = useRouter();
const sendNotification = React.useContext(SendNotificationsContext);
const slackDataSource = dataSources.find(
(ds) => ds.connectorProvider === "slack"
);
const defaultScope =
flow === "workspace_assistants" ? "workspace" : "private";

const [builderState, setBuilderState] = useState<AssistantBuilderState>({
...DEFAULT_ASSISTANT_STATE,
scope: initialBuilderState?.scope ?? defaultScope,
generationSettings: {
...DEFAULT_ASSISTANT_STATE.generationSettings,
modelSettings:
Expand Down Expand Up @@ -358,6 +373,7 @@ export default function AssistantBuilder({
initialBuilderState.databaseQueryConfiguration,
handle: initialBuilderState.handle,
description: initialBuilderState.description,
scope: initialBuilderState.scope ?? "private",
instructions: initialBuilderState.instructions,
avatarUrl: initialBuilderState.avatarUrl,
generationSettings: initialBuilderState.generationSettings ?? {
Expand Down Expand Up @@ -615,7 +631,7 @@ export default function AssistantBuilder({
pictureUrl: builderState.avatarUrl,
description: builderState.description.trim(),
status: "active",
scope: "workspace",
scope: builderState.scope,
action: actionParam,
generation: {
prompt: builderState.instructions.trim(),
Expand Down Expand Up @@ -785,24 +801,33 @@ export default function AssistantBuilder({
<AppLayoutSimpleCloseTitle
title="Create an assistant"
onClose={async () => {
await router.push(`/w/${owner.sId}/builder/assistants`);
if (flow === "workspace_assistants")
await router.push(`/w/${owner.sId}/builder/assistants`);
else await router.push(`/w/${owner.sId}/assistant/assistants`);
}}
/>
) : (
<AppLayoutSimpleSaveCancelTitle
title="Edit an Assistant"
onCancel={async () => {
await router.push(`/w/${owner.sId}/builder/assistants`);
if (flow === "workspace_assistants")
await router.push(`/w/${owner.sId}/builder/assistants`);
else await router.push(`/w/${owner.sId}/assistant/assistants`);
}}
onSave={
submitEnabled
? () => {
setIsSavingOrDeleting(true);
submitForm()
.then(async () => {
await router.push(
`/w/${owner.sId}/builder/assistants`
);
if (flow === "workspace_assistants")
await router.push(
`/w/${owner.sId}/builder/assistants`
);
else
await router.push(
`/w/${owner.sId}/assistant/assistants`
);
setIsSavingOrDeleting(false);
})
.catch((e) => {
Expand Down Expand Up @@ -895,7 +920,17 @@ export default function AssistantBuilder({
</div>
</div>
</div>

<TeamSharingSection
owner={owner}
initialScope={initialBuilderState?.scope ?? defaultScope}
newScope={builderState.scope}
setNewScope={(
scope: Exclude<AgentConfigurationScope, "global">
) => {
setEdited(true);
setBuilderState((state) => ({ ...state, scope }));
}}
/>
<div className="mt-8 flex w-full flex-row items-start">
<div className="flex w-full flex-col gap-4">
<div className="text-2xl font-bold text-element-900">
Expand Down
Loading

0 comments on commit 3d71d28

Please sign in to comment.