v0.8.0: WebUI redesign, /web, workspace switch, 75% budget, no shell timeout
The front end is rebuilt on the design tokens the desktop app ships (surfaces, color-mix borders, alpha hovers, accent): a 30-icon inline SVG sprite, dark and light themes, layout switches as deep links (?side=0, ?panel=0, ?theme=light) resolved before the first paint. The empty page is one line and leaves with the first turn; the right rail keeps three cards - todo, file changes (+N -M) and context (tokens, prompt cache hit rate). Both rails animate in and out, and a collapsed rail widens its grid track to 0 instead of being removed, so the transcript never slides into a zero-width column. - src/webui.c: POST /api/workspace - re-root the agent at another directory (permission rules, metrics, AGENTS.md follow) and start a session there, as sessions live per directory; state also reports cached/cache_miss tokens - src/agent_loop.c: cst_agent_set_workspace(), rebuilt prompt and re-measured budget; the auto-compact threshold is 75% of the window (was 60%) - src/tui.c: /web forks a WebUI next to the TUI - separate process and a new session, because cst_webui_run() blocks and two writers corrupt one session - src/os_compat.c, src/os_win.c: run_shell runs without a time limit unless CST_SHELL_TIMEOUT asks for one, so builds and long clones finish - src/main.c, include/cst_webui.h: one CST_WEBUI_DEFAULT_PORT for --help, the docs and /web; Termux opens the browser through termux-open-url - README.md, docs/webui.md, docs/env_openai.md: /web, /api/workspace, the new state fields, the 75% threshold and the layout deep links tests/e2e_webui.sh green (permission round-trip, token paths, --web-dev); make check green.
This commit is contained in:
+40
-4
@@ -2558,9 +2558,9 @@ static int can_continue(const cst_agent_t *a, const turn_t *t,
|
||||
return st->http_status > 0 && st->http_status < 400 && !st->client_stopped;
|
||||
}
|
||||
|
||||
/* Prompt size at which the session is compacted: CST_CTX_BUDGET, else 60% of
|
||||
* the context window capped at 256K tokens. Even a cached prompt is billed
|
||||
* on every step, so huge windows are not worth filling. */
|
||||
/* Prompt size at which the session is compacted: CST_CTX_BUDGET, else 75% of
|
||||
* the context window, capped at 256K tokens. Even a cached prompt is billed on
|
||||
* every step, so a 1M-token window is not worth filling. */
|
||||
static long ctx_budget(const cst_agent_t *a) {
|
||||
const char *e = getenv("CST_CTX_BUDGET");
|
||||
if (e && atol(e) > 0)
|
||||
@@ -2568,7 +2568,7 @@ static long ctx_budget(const cst_agent_t *a) {
|
||||
long win = cst_model_context_tokens(a->cfg.model);
|
||||
if (win <= 0)
|
||||
return 0;
|
||||
long b = win / 10 * 6;
|
||||
long b = win / 4 * 3;
|
||||
return b > 262144 ? 262144 : b;
|
||||
}
|
||||
|
||||
@@ -2948,6 +2948,42 @@ int cst_agent_new_session(cst_agent_t *a, char *id_out, size_t id_sz) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cst_agent_set_workspace(cst_agent_t *a, const char *path, char *err,
|
||||
size_t err_sz) {
|
||||
char dummy[8];
|
||||
if (!err || !err_sz) {
|
||||
err = dummy;
|
||||
err_sz = sizeof(dummy);
|
||||
}
|
||||
err[0] = 0;
|
||||
if (!a || !path || !path[0]) {
|
||||
snprintf(err, err_sz, "empty path");
|
||||
return -1;
|
||||
}
|
||||
char abs[sizeof(a->cfg.workspace_root)];
|
||||
if (os_realpath(path, abs, sizeof(abs)) != 0) {
|
||||
snprintf(err, err_sz, "no such directory: %s", path);
|
||||
return -1;
|
||||
}
|
||||
/* a file, or a tree we may not write to, fails here instead of halfway
|
||||
* through the next turn */
|
||||
if (cst_agent_store_ensure(abs) != 0) {
|
||||
snprintf(err, err_sz, "cannot use as a workspace: %s", abs);
|
||||
return -1;
|
||||
}
|
||||
snprintf(a->cfg.workspace_root, sizeof(a->cfg.workspace_root), "%s", abs);
|
||||
/* everything that is kept per workspace follows the new root */
|
||||
cst_perms_close(a->perms);
|
||||
a->perms = cst_perms_open(a->cfg.workspace_root);
|
||||
cst_metrics_close(a->metrics);
|
||||
a->metrics = cst_metrics_open(a->cfg.workspace_root,
|
||||
cst_session_path(a->session));
|
||||
cst_agent_reload_notes(a);
|
||||
ensure_system(a); /* the prompt names the directory */
|
||||
a->last_prompt_tokens = 0; /* the old budget was measured elsewhere */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cst_agent_switch_session(cst_agent_t *a, const char *id) {
|
||||
if (!a || !id || !id[0])
|
||||
return -1;
|
||||
|
||||
Reference in New Issue
Block a user