scheduler contexts fix
frdel committed
May 3, 2025 at 19:01 UTC
660eee209ff256a66cf228e38e5e1ff09059998f
4 files changed
+42
-29
python/api/scheduler_task_create.py
+6
-5
@@ -24,7 +24,7 @@ class SchedulerTaskCreate(ApiHandler):
24
25
# Get common fields from input
26
name = input.get("name")
27
- system_prompt = input.get("system_prompt")
27
+ system_prompt = input.get("system_prompt", "")
28
prompt = input.get("prompt")
29
attachments = input.get("attachments", [])
30
context_id = input.get("context_id", None)
@@ -44,8 +44,9 @@ class SchedulerTaskCreate(ApiHandler):
44
plan = input.get("plan", {})
45
46
# Validate required fields
47
- if not name or not system_prompt or not prompt:
48
- return {"error": "Missing required fields: name, system_prompt, prompt"}
47
+ if not name or not prompt:
48
+ # return {"error": "Missing required fields: name, system_prompt, prompt"}
49
+ raise ValueError("Missing required fields: name, system_prompt, prompt")
50
51
task = None
52
if schedule:
@@ -66,9 +67,9 @@ class SchedulerTaskCreate(ApiHandler):
67
try:
68
task_schedule = parse_task_schedule(schedule)
69
except ValueError as e:
69
- return {"error": str(e)}
70
+ raise ValueError(str(e))
71
else:
71
- return {"error": "Invalid schedule format. Must be string or object."}
72
+ raise ValueError("Invalid schedule format. Must be string or object.")
73
74
task = ScheduledTask.create(
75
name=name,
python/helpers/task_scheduler.py
+4
-4
@@ -706,10 +706,10 @@ class TaskScheduler:
706
raise ValueError(f"Task {task.name} has no context ID")
707
708
config = initialize()
709
- context: AgentContext = AgentContext(config)
710
- context.id = task.context_id
709
+ context: AgentContext = AgentContext(config, id=task.context_id, name=task.name)
710
+ # context.id = task.context_id
711
# initial name before renaming is same as task name
712
- context.name = task.name
712
+ # context.name = task.name
713
714
# Save the context
715
save_tmp_chat(context)
@@ -772,7 +772,7 @@ class TaskScheduler:
772
# Ensure the context is properly registered in the AgentContext._contexts
773
# This is critical for the polling mechanism to find and stream logs
774
# Dict operations are atomic
775
- AgentContext._contexts[context.id] = context
775
+ # AgentContext._contexts[context.id] = context
776
agent = context.streaming_agent or context.agent0
777
778
# Prepare attachment filenames for logging
webui/index.js
+25
-18
@@ -562,24 +562,8 @@ window.killChat = async function (id) {
562
const chatsAD = Alpine.$data(chatsSection);
563
console.log("Current contexts before deletion:", JSON.stringify(chatsAD.contexts.map(c => ({ id: c.id, name: c.name }))));
564
565
- // Find an alternate chat to switch to if we're deleting the current one
566
- let alternateChat = null;
567
- for (let i = 0; i < chatsAD.contexts.length; i++) {
568
- if (chatsAD.contexts[i].id !== id) {
569
- alternateChat = chatsAD.contexts[i];
570
- break;
571
- }
572
- }
573
-
574
- // If we're deleting the currently selected chat, switch to another one first
575
- if (context === id) {
576
- if (alternateChat) {
577
- setContext(alternateChat.id);
578
- } else {
579
- // If no other chats, create a new empty context
580
- setContext(generateGUID());
581
- }
582
- }
565
+ // switch to another context if deleting current
566
+ switchFromContext(id);
567
568
// Delete the chat on the server
569
await sendJsonData("/chat_remove", { context: id });
@@ -601,6 +585,29 @@ window.killChat = async function (id) {
585
}
586
}
587
588
+export function switchFromContext(id){
589
+ // If we're deleting the currently selected chat, switch to another one first
590
+ if (context === id) {
591
+ const chatsAD = Alpine.$data(chatsSection);
592
+
593
+ // Find an alternate chat to switch to if we're deleting the current one
594
+ let alternateChat = null;
595
+ for (let i = 0; i < chatsAD.contexts.length; i++) {
596
+ if (chatsAD.contexts[i].id !== id) {
597
+ alternateChat = chatsAD.contexts[i];
598
+ break;
599
+ }
600
+ }
601
+
602
+ if (alternateChat) {
603
+ setContext(alternateChat.id);
604
+ } else {
605
+ // If no other chats, create a new empty context
606
+ setContext(generateGUID());
607
+ }
608
+ }
609
+}
610
+
611
// Function to ensure proper UI state when switching contexts
612
function ensureProperTabSelection(contextId) {
613
// Get current active tab
webui/js/scheduler.js
+7
-2
@@ -4,6 +4,7 @@
4
*/
5
6
import { formatDateTime, getUserTimezone } from './time-utils.js';
7
+import { switchFromContext } from '../index.js';
8
9
// Ensure the showToast function is available
10
// if (typeof window.showToast !== 'function') {
@@ -652,8 +653,9 @@ const fullComponentImplementation = function() {
653
// Save task (create new or update existing)
654
async saveTask() {
655
// Validate task data
655
- if (!this.editingTask.name.trim()) {
656
- showToast('Task name is required', 'error');
656
+ if (!this.editingTask.name.trim() || !this.editingTask.prompt.trim()) {
657
+ // showToast('Task name and prompt are required', 'error');
658
+ alert('Task name and prompt are required');
659
return;
660
}
661
@@ -971,6 +973,9 @@ const fullComponentImplementation = function() {
973
974
showToast('Task deleted successfully', 'success');
975
976
+ // if we deleted selected context, switch to another
977
+ switchFromContext(taskId);
978
+
979
// If we were viewing the detail of the deleted task, close the detail view
980
if (this.selectedTaskForDetail && this.selectedTaskForDetail.uuid === taskId) {
981
this.closeTaskDetail();