khoj 1.24.2.dev3__py3-none-any.whl → 1.25.1.dev34__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- khoj/configure.py +13 -4
- khoj/database/adapters/__init__.py +289 -52
- khoj/database/admin.py +20 -1
- khoj/database/migrations/0065_remove_agent_avatar_remove_agent_public_and_more.py +49 -0
- khoj/database/migrations/0066_remove_agent_tools_agent_input_tools_and_more.py +69 -0
- khoj/database/migrations/0067_alter_agent_style_icon.py +50 -0
- khoj/database/migrations/0068_alter_agent_output_modes.py +24 -0
- khoj/database/migrations/0069_webscraper_serverchatsettings_web_scraper.py +89 -0
- khoj/database/models/__init__.py +136 -18
- khoj/interface/compiled/404/index.html +1 -1
- khoj/interface/compiled/_next/static/chunks/1603-fa3ee48860b9dc5c.js +1 -0
- khoj/interface/compiled/_next/static/chunks/2697-a38d01981ad3bdf8.js +1 -0
- khoj/interface/compiled/_next/static/chunks/3110-ef2cacd1b8d79ad8.js +1 -0
- khoj/interface/compiled/_next/static/chunks/4086-2c74808ba38a5a0f.js +1 -0
- khoj/interface/compiled/_next/static/chunks/477-ec86e93db10571c1.js +1 -0
- khoj/interface/compiled/_next/static/chunks/51-e8f5bdb69b5ea421.js +1 -0
- khoj/interface/compiled/_next/static/chunks/7762-79f2205740622b5c.js +1 -0
- khoj/interface/compiled/_next/static/chunks/9178-899fe9a6b754ecfe.js +1 -0
- khoj/interface/compiled/_next/static/chunks/9417-29502e39c3e7d60c.js +1 -0
- khoj/interface/compiled/_next/static/chunks/9479-7eed36fc954ef804.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/agents/{layout-e71c8e913cccf792.js → layout-75636ab3a413fa8e.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/agents/page-fa282831808ee536.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/automations/page-5480731341f34450.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/chat/{layout-8102549127db3067.js → layout-96fcf62857bf8f30.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/chat/page-702057ccbcf27881.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/factchecker/page-e7b34316ec6f44de.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/{layout-f3e40d346da53112.js → layout-d0f0a9067427fb20.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/page-10a5aad6e04f3cf8.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/search/page-d56541c746fded7d.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/settings/{layout-6f9314b0d7a26046.js → layout-a8f33dfe92f997fb.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/settings/page-e044a999468a7c5d.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/share/chat/{layout-39f03f9e32399f0f.js → layout-2df56074e42adaa0.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/share/chat/page-fbbd66a4d4633438.js +1 -0
- khoj/interface/compiled/_next/static/chunks/{webpack-d4781cada9b58e75.js → webpack-c0cd5a6afb1f0798.js} +1 -1
- khoj/interface/compiled/_next/static/css/2de69f0be774c768.css +1 -0
- khoj/interface/compiled/_next/static/css/467a524c75e7d7c0.css +1 -0
- khoj/interface/compiled/_next/static/css/592ca99f5122e75a.css +1 -0
- khoj/interface/compiled/_next/static/css/b9a6bf04305d98d7.css +25 -0
- khoj/interface/compiled/agents/index.html +1 -1
- khoj/interface/compiled/agents/index.txt +2 -2
- khoj/interface/compiled/automations/index.html +1 -1
- khoj/interface/compiled/automations/index.txt +2 -2
- khoj/interface/compiled/chat/index.html +1 -1
- khoj/interface/compiled/chat/index.txt +2 -2
- khoj/interface/compiled/factchecker/index.html +1 -1
- khoj/interface/compiled/factchecker/index.txt +2 -2
- khoj/interface/compiled/index.html +1 -1
- khoj/interface/compiled/index.txt +2 -2
- khoj/interface/compiled/search/index.html +1 -1
- khoj/interface/compiled/search/index.txt +2 -2
- khoj/interface/compiled/settings/index.html +1 -1
- khoj/interface/compiled/settings/index.txt +3 -3
- khoj/interface/compiled/share/chat/index.html +1 -1
- khoj/interface/compiled/share/chat/index.txt +2 -2
- khoj/interface/web/assets/icons/agents.svg +1 -0
- khoj/interface/web/assets/icons/automation.svg +1 -0
- khoj/interface/web/assets/icons/chat.svg +24 -0
- khoj/interface/web/login.html +11 -22
- khoj/processor/content/notion/notion_to_entries.py +2 -1
- khoj/processor/conversation/anthropic/anthropic_chat.py +2 -0
- khoj/processor/conversation/google/gemini_chat.py +6 -19
- khoj/processor/conversation/google/utils.py +33 -15
- khoj/processor/conversation/offline/chat_model.py +3 -1
- khoj/processor/conversation/openai/gpt.py +2 -0
- khoj/processor/conversation/prompts.py +67 -5
- khoj/processor/conversation/utils.py +3 -7
- khoj/processor/embeddings.py +6 -3
- khoj/processor/image/generate.py +4 -3
- khoj/processor/tools/online_search.py +139 -44
- khoj/routers/api.py +35 -6
- khoj/routers/api_agents.py +235 -4
- khoj/routers/api_chat.py +102 -530
- khoj/routers/api_content.py +14 -0
- khoj/routers/api_model.py +1 -1
- khoj/routers/auth.py +9 -1
- khoj/routers/helpers.py +181 -68
- khoj/routers/subscription.py +18 -4
- khoj/search_type/text_search.py +11 -3
- khoj/utils/helpers.py +64 -8
- khoj/utils/initialization.py +0 -3
- {khoj-1.24.2.dev3.dist-info → khoj-1.25.1.dev34.dist-info}/METADATA +19 -21
- {khoj-1.24.2.dev3.dist-info → khoj-1.25.1.dev34.dist-info}/RECORD +87 -81
- khoj/interface/compiled/_next/static/chunks/1603-3e2e1528e3b6ea1d.js +0 -1
- khoj/interface/compiled/_next/static/chunks/2697-a29cb9191a9e339c.js +0 -1
- khoj/interface/compiled/_next/static/chunks/6648-ee109f4ea33a74e2.js +0 -1
- khoj/interface/compiled/_next/static/chunks/7071-b4711cecca6619a8.js +0 -1
- khoj/interface/compiled/_next/static/chunks/743-1a64254447cda71f.js +0 -1
- khoj/interface/compiled/_next/static/chunks/8423-62ac6c832be2461b.js +0 -1
- khoj/interface/compiled/_next/static/chunks/9162-0be016519a18568b.js +0 -1
- khoj/interface/compiled/_next/static/chunks/9178-7e815211edcb3657.js +0 -1
- khoj/interface/compiled/_next/static/chunks/9417-5d14ac74aaab2c66.js +0 -1
- khoj/interface/compiled/_next/static/chunks/9984-e410179c6fac7cf1.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/agents/page-d302911777a3e027.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/automations/page-0a5de8c254c29a1c.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/chat/page-d96bf6a84bb05290.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/factchecker/page-32e61af29e6b431d.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/page-96cab08c985716f4.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/search/page-b3193d46c65571c5.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/settings/page-0db9b708366606ec.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/share/chat/page-f06ac16cfe5b5a16.js +0 -1
- khoj/interface/compiled/_next/static/css/1538cedb321e3a97.css +0 -1
- khoj/interface/compiled/_next/static/css/24f141a6e37cd204.css +0 -25
- khoj/interface/compiled/_next/static/css/4cae6c0e5c72fb2d.css +0 -1
- khoj/interface/compiled/_next/static/css/f768dddada62459d.css +0 -1
- /khoj/interface/compiled/_next/static/{_29ceahp81LhuIHo5QgOD → Jid9q6Qg851ioDaaO_fth}/_buildManifest.js +0 -0
- /khoj/interface/compiled/_next/static/{_29ceahp81LhuIHo5QgOD → Jid9q6Qg851ioDaaO_fth}/_ssgManifest.js +0 -0
- {khoj-1.24.2.dev3.dist-info → khoj-1.25.1.dev34.dist-info}/WHEEL +0 -0
- {khoj-1.24.2.dev3.dist-info → khoj-1.25.1.dev34.dist-info}/entry_points.txt +0 -0
- {khoj-1.24.2.dev3.dist-info → khoj-1.25.1.dev34.dist-info}/licenses/LICENSE +0 -0
khoj/routers/api_agents.py
CHANGED
@@ -1,13 +1,22 @@
|
|
1
1
|
import json
|
2
2
|
import logging
|
3
|
+
from typing import Dict, List, Optional
|
3
4
|
|
5
|
+
from asgiref.sync import sync_to_async
|
4
6
|
from fastapi import APIRouter, Request
|
5
7
|
from fastapi.requests import Request
|
6
8
|
from fastapi.responses import Response
|
9
|
+
from pydantic import BaseModel
|
10
|
+
from starlette.authentication import requires
|
7
11
|
|
8
12
|
from khoj.database.adapters import AgentAdapters
|
9
|
-
from khoj.database.models import KhojUser
|
10
|
-
from khoj.routers.helpers import CommonQueryParams
|
13
|
+
from khoj.database.models import Agent, KhojUser
|
14
|
+
from khoj.routers.helpers import CommonQueryParams, acheck_if_safe_prompt
|
15
|
+
from khoj.utils.helpers import (
|
16
|
+
ConversationCommand,
|
17
|
+
command_descriptions_for_agent,
|
18
|
+
mode_descriptions_for_agent,
|
19
|
+
)
|
11
20
|
|
12
21
|
# Initialize Router
|
13
22
|
logger = logging.getLogger(__name__)
|
@@ -16,6 +25,19 @@ logger = logging.getLogger(__name__)
|
|
16
25
|
api_agents = APIRouter()
|
17
26
|
|
18
27
|
|
28
|
+
class ModifyAgentBody(BaseModel):
|
29
|
+
name: str
|
30
|
+
persona: str
|
31
|
+
privacy_level: str
|
32
|
+
icon: str
|
33
|
+
color: str
|
34
|
+
chat_model: str
|
35
|
+
files: Optional[List[str]] = []
|
36
|
+
input_tools: Optional[List[str]] = []
|
37
|
+
output_modes: Optional[List[str]] = []
|
38
|
+
slug: Optional[str] = None
|
39
|
+
|
40
|
+
|
19
41
|
@api_agents.get("", response_class=Response)
|
20
42
|
async def all_agents(
|
21
43
|
request: Request,
|
@@ -25,17 +47,22 @@ async def all_agents(
|
|
25
47
|
agents = await AgentAdapters.aget_all_accessible_agents(user)
|
26
48
|
agents_packet = list()
|
27
49
|
for agent in agents:
|
50
|
+
files = agent.fileobject_set.all()
|
51
|
+
file_names = [file.file_name for file in files]
|
28
52
|
agents_packet.append(
|
29
53
|
{
|
30
54
|
"slug": agent.slug,
|
31
|
-
"avatar": agent.avatar,
|
32
55
|
"name": agent.name,
|
33
56
|
"persona": agent.personality,
|
34
|
-
"public": agent.public,
|
35
57
|
"creator": agent.creator.username if agent.creator else None,
|
36
58
|
"managed_by_admin": agent.managed_by_admin,
|
37
59
|
"color": agent.style_color,
|
38
60
|
"icon": agent.style_icon,
|
61
|
+
"privacy_level": agent.privacy_level,
|
62
|
+
"chat_model": agent.chat_model.chat_model,
|
63
|
+
"files": file_names,
|
64
|
+
"input_tools": agent.input_tools,
|
65
|
+
"output_modes": agent.output_modes,
|
39
66
|
}
|
40
67
|
)
|
41
68
|
|
@@ -43,3 +70,207 @@ async def all_agents(
|
|
43
70
|
agents_packet.sort(key=lambda x: x["name"])
|
44
71
|
agents_packet.sort(key=lambda x: x["slug"] == "khoj", reverse=True)
|
45
72
|
return Response(content=json.dumps(agents_packet), media_type="application/json", status_code=200)
|
73
|
+
|
74
|
+
|
75
|
+
@api_agents.get("/options", response_class=Response)
|
76
|
+
async def get_agent_configuration_options(
|
77
|
+
request: Request,
|
78
|
+
common: CommonQueryParams,
|
79
|
+
) -> Response:
|
80
|
+
agent_input_tools = [key for key, _ in Agent.InputToolOptions.choices]
|
81
|
+
agent_output_modes = [key for key, _ in Agent.OutputModeOptions.choices]
|
82
|
+
|
83
|
+
agent_input_tool_with_descriptions: Dict[str, str] = {}
|
84
|
+
for key in agent_input_tools:
|
85
|
+
conversation_command = ConversationCommand(key)
|
86
|
+
agent_input_tool_with_descriptions[key] = command_descriptions_for_agent[conversation_command]
|
87
|
+
|
88
|
+
agent_output_modes_with_descriptions: Dict[str, str] = {}
|
89
|
+
for key in agent_output_modes:
|
90
|
+
conversation_command = ConversationCommand(key)
|
91
|
+
agent_output_modes_with_descriptions[key] = mode_descriptions_for_agent[conversation_command]
|
92
|
+
|
93
|
+
return Response(
|
94
|
+
content=json.dumps(
|
95
|
+
{
|
96
|
+
"input_tools": agent_input_tool_with_descriptions,
|
97
|
+
"output_modes": agent_output_modes_with_descriptions,
|
98
|
+
}
|
99
|
+
),
|
100
|
+
media_type="application/json",
|
101
|
+
status_code=200,
|
102
|
+
)
|
103
|
+
|
104
|
+
|
105
|
+
@api_agents.get("/{agent_slug}", response_class=Response)
|
106
|
+
async def get_agent(
|
107
|
+
request: Request,
|
108
|
+
common: CommonQueryParams,
|
109
|
+
agent_slug: str,
|
110
|
+
) -> Response:
|
111
|
+
user: KhojUser = request.user.object if request.user.is_authenticated else None
|
112
|
+
agent = await AgentAdapters.aget_readonly_agent_by_slug(agent_slug, user)
|
113
|
+
|
114
|
+
if not agent:
|
115
|
+
return Response(
|
116
|
+
content=json.dumps({"error": f"Agent with name {agent_slug} not found."}),
|
117
|
+
media_type="application/json",
|
118
|
+
status_code=404,
|
119
|
+
)
|
120
|
+
|
121
|
+
files = agent.fileobject_set.all()
|
122
|
+
file_names = [file.file_name for file in files]
|
123
|
+
agents_packet = {
|
124
|
+
"slug": agent.slug,
|
125
|
+
"name": agent.name,
|
126
|
+
"persona": agent.personality,
|
127
|
+
"creator": agent.creator.username if agent.creator else None,
|
128
|
+
"managed_by_admin": agent.managed_by_admin,
|
129
|
+
"color": agent.style_color,
|
130
|
+
"icon": agent.style_icon,
|
131
|
+
"privacy_level": agent.privacy_level,
|
132
|
+
"chat_model": agent.chat_model.chat_model,
|
133
|
+
"files": file_names,
|
134
|
+
"input_tools": agent.input_tools,
|
135
|
+
"output_modes": agent.output_modes,
|
136
|
+
}
|
137
|
+
|
138
|
+
return Response(content=json.dumps(agents_packet), media_type="application/json", status_code=200)
|
139
|
+
|
140
|
+
|
141
|
+
@api_agents.delete("/{agent_slug}", response_class=Response)
|
142
|
+
@requires(["authenticated"])
|
143
|
+
async def delete_agent(
|
144
|
+
request: Request,
|
145
|
+
common: CommonQueryParams,
|
146
|
+
agent_slug: str,
|
147
|
+
) -> Response:
|
148
|
+
user: KhojUser = request.user.object
|
149
|
+
|
150
|
+
agent = await AgentAdapters.aget_agent_by_slug(agent_slug, user)
|
151
|
+
|
152
|
+
if not agent:
|
153
|
+
return Response(
|
154
|
+
content=json.dumps({"error": f"Agent with name {agent_slug} not found."}),
|
155
|
+
media_type="application/json",
|
156
|
+
status_code=404,
|
157
|
+
)
|
158
|
+
|
159
|
+
await AgentAdapters.adelete_agent_by_slug(agent_slug, user)
|
160
|
+
|
161
|
+
return Response(content=json.dumps({"message": "Agent deleted."}), media_type="application/json", status_code=200)
|
162
|
+
|
163
|
+
|
164
|
+
@api_agents.post("", response_class=Response)
|
165
|
+
@requires(["authenticated", "premium"])
|
166
|
+
async def create_agent(
|
167
|
+
request: Request,
|
168
|
+
common: CommonQueryParams,
|
169
|
+
body: ModifyAgentBody,
|
170
|
+
) -> Response:
|
171
|
+
user: KhojUser = request.user.object
|
172
|
+
|
173
|
+
is_safe_prompt, reason = True, ""
|
174
|
+
|
175
|
+
if body.privacy_level != Agent.PrivacyLevel.PRIVATE:
|
176
|
+
is_safe_prompt, reason = await acheck_if_safe_prompt(body.persona)
|
177
|
+
|
178
|
+
if not is_safe_prompt:
|
179
|
+
return Response(
|
180
|
+
content=json.dumps({"error": f"{reason}"}),
|
181
|
+
media_type="application/json",
|
182
|
+
status_code=400,
|
183
|
+
)
|
184
|
+
|
185
|
+
agent = await AgentAdapters.aupdate_agent(
|
186
|
+
user,
|
187
|
+
body.name,
|
188
|
+
body.persona,
|
189
|
+
body.privacy_level,
|
190
|
+
body.icon,
|
191
|
+
body.color,
|
192
|
+
body.chat_model,
|
193
|
+
body.files,
|
194
|
+
body.input_tools,
|
195
|
+
body.output_modes,
|
196
|
+
body.slug,
|
197
|
+
)
|
198
|
+
|
199
|
+
agents_packet = {
|
200
|
+
"slug": agent.slug,
|
201
|
+
"name": agent.name,
|
202
|
+
"persona": agent.personality,
|
203
|
+
"creator": agent.creator.username if agent.creator else None,
|
204
|
+
"managed_by_admin": agent.managed_by_admin,
|
205
|
+
"color": agent.style_color,
|
206
|
+
"icon": agent.style_icon,
|
207
|
+
"privacy_level": agent.privacy_level,
|
208
|
+
"chat_model": agent.chat_model.chat_model,
|
209
|
+
"files": body.files,
|
210
|
+
"input_tools": agent.input_tools,
|
211
|
+
"output_modes": agent.output_modes,
|
212
|
+
}
|
213
|
+
|
214
|
+
return Response(content=json.dumps(agents_packet), media_type="application/json", status_code=200)
|
215
|
+
|
216
|
+
|
217
|
+
@api_agents.patch("", response_class=Response)
|
218
|
+
@requires(["authenticated", "premium"])
|
219
|
+
async def update_agent(
|
220
|
+
request: Request,
|
221
|
+
common: CommonQueryParams,
|
222
|
+
body: ModifyAgentBody,
|
223
|
+
) -> Response:
|
224
|
+
user: KhojUser = request.user.object
|
225
|
+
|
226
|
+
is_safe_prompt, reason = True, ""
|
227
|
+
|
228
|
+
if body.privacy_level != Agent.PrivacyLevel.PRIVATE:
|
229
|
+
is_safe_prompt, reason = await acheck_if_safe_prompt(body.persona)
|
230
|
+
|
231
|
+
if not is_safe_prompt:
|
232
|
+
return Response(
|
233
|
+
content=json.dumps({"error": f"{reason}"}),
|
234
|
+
media_type="application/json",
|
235
|
+
status_code=400,
|
236
|
+
)
|
237
|
+
|
238
|
+
selected_agent = await AgentAdapters.aget_agent_by_slug(body.slug, user)
|
239
|
+
|
240
|
+
if not selected_agent:
|
241
|
+
return Response(
|
242
|
+
content=json.dumps({"error": f"Agent with name {body.name} not found."}),
|
243
|
+
media_type="application/json",
|
244
|
+
status_code=404,
|
245
|
+
)
|
246
|
+
|
247
|
+
agent = await AgentAdapters.aupdate_agent(
|
248
|
+
user,
|
249
|
+
body.name,
|
250
|
+
body.persona,
|
251
|
+
body.privacy_level,
|
252
|
+
body.icon,
|
253
|
+
body.color,
|
254
|
+
body.chat_model,
|
255
|
+
body.files,
|
256
|
+
body.input_tools,
|
257
|
+
body.output_modes,
|
258
|
+
body.slug,
|
259
|
+
)
|
260
|
+
|
261
|
+
agents_packet = {
|
262
|
+
"slug": agent.slug,
|
263
|
+
"name": agent.name,
|
264
|
+
"persona": agent.personality,
|
265
|
+
"creator": agent.creator.username if agent.creator else None,
|
266
|
+
"managed_by_admin": agent.managed_by_admin,
|
267
|
+
"color": agent.style_color,
|
268
|
+
"icon": agent.style_icon,
|
269
|
+
"privacy_level": agent.privacy_level,
|
270
|
+
"chat_model": agent.chat_model.chat_model,
|
271
|
+
"files": body.files,
|
272
|
+
"input_tools": agent.input_tools,
|
273
|
+
"output_modes": agent.output_modes,
|
274
|
+
}
|
275
|
+
|
276
|
+
return Response(content=json.dumps(agents_packet), media_type="application/json", status_code=200)
|