Skip to content

Commit dc7b367

Browse files
Merge pull request #2949 from danswer-ai/avoid_image_confusion
avoid image generation tool confusion
2 parents aea261d + 31a518a commit dc7b367

File tree

4 files changed

+63
-83
lines changed

4 files changed

+63
-83
lines changed

backend/danswer/server/features/persona/api.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from danswer.file_store.models import ChatFileType
3131
from danswer.llm.answering.prompts.utils import build_dummy_prompt
3232
from danswer.server.features.persona.models import CreatePersonaRequest
33+
from danswer.server.features.persona.models import ImageGenerationToolStatus
3334
from danswer.server.features.persona.models import PersonaSharedNotificationData
3435
from danswer.server.features.persona.models import PersonaSnapshot
3536
from danswer.server.features.persona.models import PromptTemplateResponse
@@ -227,6 +228,16 @@ def delete_persona(
227228
)
228229

229230

231+
@basic_router.get("/image-generation-tool")
232+
def get_image_generation_tool(
233+
_: User
234+
| None = Depends(current_user), # User param not used but kept for consistency
235+
db_session: Session = Depends(get_session),
236+
) -> ImageGenerationToolStatus: # Use bool instead of str for boolean values
237+
is_available = is_image_generation_available(db_session=db_session)
238+
return ImageGenerationToolStatus(is_available=is_available)
239+
240+
230241
@basic_router.get("")
231242
def list_personas(
232243
user: User | None = Depends(current_user),

backend/danswer/server/features/persona/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,7 @@ class PromptTemplateResponse(BaseModel):
124124

125125
class PersonaSharedNotificationData(BaseModel):
126126
persona_id: int
127+
128+
129+
class ImageGenerationToolStatus(BaseModel):
130+
is_available: bool

web/src/app/admin/assistants/AssistantEditor.tsx

Lines changed: 18 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,7 @@ import { FullLLMProvider } from "../configuration/llm/interfaces";
4545
import CollapsibleSection from "./CollapsibleSection";
4646
import { SuccessfulPersonaUpdateRedirectType } from "./enums";
4747
import { Persona, StarterMessage } from "./interfaces";
48-
import {
49-
buildFinalPrompt,
50-
createPersona,
51-
providersContainImageGeneratingSupport,
52-
updatePersona,
53-
} from "./lib";
48+
import { buildFinalPrompt, createPersona, updatePersona } from "./lib";
5449
import { Popover } from "@/components/popover/Popover";
5550
import {
5651
CameraIcon,
@@ -106,7 +101,7 @@ export function AssistantEditor({
106101
shouldAddAssistantToUserPreferences?: boolean;
107102
admin?: boolean;
108103
}) {
109-
const { refreshAssistants } = useAssistants();
104+
const { refreshAssistants, isImageGenerationAvailable } = useAssistants();
110105
const router = useRouter();
111106

112107
const { popup, setPopup } = usePopup();
@@ -138,42 +133,13 @@ export function AssistantEditor({
138133

139134
const [isIconDropdownOpen, setIsIconDropdownOpen] = useState(false);
140135

141-
const [finalPrompt, setFinalPrompt] = useState<string | null>("");
142-
const [finalPromptError, setFinalPromptError] = useState<string>("");
143136
const [removePersonaImage, setRemovePersonaImage] = useState(false);
144137

145-
const triggerFinalPromptUpdate = async (
146-
systemPrompt: string,
147-
taskPrompt: string,
148-
retrievalDisabled: boolean
149-
) => {
150-
const response = await buildFinalPrompt(
151-
systemPrompt,
152-
taskPrompt,
153-
retrievalDisabled
154-
);
155-
if (response.ok) {
156-
setFinalPrompt((await response.json()).final_prompt_template);
157-
}
158-
};
159-
160138
const isUpdate = existingPersona !== undefined && existingPersona !== null;
161139
const existingPrompt = existingPersona?.prompts[0] ?? null;
162-
163-
useEffect(() => {
164-
if (isUpdate && existingPrompt) {
165-
triggerFinalPromptUpdate(
166-
existingPrompt.system_prompt,
167-
existingPrompt.task_prompt,
168-
existingPersona.num_chunks === 0
169-
);
170-
}
171-
}, [isUpdate, existingPrompt, existingPersona?.num_chunks]);
172-
173140
const defaultProvider = llmProviders.find(
174141
(llmProvider) => llmProvider.is_default_provider
175142
);
176-
const defaultProviderName = defaultProvider?.provider;
177143
const defaultModelName = defaultProvider?.default_model_name;
178144
const providerDisplayNameToProviderName = new Map<string, string>();
179145
llmProviders.forEach((llmProvider) => {
@@ -314,14 +280,6 @@ export function AssistantEditor({
314280
}
315281
)}
316282
onSubmit={async (values, formikHelpers) => {
317-
if (finalPromptError) {
318-
setPopup({
319-
type: "error",
320-
message: "Cannot submit while there are errors in the form",
321-
});
322-
return;
323-
}
324-
325283
if (
326284
values.llm_model_provider_override &&
327285
!values.llm_model_version_override
@@ -642,13 +600,7 @@ export function AssistantEditor({
642600
placeholder="e.g. 'You are a professional email writing assistant that always uses a polite enthusiastic tone, emphasizes action items, and leaves blanks for the human to fill in when you have unknowns'"
643601
onChange={(e) => {
644602
setFieldValue("system_prompt", e.target.value);
645-
triggerFinalPromptUpdate(
646-
e.target.value,
647-
values.task_prompt,
648-
searchToolEnabled()
649-
);
650603
}}
651-
error={finalPromptError}
652604
/>
653605

654606
<div>
@@ -775,7 +727,8 @@ export function AssistantEditor({
775727
<TooltipTrigger asChild>
776728
<div
777729
className={`w-fit ${
778-
!currentLLMSupportsImageOutput
730+
!currentLLMSupportsImageOutput ||
731+
!isImageGenerationAvailable
779732
? "opacity-70 cursor-not-allowed"
780733
: ""
781734
}`}
@@ -787,18 +740,30 @@ export function AssistantEditor({
787740
onChange={() => {
788741
toggleToolInValues(imageGenerationTool.id);
789742
}}
790-
disabled={!currentLLMSupportsImageOutput}
743+
disabled={
744+
!currentLLMSupportsImageOutput ||
745+
!isImageGenerationAvailable
746+
}
791747
/>
792748
</div>
793749
</TooltipTrigger>
794-
{!currentLLMSupportsImageOutput && (
750+
{!currentLLMSupportsImageOutput ? (
795751
<TooltipContent side="top" align="center">
796752
<p className="bg-background-900 max-w-[200px] mb-1 text-sm rounded-lg p-1.5 text-white">
797753
To use Image Generation, select GPT-4o or another
798754
image compatible model as the default model for
799755
this Assistant.
800756
</p>
801757
</TooltipContent>
758+
) : (
759+
!isImageGenerationAvailable && (
760+
<TooltipContent side="top" align="center">
761+
<p className="bg-background-900 max-w-[200px] mb-1 text-sm rounded-lg p-1.5 text-white">
762+
Image Generation requires an OpenAI or Azure
763+
Dalle configuration.
764+
</p>
765+
</TooltipContent>
766+
)
802767
)}
803768
</Tooltip>
804769
</TooltipProvider>
@@ -1024,11 +989,6 @@ export function AssistantEditor({
1024989
placeholder="e.g. 'Remember to reference all of the points mentioned in my message to you and focus on identifying action items that can move things forward'"
1025990
onChange={(e) => {
1026991
setFieldValue("task_prompt", e.target.value);
1027-
triggerFinalPromptUpdate(
1028-
values.system_prompt,
1029-
e.target.value,
1030-
searchToolEnabled()
1031-
);
1032992
}}
1033993
explanationText="Learn about prompting in our docs!"
1034994
explanationLink="https://docs.danswer.dev/guides/assistants"

web/src/components/context/AssistantsContext.tsx

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ interface AssistantsContextProps {
2121
finalAssistants: Persona[];
2222
ownedButHiddenAssistants: Persona[];
2323
refreshAssistants: () => Promise<void>;
24+
isImageGenerationAvailable: boolean;
2425

2526
// Admin only
2627
editablePersonas: Persona[];
@@ -47,51 +48,54 @@ export const AssistantsProvider: React.FC<{
4748
);
4849
const { user, isLoadingUser, isAdmin } = useUser();
4950
const [editablePersonas, setEditablePersonas] = useState<Persona[]>([]);
51+
const [allAssistants, setAllAssistants] = useState<Persona[]>([]);
5052

51-
useEffect(() => {
52-
const fetchEditablePersonas = async () => {
53-
if (!isAdmin) {
54-
return;
55-
}
53+
const [isImageGenerationAvailable, setIsImageGenerationAvailable] =
54+
useState<boolean>(false);
5655

56+
useEffect(() => {
57+
const checkImageGenerationAvailability = async () => {
5758
try {
58-
const response = await fetch("/api/admin/persona?get_editable=true");
59-
if (!response.ok) {
60-
console.error("Failed to fetch editable personas");
61-
return;
59+
const response = await fetch("/api/persona/image-generation-tool");
60+
if (response.ok) {
61+
const { is_available } = await response.json();
62+
setIsImageGenerationAvailable(is_available);
6263
}
63-
const personas = await response.json();
64-
setEditablePersonas(personas);
6564
} catch (error) {
66-
console.error("Error fetching editable personas:", error);
65+
console.error("Error checking image generation availability:", error);
6766
}
6867
};
6968

70-
fetchEditablePersonas();
71-
}, [isAdmin]);
72-
73-
const [allAssistants, setAllAssistants] = useState<Persona[]>([]);
69+
checkImageGenerationAvailability();
70+
}, []);
7471

7572
useEffect(() => {
76-
const fetchAllAssistants = async () => {
73+
const fetchPersonas = async () => {
7774
if (!isAdmin) {
7875
return;
7976
}
8077

8178
try {
82-
const response = await fetch("/api/admin/persona");
83-
if (!response.ok) {
84-
console.error("Failed to fetch all personas");
85-
return;
79+
const [editableResponse, allResponse] = await Promise.all([
80+
fetch("/api/admin/persona?get_editable=true"),
81+
fetch("/api/admin/persona"),
82+
]);
83+
84+
if (editableResponse.ok) {
85+
const editablePersonas = await editableResponse.json();
86+
setEditablePersonas(editablePersonas);
87+
}
88+
89+
if (allResponse.ok) {
90+
const allPersonas = await allResponse.json();
91+
setAllAssistants(allPersonas);
8692
}
87-
const personas = await response.json();
88-
setAllAssistants(personas);
8993
} catch (error) {
90-
console.error("Error fetching all personas:", error);
94+
console.error("Error fetching personas:", error);
9195
}
9296
};
9397

94-
fetchAllAssistants();
98+
fetchPersonas();
9599
}, [isAdmin]);
96100

97101
const refreshAssistants = async () => {
@@ -162,6 +166,7 @@ export const AssistantsProvider: React.FC<{
162166
refreshAssistants,
163167
editablePersonas,
164168
allAssistants,
169+
isImageGenerationAvailable,
165170
}}
166171
>
167172
{children}

0 commit comments

Comments
 (0)