diff --git a/Cargo.toml b/Cargo.toml index 98daec3..87799a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "picobot" -version = "1.13.0" +version = "1.13.1" edition = "2024" [dependencies] diff --git a/webui/package-lock.json b/webui/package-lock.json index 58ae6ec..06a363e 100644 --- a/webui/package-lock.json +++ b/webui/package-lock.json @@ -1,12 +1,12 @@ { "name": "picobot-webui", - "version": "1.13.0", + "version": "1.13.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "picobot-webui", - "version": "1.13.0", + "version": "1.13.1", "dependencies": { "bits-ui": "^2.0.0", "dompurify": "^3.4.12", diff --git a/webui/package.json b/webui/package.json index e9609a4..e5be8c7 100644 --- a/webui/package.json +++ b/webui/package.json @@ -1,7 +1,7 @@ { "name": "picobot-webui", "private": true, - "version": "1.13.0", + "version": "1.13.1", "type": "module", "engines": { "node": ">=20" diff --git a/webui/src/lib/components/SubAgentDefinitions.svelte b/webui/src/lib/components/SubAgentDefinitions.svelte index 06479b5..f015725 100644 --- a/webui/src/lib/components/SubAgentDefinitions.svelte +++ b/webui/src/lib/components/SubAgentDefinitions.svelte @@ -10,8 +10,23 @@ let error = $state(""); let editing = $state(null); let saving = $state(false); + let reloading = $state(false); + let reloadStatus = $state(null); + let pollTimer = null; let { notify } = $props(); + const phaseBadge = $derived.by(() => { + if (!reloadStatus) return "ok"; + const map = { active: "ok", preparing: "run", draining: "run", activating: "run", failed: "fail" }; + return map[reloadStatus.phase] || "ok"; + }); + + const phaseLabel = $derived.by(() => { + if (!reloadStatus) return ""; + const map = { active: "运行中", preparing: "准备中", draining: "等待任务完成", activating: "激活中", failed: "失败" }; + return map[reloadStatus.phase] || reloadStatus.phase; + }); + const blank = () => ({ id: "", description: "", @@ -44,6 +59,33 @@ } } + async function reload() { + reloading = true; + try { + const result = await api("/api/config/reload", { method: "POST" }); + notify(result.message || "已触发热重载"); + await pollReloadStatus(); + } catch (caught) { + notify(caught.message, true); + } finally { + reloading = false; + } + } + + async function pollReloadStatus() { + try { reloadStatus = await api("/api/config/reload/status"); } catch {} + } + + function startPolling() { + stopPolling(); + pollReloadStatus(); + pollTimer = setInterval(pollReloadStatus, 3000); + } + + function stopPolling() { + if (pollTimer) { clearInterval(pollTimer); pollTimer = null; } + } + function toggleTool(list, name) { const i = list.indexOf(name); if (i >= 0) list.splice(i, 1); @@ -132,7 +174,7 @@ else if (editing.delegateMode === "list") payload.delegates = editing.delegates; await api("/api/agents", { method: "POST", body: JSON.stringify(payload) }); editing = null; - notify("子代理已保存(需重载配置生效)"); + notify("子代理已保存,点击「热重载」使其生效"); await load(); } catch (caught) { notify(caught.message, true); @@ -181,7 +223,11 @@ return tool?.description || ""; } - onMount(load); + onMount(() => { + load(); + startPolling(); + return stopPolling; + });
@@ -189,10 +235,16 @@

具名子代理

- 子代理由 ~/.picobot/agents/*.md 定义;工具、Skill、Provider 与模型在此直接指定。主 Agent 可委托给任意子代理。改动需热重载后生效。 + 子代理由 ~/.picobot/agents/*.md 定义;工具、Skill、Provider 与模型在此直接指定。保存后点击「热重载」使改动生效。

- +
+ {#if reloadStatus} + {phaseLabel} + {/if} + + +
{#if loading} @@ -239,7 +291,7 @@