Merge branch 'master' into features/advanced-reasoning

This commit is contained in:
Debanjum Singh Solanky
2024-10-15 01:27:36 -07:00
9 changed files with 693 additions and 515 deletions

View File

@@ -35,8 +35,10 @@ import {
DotsThreeVertical, DotsThreeVertical,
Pencil, Pencil,
Trash, Trash,
ArrowRight,
ArrowLeft,
} from "@phosphor-icons/react"; } from "@phosphor-icons/react";
import { set, z } from "zod"; import { set, z, ZodError } from "zod";
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
import { import {
Dialog, Dialog,
@@ -245,12 +247,18 @@ function AgentCard(props: AgentCardProps) {
let agentsApiUrl = `/api/agents`; let agentsApiUrl = `/api/agents`;
let method = props.editCard ? "PATCH" : "POST"; let method = props.editCard ? "PATCH" : "POST";
let valuesToSend: any = values;
if (props.editCard) {
valuesToSend = { ...values, slug: props.data.slug };
}
fetch(agentsApiUrl, { fetch(agentsApiUrl, {
method: method, method: method,
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify(values), body: JSON.stringify(valuesToSend),
}) })
.then((response) => { .then((response) => {
if (response.status === 200) { if (response.status === 200) {
@@ -537,9 +545,36 @@ function AgentModificationForm(props: AgentModificationFormProps) {
const [progressValue, setProgressValue] = useState(0); const [progressValue, setProgressValue] = useState(0);
const [uploadedFiles, setUploadedFiles] = useState<string[]>([]); const [uploadedFiles, setUploadedFiles] = useState<string[]>([]);
const [allFileOptions, setAllFileOptions] = useState<string[]>([]); const [allFileOptions, setAllFileOptions] = useState<string[]>([]);
const [currentStep, setCurrentStep] = useState(0);
const [showSubscribeDialog, setShowSubscribeDialog] = useState(true); const [showSubscribeDialog, setShowSubscribeDialog] = useState(true);
const privacyOptions = ["public", "private", "protected"];
const basicFields = [
{ name: "name", label: "Name" },
{ name: "persona", label: "Personality" },
];
const advancedFields = [
{ name: "files", label: "Knowledge Base" },
{ name: "input_tools", label: "Input Tools" },
{ name: "output_modes", label: "Output Modes" },
];
const customizationFields = [
{ name: "color", label: "Color" },
{ name: "icon", label: "Icon" },
{ name: "chat_model", label: "Chat Model" },
{ name: "privacy_level", label: "Privacy Level" },
];
const formGroups = [
{ fields: basicFields, label: "Basic Settings" },
{ fields: customizationFields, label: "Customization & Access" },
{ fields: advancedFields, label: "Advanced Settings" },
];
const fileInputRef = useRef<HTMLInputElement>(null); const fileInputRef = useRef<HTMLInputElement>(null);
useEffect(() => { useEffect(() => {
@@ -563,7 +598,9 @@ function AgentModificationForm(props: AgentModificationFormProps) {
const currentFiles = props.form.getValues("files") || []; const currentFiles = props.form.getValues("files") || [];
const fileOptions = props.filesOptions || []; const fileOptions = props.filesOptions || [];
const concatenatedFiles = [...currentFiles, ...fileOptions]; const concatenatedFiles = [...currentFiles, ...fileOptions];
setAllFileOptions((prev) => [...prev, ...concatenatedFiles]); const fullAllFileOptions = [...allFileOptions, ...concatenatedFiles];
const dedupedAllFileOptions = Array.from(new Set(fullAllFileOptions));
setAllFileOptions(dedupedAllFileOptions);
}, []); }, []);
useEffect(() => { useEffect(() => {
@@ -614,6 +651,25 @@ function AgentModificationForm(props: AgentModificationFormProps) {
uploadFiles(event.target.files); uploadFiles(event.target.files);
} }
const handleNext = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
if (currentStep < formGroups.length - 1) {
setCurrentStep(currentStep + 1);
}
};
const handlePrevious = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
if (currentStep > 0) {
setCurrentStep(currentStep - 1);
}
};
const handleSubmit = (values: any) => {
props.onSubmit(values);
setIsSaving(true);
};
const handleAgentFileChange = (files: string[]) => { const handleAgentFileChange = (files: string[]) => {
for (const file of files) { for (const file of files) {
const currentFiles = props.form.getValues("files") || []; const currentFiles = props.form.getValues("files") || [];
@@ -624,7 +680,30 @@ function AgentModificationForm(props: AgentModificationFormProps) {
} }
}; };
const privacyOptions = ["public", "private", "protected"]; const areRequiredFieldsCompletedForCurrentStep = (formGroup: {
fields: { name: string }[];
}) => {
try {
EditAgentSchema.parse(props.form.getValues());
return true;
} catch (error) {
const errors: { [key: string]: string } = (error as ZodError).errors.reduce(
(acc: any, curr: any) => {
acc[curr.path[0]] = curr.message;
return acc;
},
{},
);
for (const field of formGroup.fields) {
if (errors[field.name]) {
return false;
}
}
return true;
}
};
if (!props.isSubscribed && showSubscribeDialog) { if (!props.isSubscribed && showSubscribeDialog) {
return ( return (
@@ -658,16 +737,12 @@ function AgentModificationForm(props: AgentModificationFormProps) {
); );
} }
const renderFormField = (fieldName: string) => {
switch (fieldName) {
case "name":
return ( return (
<Form {...props.form}>
<form
onSubmit={props.form.handleSubmit((values) => {
props.onSubmit(values);
setIsSaving(true);
})}
className="space-y-6"
>
<FormField <FormField
key={fieldName}
control={props.form.control} control={props.form.control}
name="name" name="name"
render={({ field }) => ( render={({ field }) => (
@@ -684,29 +759,11 @@ function AgentModificationForm(props: AgentModificationFormProps) {
</FormItem> </FormItem>
)} )}
/> />
);
<FormField case "chat_model":
control={props.form.control} return (
name="persona"
render={({ field }) => (
<FormItem className="space-y-1 grid gap-2">
<FormLabel>Personality</FormLabel>
<FormDescription>
What is the personality, thought process, or tuning of this agent?
Get creative; this is how you can influence the agent constitution.
</FormDescription>
<FormControl>
<Textarea
placeholder="You are an excellent biologist, at the top of your field in marine biology."
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField <FormField
key={fieldName}
control={props.form.control} control={props.form.control}
name="chat_model" name="chat_model"
render={({ field }) => ( render={({ field }) => (
@@ -723,7 +780,10 @@ function AgentModificationForm(props: AgentModificationFormProps) {
</FormControl> </FormControl>
<SelectContent className="items-start space-y-1 inline-flex flex-col"> <SelectContent className="items-start space-y-1 inline-flex flex-col">
{props.modelOptions.map((modelOption) => ( {props.modelOptions.map((modelOption) => (
<SelectItem key={modelOption.id} value={modelOption.name}> <SelectItem
key={modelOption.id}
value={modelOption.name}
>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
{modelOption.name} {modelOption.name}
</div> </div>
@@ -735,7 +795,11 @@ function AgentModificationForm(props: AgentModificationFormProps) {
</FormItem> </FormItem>
)} )}
/> />
);
case "privacy_level":
return (
<FormField <FormField
key={fieldName}
control={props.form.control} control={props.form.control}
name="privacy_level" name="privacy_level"
render={({ field }) => ( render={({ field }) => (
@@ -746,7 +810,10 @@ function AgentModificationForm(props: AgentModificationFormProps) {
<FormDescription> <FormDescription>
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
<Button variant={"ghost" as const} className="p-0 h-fit"> <Button
variant={"ghost" as const}
className="p-0 h-fit"
>
<span className="items-center flex gap-1 text-sm"> <span className="items-center flex gap-1 text-sm">
<Info className="inline" /> <Info className="inline" />
<p className="text-sm">Learn more</p> <p className="text-sm">Learn more</p>
@@ -785,18 +852,18 @@ function AgentModificationForm(props: AgentModificationFormProps) {
</FormItem> </FormItem>
)} )}
/> />
<div className="grid"> );
<FormLabel className="mb-2">Look & Feel</FormLabel> case "color":
<div className="flex gap-1 justify-left flex-col md:flex-row"> return (
<FormField <FormField
key={fieldName}
control={props.form.control} control={props.form.control}
name="color" name="color"
render={({ field }) => ( render={({ field }) => (
<FormItem className="space-y-3"> <FormItem className="space-y-3">
<Select <FormLabel>Color</FormLabel>
onValueChange={field.onChange} <FormDescription>Choose a color for your agent.</FormDescription>
defaultValue={field.value} <Select onValueChange={field.onChange} defaultValue={field.value}>
>
<FormControl> <FormControl>
<SelectTrigger className="w-[200px]"> <SelectTrigger className="w-[200px]">
<SelectValue placeholder="Color" /> <SelectValue placeholder="Color" />
@@ -820,16 +887,18 @@ function AgentModificationForm(props: AgentModificationFormProps) {
</FormItem> </FormItem>
)} )}
/> />
);
case "icon":
return (
<FormField <FormField
key={fieldName}
control={props.form.control} control={props.form.control}
name="icon" name="icon"
render={({ field }) => ( render={({ field }) => (
<FormItem className="space-y-3"> <FormItem className="space-y-3">
<Select <FormLabel>Icon</FormLabel>
onValueChange={field.onChange} <FormDescription>Choose an icon for your agent.</FormDescription>
defaultValue={field.value} <Select onValueChange={field.onChange} defaultValue={field.value}>
>
<FormControl> <FormControl>
<SelectTrigger className="w-[200px]"> <SelectTrigger className="w-[200px]">
<SelectValue placeholder="Icon" /> <SelectValue placeholder="Icon" />
@@ -855,16 +924,36 @@ function AgentModificationForm(props: AgentModificationFormProps) {
</FormItem> </FormItem>
)} )}
/> />
</div> );
</div> case "persona":
<FormItem className="flex flex-col"> return (
<FormLabel className="text-md">Advanced Settings</FormLabel>
<FormDescription>
These are optional settings that you can use to customize your agent.
</FormDescription>
</FormItem>
<FormField <FormField
key={fieldName}
control={props.form.control}
name="persona"
render={({ field }) => (
<FormItem className="space-y-1 grid gap-2">
<FormLabel>Personality</FormLabel>
<FormDescription>
What is the personality, thought process, or tuning of this
agent? Get creative; this is how you can influence the agent
constitution.
</FormDescription>
<FormControl>
<Textarea
placeholder="You are an excellent biologist, at the top of your field in marine biology."
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
);
case "files":
return (
<FormField
key={fieldName}
control={props.form.control} control={props.form.control}
name="files" name="files"
render={({ field }) => ( render={({ field }) => (
@@ -938,7 +1027,9 @@ function AgentModificationForm(props: AgentModificationFormProps) {
) : ( ) : (
<div className="flex items-center justify-center w-full h-full"> <div className="flex items-center justify-center w-full h-full">
<Plus className="h-6 w-6 mr-2" /> <Plus className="h-6 w-6 mr-2" />
<span>Drag and drop files here</span> <span>
Drag and drop files here
</span>
</div> </div>
)} )}
</div> </div>
@@ -954,15 +1045,19 @@ function AgentModificationForm(props: AgentModificationFormProps) {
key={file} key={file}
onSelect={() => { onSelect={() => {
const currentFiles = const currentFiles =
props.form.getValues("files") || []; props.form.getValues("files") ||
const newFiles = currentFiles.includes( [];
file, const newFiles =
) currentFiles.includes(file)
? currentFiles.filter( ? currentFiles.filter(
(item) => item !== file, (item) =>
item !== file,
) )
: [...currentFiles, file]; : [...currentFiles, file];
props.form.setValue("files", newFiles); props.form.setValue(
"files",
newFiles,
);
}} }}
> >
<Check <Check
@@ -985,7 +1080,11 @@ function AgentModificationForm(props: AgentModificationFormProps) {
</FormItem> </FormItem>
)} )}
/> />
);
case "input_tools":
return (
<FormField <FormField
key={fieldName}
control={props.form.control} control={props.form.control}
name="input_tools" name="input_tools"
render={({ field }) => ( render={({ field }) => (
@@ -1018,7 +1117,9 @@ function AgentModificationForm(props: AgentModificationFormProps) {
"input_tools", "input_tools",
) || []; ) || [];
const newInputTools = const newInputTools =
currentInputTools.includes(key) currentInputTools.includes(
key,
)
? currentInputTools.filter( ? currentInputTools.filter(
(item) => (item) =>
item !== key, item !== key,
@@ -1037,12 +1138,23 @@ function AgentModificationForm(props: AgentModificationFormProps) {
className={cn( className={cn(
"mr-2 h-4 w-4", "mr-2 h-4 w-4",
field.value && field.value &&
field.value.includes(key) field.value.includes(
key,
)
? "opacity-100" ? "opacity-100"
: "opacity-0", : "opacity-0",
)} )}
/> />
<b>{key}</b>: {value} <div
className={cn(
"flex items-center space-x-2",
)}
>
<p>
<b>{key}</b>
</p>
<p>{value}</p>
</div>
</CommandItem> </CommandItem>
), ),
)} )}
@@ -1054,7 +1166,11 @@ function AgentModificationForm(props: AgentModificationFormProps) {
</FormItem> </FormItem>
)} )}
/> />
);
case "output_modes":
return (
<FormField <FormField
key={fieldName}
control={props.form.control} control={props.form.control}
name="output_modes" name="output_modes"
render={({ field }) => ( render={({ field }) => (
@@ -1087,7 +1203,9 @@ function AgentModificationForm(props: AgentModificationFormProps) {
"output_modes", "output_modes",
) || []; ) || [];
const newOutputModes = const newOutputModes =
currentOutputModes.includes(key) currentOutputModes.includes(
key,
)
? currentOutputModes.filter( ? currentOutputModes.filter(
(item) => (item) =>
item !== key, item !== key,
@@ -1106,12 +1224,23 @@ function AgentModificationForm(props: AgentModificationFormProps) {
className={cn( className={cn(
"mr-2 h-4 w-4", "mr-2 h-4 w-4",
field.value && field.value &&
field.value.includes(key) field.value.includes(
key,
)
? "opacity-100" ? "opacity-100"
: "opacity-0", : "opacity-0",
)} )}
/> />
<b>{key}</b>: {value} <div
className={cn(
"flex items-center space-x-2",
)}
>
<p>
<b>{key}</b>
</p>
<p>{value}</p>
</div>
</CommandItem> </CommandItem>
), ),
)} )}
@@ -1123,6 +1252,55 @@ function AgentModificationForm(props: AgentModificationFormProps) {
</FormItem> </FormItem>
)} )}
/> />
);
default:
return null;
}
};
return (
<Form {...props.form}>
<form onSubmit={props.form.handleSubmit(handleSubmit)} className="space-y-6">
<div className="space-y-6">{formGroups[currentStep].label}</div>
{currentStep < formGroups.length &&
formGroups[currentStep].fields.map((field) => renderFormField(field.name))}
<div className="flex justify-between mt-4">
<Button
type="button"
variant={"outline"}
onClick={handlePrevious}
disabled={currentStep === 0}
className={`items-center ${isSaving ? "bg-stone-100 dark:bg-neutral-900" : ""} text-white ${colorOptionClassName}`}
>
<ArrowLeft className="mr-2 h-4 w-4" />
Previous
</Button>
{currentStep < formGroups.length - 1 ? (
<Button
type="button"
variant={"outline"}
onClick={handleNext}
disabled={
!areRequiredFieldsCompletedForCurrentStep(formGroups[currentStep])
}
className={`items-center ${isSaving ? "bg-stone-100 dark:bg-neutral-900" : ""} text-white ${colorOptionClassName}`}
>
Next
<ArrowRight className="ml-2 h-4 w-4" />
</Button>
) : (
<Button
type="submit"
variant={"outline"}
disabled={isSaving || !props.isSubscribed}
className={`items-center ${isSaving ? "bg-stone-100 dark:bg-neutral-900" : ""} text-white ${colorOptionClassName}`}
>
<FloppyDisk className="h-4 w-4 mr-2" />
{isSaving ? "Booting..." : "Save"}
</Button>
)}
</div>
{props.errors && ( {props.errors && (
<Alert className="bg-secondary border-none my-4"> <Alert className="bg-secondary border-none my-4">
<AlertDescription className="flex items-center gap-1"> <AlertDescription className="flex items-center gap-1">
@@ -1134,28 +1312,6 @@ function AgentModificationForm(props: AgentModificationFormProps) {
</AlertDescription> </AlertDescription>
</Alert> </Alert>
)} )}
<fieldset>
<Button
type="submit"
variant={"ghost"}
disabled={isSaving || !props.isSubscribed}
className={`items-center ${isSaving ? "bg-stone-100 dark:bg-neutral-900" : ""} text-white ${colorOptionClassName}`}
>
<FloppyDisk className="h-4 w-4 mr-2" />
{isSaving ? "Booting..." : "Save"}
</Button>
{!!!props.create && props.form.getValues("privacy_level") !== "private" && (
<ShareLink
buttonTitle="Share"
title="Share Agent"
description="Share a link to this agent with others. They'll be able to chat with it, and ask questions to all of its knowledge base."
buttonVariant={"ghost" as const}
buttonClassName={`${colorOptionClassName}`}
includeIcon={true}
url={`${window.location.origin}/agents?agent=${props.slug}`}
/>
)}
</fieldset>
</form> </form>
</Form> </Form>
); );

View File

@@ -696,10 +696,12 @@ class AgentAdapters:
files: List[str], files: List[str],
input_tools: List[str], input_tools: List[str],
output_modes: List[str], output_modes: List[str],
slug: Optional[str] = None,
): ):
chat_model_option = await ChatModelOptions.objects.filter(chat_model=chat_model).afirst() chat_model_option = await ChatModelOptions.objects.filter(chat_model=chat_model).afirst()
agent, created = await Agent.objects.filter(name=name, creator=user).aupdate_or_create( # Slug will be None for new agents, which will trigger a new agent creation with a generated, immutable slug
agent, created = await Agent.objects.filter(slug=slug, creator=user).aupdate_or_create(
defaults={ defaults={
"name": name, "name": name,
"creator": user, "creator": user,

View File

@@ -114,6 +114,7 @@ class CrossEncoderModel:
payload = {"inputs": {"query": query, "passages": [hit.additional[key] for hit in hits]}} payload = {"inputs": {"query": query, "passages": [hit.additional[key] for hit in hits]}}
headers = {"Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json"} headers = {"Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json"}
response = requests.post(target_url, json=payload, headers=headers) response = requests.post(target_url, json=payload, headers=headers)
response.raise_for_status()
return response.json()["scores"] return response.json()["scores"]
cross_inp = [[query, hit.additional[key]] for hit in hits] cross_inp = [[query, hit.additional[key]] for hit in hits]

View File

@@ -143,7 +143,6 @@ async def read_webpages(
conversation_history: dict, conversation_history: dict,
location: LocationData, location: LocationData,
user: KhojUser, user: KhojUser,
subscribed: bool = False,
send_status_func: Optional[Callable] = None, send_status_func: Optional[Callable] = None,
uploaded_image_url: str = None, uploaded_image_url: str = None,
agent: Agent = None, agent: Agent = None,

View File

@@ -35,6 +35,7 @@ class ModifyAgentBody(BaseModel):
files: Optional[List[str]] = [] files: Optional[List[str]] = []
input_tools: Optional[List[str]] = [] input_tools: Optional[List[str]] = []
output_modes: Optional[List[str]] = [] output_modes: Optional[List[str]] = []
slug: Optional[str] = None
@api_agents.get("", response_class=Response) @api_agents.get("", response_class=Response)
@@ -192,6 +193,7 @@ async def create_agent(
body.files, body.files,
body.input_tools, body.input_tools,
body.output_modes, body.output_modes,
body.slug,
) )
agents_packet = { agents_packet = {
@@ -233,7 +235,7 @@ async def update_agent(
status_code=400, status_code=400,
) )
selected_agent = await AgentAdapters.aget_agent_by_name(body.name, user) selected_agent = await AgentAdapters.aget_agent_by_slug(body.slug, user)
if not selected_agent: if not selected_agent:
return Response( return Response(
@@ -253,6 +255,7 @@ async def update_agent(
body.files, body.files,
body.input_tools, body.input_tools,
body.output_modes, body.output_modes,
body.slug,
) )
agents_packet = { agents_packet = {

View File

@@ -213,7 +213,7 @@ def chat_history(
agent_metadata = None agent_metadata = None
if conversation.agent: if conversation.agent:
if conversation.agent.privacy_level == Agent.PrivacyLevel.PRIVATE: if conversation.agent.privacy_level == Agent.PrivacyLevel.PRIVATE and conversation.agent.creator != user:
conversation.agent = None conversation.agent = None
else: else:
agent_metadata = { agent_metadata = {
@@ -853,6 +853,8 @@ async def chat(
return return
# # Gather Context # # Gather Context
# # Extract Document References
# try:
# async for result in extract_references_and_questions( # async for result in extract_references_and_questions(
# request, # request,
# meta_log, # meta_log,
@@ -872,8 +874,15 @@ async def chat(
# compiled_references.extend(result[0]) # compiled_references.extend(result[0])
# inferred_queries.extend(result[1]) # inferred_queries.extend(result[1])
# defiltered_query = result[2] # defiltered_query = result[2]
# except Exception as e:
# if not is_none_or_empty(compiled_references): # error_message = f"Error searching knowledge base: {e}. Attempting to respond without document references."
# logger.warning(error_message)
# async for result in send_event(
# ChatEvent.STATUS, "Document search failed. I'll try respond without document references"
# ):
# yield result
#
# # if not is_none_or_empty(compiled_references):
# try: # try:
# headings = "\n- " + "\n- ".join(set([c.get("compiled", c).split("\n")[0] for c in compiled_references])) # headings = "\n- " + "\n- ".join(set([c.get("compiled", c).split("\n")[0] for c in compiled_references]))
# # Strip only leading # from headings # # Strip only leading # from headings
@@ -910,12 +919,13 @@ async def chat(
yield result[ChatEvent.STATUS] yield result[ChatEvent.STATUS]
else: else:
online_results = result online_results = result
except ValueError as e: except Exception as e:
error_message = f"Error searching online: {e}. Attempting to respond without online results" error_message = f"Error searching online: {e}. Attempting to respond without online results"
logger.warning(error_message) logger.warning(error_message)
async for result in send_llm_response(error_message): async for result in send_event(
ChatEvent.STATUS, "Online search failed. I'll try respond without online references"
):
yield result yield result
return
## Gather Webpage References ## Gather Webpage References
if ConversationCommand.Webpage in conversation_commands and pending_research: if ConversationCommand.Webpage in conversation_commands and pending_research:
@@ -925,7 +935,6 @@ async def chat(
meta_log, meta_log,
location, location,
user, user,
subscribed,
partial(send_event, ChatEvent.STATUS), partial(send_event, ChatEvent.STATUS),
uploaded_image_url=uploaded_image_url, uploaded_image_url=uploaded_image_url,
agent=agent, agent=agent,
@@ -945,11 +954,15 @@ async def chat(
webpages.append(webpage["link"]) webpages.append(webpage["link"])
async for result in send_event(ChatEvent.STATUS, f"**Read web pages**: {webpages}"): async for result in send_event(ChatEvent.STATUS, f"**Read web pages**: {webpages}"):
yield result yield result
except ValueError as e: except Exception as e:
logger.warning( logger.warning(
f"Error directly reading webpages: {e}. Attempting to respond without online results", f"Error reading webpages: {e}. Attempting to respond without webpage results",
exc_info=True, exc_info=True,
) )
async for result in send_event(
ChatEvent.STATUS, "Webpage read failed. I'll try respond without webpage references"
):
yield result
## Gather Code Results ## Gather Code Results
if ConversationCommand.Code in conversation_commands and pending_research: if ConversationCommand.Code in conversation_commands and pending_research:

View File

@@ -345,13 +345,13 @@ async def aget_relevant_information_sources(
final_response = [ConversationCommand.Default] final_response = [ConversationCommand.Default]
else: else:
final_response = [ConversationCommand.General] final_response = [ConversationCommand.General]
return final_response except Exception:
except Exception as e:
logger.error(f"Invalid response for determining relevant tools: {response}") logger.error(f"Invalid response for determining relevant tools: {response}")
if len(agent_tools) == 0: if len(agent_tools) == 0:
final_response = [ConversationCommand.Default] final_response = [ConversationCommand.Default]
else: else:
final_response = agent_tools final_response = agent_tools
return final_response
async def aget_relevant_output_modes( async def aget_relevant_output_modes(

View File

@@ -227,7 +227,6 @@ async def execute_information_collection(
conversation_history, conversation_history,
location, location,
user, user,
subscribed,
send_status_func, send_status_func,
uploaded_image_url=uploaded_image_url, uploaded_image_url=uploaded_image_url,
agent=agent, agent=agent,

View File

@@ -3,6 +3,7 @@ import math
from pathlib import Path from pathlib import Path
from typing import List, Optional, Tuple, Type, Union from typing import List, Optional, Tuple, Type, Union
import requests
import torch import torch
from asgiref.sync import sync_to_async from asgiref.sync import sync_to_async
from sentence_transformers import util from sentence_transformers import util
@@ -231,8 +232,12 @@ def setup(
def cross_encoder_score(query: str, hits: List[SearchResponse], search_model_name: str) -> List[SearchResponse]: def cross_encoder_score(query: str, hits: List[SearchResponse], search_model_name: str) -> List[SearchResponse]:
"""Score all retrieved entries using the cross-encoder""" """Score all retrieved entries using the cross-encoder"""
try:
with timer("Cross-Encoder Predict Time", logger, state.device): with timer("Cross-Encoder Predict Time", logger, state.device):
cross_scores = state.cross_encoder_model[search_model_name].predict(query, hits) cross_scores = state.cross_encoder_model[search_model_name].predict(query, hits)
except requests.exceptions.HTTPError as e:
logger.error(f"Failed to rerank documents using the inference endpoint. Error: {e}.", exc_info=True)
cross_scores = [0.0] * len(hits)
# Convert cross-encoder scores to distances and pass in hits for reranking # Convert cross-encoder scores to distances and pass in hits for reranking
for idx in range(len(cross_scores)): for idx in range(len(cross_scores)):