From 5aadba20a6a454558a5464646abadfe1c42654cb Mon Sep 17 00:00:00 2001 From: sabaimran Date: Fri, 17 Jan 2025 16:46:37 -0800 Subject: [PATCH] Add backend support for hidden agents (not yet enabled) --- src/khoj/database/adapters/__init__.py | 7 ++++- ...s_hidden_chatmodel_description_and_more.py | 27 +++++++++++++++++++ src/khoj/database/models/__init__.py | 4 +++ src/khoj/routers/api_agents.py | 3 +++ src/khoj/routers/api_chat.py | 3 ++- src/khoj/routers/api_model.py | 17 ++++++++---- src/khoj/routers/helpers.py | 9 ++++++- 7 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 src/khoj/database/migrations/0081_agent_is_hidden_chatmodel_description_and_more.py diff --git a/src/khoj/database/adapters/__init__.py b/src/khoj/database/adapters/__init__.py index 8e595dae..31ccd2f2 100644 --- a/src/khoj/database/adapters/__init__.py +++ b/src/khoj/database/adapters/__init__.py @@ -714,9 +714,12 @@ class AgentAdapters: public_query = Q(privacy_level=Agent.PrivacyLevel.PUBLIC) # TODO Update this to allow any public agent that's officially approved once that experience is launched public_query &= Q(managed_by_admin=True) + + user_query = Q(creator=user) + user_query &= Q(is_hidden=False) if user: return ( - Agent.objects.filter(public_query | Q(creator=user)) + Agent.objects.filter(public_query | user_query) .distinct() .order_by("created_at") .prefetch_related("creator", "chat_model", "fileobject_set") @@ -808,6 +811,7 @@ class AgentAdapters: input_tools: List[str], output_modes: List[str], slug: Optional[str] = None, + is_hidden: Optional[bool] = False, ): chat_model_option = await ChatModel.objects.filter(name=chat_model).afirst() @@ -823,6 +827,7 @@ class AgentAdapters: "chat_model": chat_model_option, "input_tools": input_tools, "output_modes": output_modes, + "is_hidden": is_hidden, } ) diff --git a/src/khoj/database/migrations/0081_agent_is_hidden_chatmodel_description_and_more.py b/src/khoj/database/migrations/0081_agent_is_hidden_chatmodel_description_and_more.py new file mode 100644 index 00000000..adbbe7fa --- /dev/null +++ b/src/khoj/database/migrations/0081_agent_is_hidden_chatmodel_description_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 5.0.10 on 2025-01-16 23:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("database", "0080_speechtotextmodeloptions_ai_model_api"), + ] + + operations = [ + migrations.AddField( + model_name="agent", + name="is_hidden", + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name="chatmodel", + name="description", + field=models.TextField(blank=True, default=None, null=True), + ), + migrations.AddField( + model_name="chatmodel", + name="strengths", + field=models.TextField(blank=True, default=None, null=True), + ), + ] diff --git a/src/khoj/database/models/__init__.py b/src/khoj/database/models/__init__.py index f46f107b..97b24510 100644 --- a/src/khoj/database/models/__init__.py +++ b/src/khoj/database/models/__init__.py @@ -209,6 +209,8 @@ class ChatModel(DbBaseModel): model_type = models.CharField(max_length=200, choices=ModelType.choices, default=ModelType.OFFLINE) vision_enabled = models.BooleanField(default=False) ai_model_api = models.ForeignKey(AiModelApi, on_delete=models.CASCADE, default=None, null=True, blank=True) + description = models.TextField(default=None, null=True, blank=True) + strengths = models.TextField(default=None, null=True, blank=True) def __str__(self): return self.name @@ -286,6 +288,7 @@ class Agent(DbBaseModel): TEXT = "text" IMAGE = "image" AUTOMATION = "automation" + DIAGRAM = "diagram" creator = models.ForeignKey( KhojUser, on_delete=models.CASCADE, default=None, null=True, blank=True @@ -304,6 +307,7 @@ class Agent(DbBaseModel): style_color = models.CharField(max_length=200, choices=StyleColorTypes.choices, default=StyleColorTypes.BLUE) style_icon = models.CharField(max_length=200, choices=StyleIconTypes.choices, default=StyleIconTypes.LIGHTBULB) privacy_level = models.CharField(max_length=30, choices=PrivacyLevel.choices, default=PrivacyLevel.PRIVATE) + is_hidden = models.BooleanField(default=False) def save(self, *args, **kwargs): is_new = self._state.adding diff --git a/src/khoj/routers/api_agents.py b/src/khoj/routers/api_agents.py index e14a666f..87693f56 100644 --- a/src/khoj/routers/api_agents.py +++ b/src/khoj/routers/api_agents.py @@ -38,6 +38,7 @@ class ModifyAgentBody(BaseModel): input_tools: Optional[List[str]] = [] output_modes: Optional[List[str]] = [] slug: Optional[str] = None + is_hidden: Optional[bool] = False @api_agents.get("", response_class=Response) @@ -214,6 +215,7 @@ async def create_agent( body.input_tools, body.output_modes, body.slug, + body.is_hidden, ) agents_packet = { @@ -229,6 +231,7 @@ async def create_agent( "files": body.files, "input_tools": agent.input_tools, "output_modes": agent.output_modes, + "is_hidden": agent.is_hidden, } return Response(content=json.dumps(agents_packet), media_type="application/json", status_code=200) diff --git a/src/khoj/routers/api_chat.py b/src/khoj/routers/api_chat.py index d3b933ee..8d9bd7cc 100644 --- a/src/khoj/routers/api_chat.py +++ b/src/khoj/routers/api_chat.py @@ -474,6 +474,7 @@ async def create_chat_session( request: Request, common: CommonQueryParams, agent_slug: Optional[str] = None, + # Add parameters here to create a custom hidden agent on the fly ): user = request.user.object @@ -865,7 +866,7 @@ async def chat( # and not triggered via slash command and not used_slash_summarize # but we can't actually summarize - and len(file_filters) != 1 + and len(file_filters) == 0 ): conversation_commands.remove(ConversationCommand.Summarize) elif ConversationCommand.Summarize in conversation_commands: diff --git a/src/khoj/routers/api_model.py b/src/khoj/routers/api_model.py index 88cb72ec..26404c3f 100644 --- a/src/khoj/routers/api_model.py +++ b/src/khoj/routers/api_model.py @@ -20,13 +20,20 @@ def get_chat_model_options( request: Request, client: Optional[str] = None, ): - conversation_options = ConversationAdapters.get_conversation_processor_options().all() + chat_models = ConversationAdapters.get_conversation_processor_options().all() - all_conversation_options = list() - for conversation_option in conversation_options: - all_conversation_options.append({"chat_model": conversation_option.name, "id": conversation_option.id}) + chat_model_options = list() + for chat_model in chat_models: + chat_model_options.append( + { + "name": chat_model.name, + "id": chat_model.id, + "strengths": chat_model.strengths, + "description": chat_model.description, + } + ) - return Response(content=json.dumps(all_conversation_options), media_type="application/json", status_code=200) + return Response(content=json.dumps(chat_model_options), media_type="application/json", status_code=200) @api_model.get("/chat") diff --git a/src/khoj/routers/helpers.py b/src/khoj/routers/helpers.py index 4d545bc8..9cfc492a 100644 --- a/src/khoj/routers/helpers.py +++ b/src/khoj/routers/helpers.py @@ -2231,7 +2231,14 @@ def get_user_config(user: KhojUser, request: Request, is_detailed: bool = False) chat_models = ConversationAdapters.get_conversation_processor_options().all() chat_model_options = list() for chat_model in chat_models: - chat_model_options.append({"name": chat_model.name, "id": chat_model.id}) + chat_model_options.append( + { + "name": chat_model.name, + "id": chat_model.id, + "strengths": chat_model.strengths, + "description": chat_model.description, + } + ) selected_paint_model_config = ConversationAdapters.get_user_text_to_image_model_config(user) paint_model_options = ConversationAdapters.get_text_to_image_model_options().all()