diff --git a/src/khoj/interface/web/assets/icons/edit.svg b/src/khoj/interface/web/assets/icons/edit.svg
new file mode 100644
index 00000000..9dd66854
--- /dev/null
+++ b/src/khoj/interface/web/assets/icons/edit.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/src/khoj/interface/web/config.html b/src/khoj/interface/web/config.html
index 50858f26..37a68e57 100644
--- a/src/khoj/interface/web/config.html
+++ b/src/khoj/interface/web/config.html
@@ -689,10 +689,11 @@
${automationObj.subject} |
${automationObj.scheduling_request} |
- ${automationObj.query_to_run} |
+ ${automationObj.query_to_run} |
${automationObj.schedule} |
+
|
`;
@@ -730,6 +731,23 @@
}
document.getElementById("create-automation").addEventListener("click", async () => { await createAutomation(); });
+ function editAutomation(automationId) {
+ const query_to_run = window.prompt("What is the query you want to run on this automation's schedule?");
+ if (!query_to_run) return;
+
+ fetch(`/api/automation?automation_id=${automationId}&query_to_run=${query_to_run}`, {
+ method: 'PATCH',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ }).then(response => {
+ if (response.ok) {
+ const automationQueryToRunColumn = document.getElementById(`automation-query-to-run-${automationId}`);
+ automationQueryToRunColumn.innerHTML = `${query_to_run}`;
+ }
+ });
+ }
+
function getIndexedDataSize() {
document.getElementById("indexed-data-size").innerHTML = "Calculating...";
fetch('/api/config/index/size')
diff --git a/src/khoj/routers/api.py b/src/khoj/routers/api.py
index 663dc99a..7f1d82e4 100644
--- a/src/khoj/routers/api.py
+++ b/src/khoj/routers/api.py
@@ -487,3 +487,40 @@ async def make_automation(
}
# Return information about the created automation as a JSON response
return Response(content=json.dumps(automation_info), media_type="application/json", status_code=200)
+
+
+@api.patch("/automation", response_class=Response)
+@requires(["authenticated"])
+def edit_job(
+ request: Request, automation_id: str, query_to_run: Optional[str] = None, crontime: Optional[str] = None
+) -> Response:
+ user: KhojUser = request.user.object
+
+ # Perform validation checks
+ # Check at least one of query or crontime is provided
+ if not query_to_run and not crontime:
+ return Response(content="A query or crontime is required", status_code=400)
+ # Check if user is allowed to edit this automation id
+ if not automation_id.startswith(f"automation_{user.uuid}_"):
+ return Response(content="Unauthorized automation deletion request", status_code=403)
+ # Check if automation with this id exist
+ automation: Job = state.scheduler.get_job(job_id=automation_id)
+ if not automation:
+ return Response(content="Invalid automation", status_code=403)
+ if not query_to_run.startswith("/automated_task"):
+ query_to_run = f"/automated_task {query_to_run}"
+
+ # Update automation with new query
+ automation_metadata = json.loads(automation.name)
+ automation_metadata["query_to_run"] = query_to_run
+ automation.modify(kwargs={"query_to_run": query_to_run}, name=json.dumps(automation_metadata))
+
+ # Collate info about the modified user automation
+ automation_info = {
+ "id": automation.id,
+ "name": automation.name,
+ "next": automation.next_run_time.strftime("%Y-%m-%d %H:%MS"),
+ }
+
+ # Return modified automation information as a JSON response
+ return Response(content=json.dumps(automation_info), media_type="application/json", status_code=200)