khoj 1.17.1.dev229__py3-none-any.whl → 1.17.1.dev233__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 (51) hide show
  1. khoj/routers/web_client.py +29 -130
  2. {khoj-1.17.1.dev229.dist-info → khoj-1.17.1.dev233.dist-info}/METADATA +1 -1
  3. {khoj-1.17.1.dev229.dist-info → khoj-1.17.1.dev233.dist-info}/RECORD +6 -51
  4. khoj/interface/web/404.html +0 -56
  5. khoj/interface/web/agent.html +0 -312
  6. khoj/interface/web/agents.html +0 -276
  7. khoj/interface/web/assets/icons/cancel.svg +0 -3
  8. khoj/interface/web/assets/icons/collapse.svg +0 -17
  9. khoj/interface/web/assets/icons/computer.png +0 -0
  10. khoj/interface/web/assets/icons/confirm-icon.svg +0 -1
  11. khoj/interface/web/assets/icons/copy-button-success.svg +0 -6
  12. khoj/interface/web/assets/icons/copy-button.svg +0 -5
  13. khoj/interface/web/assets/icons/credit-card.png +0 -0
  14. khoj/interface/web/assets/icons/delete.svg +0 -26
  15. khoj/interface/web/assets/icons/docx.svg +0 -7
  16. khoj/interface/web/assets/icons/edit.svg +0 -4
  17. khoj/interface/web/assets/icons/key.svg +0 -4
  18. khoj/interface/web/assets/icons/markdown.svg +0 -1
  19. khoj/interface/web/assets/icons/new.svg +0 -23
  20. khoj/interface/web/assets/icons/notion.svg +0 -4
  21. khoj/interface/web/assets/icons/openai-logomark.svg +0 -1
  22. khoj/interface/web/assets/icons/org.svg +0 -1
  23. khoj/interface/web/assets/icons/pdf.svg +0 -23
  24. khoj/interface/web/assets/icons/pencil-edit.svg +0 -5
  25. khoj/interface/web/assets/icons/plaintext.svg +0 -1
  26. khoj/interface/web/assets/icons/question-mark-icon.svg +0 -1
  27. khoj/interface/web/assets/icons/send.svg +0 -1
  28. khoj/interface/web/assets/icons/share.svg +0 -8
  29. khoj/interface/web/assets/icons/speaker.svg +0 -4
  30. khoj/interface/web/assets/icons/stop-solid.svg +0 -37
  31. khoj/interface/web/assets/icons/thumbs-down-svgrepo-com.svg +0 -6
  32. khoj/interface/web/assets/icons/thumbs-up-svgrepo-com.svg +0 -6
  33. khoj/interface/web/assets/icons/user-silhouette.svg +0 -4
  34. khoj/interface/web/assets/icons/voice.svg +0 -8
  35. khoj/interface/web/assets/icons/web.svg +0 -2
  36. khoj/interface/web/assets/icons/whatsapp.svg +0 -17
  37. khoj/interface/web/assets/markdown-it.min.js +0 -8476
  38. khoj/interface/web/assets/natural-cron.min.js +0 -1
  39. khoj/interface/web/assets/org.min.js +0 -1823
  40. khoj/interface/web/assets/pico.min.css +0 -5
  41. khoj/interface/web/assets/purify.min.js +0 -3
  42. khoj/interface/web/chat.html +0 -3436
  43. khoj/interface/web/config_automation.html +0 -1103
  44. khoj/interface/web/content_source_computer_input.html +0 -139
  45. khoj/interface/web/content_source_notion_input.html +0 -94
  46. khoj/interface/web/public_conversation.html +0 -2006
  47. khoj/interface/web/search.html +0 -470
  48. khoj/interface/web/settings.html +0 -1011
  49. {khoj-1.17.1.dev229.dist-info → khoj-1.17.1.dev233.dist-info}/WHEEL +0 -0
  50. {khoj-1.17.1.dev229.dist-info → khoj-1.17.1.dev233.dist-info}/entry_points.txt +0 -0
  51. {khoj-1.17.1.dev229.dist-info → khoj-1.17.1.dev233.dist-info}/licenses/LICENSE +0 -0
@@ -1,470 +0,0 @@
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 - Search</title>
6
-
7
- <link rel="icon" type="image/png" sizes="128x128" href="/static/assets/icons/favicon-128x128.png?v={{ khoj_version }}">
8
- <link rel="apple-touch-icon" href="/static/assets/icons/favicon-128x128.png?v={{ khoj_version }}">
9
- <link rel="manifest" href="/static/khoj.webmanifest?v={{ khoj_version }}">
10
- <link rel="stylesheet" href="/static/assets/khoj.css?v={{ khoj_version }}">
11
- </head>
12
- <script type="text/javascript" src="/static/assets/org.min.js?v={{ khoj_version }}"></script>
13
- <script type="text/javascript" src="/static/assets/markdown-it.min.js?v={{ khoj_version }}"></script>
14
- <script type="text/javascript" src="/static/assets/utils.js?v={{ khoj_version }}"></script>
15
-
16
- <script>
17
- function render_image(item) {
18
- return `
19
- <div class="results-image">
20
- <a href="${item.entry}" class="image-link">
21
- <img id=${item.score} src="${item.entry}?${Math.random()}"
22
- title="Effective Score: ${item.score}, Meta: ${item.additional.metadata_score}, Image: ${item.additional.image_score}"
23
- class="image">
24
- </a>
25
- </div>`;
26
- }
27
-
28
- function render_org(query, data, classPrefix="") {
29
- return data.map(function (item) {
30
- var orgParser = new Org.Parser();
31
- var orgDocument = orgParser.parse(item.entry);
32
- var orgHTMLDocument = orgDocument.convert(Org.ConverterHTML, { htmlClassPrefix: classPrefix });
33
- return `<div class="results-org">` + orgHTMLDocument.toString() + `</div>`;
34
- }).join("\n");
35
- }
36
-
37
- function render_markdown(query, data) {
38
- var md = window.markdownit();
39
- return data.map(function (item) {
40
- let rendered = "";
41
- if (item.additional.file.startsWith("http")) {
42
- lines = item.entry.split("\n");
43
- rendered = md.render(`${lines[0]}\t[*](${item.additional.file})\n${lines.slice(1).join("\n")}`);
44
- }
45
- else {
46
- rendered = md.render(`${item.entry}`);
47
- }
48
- return `<div class="results-markdown">` + rendered + `</div>`;
49
- }).join("\n");
50
- }
51
-
52
- function render_pdf(query, data) {
53
- return data.map(function (item) {
54
- let compiled_lines = item.additional.compiled.split("\n");
55
- let filename = compiled_lines.shift();
56
- let text_match = compiled_lines.join("\n")
57
- return `<div class="results-pdf">` + `<h2>${filename}</h2>\n<p>${text_match}</p>` + `</div>`;
58
- }).join("\n");
59
- }
60
-
61
- function render_html(query, data) {
62
- return data.map(function (item) {
63
- let document = new DOMParser().parseFromString(item.entry, "text/html");
64
- // Scrub the HTML to remove any script tags and associated content
65
- let script_tags = document.querySelectorAll("script");
66
- for (let i = 0; i < script_tags.length; i++) {
67
- script_tags[i].remove();
68
- }
69
- // Scrub the HTML to remove any style tags and associated content
70
- let style_tags = document.querySelectorAll("style");
71
- for (let i = 0; i < style_tags.length; i++) {
72
- style_tags[i].remove();
73
- }
74
- // Scrub the HTML to remove any noscript tags and associated content
75
- let noscript_tags = document.querySelectorAll("noscript");
76
- for (let i = 0; i < noscript_tags.length; i++) {
77
- noscript_tags[i].remove();
78
- }
79
- // Scrub the HTML to remove any iframe tags and associated content
80
- let iframe_tags = document.querySelectorAll("iframe");
81
- for (let i = 0; i < iframe_tags.length; i++) {
82
- iframe_tags[i].remove();
83
- }
84
- // Scrub the HTML to remove any object tags and associated content
85
- let object_tags = document.querySelectorAll("object");
86
- for (let i = 0; i < object_tags.length; i++) {
87
- object_tags[i].remove();
88
- }
89
- // Scrub the HTML to remove any embed tags and associated content
90
- let embed_tags = document.querySelectorAll("embed");
91
- for (let i = 0; i < embed_tags.length; i++) {
92
- embed_tags[i].remove();
93
- }
94
- let scrubbedHTML = document.body.outerHTML;
95
- return `<div class="results-html">` + scrubbedHTML + `</div>`;
96
- }).join("\n");
97
- }
98
-
99
- function render_xml(query, data) {
100
- return data.map(function (item) {
101
- return `<div class="results-xml">` +
102
- `<b><a href="${item.additional.file}">${item.additional.heading}</a></b>` +
103
- `<xml>${item.entry}</xml>` +
104
- `</div>`
105
- }).join("\n");
106
- }
107
-
108
- function render_multiple(query, data, type) {
109
- let html = "";
110
- data.forEach(item => {
111
- if (item.additional.file.endsWith(".org")) {
112
- html += render_org(query, [item], "org-");
113
- } else if (
114
- item.additional.file.endsWith(".md") ||
115
- item.additional.file.endsWith(".markdown") ||
116
- (item.additional.file.includes("issues") && item.additional.source === "github") ||
117
- (item.additional.file.includes("commit") && item.additional.source === "github")
118
- )
119
- {
120
- html += render_markdown(query, [item]);
121
- } else if (item.additional.file.endsWith(".pdf")) {
122
- html += render_pdf(query, [item]);
123
- } else if (item.additional.source === "notion") {
124
- html += `<div class="results-notion">` + `<b><a href="${item.additional.file}">${item.additional.heading}</a></b>` + `<p>${item.entry}</p>` + `</div>`;
125
- } else if (item.additional.file.endsWith(".html")) {
126
- html += render_html(query, [item]);
127
- } else if (item.additional.file.endsWith(".xml")) {
128
- html += render_xml(query, [item])
129
- } else {
130
- html += `<div class="results-plugin">` + `<b><a href="${item.additional.file}">${item.additional.heading}</a></b>` + `<p>${item.entry}</p>` + `</div>`;
131
- }
132
- });
133
- return html;
134
- }
135
-
136
- function render_results(data, query, type) {
137
- let results = "";
138
- if (type === "markdown") {
139
- results = render_markdown(query, data);
140
- } else if (type === "org") {
141
- results = render_org(query, data, "org-");
142
- } else if (type === "image") {
143
- results = data.map(render_image).join('');
144
- } else if (type === "pdf") {
145
- results = render_pdf(query, data);
146
- } else if (type === "github" || type === "all" || type === "notion") {
147
- results = render_multiple(query, data, type);
148
- } else {
149
- results = data.map((item) => `<div class="results-plugin">` + `<p>${item.entry}</p>` + `</div>`).join("\n")
150
- }
151
-
152
- // Any POST rendering goes here.
153
-
154
- let renderedResults = document.createElement("div");
155
- renderedResults.id = `results-${type}`;
156
- renderedResults.innerHTML = results;
157
-
158
- // For all elements that are of type img in the results html and have a src with 'avatar' in the URL, add the class 'avatar'
159
- // This is used to make the avatar images round
160
- let images = renderedResults.querySelectorAll("img[src*='avatar']");
161
- for (let i = 0; i < images.length; i++) {
162
- images[i].classList.add("avatar");
163
- }
164
-
165
- return renderedResults.outerHTML;
166
- }
167
-
168
- function search(rerank=false) {
169
- // Extract required fields for search from form
170
- query = document.getElementById("query").value.trim();
171
- type = document.getElementById("type").value;
172
- results_count = localStorage.getItem("khojResultsCount") || 5;
173
- console.log(`Query: ${query}, Type: ${type}, Results Count: ${results_count}`);
174
-
175
- // Short circuit on empty query
176
- if (query.length === 0) {
177
- return;
178
- }
179
-
180
- // If set query field in url query param on rerank
181
- if (rerank)
182
- setQueryFieldInUrl(query);
183
-
184
- // Execute Search and Render Results
185
- url = createRequestUrl(query, type, results_count || 5, rerank);
186
- fetch(url, {
187
- headers: {
188
- "Content-Type": "application/json"
189
- }
190
- })
191
- .then(response => response.json())
192
- .then(data => {
193
- document.getElementById("results").innerHTML = render_results(data, query, type);
194
- });
195
- }
196
-
197
- let debounceTimeout;
198
- function incrementalSearch(event) {
199
- // Run incremental search only after waitTime passed since the last key press
200
- let waitTime = 300;
201
- clearTimeout(debounceTimeout);
202
- debounceTimeout = setTimeout(() => {
203
- type = document.getElementById("type").value;
204
- // Search with reranking on 'Enter'
205
- let should_rerank = event.key === 'Enter';
206
- search(rerank=should_rerank);
207
- }, waitTime);
208
- }
209
-
210
- function populate_type_dropdown() {
211
- // Populate type dropdown field with enabled content types only
212
- fetch("/api/content/types")
213
- .then(response => response.json())
214
- .then(enabled_types => {
215
- // Show warning if no content types are enabled, or just one ("all")
216
- if (enabled_types[0] === "all" && enabled_types.length === 1) {
217
- document.getElementById("results").innerHTML = "<div id='results-error'>To use Khoj search, setup your content plugins on the Khoj <a class='inline-chat-link' href='/settings'>settings page</a>.</div>";
218
- document.getElementById("query").setAttribute("disabled", "disabled");
219
- document.getElementById("query").setAttribute("placeholder", "Configure Khoj to enable search");
220
- return [];
221
- }
222
-
223
- document.getElementById("type").innerHTML =
224
- enabled_types
225
- .map(type => `<option value="${type}">${type.slice(0,1).toUpperCase() + type.slice(1)}</option>`)
226
- .join('');
227
-
228
- return enabled_types;
229
- })
230
- .then(enabled_types => {
231
- // Set type field to content type passed in URL query parameter, if valid
232
- var type_via_url = new URLSearchParams(window.location.search).get("t");
233
- if (type_via_url && enabled_types.includes(type_via_url))
234
- document.getElementById("type").value = type_via_url;
235
- });
236
- }
237
-
238
- function createRequestUrl(query, type, results_count, rerank) {
239
- // Generate Backend API URL to execute Search
240
- let url = `/api/search?q=${encodeURIComponent(query)}&n=${results_count}&client=web`;
241
- // If type is not 'all', append type to URL
242
- if (type !== 'all')
243
- url += `&t=${type}`;
244
- // Rerank is only supported by text types
245
- if (type !== "image")
246
- url += `&r=${rerank}`;
247
- return url;
248
- }
249
-
250
- function setTypeFieldInUrl(type) {
251
- var url = new URL(window.location.href);
252
- url.searchParams.set("t", type.value);
253
- window.history.pushState({}, "", url.href);
254
- }
255
-
256
- function setQueryFieldInUrl(query) {
257
- var url = new URL(window.location.href);
258
- url.searchParams.set("q", query);
259
- window.history.pushState({}, "", url.href);
260
- }
261
-
262
- window.onload = function () {
263
- // Dynamically populate type dropdown based on enabled content types and type passed as URL query parameter
264
- populate_type_dropdown();
265
-
266
- // Fill query field with value passed in URL query parameters, if any.
267
- var query_via_url = new URLSearchParams(window.location.search).get("q");
268
- if (query_via_url)
269
- document.getElementById("query").value = query_via_url;
270
- }
271
- </script>
272
-
273
- <body>
274
- <!--Add Header Logo and Nav Pane-->
275
- {% import 'utils.html' as utils %}
276
- {{ utils.heading_pane(user_photo, username, is_active, has_documents) }}
277
-
278
- <!--Add Text Box To Enter Query, Trigger Incremental Search OnChange -->
279
- <input type="text" id="query" class="option" onkeyup=incrementalSearch(event) autofocus="autofocus" placeholder="Search your knowledge base using natural language">
280
-
281
- <div id="options">
282
- <!--Add Dropdown to Select Query Type -->
283
- <select id="type" class="option" onchange="setTypeFieldInUrl(this)"></select>
284
- </div>
285
-
286
- <!-- Section to Render Results -->
287
- <div id="results"></div>
288
- </body>
289
- <script>
290
- document.getElementById("search-nav").classList.add("khoj-nav-selected");
291
- </script>
292
-
293
- <style>
294
- @media only screen and (max-width: 700px) {
295
- body {
296
- display: grid;
297
- grid-template-columns: 1fr;
298
- grid-template-rows: 1fr auto auto auto minmax(80px, 100%);
299
- font-size: small!important;
300
- }
301
- body > * {
302
- grid-column: 1;
303
- }
304
- }
305
- @media only screen and (min-width: 700px) {
306
- body {
307
- display: grid;
308
- grid-template-columns: 1fr min(70vw, 100%) 1fr;
309
- grid-template-rows: 1fr auto auto auto minmax(80px, 100%);
310
- padding-top: 60vw;
311
- }
312
- body > * {
313
- grid-column: 2;
314
- }
315
- }
316
- body {
317
- padding: 0px;
318
- margin: 0px;
319
- background: var(--background-color);
320
- color: var(--main-text-color);
321
- font-family: var(--font-family);
322
- font-size: 20px;
323
- font-weight: 300;
324
- line-height: 1.5em;
325
- }
326
- body > * {
327
- padding: 10px;
328
- margin: 10px;
329
- }
330
- #options {
331
- padding: 0;
332
- display: grid;
333
- grid-template-columns: 1fr;
334
- }
335
- #options > * {
336
- padding: 15px;
337
- border-radius: 5px;
338
- border: 1px solid var(--main-text-color);
339
- background: #f9fafc
340
- }
341
- .option:hover {
342
- box-shadow: 0 0 11px #aaa;
343
- }
344
- #options > button {
345
- margin-right: 10px;
346
- }
347
-
348
- #query {
349
- font-size: larger;
350
- }
351
- #results {
352
- font-size: medium;
353
- margin: 0px;
354
- line-height: 20px;
355
- }
356
- .results-image {
357
- display: grid;
358
- grid-template-columns: repeat(3, 1fr);
359
- }
360
- .image-link {
361
- place-self: center;
362
- }
363
- .image {
364
- width: 20vw;
365
- border-radius: 10px;
366
- border: 1px solid var(--main-text-color);
367
- }
368
- #json {
369
- white-space: pre-wrap;
370
- }
371
- .results-pdf,
372
- .results-notion,
373
- .results-html,
374
- .results-plugin {
375
- text-align: left;
376
- white-space: pre-line;
377
- }
378
- .results-markdown,
379
- .results-github {
380
- text-align: left;
381
- }
382
- .results-org {
383
- text-align: left;
384
- white-space: pre-line;
385
- }
386
- .results-org h3 {
387
- margin: 20px 0 0 0;
388
- font-size: larger;
389
- }
390
- span.org-task-status {
391
- color: white;
392
- padding: 3.5px 3.5px 0;
393
- margin-right: 5px;
394
- border-radius: 5px;
395
- background-color: #eab308;
396
- font-size: medium;
397
- }
398
- span.org-task-status.todo {
399
- background-color: #3b82f6
400
- }
401
- span.org-task-status.done {
402
- background-color: #22c55e;
403
- }
404
- span.org-task-tag {
405
- color: white;
406
- padding: 3.5px 3.5px 0;
407
- margin-right: 5px;
408
- border-radius: 5px;
409
- border: 1px solid var(--main-text-color);
410
- background-color: #ef4444;
411
- font-size: small;
412
- }
413
-
414
- pre {
415
- max-width: 100;
416
- }
417
-
418
- a {
419
- color: #3b82f6;
420
- text-decoration: none;
421
- }
422
-
423
- img.avatar {
424
- width: 20px;
425
- height: 20px;
426
- border-radius: 50%;
427
- }
428
-
429
- div#results-error,
430
- div.results-markdown,
431
- div.results-notion,
432
- div.results-org,
433
- div.results-plugin,
434
- div.results-html,
435
- div.results-pdf {
436
- text-align: left;
437
- box-shadow: 2px 2px 2px var(--primary-hover);
438
- border-radius: 5px;
439
- padding: 10px;
440
- margin: 10px 0;
441
- border: 4px solid rgb(229, 229, 229);
442
- }
443
-
444
- div#results-error {
445
- box-shadow: 2px 2px 2px #FF5722;
446
- }
447
-
448
- img {
449
- max-width: 90%;
450
- }
451
-
452
- @keyframes gradient {
453
- 0% {
454
- background-position: 0% 50%;
455
- }
456
- 50% {
457
- background-position: 100% 50%;
458
- }
459
- 100% {
460
- background-position: 0% 50%;
461
- }
462
- }
463
-
464
- a.khoj-logo {
465
- text-align: center;
466
- }
467
-
468
- </style>
469
-
470
- </html>