khoj 1.23.4.dev12__py3-none-any.whl → 1.24.1__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.
Files changed (57) hide show
  1. khoj/configure.py +1 -0
  2. khoj/database/adapters/__init__.py +8 -1
  3. khoj/interface/compiled/404/index.html +1 -1
  4. khoj/interface/compiled/_next/static/chunks/1603-3e2e1528e3b6ea1d.js +1 -0
  5. khoj/interface/compiled/_next/static/chunks/2697-a29cb9191a9e339c.js +1 -0
  6. khoj/interface/compiled/_next/static/chunks/app/agents/{page-d302911777a3e027.js → page-a3db5b3869f83937.js} +1 -1
  7. khoj/interface/compiled/_next/static/chunks/app/automations/page-4b5ccea059588a4f.js +1 -0
  8. khoj/interface/compiled/_next/static/chunks/app/chat/page-5b1626fc2882c1f9.js +1 -0
  9. khoj/interface/compiled/_next/static/chunks/app/factchecker/{page-32e61af29e6b431d.js → page-b01f8a9b9107ecbe.js} +1 -1
  10. khoj/interface/compiled/_next/static/chunks/app/{page-96cab08c985716f4.js → page-ee9ee504f0d5ace6.js} +1 -1
  11. khoj/interface/compiled/_next/static/chunks/app/search/{page-b3193d46c65571c5.js → page-53c2494182551684.js} +1 -1
  12. khoj/interface/compiled/_next/static/chunks/app/settings/{page-0db9b708366606ec.js → page-2a7e60e3782ed95e.js} +1 -1
  13. khoj/interface/compiled/_next/static/chunks/app/share/chat/page-9d9faa4a155bbf58.js +1 -0
  14. khoj/interface/compiled/_next/static/chunks/{webpack-3875a06385370d08.js → webpack-c4376b110507dd22.js} +1 -1
  15. khoj/interface/compiled/_next/static/css/2de69f0be774c768.css +1 -0
  16. khoj/interface/compiled/_next/static/css/592ca99f5122e75a.css +1 -0
  17. khoj/interface/compiled/agents/index.html +1 -1
  18. khoj/interface/compiled/agents/index.txt +2 -2
  19. khoj/interface/compiled/automations/index.html +1 -1
  20. khoj/interface/compiled/automations/index.txt +2 -2
  21. khoj/interface/compiled/chat/index.html +1 -1
  22. khoj/interface/compiled/chat/index.txt +2 -2
  23. khoj/interface/compiled/factchecker/index.html +1 -1
  24. khoj/interface/compiled/factchecker/index.txt +2 -2
  25. khoj/interface/compiled/index.html +1 -1
  26. khoj/interface/compiled/index.txt +2 -2
  27. khoj/interface/compiled/search/index.html +1 -1
  28. khoj/interface/compiled/search/index.txt +2 -2
  29. khoj/interface/compiled/settings/index.html +1 -1
  30. khoj/interface/compiled/settings/index.txt +2 -2
  31. khoj/interface/compiled/share/chat/index.html +1 -1
  32. khoj/interface/compiled/share/chat/index.txt +2 -2
  33. khoj/interface/web/login.html +261 -159
  34. khoj/processor/conversation/anthropic/anthropic_chat.py +2 -3
  35. khoj/processor/conversation/google/gemini_chat.py +2 -3
  36. khoj/processor/conversation/offline/chat_model.py +2 -3
  37. khoj/processor/conversation/openai/gpt.py +2 -3
  38. khoj/processor/tools/online_search.py +5 -5
  39. khoj/routers/api.py +2 -2
  40. khoj/routers/api_chat.py +15 -6
  41. khoj/routers/helpers.py +4 -5
  42. khoj/utils/helpers.py +24 -1
  43. khoj/utils/rawconfig.py +11 -0
  44. {khoj-1.23.4.dev12.dist-info → khoj-1.24.1.dist-info}/METADATA +1 -1
  45. {khoj-1.23.4.dev12.dist-info → khoj-1.24.1.dist-info}/RECORD +50 -50
  46. khoj/interface/compiled/_next/static/chunks/1603-e13f41ec2cb3f147.js +0 -1
  47. khoj/interface/compiled/_next/static/chunks/2697-5b013077cfa7aaf0.js +0 -1
  48. khoj/interface/compiled/_next/static/chunks/app/automations/page-e0bedd962fcfa0dd.js +0 -1
  49. khoj/interface/compiled/_next/static/chunks/app/chat/page-1b886aa4f57af1fa.js +0 -1
  50. khoj/interface/compiled/_next/static/chunks/app/share/chat/page-7df9c23b5fec66de.js +0 -1
  51. khoj/interface/compiled/_next/static/css/4cae6c0e5c72fb2d.css +0 -1
  52. khoj/interface/compiled/_next/static/css/b1094827d745306b.css +0 -1
  53. /khoj/interface/compiled/_next/static/{Zrkt-GIpzmx8bi8YqQLwh → ur0fLamZjkY1Cn46tcnnQ}/_buildManifest.js +0 -0
  54. /khoj/interface/compiled/_next/static/{Zrkt-GIpzmx8bi8YqQLwh → ur0fLamZjkY1Cn46tcnnQ}/_ssgManifest.js +0 -0
  55. {khoj-1.23.4.dev12.dist-info → khoj-1.24.1.dist-info}/WHEEL +0 -0
  56. {khoj-1.23.4.dev12.dist-info → khoj-1.24.1.dist-info}/entry_points.txt +0 -0
  57. {khoj-1.23.4.dev12.dist-info → khoj-1.24.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,219 +1,321 @@
1
1
  <html>
2
- <head>
3
- <meta charset="utf-8">
4
- <meta name="viewport" content="width=device-width, initial-scale=1.0 maximum-scale=1.0">
5
- <title>Khoj - Login</title>
6
-
7
- <link rel="icon" type="image/png" sizes="128x128" href="https://assets.khoj.dev/khoj_lantern_128x128.png">
8
- <link rel="manifest" href="/static/khoj.webmanifest">
9
- <link rel="stylesheet" href="/static/assets/khoj.css">
10
- <meta property="og:image" content="https://assets.khoj.dev/khoj_hero.png">
11
- </head>
12
-
13
- <body>
14
- <div class="khoj-header"></div>
15
- <!-- Login Modal -->
2
+
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
6
+ <title>Khoj - Login</title>
7
+ <link rel="icon" type="image/png" sizes="128x128" href="https://assets.khoj.dev/khoj_lantern_128x128.png">
8
+ <link rel="manifest" href="/static/khoj.webmanifest">
9
+ <link rel="stylesheet" href="/static/assets/khoj.css">
10
+ <meta property="og:image" content="https://assets.khoj.dev/khoj_hero.png">
11
+ </head>
12
+
13
+ <body>
14
+ <div class="split-container">
15
+ <!-- Left side with login -->
16
+ <div class="split left">
16
17
  <div id="login-modal">
17
- <img class="khoj-logo" src="https://assets.khoj.dev/khoj_lantern_128x128.png" alt="Khoj"></img>
18
+ <img class="khoj-logo" src="https://assets.khoj.dev/khoj_lantern_128x128.png" alt="Khoj">
18
19
  <div class="login-modal-title">Login to Khoj</div>
20
+ <!-- Sign Up/Login with Google OAuth -->
21
+ <div class="g_id_signin" data-shape="circle" data-text="continue_with" data-logo_alignment="center"
22
+ data-size="large" data-type="standard"></div>
23
+ <div id="g_id_onload" data-client_id="{{ google_client_id }}" data-ux_mode="popup"
24
+ data-use_fedcm_for_prompt="true" data-login_uri="{{ redirect_uri }}" data-auto-select="true"></div>
25
+
26
+ <!-- Divider -->
27
+ <div class="divider">OR</div>
19
28
  <!-- Sign in with Magic Link -->
20
29
  <div class="khoj-magic-link">
21
30
  <input type="email" id="email" placeholder="Email" autofocus required>
22
- <button id="magic-link-button">Send Magic Link</button>
31
+ <button id="magic-link-button">Get Login Link</button>
23
32
  </div>
24
- <!-- Divider -->
25
- <div style="text-align: center; font-size: 16px; font-weight: 500; border-top: 1px solid black;">OR</div>
26
- <!-- Sign Up/Login with Google OAuth -->
27
- <div
28
- class="g_id_signin"
29
- data-shape="circle"
30
- data-text="continue_with"
31
- data-logo_alignment="center"
32
- data-size="large"
33
- data-type="standard">
34
- </div>
35
- <div id="g_id_onload"
36
- data-client_id="{{ google_client_id }}"
37
- data-ux_mode="popup"
38
- data-use_fedcm_for_prompt="true"
39
- data-login_uri="{{ redirect_uri }}"
40
- data-auto-select="true">
33
+
34
+ </div>
35
+ <!-- Footer links -->
36
+ <div class="footer-links">
37
+ <a href="https://khoj.dev/terms-of-service" target="_blank">Terms of Service</a>
38
+ <span class="divider-vertical"></span>
39
+ <a href="https://khoj.dev/privacy-policy" target="_blank">Privacy Policy</a>
40
+ </div>
41
+ </div>
42
+ <!-- Right side with content -->
43
+ <div class="split right">
44
+ <div class="right-content">
45
+ <h1>Unlock Your Second Brain</h1>
46
+ <p>Transform the way you think, create, and remember</p>
47
+ <div class="features">
48
+ <div class="feature">
49
+ <svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2"
50
+ fill="none">
51
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
52
+ <path d="M14 2v6h6" />
53
+ <path d="M16 13H8" />
54
+ <path d="M16 17H8" />
55
+ <path d="M10 9H8" />
56
+ </svg>
57
+ <span>Get answers across your documents and the internet</span>
58
+ </div>
59
+ <div class="feature">
60
+ <svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2"
61
+ fill="none">
62
+ <path
63
+ d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" />
64
+ <path d="M3.3 7l8.7 5 8.7-5" />
65
+ </svg>
66
+ <span>Go deeper in the topics personal to you</span>
67
+ </div>
68
+ <div class="feature">
69
+ <svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2"
70
+ fill="none">
71
+ <path d="M12 2L2 7l10 5 10-5-10-5z" />
72
+ <path d="M2 17l10 5 10-5" />
73
+ <path d="M2 12l10 5 10-5" />
74
+ </svg>
75
+ <span>Use specialized agents</span>
76
+ </div>
41
77
  </div>
42
78
  </div>
43
-
44
- <div class="khoj-footer"></div>
45
79
  </div>
46
- </body>
80
+ </div>
47
81
 
48
- <script>
49
- const magicLinkButton = document.getElementById('magic-link-button');
50
- const emailInput = document.getElementById('email');
51
-
52
- magicLinkButton.addEventListener('click', async () => {
53
- const email = emailInput.value;
54
- if (!email) {
55
- alert('Please enter a valid email address');
56
- return;
57
- }
58
-
59
- if (!email.includes('@')) {
60
- alert('Please enter a valid email address');
61
- return;
62
- }
63
-
64
- magicLinkButton.disabled = true;
65
- magicLinkButton.innerText = 'Check your email for a sign-in link!';
82
+ <style>
83
+ body {
84
+ margin: 0;
85
+ height: 100vh;
86
+ font-family: 'Arial', sans-serif;
87
+ color: #333;
88
+ overflow: hidden;
89
+ }
66
90
 
67
- const response = await fetch('/auth/magic', {
68
- method: 'POST',
69
- headers: {
70
- 'Content-Type': 'application/json',
71
- },
72
- body: JSON.stringify({ "email": email }),
73
- })
91
+ .split-container {
92
+ display: flex;
93
+ height: 100vh;
94
+ }
74
95
 
75
- if (response.status === 200) {
76
- console.log('Magic link sent to your email');
77
- } else {
78
- alert('Failed to send magic link');
79
- }
80
- });
81
- </script>
96
+ .split {
97
+ flex: 1;
98
+ display: flex;
99
+ justify-content: center;
100
+ align-items: center;
101
+ flex-direction: column;
102
+ }
82
103
 
83
- <style>
84
- @media only screen and (max-width: 700px) {
85
- body {
86
- display: grid;
87
- grid-template-columns: 1fr;
88
- grid-template-rows: 1fr auto 1fr;
89
- font-size: small!important;
90
- }
91
- body > * {
92
- grid-column: 1;
93
- }
104
+ .left {
105
+ background-color: #fff;
94
106
  }
95
- @media only screen and (min-width: 700px) {
96
- body {
97
- display: grid;
98
- grid-template-columns: 1fr min(50vw, 100%) 1fr;
99
- grid-template-rows: 1fr auto 1fr;
100
- }
101
- body > * {
102
- grid-column: 2;
103
- }
107
+
108
+ .right {
109
+ background: linear-gradient(135deg, #FFA07A 0%, #c4e4c6 100%);
110
+ color: white;
111
+ position: relative;
112
+ overflow: hidden;
104
113
  }
105
- body {
106
- padding: 0px;
107
- margin: 0px;
108
- height: 100%;
109
- background: url('/static/assets/samples/desktop-plain-chat-sample.png') no-repeat center center fixed;
110
- background-size: contain;
111
- color: var(--main-text-color);
112
- font-family: var(--font-family);
113
- font-size: 20px;
114
- font-weight: 300;
115
- line-height: 1.5em;
116
- }
117
- body::before {
118
- content: "";
114
+
115
+ .right::before {
116
+ content: '';
119
117
  position: absolute;
120
118
  top: 0;
121
119
  left: 0;
122
- width: 100%;
123
- height: 100%;
124
- background: var(--frosted-background-color);
125
- backdrop-filter: blur(10px);
120
+ right: 0;
121
+ bottom: 0;
122
+ opacity: 0.1;
126
123
  }
127
- body > * {
128
- padding: 10px;
129
- margin: 10px;
124
+
125
+ .right-content {
126
+ text-align: center;
127
+ padding: 2rem;
128
+ position: relative;
129
+ z-index: 1;
130
130
  }
131
131
 
132
- @keyframes gradient {
133
- 0% {
134
- background-position: 0% 50%;
135
- }
136
- 50% {
137
- background-position: 100% 50%;
138
- }
139
- 100% {
140
- background-position: 0% 50%;
141
- }
132
+ .right-content h1 {
133
+ font-size: 3rem;
134
+ margin-bottom: 1rem;
135
+ font-weight: 700;
142
136
  }
143
137
 
144
- a.khoj-logo {
145
- text-align: center;
146
- justify-self: center;
138
+ .right-content p {
139
+ font-size: 1.2rem;
140
+ margin-bottom: 3rem;
141
+ opacity: 0.9;
147
142
  }
148
143
 
149
- div#login-modal {
150
- display: grid;
151
- grid-template-columns: 1fr;
152
- gap: 32px;
153
- min-height: 300px;
154
- margin-left: 25%;
155
- margin-right: 25%;
156
- z-index: 1;
144
+ .features {
145
+ display: flex;
146
+ flex-direction: column;
147
+ gap: 1.5rem;
148
+ align-items: center;
157
149
  }
158
150
 
159
- .khoj-magic-link {
151
+ .feature {
152
+ display: flex;
153
+ align-items: center;
154
+ gap: 1rem;
155
+ font-size: 1.1rem;
156
+ }
157
+
158
+ .feature svg {
159
+ width: 24px;
160
+ height: 24px;
161
+ stroke: white;
162
+ }
163
+
164
+ #login-modal {
160
165
  display: grid;
161
- grid-template-columns: 1fr;
162
- gap: 16px;
166
+ background: white;
167
+ border-radius: 10px;
168
+ padding: 40px;
169
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
163
170
  text-align: center;
171
+ width: max-content;
172
+ }
173
+
174
+ .khoj-logo {
175
+ width: 80px;
176
+ margin-bottom: 20px;
177
+ }
178
+
179
+ .login-modal-title {
180
+ font-size: 24px;
181
+ font-weight: 600;
182
+ margin-bottom: 20px;
183
+ }
184
+
185
+ .khoj-magic-link {
186
+ display: flex;
187
+ flex-direction: column;
188
+ gap: 10px;
164
189
  }
165
190
 
166
191
  #email {
167
192
  padding: 10px;
168
- font-size: 16px;
169
- border: 1px solid var(--main-text-color);
193
+ border: 1px solid #ccc;
170
194
  border-radius: 5px;
171
195
  width: 100%;
172
- }
173
-
174
- #email:focus {
175
- box-shadow: 0 0 10px var(--main-text-color);
196
+ font-size: 16px;
176
197
  }
177
198
 
178
199
  #magic-link-button {
179
200
  padding: 10px;
180
- font-size: 16px;
181
- border: 1px solid var(--main-text-color);
201
+ border: none;
182
202
  border-radius: 5px;
183
- width: 100%;
184
- background: var(--main-text-color);
185
- color: var(--frosted-background-color);
203
+ background-color: #FFA07A;
204
+ color: white;
186
205
  cursor: pointer;
206
+ font-size: 16px;
207
+ transition: background-color 0.3s;
187
208
  }
188
209
 
189
210
  #magic-link-button:hover {
190
- box-shadow: 0 0 10px var(--main-text-color);
211
+ background-color: #FFA07A
212
+ }
213
+
214
+ #magic-link-button:disabled {
215
+ background-color: #cccccc;
216
+ cursor: not-allowed;
191
217
  }
192
218
 
193
- div.g_id_signin {
219
+ .divider {
220
+ display: flex;
221
+ align-items: center;
222
+ text-align: center;
223
+ color: #000;
224
+ /* Adjust the text color as needed */
225
+ margin: 20px 0;
226
+ /* Adjust the margin as needed */
227
+ }
228
+
229
+ .divider::before,
230
+ .divider::after {
231
+ content: '';
232
+ flex: 1;
233
+ border-bottom: 1px solid #000;
234
+ /* Adjust the line color as needed */
235
+ margin: 0 10px;
236
+ /* Adjust the spacing as needed */
237
+ }
238
+
239
+ .g_id_signin {
194
240
  margin: 0 auto;
195
241
  display: block;
196
242
  }
197
243
 
198
- div.login-modal-title {
244
+ .footer-links {
245
+ width: 100%;
199
246
  text-align: center;
200
- line-height: 28px;
201
- font-size: 24px;
202
- font-weight: 500;
247
+ font-size: 0.9em;
248
+ color: #666;
249
+ margin-top: 20px;
250
+ }
251
+
252
+ .footer-links a {
253
+ color: #666;
254
+ text-decoration: none;
255
+ margin: 0 10px;
256
+ }
257
+
258
+ .footer-links a:hover {
259
+ text-decoration: underline;
260
+ }
261
+
262
+ .divider-vertical {
263
+ display: inline-block;
264
+ width: 1px;
265
+ height: 12px;
266
+ background-color: #666;
267
+ margin: 0 10px;
268
+ vertical-align: middle;
203
269
  }
204
270
 
205
- @media only screen and (max-width: 700px) {
206
- body{
207
- background: url('/static/assets/samples/phone-plain-chat-sample.png') no-repeat center center fixed;
208
- background-size: contain;
271
+ @media (max-width: 768px) {
272
+ .split-container {
273
+ flex-direction: column;
209
274
  }
210
- div#login-modal {
211
- margin-left: 10%;
212
- margin-right: 10%;
213
- z-index: 1;
275
+
276
+ .right {
277
+ display: none;
214
278
  }
215
- }
216
279
 
280
+ .left {
281
+ padding: 2rem;
282
+ }
283
+ }
217
284
  </style>
285
+
286
+ <script>
287
+ const magicLinkButton = document.getElementById('magic-link-button');
288
+ const emailInput = document.getElementById('email');
289
+ magicLinkButton.addEventListener('click', async () => {
290
+ const email = emailInput.value;
291
+ if (!email) {
292
+ alert('Please enter a valid email address');
293
+ return;
294
+ }
295
+ if (!email.includes('@')) {
296
+ alert('Please enter a valid email address');
297
+ return;
298
+ }
299
+ magicLinkButton.disabled = true;
300
+ magicLinkButton.innerText = 'Check your email for a sign-in link!';
301
+ const response = await fetch('/auth/magic', {
302
+ method: 'POST',
303
+ headers: {
304
+ 'Content-Type': 'application/json',
305
+ },
306
+ body: JSON.stringify({ "email": email }),
307
+ });
308
+ if (response.status === 200) {
309
+ console.log('Magic link sent to your email');
310
+ } else {
311
+ alert('Failed to send magic link');
312
+ magicLinkButton.disabled = false;
313
+ magicLinkButton.innerText = 'Get Login Link';
314
+ }
315
+ });
316
+ </script>
317
+
218
318
  <script src="https://accounts.google.com/gsi/client" async defer></script>
319
+ </body>
320
+
219
321
  </html>
@@ -32,7 +32,7 @@ def extract_questions_anthropic(
32
32
  Infer search queries to retrieve relevant notes to answer user query
33
33
  """
34
34
  # Extract Past User Message and Inferred Questions from Conversation Log
35
- location = f"{location_data.city}, {location_data.region}, {location_data.country}" if location_data else "Unknown"
35
+ location = f"{location_data}" if location_data else "Unknown"
36
36
  username = prompts.user_name.format(name=user.get_full_name()) if user and user.get_full_name() else ""
37
37
 
38
38
  # Extract Past User Message and Inferred Questions from Conversation Log
@@ -158,8 +158,7 @@ def converse_anthropic(
158
158
  )
159
159
 
160
160
  if location_data:
161
- location = f"{location_data.city}, {location_data.region}, {location_data.country}"
162
- location_prompt = prompts.user_location.format(location=location)
161
+ location_prompt = prompts.user_location.format(location=f"{location_data}")
163
162
  system_prompt = f"{system_prompt}\n{location_prompt}"
164
163
 
165
164
  if user_name:
@@ -33,7 +33,7 @@ def extract_questions_gemini(
33
33
  Infer search queries to retrieve relevant notes to answer user query
34
34
  """
35
35
  # Extract Past User Message and Inferred Questions from Conversation Log
36
- location = f"{location_data.city}, {location_data.region}, {location_data.country}" if location_data else "Unknown"
36
+ location = f"{location_data}" if location_data else "Unknown"
37
37
  username = prompts.user_name.format(name=user.get_full_name()) if user and user.get_full_name() else ""
38
38
 
39
39
  # Extract Past User Message and Inferred Questions from Conversation Log
@@ -163,8 +163,7 @@ def converse_gemini(
163
163
  )
164
164
 
165
165
  if location_data:
166
- location = f"{location_data.city}, {location_data.region}, {location_data.country}"
167
- location_prompt = prompts.user_location.format(location=location)
166
+ location_prompt = prompts.user_location.format(location=f"{location_data}")
168
167
  system_prompt = f"{system_prompt}\n{location_prompt}"
169
168
 
170
169
  if user_name:
@@ -46,7 +46,7 @@ def extract_questions_offline(
46
46
  assert loaded_model is None or isinstance(loaded_model, Llama), "loaded_model must be of type Llama, if configured"
47
47
  offline_chat_model = loaded_model or download_model(model, max_tokens=max_prompt_size)
48
48
 
49
- location = f"{location_data.city}, {location_data.region}, {location_data.country}" if location_data else "Unknown"
49
+ location = f"{location_data}" if location_data else "Unknown"
50
50
  username = prompts.user_name.format(name=user.get_full_name()) if user and user.get_full_name() else ""
51
51
 
52
52
  # Extract Past User Message and Inferred Questions from Conversation Log
@@ -171,8 +171,7 @@ def converse_offline(
171
171
  conversation_primer = prompts.query_prompt.format(query=user_query)
172
172
 
173
173
  if location_data:
174
- location = f"{location_data.city}, {location_data.region}, {location_data.country}"
175
- location_prompt = prompts.user_location.format(location=location)
174
+ location_prompt = prompts.user_location.format(location=f"{location_data}")
176
175
  system_prompt = f"{system_prompt}\n{location_prompt}"
177
176
 
178
177
  if user_name:
@@ -36,7 +36,7 @@ def extract_questions(
36
36
  """
37
37
  Infer search queries to retrieve relevant notes to answer user query
38
38
  """
39
- location = f"{location_data.city}, {location_data.region}, {location_data.country}" if location_data else "Unknown"
39
+ location = f"{location_data}" if location_data else "Unknown"
40
40
  username = prompts.user_name.format(name=user.get_full_name()) if user and user.get_full_name() else ""
41
41
 
42
42
  # Extract Past User Message and Inferred Questions from Conversation Log
@@ -159,8 +159,7 @@ def converse(
159
159
  )
160
160
 
161
161
  if location_data:
162
- location = f"{location_data.city}, {location_data.region}, {location_data.country}"
163
- location_prompt = prompts.user_location.format(location=location)
162
+ location_prompt = prompts.user_location.format(location=f"{location_data}")
164
163
  system_prompt = f"{system_prompt}\n{location_prompt}"
165
164
 
166
165
  if user_name:
@@ -7,7 +7,6 @@ from collections import defaultdict
7
7
  from typing import Callable, Dict, List, Optional, Tuple, Union
8
8
 
9
9
  import aiohttp
10
- import requests
11
10
  from bs4 import BeautifulSoup
12
11
  from markdownify import markdownify
13
12
 
@@ -80,7 +79,7 @@ async def search_online(
80
79
 
81
80
  with timer(f"Internet searches for {list(subqueries)} took", logger):
82
81
  search_func = search_with_google if SERPER_DEV_API_KEY else search_with_jina
83
- search_tasks = [search_func(subquery) for subquery in subqueries]
82
+ search_tasks = [search_func(subquery, location) for subquery in subqueries]
84
83
  search_results = await asyncio.gather(*search_tasks)
85
84
  response_dict = {subquery: search_result for subquery, search_result in search_results}
86
85
 
@@ -115,8 +114,9 @@ async def search_online(
115
114
  yield response_dict
116
115
 
117
116
 
118
- async def search_with_google(query: str) -> Tuple[str, Dict[str, List[Dict]]]:
119
- payload = json.dumps({"q": query})
117
+ async def search_with_google(query: str, location: LocationData) -> Tuple[str, Dict[str, List[Dict]]]:
118
+ country_code = location.country_code.lower() if location and location.country_code else "us"
119
+ payload = json.dumps({"q": query, "gl": country_code})
120
120
  headers = {"X-API-KEY": SERPER_DEV_API_KEY, "Content-Type": "application/json"}
121
121
 
122
122
  async with aiohttp.ClientSession() as session:
@@ -220,7 +220,7 @@ async def read_webpage_with_jina(web_url: str) -> str:
220
220
  return response_json["data"]["content"]
221
221
 
222
222
 
223
- async def search_with_jina(query: str) -> Tuple[str, Dict[str, List[Dict]]]:
223
+ async def search_with_jina(query: str, location: LocationData) -> Tuple[str, Dict[str, List[Dict]]]:
224
224
  encoded_query = urllib.parse.quote(query)
225
225
  jina_search_api_url = f"{JINA_SEARCH_API_URL}/{encoded_query}"
226
226
  headers = {"Accept": "application/json"}
khoj/routers/api.py CHANGED
@@ -574,7 +574,7 @@ async def post_automation(
574
574
  try:
575
575
  # Use the query to run as the scheduling request if the scheduling request is unset
576
576
  automation = await schedule_automation(
577
- query_to_run, subject, crontime, timezone, q, user, calling_url, conversation.id
577
+ query_to_run, subject, crontime, timezone, q, user, calling_url, str(conversation.id)
578
578
  )
579
579
  except Exception as e:
580
580
  logger.error(f"Error creating automation {q} for {user.email}: {e}", exc_info=True)
@@ -679,7 +679,7 @@ def edit_job(
679
679
  # Create new Conversation Session associated with this new task
680
680
  conversation = ConversationAdapters.create_conversation_session(user, request.user.client_app, title=title)
681
681
 
682
- conversation_id = conversation.id
682
+ conversation_id = str(conversation.id)
683
683
  automation_metadata["conversation_id"] = conversation_id
684
684
 
685
685
  # Modify automation with updated query, subject