Spaces:
Paused
Paused
frdel commited on
Commit ·
9b39360
1
Parent(s): 896ad5f
scheduler contexts fix
Browse files- python/api/scheduler_task_create.py +6 -5
- python/helpers/task_scheduler.py +4 -4
- webui/index.js +25 -18
- webui/js/scheduler.js +7 -2
python/api/scheduler_task_create.py
CHANGED
|
@@ -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")
|
| 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
|
| 48 |
-
return {"error": "Missing required fields: name, system_prompt, prompt"}
|
|
|
|
| 49 |
|
| 50 |
task = None
|
| 51 |
if schedule:
|
|
@@ -66,9 +67,9 @@ class SchedulerTaskCreate(ApiHandler):
|
|
| 66 |
try:
|
| 67 |
task_schedule = parse_task_schedule(schedule)
|
| 68 |
except ValueError as e:
|
| 69 |
-
|
| 70 |
else:
|
| 71 |
-
|
| 72 |
|
| 73 |
task = ScheduledTask.create(
|
| 74 |
name=name,
|
|
|
|
| 24 |
|
| 25 |
# Get common fields from input
|
| 26 |
name = input.get("name")
|
| 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 |
plan = input.get("plan", {})
|
| 45 |
|
| 46 |
# Validate required fields
|
| 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:
|
|
|
|
| 67 |
try:
|
| 68 |
task_schedule = parse_task_schedule(schedule)
|
| 69 |
except ValueError as e:
|
| 70 |
+
raise ValueError(str(e))
|
| 71 |
else:
|
| 72 |
+
raise ValueError("Invalid schedule format. Must be string or object.")
|
| 73 |
|
| 74 |
task = ScheduledTask.create(
|
| 75 |
name=name,
|
python/helpers/task_scheduler.py
CHANGED
|
@@ -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
|
| 711 |
# initial name before renaming is same as 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
|
| 776 |
agent = context.streaming_agent or context.agent0
|
| 777 |
|
| 778 |
# Prepare attachment filenames for logging
|
|
|
|
| 706 |
raise ValueError(f"Task {task.name} has no context ID")
|
| 707 |
|
| 708 |
config = initialize()
|
| 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
|
| 713 |
|
| 714 |
# Save the context
|
| 715 |
save_tmp_chat(context)
|
|
|
|
| 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
|
| 776 |
agent = context.streaming_agent or context.agent0
|
| 777 |
|
| 778 |
# Prepare attachment filenames for logging
|
webui/index.js
CHANGED
|
@@ -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 |
-
//
|
| 566 |
-
|
| 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 |
-
}
|
| 583 |
|
| 584 |
// Delete the chat on the server
|
| 585 |
await sendJsonData("/chat_remove", { context: id });
|
|
@@ -601,6 +585,29 @@ window.killChat = async function (id) {
|
|
| 601 |
}
|
| 602 |
}
|
| 603 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 604 |
// Function to ensure proper UI state when switching contexts
|
| 605 |
function ensureProperTabSelection(contextId) {
|
| 606 |
// Get current active tab
|
|
|
|
| 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 |
+
// 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 });
|
|
|
|
| 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
CHANGED
|
@@ -4,6 +4,7 @@
|
|
| 4 |
*/
|
| 5 |
|
| 6 |
import { formatDateTime, getUserTimezone } from './time-utils.js';
|
|
|
|
| 7 |
|
| 8 |
// Ensure the showToast function is available
|
| 9 |
// if (typeof window.showToast !== 'function') {
|
|
@@ -652,8 +653,9 @@ const fullComponentImplementation = function() {
|
|
| 652 |
// Save task (create new or update existing)
|
| 653 |
async saveTask() {
|
| 654 |
// Validate task data
|
| 655 |
-
if (!this.editingTask.name.trim()) {
|
| 656 |
-
showToast('Task name
|
|
|
|
| 657 |
return;
|
| 658 |
}
|
| 659 |
|
|
@@ -971,6 +973,9 @@ const fullComponentImplementation = function() {
|
|
| 971 |
|
| 972 |
showToast('Task deleted successfully', 'success');
|
| 973 |
|
|
|
|
|
|
|
|
|
|
| 974 |
// If we were viewing the detail of the deleted task, close the detail view
|
| 975 |
if (this.selectedTaskForDetail && this.selectedTaskForDetail.uuid === taskId) {
|
| 976 |
this.closeTaskDetail();
|
|
|
|
| 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') {
|
|
|
|
| 653 |
// Save task (create new or update existing)
|
| 654 |
async saveTask() {
|
| 655 |
// Validate task data
|
| 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 |
|
|
|
|
| 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();
|