Enable persistence / removal of assistant icons + remove accidental regression (#2153)

* enable persistence / removal of assistant icons + remove accidental regression

* simpler env seeding for web building
This commit is contained in:
pablodanswer 2024-08-16 18:11:04 -07:00 committed by GitHub
parent 46c7089328
commit 3cbc341b60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 50 additions and 12 deletions

View File

@ -64,6 +64,7 @@ def create_update_persona(
) -> PersonaSnapshot:
"""Higher level function than upsert_persona, although either is valid to use."""
# Permission to actually use these is checked later
try:
persona = upsert_persona(
persona_id=persona_id,
@ -85,6 +86,7 @@ def create_update_persona(
icon_color=create_persona_request.icon_color,
icon_shape=create_persona_request.icon_shape,
uploaded_image_id=create_persona_request.uploaded_image_id,
remove_image=create_persona_request.remove_image,
)
versioned_make_persona_private = fetch_versioned_implementation(
@ -338,6 +340,7 @@ def upsert_persona(
uploaded_image_id: str | None = None,
display_priority: int | None = None,
is_visible: bool = True,
remove_image: bool | None = None,
) -> Persona:
if persona_id is not None:
persona = db_session.query(Persona).filter_by(id=persona_id).first()
@ -395,7 +398,8 @@ def upsert_persona(
persona.is_public = is_public
persona.icon_color = icon_color
persona.icon_shape = icon_shape
persona.uploaded_image_id = uploaded_image_id
if remove_image or uploaded_image_id:
persona.uploaded_image_id = uploaded_image_id
persona.display_priority = display_priority
persona.is_visible = is_visible

View File

@ -36,6 +36,7 @@ class CreatePersonaRequest(BaseModel):
icon_color: str | None = None
icon_shape: int | None = None
uploaded_image_id: str | None = None # New field for uploaded image
remove_image: bool | None = None
class PersonaSnapshot(BaseModel):

View File

@ -35,7 +35,7 @@ class SeedConfiguration(BaseModel):
personas: list[CreatePersonaRequest] | None = None
settings: Settings | None = None
enterprise_settings: EnterpriseSettings | None = None
analytics_script_key: str | None = None
# Use existing `CUSTOM_ANALYTICS_SECRET_KEY` for reference
analytics_script_path: str | None = None
@ -119,13 +119,14 @@ def _seed_logo(db_session: Session, logo_path: str | None) -> None:
def _seed_analytics_script(seed_config: SeedConfiguration) -> None:
if seed_config.analytics_script_path and seed_config.analytics_script_key:
custom_analytics_secret_key = os.environ.get("CUSTOM_ANALYTICS_SECRET_KEY")
if seed_config.analytics_script_path and custom_analytics_secret_key:
logger.info("Seeding analytics script")
try:
with open(seed_config.analytics_script_path, "r") as file:
script_content = file.read()
analytics_script = AnalyticsScriptUpload(
script=script_content, secret_key=seed_config.analytics_script_key
script=script_content, secret_key=custom_analytics_secret_key
)
store_analytics_script(analytics_script)
except FileNotFoundError:

View File

@ -114,6 +114,7 @@ export function AssistantEditor({
const [finalPrompt, setFinalPrompt] = useState<string | null>("");
const [finalPromptError, setFinalPromptError] = useState<string>("");
const [removePersonaImage, setRemovePersonaImage] = useState(false);
const triggerFinalPromptUpdate = async (
systemPrompt: string,
@ -228,6 +229,9 @@ export function AssistantEditor({
groups: existingPersona?.groups ?? [],
};
const [existingPersonaImageId, setExistingPersonaImageId] = useState<
string | null
>(existingPersona?.uploaded_image_id || null);
return (
<div>
{popup}
@ -352,6 +356,7 @@ export function AssistantEditor({
user && !checkUserIsNoAuthUser(user.id) ? [user.id] : undefined,
groups,
tool_ids: enabledTools,
remove_image: removePersonaImage,
});
} else {
[promptResponse, personaResponse] = await createPersona({
@ -488,7 +493,9 @@ export function AssistantEditor({
<IconImageSelection
setFieldValue={setFieldValue}
existingPersona={existingPersona!}
existingPersonaImageId={existingPersonaImageId!}
setExistingPersonaImageId={setExistingPersonaImageId}
setRemovePersonaImage={setRemovePersonaImage}
/>
</div>

View File

@ -18,6 +18,7 @@ interface PersonaCreationRequest {
tool_ids: number[];
icon_color: string | null;
icon_shape: number | null;
remove_image?: boolean;
uploaded_image: File | null;
}
@ -41,6 +42,7 @@ interface PersonaUpdateRequest {
tool_ids: number[];
icon_color: string | null;
icon_shape: number | null;
remove_image: boolean;
uploaded_image: File | null;
}
@ -119,6 +121,7 @@ function buildPersonaAPIBody(
tool_ids,
icon_color,
icon_shape,
remove_image,
} = creationRequest;
return {
@ -140,6 +143,7 @@ function buildPersonaAPIBody(
icon_color,
icon_shape,
uploaded_image_id,
remove_image,
};
}

View File

@ -71,7 +71,6 @@ export function PagesTab({
<div className="py-2 border-b border-border">
<div className="text-xs text-subtle flex pb-0.5 mb-1.5 mt-2 font-bold">
Chat Folders
{newFolderId ? newFolderId : "Hi"}
</div>
<FolderList
newFolderId={newFolderId}

View File

@ -1,19 +1,23 @@
import { Persona } from "@/app/admin/assistants/interfaces";
import { buildImgUrl } from "@/app/chat/files/images/utils";
import { useEffect, useState } from "react";
import { Dispatch, SetStateAction, useEffect, useState } from "react";
import Dropzone from "react-dropzone";
import { usePopup } from "../admin/connectors/Popup";
export const IconImageSelection = ({
existingPersona,
setFieldValue,
existingPersonaImageId,
setExistingPersonaImageId,
setRemovePersonaImage,
}: {
existingPersona: Persona | null;
setExistingPersonaImageId: Dispatch<SetStateAction<string | null>>;
existingPersonaImageId: string | null;
setFieldValue: (
field: string,
value: any,
shouldValidate?: boolean
) => Promise<any>;
setRemovePersonaImage: Dispatch<SetStateAction<boolean>>;
}) => {
const [uploadedImage, setUploadedImage] = useState<File | null>(null);
@ -22,19 +26,37 @@ export const IconImageSelection = ({
setFieldValue("uploaded_image", image);
};
const resetPreviousAssistantImage = () => {
setRemovePersonaImage(true);
setExistingPersonaImageId(null);
};
return (
<div className="mt-2 gap-y-2 flex flex-col">
<p className="font-bold text-sm text-gray-800">Or Upload Image</p>
{existingPersona && existingPersona.uploaded_image_id && (
{existingPersonaImageId && (
<div className="flex gap-x-2">
Current image:
<img
className="h-12 w-12"
src={buildImgUrl(existingPersona?.uploaded_image_id)}
src={buildImgUrl(existingPersonaImageId)}
/>
</div>
)}
<IconImageUpload selectedFile={uploadedImage} updateFile={updateFile} />
<div className="flex gap-x-2">
<IconImageUpload selectedFile={uploadedImage} updateFile={updateFile} />
{existingPersonaImageId && (
<button
onClick={resetPreviousAssistantImage}
className={
"text-sm text-text-800 max-w-[200px] p-2 rounded " +
"shadow-lg border border-border cursor-pointer"
}
>
Remove current image
</button>
)}
</div>
<p className="text-sm text-gray-600">
Uploading an image will override the generated icon.
</p>