feat: add v2 task control and asynchronous isolated workers

This commit is contained in:
WHC
2026-10-20 14:46:57 +08:00
parent 143dba203b
commit d971cb02b0
26 changed files with 1590 additions and 66 deletions
+25 -21
View File
@@ -14,6 +14,7 @@
#include "cst_provider_switch.h"
#include "cst_skills.h"
#include "cst_subagent.h"
#include "cst_runtime.h"
#include "cst_textsel.h"
#include "cst_perms.h"
#include "cst_sandbox.h"
@@ -2204,7 +2205,7 @@ static void draw_input(tui_t *t) {
HAS_COLOR() ? (int)COLOR_PAIR(CP_BOX_MUTED) : 0);
if (t->in_len == 0) {
const char *hint =
t->busy ? "Enter queues a message"
t->busy ? "Enter redirects the active task"
: (g_ascii ? "Ask anything... \"Fix a TODO in this repo\""
: "Ask anything… \"Fix a TODO in this repo\"");
draw_ansi_at(w, pad, IN_COL, bw - IN_COL - 1, hint, CP_BOX_MUTED, 0, 0);
@@ -3201,18 +3202,6 @@ static void hist_load_into_input(tui_t *t, int idx) {
t->hist_browse = idx;
}
static int queue_push(tui_t *t, const char *prompt) {
if (!prompt || !prompt[0])
return -1;
if (t->queue_n >= QUEUE_CAP)
return -1;
t->queue[t->queue_n] = strdup(prompt);
if (!t->queue[t->queue_n])
return -1;
t->queue_n++;
return 0;
}
static char *queue_pop(tui_t *t) {
if (t->queue_n <= 0)
return NULL;
@@ -5328,6 +5317,25 @@ static void show_subagent(tui_t *t, const char *pid,
cst_session_close(s);
}
static void cmd_task(tui_t *t, char *arg, int *quit) {
(void)quit;
if (!arg || !*arg || !strcmp(arg, "state")) {
char *s = cst_runtime_json(cst_agent_config(t->agent)->runtime);
push_system_line(t, "%s", s ? s : "{}"); free(s); return;
}
if (!strncmp(arg, "cancel ", 7) || !strncmp(arg, "force ", 6)) {
int force = !strncmp(arg, "force ", 6);
int rc = cst_job_cancel(cst_agent_config(t->agent)->runtime, arg + (force ? 6 : 7), force, "user");
push_system_line(t, "%s", rc ? "active job not found" : "job cancellation requested"); return;
}
int ro = !strcmp(arg, "readonly") ? 1 : !strcmp(arg, "write") ? 0 : -1;
int delegate = !strcmp(arg, "direct") ? 0 : !strcmp(arg, "auto") ? 1 : -1;
int paused = !strcmp(arg, "pause") ? 1 : !strcmp(arg, "resume") ? 0 : -1;
if (ro < 0 && delegate < 0 && paused < 0) { push_system_line(t, "Use /task state|readonly|write|direct|auto|pause|resume|cancel ID|force ID"); return; }
cst_agent_control(t->agent, ro, delegate, paused);
push_system_line(t, "Task controls updated; stale actions will not execute.");
}
static void cmd_agents(tui_t *t, char *arg, int *quit) {
(void)quit;
const char *ws = cst_agent_config(t->agent)->workspace_root;
@@ -5602,6 +5610,7 @@ static const slash_cmd_t SLASH[] = {
{"mcp", "", "[reload]", "MCP servers and their state", 0, cmd_mcp},
{"agents", "", "", "sub-agent roles and this session's runs", 0,
cmd_agents},
{"task", "jobs", "[state|readonly|write|direct|auto|pause|resume]", "task controls and jobs", 1, cmd_task},
{"skill", "", "<name> [task]", "run a task with a skill loaded", 0,
cmd_skill},
{"web", "", "", "start the WebUI in the background (127.0.0.1:8787)", 1,
@@ -6007,14 +6016,9 @@ static int submit_input(tui_t *t, int busy) {
return q ? -2 : 0;
}
if (busy) {
if (queue_push(t, prompt) != 0) {
push_system_line(t, "(queue full — max %d)", QUEUE_CAP);
set_status(t, "queue full");
} else {
char msg[64];
snprintf(msg, sizeof(msg), "queued (%d)", t->queue_n);
set_status(t, msg);
}
cst_agent_steer(t->agent, prompt, -1, -1);
push_system_line(t, "New instruction sent; conflicting queued actions stopped.");
set_status(t, "applying new instruction");
free(prompt);
draw_status(t);
return 0;