Skip to content

Commit

Permalink
feat: maintain brain last_update time
Browse files Browse the repository at this point in the history
  • Loading branch information
mamadoudicko committed Sep 21, 2023
1 parent b67e2db commit 8e477cc
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 28 deletions.
6 changes: 6 additions & 0 deletions backend/celery_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
from models.notifications import NotificationsStatusEnum
from models.settings import get_supabase_client
from parsers.github import process_github
from repository.brain.update_brain_last_update_time import (
update_brain_last_update_time,
)
from repository.notification.update_notification import update_notification_by_id
from utils.processors import filter_file

Expand Down Expand Up @@ -98,6 +101,8 @@ def process_file_and_notify(
message=str(notification_message),
),
)
update_brain_last_update_time(brain_id)

return True


Expand Down Expand Up @@ -158,4 +163,5 @@ def process_crawl_and_notify(
message=str(notification_message),
),
)
update_brain_last_update_time(brain_id)
return True
5 changes: 5 additions & 0 deletions backend/models/databases/supabase/brains.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ def get_public_brains(self) -> list[PublicBrain]:
public_brains.append(brain)
return public_brains

def update_brain_last_update_time(self, brain_id: UUID) -> None:
self.db.table("brains").update({"last_update": "now()"}).match(
{"brain_id": brain_id}
).execute()

def get_brain_for_user(self, user_id, brain_id) -> MinimalBrainEntity | None:
response = (
self.db.from_("brains_users")
Expand Down
9 changes: 8 additions & 1 deletion backend/repository/brain/update_brain.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@
from models import BrainEntity, get_supabase_db
from models.databases.supabase.brains import BrainUpdatableProperties

from repository.brain.update_brain_last_update_time import update_brain_last_update_time


def update_brain_by_id(brain_id: UUID, brain: BrainUpdatableProperties) -> BrainEntity:
"""Update a prompt by id"""
supabase_db = get_supabase_db()

return supabase_db.update_brain_by_id(brain_id, brain) # type: ignore
brain_update_answer = supabase_db.update_brain_by_id(brain_id, brain)
if brain_update_answer is None:
raise Exception("Brain not found")

update_brain_last_update_time(brain_id)
return brain_update_answer
8 changes: 8 additions & 0 deletions backend/repository/brain/update_brain_last_update_time.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from uuid import UUID

from models.settings import get_supabase_db


def update_brain_last_update_time(brain_id: UUID):
supabase_db = get_supabase_db()
supabase_db.update_brain_last_update_time(brain_id)
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
/* eslint-disable max-lines */
import { Content, List, Root } from "@radix-ui/react-tabs";
import { useTranslation } from "react-i18next";

import Button from "@/lib/components/ui/Button";
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";

import { BrainTabTrigger, KnowledgeTab, PeopleTab } from "./components";
import ConfirmationDeleteModal from "./components/Modals/ConfirmationDeleteModal";
import { SettingsTab } from "./components/SettingsTab/SettingsTab";
import { useBrainManagementTabs } from "./hooks/useBrainManagementTabs";
import { isUserBrainOwner } from "./utils/canManageBrain";

export const BrainManagementTabs = (): JSX.Element => {
const { t } = useTranslation(["translation", "config", "delete_brain"]);
Expand All @@ -19,13 +22,21 @@ export const BrainManagementTabs = (): JSX.Element => {
setIsDeleteModalOpen,
brain,
} = useBrainManagementTabs();

const isPubliclyAccessible = brain?.status === "public";
const { allBrains } = useBrainContext();

if (brainId === undefined) {
return <div />;
}

const isCurrentUserBrainOwner = isUserBrainOwner({
brainId,
userAccessibleBrains: allBrains,
});

const isPublicBrain = brain?.status === "public";

const hasEditRights = !isPublicBrain || isCurrentUserBrainOwner;

return (
<Root
className="flex flex-col w-full h-full shadow-md dark:shadow-primary/25 hover:shadow-xl transition-shadow rounded-xl overflow-hidden bg-white dark:bg-black border border-black/10 dark:border-white/25 p-4 md:p-10"
Expand All @@ -41,7 +52,7 @@ export const BrainManagementTabs = (): JSX.Element => {
value="settings"
onChange={setSelectedTab}
/>
{!isPubliclyAccessible && (
{hasEditRights && (
<>
<BrainTabTrigger
selected={selectedTab === "people"}
Expand Down Expand Up @@ -73,7 +84,7 @@ export const BrainManagementTabs = (): JSX.Element => {

<div className="flex justify-center mt-4">
<Button
disabled={isPubliclyAccessible}
disabled={!isCurrentUserBrainOwner}
className="px-8 md:px-20 py-2 bg-red-500 text-white rounded-md"
onClick={() => setIsDeleteModalOpen(true)}
>
Expand All @@ -89,5 +100,3 @@ export const BrainManagementTabs = (): JSX.Element => {
</Root>
);
};

export default BrainManagementTabs;
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@ import { Chip } from "@/lib/components/ui/Chip";
import { Divider } from "@/lib/components/ui/Divider";
import Field from "@/lib/components/ui/Field";
import { TextArea } from "@/lib/components/ui/TextArea";
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
import { defineMaxTokens } from "@/lib/helpers/defineMaxTokens";
import { SaveButton } from "@/shared/SaveButton";

import { PublicPrompts } from "./components/PublicPrompts/PublicPrompts";
import { useSettingsTab } from "./hooks/useSettingsTab";
import { isUserBrainOwner } from "../../utils/canManageBrain";

type SettingsTabProps = {
brainId: UUID;
};

// eslint-disable-next-line complexity
export const SettingsTab = ({ brainId }: SettingsTabProps): JSX.Element => {
const { t } = useTranslation(["translation", "brain", "config"]);
const {
Expand All @@ -38,8 +41,16 @@ export const SettingsTab = ({ brainId }: SettingsTabProps): JSX.Element => {
accessibleModels,
brain,
} = useSettingsTab({ brainId });
const { allBrains } = useBrainContext();

const isPubliclyAccessible = brain?.status === "public";
const isCurrentUserBrainOwner = isUserBrainOwner({
brainId,
userAccessibleBrains: allBrains,
});

const isPublicBrain = brain?.status === "public";

const hasEditRights = !isPublicBrain || isCurrentUserBrainOwner;

return (
<form
Expand All @@ -58,14 +69,14 @@ export const SettingsTab = ({ brainId }: SettingsTabProps): JSX.Element => {
autoComplete="off"
className="flex-1"
required
disabled={isPubliclyAccessible}
disabled={!hasEditRights}
{...register("name")}
/>
</div>

<div className="mt-4">
<div className="flex flex-1 items-center flex-col">
{isPubliclyAccessible && (
{isPublicBrain && (
<Chip className="mb-3 bg-purple-600 text-white w-full">
{t("brain:public_brain_label")}
</Chip>
Expand All @@ -80,7 +91,7 @@ export const SettingsTab = ({ brainId }: SettingsTabProps): JSX.Element => {
isLoading={isSettingAsDefault}
onClick={() => void setAsDefaultBrainHandler()}
type="button"
disabled={isPubliclyAccessible}
disabled={!hasEditRights}
>
{t("setDefaultBrain", { ns: "brain" })}
</Button>
Expand All @@ -93,7 +104,7 @@ export const SettingsTab = ({ brainId }: SettingsTabProps): JSX.Element => {
placeholder={t("brainDescriptionPlaceholder", { ns: "brain" })}
autoComplete="off"
className="flex-1 m-3"
disabled={isPubliclyAccessible}
disabled={!hasEditRights}
{...register("description")}
/>
<Divider text={t("modelSection", { ns: "config" })} />
Expand All @@ -102,7 +113,7 @@ export const SettingsTab = ({ brainId }: SettingsTabProps): JSX.Element => {
placeholder={t("openAiKeyPlaceholder", { ns: "config" })}
autoComplete="off"
className="flex-1"
disabled={isPubliclyAccessible}
disabled={!hasEditRights}
{...register("openAiKey")}
/>
<fieldset className="w-full flex flex-col mt-2">
Expand All @@ -111,7 +122,7 @@ export const SettingsTab = ({ brainId }: SettingsTabProps): JSX.Element => {
</label>
<select
id="model"
disabled={isPubliclyAccessible}
disabled={!hasEditRights}
{...register("model")}
className="px-5 py-2 dark:bg-gray-700 bg-gray-200 rounded-md"
onChange={() => {
Expand All @@ -136,7 +147,7 @@ export const SettingsTab = ({ brainId }: SettingsTabProps): JSX.Element => {
max="1"
step="0.01"
value={temperature}
disabled={isPubliclyAccessible}
disabled={!hasEditRights}
{...register("temperature")}
/>
</fieldset>
Expand All @@ -149,43 +160,37 @@ export const SettingsTab = ({ brainId }: SettingsTabProps): JSX.Element => {
min="10"
max={defineMaxTokens(model)}
value={maxTokens}
disabled={isPubliclyAccessible}
disabled={!hasEditRights}
{...register("maxTokens")}
/>
</fieldset>
<div className="flex w-full justify-end py-4">
<SaveButton
disabled={isPubliclyAccessible}
handleSubmit={handleSubmit}
/>
<SaveButton disabled={!hasEditRights} handleSubmit={handleSubmit} />
</div>
<Divider text={t("customPromptSection", { ns: "config" })} />
{!isPubliclyAccessible && <PublicPrompts onSelect={pickPublicPrompt} />}
{hasEditRights && <PublicPrompts onSelect={pickPublicPrompt} />}
<Field
label={t("promptName", { ns: "config" })}
placeholder={t("promptNamePlaceholder", { ns: "config" })}
autoComplete="off"
className="flex-1"
disabled={isPubliclyAccessible}
disabled={!hasEditRights}
{...register("prompt.title")}
/>
<TextArea
label={t("promptContent", { ns: "config" })}
placeholder={t("promptContentPlaceholder", { ns: "config" })}
autoComplete="off"
className="flex-1"
disabled={isPubliclyAccessible}
disabled={!hasEditRights}
{...register("prompt.content")}
/>
<div className="flex w-full justify-end py-4">
<SaveButton
disabled={isPubliclyAccessible}
handleSubmit={handleSubmit}
/>
<SaveButton disabled={!hasEditRights} handleSubmit={handleSubmit} />
</div>
{promptId !== "" && (
<Button
disabled={isUpdating || isPubliclyAccessible}
disabled={isUpdating || !hasEditRights}
onClick={() => void removeBrainPrompt()}
>
{t("removePrompt", { ns: "config" })}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { UUID } from "crypto";

import { MinimalBrainForUser } from "@/lib/context/BrainProvider/types";

type IsUserBrainOwnerProps = {
userAccessibleBrains: MinimalBrainForUser[];
brainId?: UUID;
};
export const isUserBrainOwner = ({
brainId,
userAccessibleBrains,
}: IsUserBrainOwnerProps): boolean => {
const brain = userAccessibleBrains.find(({ id }) => id === brainId);
if (brain === undefined) {
return false;
}

return brain.role === "Owner";
};

0 comments on commit 8e477cc

Please sign in to comment.