diff --git a/src/interface/desktop/main.js b/src/interface/desktop/main.js index 76abe63c..618825e1 100644 --- a/src/interface/desktop/main.js +++ b/src/interface/desktop/main.js @@ -233,11 +233,15 @@ function pushDataToKhoj (regenerate = false) { // Request indexing files on server. With upto 1000 files in each request for (let i = 0; i < filesDataToPush.length; i += 1000) { + const syncUrl = `${hostURL}/api/content?client=desktop`; const filesDataGroup = filesDataToPush.slice(i, i + 1000); const formData = new FormData(); filesDataGroup.forEach(fileData => { formData.append('files', fileData.blob, fileData.path) }); - let request = axios.post(`${hostURL}/api/v1/index/update?force=${regenerate}&client=desktop`, formData, { headers }); - requests.push(request); + requests.push( + regenerate + ? axios.put(syncUrl, formData, { headers }) + : axios.patch(syncUrl, formData, { headers }) + ); } // Wait for requests batch to finish diff --git a/src/interface/desktop/search.html b/src/interface/desktop/search.html index 6a6cf694..792470a6 100644 --- a/src/interface/desktop/search.html +++ b/src/interface/desktop/search.html @@ -212,7 +212,7 @@ const headers = { 'Authorization': `Bearer ${khojToken}` }; // Populate type dropdown field with enabled content types only - fetch(`${hostURL}/api/configure/types`, { headers }) + fetch(`${hostURL}/api/content/types`, { headers }) .then(response => response.json()) .then(enabled_types => { // Show warning if no content types are enabled diff --git a/src/interface/emacs/khoj.el b/src/interface/emacs/khoj.el index c5a07cde..6f6747a8 100644 --- a/src/interface/emacs/khoj.el +++ b/src/interface/emacs/khoj.el @@ -424,12 +424,12 @@ Auto invokes setup steps on calling main entrypoint." "Send multi-part form `BODY' of `CONTENT-TYPE' in request to khoj server. Append 'TYPE-QUERY' as query parameter in request url. Specify `BOUNDARY' used to separate files in request header." - (let ((url-request-method "POST") + (let ((url-request-method ((if force) "PUT" "PATCH")) (url-request-data body) (url-request-extra-headers `(("content-type" . ,(format "multipart/form-data; boundary=%s" boundary)) ("Authorization" . ,(format "Bearer %s" khoj-api-key))))) (with-current-buffer - (url-retrieve (format "%s/api/v1/index/update?%s&force=%s&client=emacs" khoj-server-url type-query (or force "false")) + (url-retrieve (format "%s/api/content?%s&client=emacs" khoj-server-url type-query) ;; render response from indexing API endpoint on server (lambda (status) (if (not (plist-get status :error)) @@ -697,7 +697,7 @@ Optionally apply CALLBACK with JSON parsed response and CBARGS." (defun khoj--get-enabled-content-types () "Get content types enabled for search from API." - (khoj--call-api "/api/configure/types" "GET" nil `(lambda (item) (mapcar #'intern item)))) + (khoj--call-api "/api/content/types" "GET" nil `(lambda (item) (mapcar #'intern item)))) (defun khoj--query-search-api-and-render-results (query content-type buffer-name &optional rerank is-find-similar) "Query Khoj Search API with QUERY, CONTENT-TYPE and RERANK as query params. diff --git a/src/interface/obsidian/src/utils.ts b/src/interface/obsidian/src/utils.ts index 5c8b3cf9..55e3f63a 100644 --- a/src/interface/obsidian/src/utils.ts +++ b/src/interface/obsidian/src/utils.ts @@ -89,10 +89,11 @@ export async function updateContentIndex(vault: Vault, setting: KhojSetting, las for (let i = 0; i < fileData.length; i += 1000) { const filesGroup = fileData.slice(i, i + 1000); const formData = new FormData(); + const method = regenerate ? "PUT" : "PATCH"; filesGroup.forEach(fileItem => { formData.append('files', fileItem.blob, fileItem.path) }); // Call Khoj backend to update index with all markdown, pdf files - const response = await fetch(`${setting.khojUrl}/api/v1/index/update?force=${regenerate}&client=obsidian`, { - method: 'POST', + const response = await fetch(`${setting.khojUrl}/api/content?client=obsidian`, { + method: method, headers: { 'Authorization': `Bearer ${setting.khojApiKey}`, }, diff --git a/src/interface/web/app/common/chatFunctions.ts b/src/interface/web/app/common/chatFunctions.ts index 18d640e2..04acdba2 100644 --- a/src/interface/web/app/common/chatFunctions.ts +++ b/src/interface/web/app/common/chatFunctions.ts @@ -277,8 +277,8 @@ export function uploadDataForIndexing( // Wait for all files to be read before making the fetch request Promise.all(fileReadPromises) .then(() => { - return fetch("/api/v1/index/update?force=false&client=web", { - method: "POST", + return fetch("/api/content?client=web", { + method: "PATCH", body: formData, }); }) diff --git a/src/interface/web/app/components/modelPicker/modelPicker.tsx b/src/interface/web/app/components/modelPicker/modelPicker.tsx index 8e77db41..17244707 100644 --- a/src/interface/web/app/components/modelPicker/modelPicker.tsx +++ b/src/interface/web/app/components/modelPicker/modelPicker.tsx @@ -68,8 +68,8 @@ interface ModelPickerProps { } export const ModelPicker: React.FC = (props: ModelPickerProps) => { - const { data: models } = useOptionsRequest('/api/configure/chat/model/options'); - const { data: selectedModel } = useSelectedModel('/api/configure/chat/model'); + const { data: models } = useOptionsRequest('/api/model/chat/options'); + const { data: selectedModel } = useSelectedModel('/api/model/chat'); const [openLoginDialog, setOpenLoginDialog] = React.useState(false); let userData = useAuthenticatedData(); @@ -94,7 +94,7 @@ export const ModelPicker: React.FC = (props: ModelPickerProps) => { props.setModelUsed(model); } - fetch('/api/configure/chat/model' + '?id=' + String(model.id), { method: 'POST', body: JSON.stringify(model) }) + fetch('/api/model/chat' + '?id=' + String(model.id), { method: 'POST', body: JSON.stringify(model) }) .then((response) => { if (!response.ok) { throw new Error('Failed to select model'); diff --git a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx index 705bcbc1..955bd26a 100644 --- a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx +++ b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx @@ -148,7 +148,7 @@ interface FilesMenuProps { function FilesMenu(props: FilesMenuProps) { // Use SWR to fetch files - const { data: files, error } = useSWR(props.conversationId ? '/api/configure/content/computer' : null, fetcher); + const { data: files, error } = useSWR(props.conversationId ? '/api/content/computer' : null, fetcher); const { data: selectedFiles, error: selectedFilesError } = useSWR(props.conversationId ? `/api/chat/conversation/file-filters/${props.conversationId}` : null, fetcher); const [isOpen, setIsOpen] = useState(false); const [unfilteredFiles, setUnfilteredFiles] = useState([]); diff --git a/src/khoj/configure.py b/src/khoj/configure.py index 819fc15d..a77ade87 100644 --- a/src/khoj/configure.py +++ b/src/khoj/configure.py @@ -42,7 +42,7 @@ from khoj.database.adapters import ( ) from khoj.database.models import ClientApplication, KhojUser, ProcessLock, Subscription from khoj.processor.embeddings import CrossEncoderModel, EmbeddingsModel -from khoj.routers.indexer import configure_content, configure_search +from khoj.routers.api_content import configure_content, configure_search from khoj.routers.twilio import is_twilio_enabled from khoj.utils import constants, state from khoj.utils.config import SearchType @@ -308,16 +308,16 @@ def configure_routes(app): from khoj.routers.api import api from khoj.routers.api_agents import api_agents from khoj.routers.api_chat import api_chat - from khoj.routers.api_config import api_config - from khoj.routers.indexer import indexer + from khoj.routers.api_content import api_content + from khoj.routers.api_model import api_model from khoj.routers.notion import notion_router from khoj.routers.web_client import web_client app.include_router(api, prefix="/api") app.include_router(api_chat, prefix="/api/chat") app.include_router(api_agents, prefix="/api/agents") - app.include_router(api_config, prefix="/api/configure") - app.include_router(indexer, prefix="/api/v1/index") + app.include_router(api_model, prefix="/api/model") + app.include_router(api_content, prefix="/api/content") app.include_router(notion_router, prefix="/api/notion") app.include_router(web_client) @@ -336,7 +336,7 @@ def configure_routes(app): if is_twilio_enabled(): from khoj.routers.api_phone import api_phone - app.include_router(api_phone, prefix="/api/configure/phone") + app.include_router(api_phone, prefix="/api/phone") logger.info("📞 Enabled Twilio") diff --git a/src/khoj/interface/web/chat.html b/src/khoj/interface/web/chat.html index 38007ce2..149a0a66 100644 --- a/src/khoj/interface/web/chat.html +++ b/src/khoj/interface/web/chat.html @@ -998,8 +998,8 @@ To get started, just start typing below. You can also type / to see a list of co // Wait for all files to be read before making the fetch request Promise.all(fileReadPromises) .then(() => { - return fetch("/api/v1/index/update?force=false&client=web", { - method: "POST", + return fetch("/api/content?client=web", { + method: "PATCH", body: formData, }); }) @@ -1954,7 +1954,7 @@ To get started, just start typing below. You can also type / to see a list of co } var allFiles; function renderAllFiles() { - fetch('/api/configure/content/computer') + fetch('/api/content/computer') .then(response => response.json()) .then(data => { var indexedFiles = document.getElementsByClassName("indexed-files")[0]; diff --git a/src/khoj/interface/web/content_source_computer_input.html b/src/khoj/interface/web/content_source_computer_input.html index e0ffc4e9..fd66360d 100644 --- a/src/khoj/interface/web/content_source_computer_input.html +++ b/src/khoj/interface/web/content_source_computer_input.html @@ -32,7 +32,7 @@