turbollm 1.13.2 → 1.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/{chunk-HOKZAC3U.js → chunk-Y3TMLJQD.js} +43 -5
- package/dist/cli.js +213 -45
- package/dist/{factory-7ITNXXOI.js → factory-NOUUQICH.js} +1 -1
- package/dist/webdist/assets/{AgentEditPage-DS2SLHM_.js → AgentEditPage-8XwklBCN.js} +1 -1
- package/dist/webdist/assets/{ChatScreen-COYA_6ek.js → ChatScreen-BG-gWo8i.js} +1 -1
- package/dist/webdist/assets/CodeComposer-Bui_gqhF.js +1 -0
- package/dist/webdist/assets/{CodeHomeScreen-Csc_MF8U.js → CodeHomeScreen-CEaCj3je.js} +1 -1
- package/dist/webdist/assets/{CodeSessionScreen-6E3XY4su.js → CodeSessionScreen-DUTkKMNW.js} +1 -1
- package/dist/webdist/assets/{CustomizeScreen-CFr1srQu.js → CustomizeScreen-ze18T4hb.js} +1 -1
- package/dist/webdist/assets/{EnginesScreen-D2keJZ8l.js → EnginesScreen-CmJVhifa.js} +1 -1
- package/dist/webdist/assets/HardwareSection-63UUvSMO.js +1 -0
- package/dist/webdist/assets/{ModelDetailDialog-BQCs3W1u.js → ModelDetailDialog-C2lnCsw6.js} +1 -1
- package/dist/webdist/assets/{ModelLoadMenu-Bk0HSsac.js → ModelLoadMenu-D0bpk6p2.js} +1 -1
- package/dist/webdist/assets/{ModelsScreen-BSnFI83c.js → ModelsScreen-DYSvF-AP.js} +1 -1
- package/dist/webdist/assets/OnboardingScreen-Bti1XKVZ.js +1 -0
- package/dist/webdist/assets/{RoutineEditPage-C0GmeKlu.js → RoutineEditPage-Dytik45T.js} +1 -1
- package/dist/webdist/assets/{RoutinesPanel-CZ7kGceG.js → RoutinesPanel-CK2_OmGj.js} +1 -1
- package/dist/webdist/assets/{SettingsScreen-BnC6qSFo.js → SettingsScreen-qcB-Wlhm.js} +1 -1
- package/dist/webdist/assets/{SidebarResizeHandle-D-1cxpNM.js → SidebarResizeHandle-C6DzzA0i.js} +2 -2
- package/dist/webdist/assets/{SkillEditPage-BFnoGYE4.js → SkillEditPage-BoVodeSt.js} +1 -1
- package/dist/webdist/assets/{ToolApprovalBar-gBl1Pne_.js → ToolApprovalBar-CkVy2BpV.js} +3 -3
- package/dist/webdist/assets/WorkspaceScreen-BzYimITz.js +1 -0
- package/dist/webdist/assets/{abnfDiagram-N423BO3Z-B-yxOJAr.js → abnfDiagram-N423BO3Z-BsFZfp7v.js} +1 -1
- package/dist/webdist/assets/{agent-api-1EptCITO.js → agent-api-CeGvce9t.js} +1 -1
- package/dist/webdist/assets/{alert-dialog-DId8mvnn.js → alert-dialog-Crc_A3Jz.js} +1 -1
- package/dist/webdist/assets/{arc-CmG0J3F-.js → arc-DBKAh_3p.js} +1 -1
- package/dist/webdist/assets/{architectureDiagram-T3A2C74G-CLcR4aXc.js → architectureDiagram-T3A2C74G-DF2Iau9y.js} +1 -1
- package/dist/webdist/assets/{blockDiagram-VBNYF7ZC-ImyoZH5n.js → blockDiagram-VBNYF7ZC-EIM7OH8W.js} +1 -1
- package/dist/webdist/assets/{c4Diagram-5PPSVZJV-Dn1etOjf.js → c4Diagram-5PPSVZJV-DfTJQH_y.js} +1 -1
- package/dist/webdist/assets/channel-BF2z4CLG.js +1 -0
- package/dist/webdist/assets/{chat-api-CCZfNFmH.js → chat-api-BspgdIew.js} +1 -1
- package/dist/webdist/assets/{chat-queries-6aDORXMQ.js → chat-queries-dQVxfOyx.js} +1 -1
- package/dist/webdist/assets/{chevron-down-CquxAQxl.js → chevron-down-DNeXZ14t.js} +1 -1
- package/dist/webdist/assets/{chevron-left-irxTskG3.js → chevron-left-yPpon0Zo.js} +1 -1
- package/dist/webdist/assets/{chevron-right-BxDhzUZl.js → chevron-right-qwzlPkv4.js} +1 -1
- package/dist/webdist/assets/{chunk-2GRJ4B5K-et7nGso8.js → chunk-2GRJ4B5K-g8WkdrcJ.js} +1 -1
- package/dist/webdist/assets/{chunk-2Q5K7J3B-C7vz-PvX.js → chunk-2Q5K7J3B-DiSXrpfm.js} +1 -1
- package/dist/webdist/assets/{chunk-5RXB4S5H-DWdBsuyj.js → chunk-5RXB4S5H--rX8NQES.js} +1 -1
- package/dist/webdist/assets/{chunk-5VM5RSS4-DqfZvvbb.js → chunk-5VM5RSS4-D0bbkNOA.js} +1 -1
- package/dist/webdist/assets/{chunk-6Q2QTUOP-qF-CNBFu.js → chunk-6Q2QTUOP-CyjvDHy7.js} +1 -1
- package/dist/webdist/assets/{chunk-GF5L2VYU-CrVRwghC.js → chunk-GF5L2VYU-DBsZFyHH.js} +1 -1
- package/dist/webdist/assets/{chunk-JWPE2WC7-BRr2laYf.js → chunk-JWPE2WC7-BJX8rZY8.js} +1 -1
- package/dist/webdist/assets/{chunk-KBJHAD2P-JxaAF9FJ.js → chunk-KBJHAD2P-CzHI537O.js} +1 -1
- package/dist/webdist/assets/{chunk-RYQCIY6F-W9k-woT3.js → chunk-RYQCIY6F-DcQ5BoLP.js} +1 -1
- package/dist/webdist/assets/{chunk-XXDRQBXY-BEf2Mob4.js → chunk-XXDRQBXY-DwaqNMb3.js} +1 -1
- package/dist/webdist/assets/{circle-check-oj-qQsUY.js → circle-check-Brhy4Orf.js} +1 -1
- package/dist/webdist/assets/{circle-x-gGXzROsQ.js → circle-x-BvhAr_O9.js} +1 -1
- package/dist/webdist/assets/classDiagram-JCYQIIEL-D-pqoTab.js +1 -0
- package/dist/webdist/assets/classDiagram-v2-OCEON4UE-D-pqoTab.js +1 -0
- package/dist/webdist/assets/{collapsible-DL9VySa3.js → collapsible-Bg5PA5Nz.js} +1 -1
- package/dist/webdist/assets/{cose-bilkent-JH36ORCC-tkfBcHU9.js → cose-bilkent-JH36ORCC-DT2idxjo.js} +1 -1
- package/dist/webdist/assets/{cynefin-VYW2F7L2-zJZI0irR.js → cynefin-VYW2F7L2-9kVBD_9a.js} +1 -1
- package/dist/webdist/assets/{cynefinDiagram-MW4NZA55-BbH3UWYG.js → cynefinDiagram-MW4NZA55-CTix7oEO.js} +1 -1
- package/dist/webdist/assets/{dagre-VZM6K2ZE-DyC5hntE.js → dagre-VZM6K2ZE-DbRB_1Ng.js} +1 -1
- package/dist/webdist/assets/{diagram-7IWD3JNH-Cn3vmigd.js → diagram-7IWD3JNH-ClCpikH_.js} +1 -1
- package/dist/webdist/assets/{diagram-B4RE2ZJO-DzIzUUTv.js → diagram-B4RE2ZJO-wQlXyd4e.js} +1 -1
- package/dist/webdist/assets/{diagram-LBJQPF4R-BbtaHnkO.js → diagram-LBJQPF4R-zgM6REwi.js} +1 -1
- package/dist/webdist/assets/{diagram-Q27KOJAE-CFenKIgI.js → diagram-Q27KOJAE-DvIssBlm.js} +1 -1
- package/dist/webdist/assets/{diagram-UB23O5K3-CuyPU_Mu.js → diagram-UB23O5K3-DdQiF9NE.js} +1 -1
- package/dist/webdist/assets/{dropdown-menu-Be7l1fxe.js → dropdown-menu-HI5N3Rmt.js} +1 -1
- package/dist/webdist/assets/{ebnfDiagram-BXEA7PRR-DOODd0MH.js → ebnfDiagram-BXEA7PRR-CpSxEGTe.js} +1 -1
- package/dist/webdist/assets/{erDiagram-JOGREHBK-Dcr04SmE.js → erDiagram-JOGREHBK-BrhRHXD4.js} +1 -1
- package/dist/webdist/assets/{file-text-FE03rWAa.js → file-text-Cx83fgk0.js} +1 -1
- package/dist/webdist/assets/{flowDiagram-UKHOOZJN-Bz7rFGfl.js → flowDiagram-UKHOOZJN-CIxMbmNO.js} +1 -1
- package/dist/webdist/assets/{folder-input-D15LVeML.js → folder-input-BN5lzecG.js} +1 -1
- package/dist/webdist/assets/{folder-plus-DzkiCb2B.js → folder-plus-B-imiY57.js} +1 -1
- package/dist/webdist/assets/{ganttDiagram-PKOTCBZU-Bj_ZOPAJ.js → ganttDiagram-PKOTCBZU-CiO9YNNt.js} +1 -1
- package/dist/webdist/assets/{git-branch-HP8nxDTj.js → git-branch-BY-pdlSo.js} +1 -1
- package/dist/webdist/assets/{gitGraphDiagram-DS77QQ5N-8baKuWz3.js → gitGraphDiagram-DS77QQ5N-Dz_fBDX6.js} +1 -1
- package/dist/webdist/assets/{globe-r-Gk9vO_.js → globe-FB3s-Kjz.js} +1 -1
- package/dist/webdist/assets/{index-DWD1Hz6g.js → index-CfwXVQIu.js} +4 -4
- package/dist/webdist/assets/{infoDiagram-6WML65LV-CZh4edQp.js → infoDiagram-6WML65LV-BP9JLl_M.js} +1 -1
- package/dist/webdist/assets/{ishikawaDiagram-WSZJBQD7-BT7RJUZO.js → ishikawaDiagram-WSZJBQD7-CeBpQALC.js} +1 -1
- package/dist/webdist/assets/{journeyDiagram-NVQOT4AX-Brz2ooLj.js → journeyDiagram-NVQOT4AX-Cnn5M1YO.js} +1 -1
- package/dist/webdist/assets/{kanban-definition-27J2QSJJ-ByeIutfh.js → kanban-definition-27J2QSJJ-BMnM-8zj.js} +1 -1
- package/dist/webdist/assets/{linear-Bfr0xFLl.js → linear-ontMFf7q.js} +1 -1
- package/dist/webdist/assets/{lock-CKcOp4XJ.js → lock-CVTYolJH.js} +1 -1
- package/dist/webdist/assets/{mermaid.core-D-E5f09M.js → mermaid.core-BX4U-c4C.js} +4 -4
- package/dist/webdist/assets/{mindmap-definition-FAOFIHXS-hrzHqptK.js → mindmap-definition-FAOFIHXS-D55lobOz.js} +1 -1
- package/dist/webdist/assets/{monitor--WNtubB8.js → monitor-BVyi9riP.js} +1 -1
- package/dist/webdist/assets/{pegDiagram-VL7TDLO6-B441EsMI.js → pegDiagram-VL7TDLO6-BE11XRQ7.js} +1 -1
- package/dist/webdist/assets/{pencil-DLms_KS_.js → pencil-xiVy9lBH.js} +1 -1
- package/dist/webdist/assets/{pieDiagram-7S7Q4E2Y-ByhCEyi1.js → pieDiagram-7S7Q4E2Y-BMHDg8ys.js} +1 -1
- package/dist/webdist/assets/{quadrantDiagram-CIZ2JOQS-BoVd-30d.js → quadrantDiagram-CIZ2JOQS-2sqR5qXm.js} +1 -1
- package/dist/webdist/assets/{railroadDiagram-AXF67PYL-2uvCDUaS.js → railroadDiagram-AXF67PYL-CrA2ZKhq.js} +1 -1
- package/dist/webdist/assets/{refresh-cw-BZK9PNk2.js → refresh-cw-BGipAyiS.js} +1 -1
- package/dist/webdist/assets/{remote-failure-BUHwngKj.js → remote-failure-CGk8OyjK.js} +1 -1
- package/dist/webdist/assets/{requirementDiagram-LRYGKXZP-BgJIRdwB.js → requirementDiagram-LRYGKXZP-RlYw_SgL.js} +1 -1
- package/dist/webdist/assets/{rocket-CZ554uI4.js → rocket-DHnkfnhQ.js} +1 -1
- package/dist/webdist/assets/{rotate-ccw-CYnZI5-z.js → rotate-ccw-DmG7PkUG.js} +1 -1
- package/dist/webdist/assets/{sankeyDiagram-W5VNT64P-Owz2xIZe.js → sankeyDiagram-W5VNT64P-B61EFr-D.js} +1 -1
- package/dist/webdist/assets/{sequenceDiagram-SI44F4Z6-DaoxE-fa.js → sequenceDiagram-SI44F4Z6-Cj4e2tXy.js} +1 -1
- package/dist/webdist/assets/{sheet-Df9khmUy.js → sheet-DFCO49jw.js} +1 -1
- package/dist/webdist/assets/{sizeCapture-X5ZJPWSS-dcdfbtqP.js → sizeCapture-X5ZJPWSS-CYyUy4Qg.js} +1 -1
- package/dist/webdist/assets/{skeleton-Duv5iwwK.js → skeleton-DVrIPwv0.js} +1 -1
- package/dist/webdist/assets/{sliders-horizontal-Cr87JkWR.js → sliders-horizontal-DQYu0jQs.js} +1 -1
- package/dist/webdist/assets/{sparkles-Cz9OBDET.js → sparkles-DKoUw0Ra.js} +1 -1
- package/dist/webdist/assets/{star-DdqpME5N.js → star-EY1hsb1g.js} +1 -1
- package/dist/webdist/assets/{stateDiagram-OKZ733FA-CXX12BPj.js → stateDiagram-OKZ733FA-CIAre6fb.js} +1 -1
- package/dist/webdist/assets/stateDiagram-v2-UEYNNEHI-c4H1EbPk.js +1 -0
- package/dist/webdist/assets/{swimlanes-SLNWSIFB-fq1Cou-U.js → swimlanes-SLNWSIFB-DGZBf-GQ.js} +2 -2
- package/dist/webdist/assets/swimlanesDiagram-ULZ7WXOC-C9AdErpx.js +8 -0
- package/dist/webdist/assets/{switch-C6JFP8Mz.js → switch-CXoaYXdG.js} +1 -1
- package/dist/webdist/assets/{terminal-BsWKdFvy.js → terminal-BrWVclQ0.js} +1 -1
- package/dist/webdist/assets/{timeline-definition-Z64GVDOM-BvUBrPbD.js → timeline-definition-Z64GVDOM-mu5ti0bv.js} +1 -1
- package/dist/webdist/assets/{trash-2-B4G2scm5.js → trash-2-WYWL4BUK.js} +1 -1
- package/dist/webdist/assets/{vennDiagram-T6HMQDX7-CEeg53T_.js → vennDiagram-T6HMQDX7-OxY1RaKm.js} +1 -1
- package/dist/webdist/assets/{wardleyDiagram-T6FBY63Y-C7jkNVGw.js → wardleyDiagram-T6FBY63Y-BtG14vOo.js} +1 -1
- package/dist/webdist/assets/{wrench-8U77f_Yu.js → wrench-D_MLSbdw.js} +1 -1
- package/dist/webdist/assets/{xychartDiagram-ELKLHX3M-BqzboKBI.js → xychartDiagram-ELKLHX3M-DeNO3ZVS.js} +1 -1
- package/dist/webdist/index.html +1 -1
- package/package.json +1 -1
- package/dist/webdist/assets/CodeComposer-DMDibXma.js +0 -1
- package/dist/webdist/assets/HardwareSection-CE799Eq2.js +0 -1
- package/dist/webdist/assets/OnboardingScreen-T-PZwwoj.js +0 -1
- package/dist/webdist/assets/WorkspaceScreen-B52K9UEq.js +0 -1
- package/dist/webdist/assets/channel-BwZvGoK9.js +0 -1
- package/dist/webdist/assets/classDiagram-JCYQIIEL-DzGOglmc.js +0 -1
- package/dist/webdist/assets/classDiagram-v2-OCEON4UE-DzGOglmc.js +0 -1
- package/dist/webdist/assets/stateDiagram-v2-UEYNNEHI-Cm8sAKH-.js +0 -1
- package/dist/webdist/assets/swimlanesDiagram-ULZ7WXOC-BEleuPZP.js +0 -8
package/README.md
CHANGED
|
@@ -443,8 +443,9 @@ connected); **Remove** undoes it.
|
|
|
443
443
|
|
|
444
444
|
- A **persistent bottom strip** on every screen shows real-time CPU, RAM, GPU and VRAM — values
|
|
445
445
|
and percentages — pulled from `nvidia-smi`, WDDM counters, `rocm-smi`, AMD sysfs, `ioreg`,
|
|
446
|
-
or `/proc` on Linux. Clicking the bar opens detailed gauges and sparklines in Settings → System
|
|
447
|
-
|
|
446
|
+
or `/proc` on Linux. Clicking the bar opens detailed gauges and sparklines in Settings → System,
|
|
447
|
+
including live **disk I/O** (read/write MB/s) and a **shared/spilled VRAM** figure that shows
|
|
448
|
+
when a discrete GPU has spilled into system memory. Toggle it off entirely from Settings → General.
|
|
448
449
|
- **Engines → Monitor** puts the live engine log and those same hardware gauges on one
|
|
449
450
|
always-visible split screen, plus a second, LM Studio-style **developer request log**: every
|
|
450
451
|
completion the daemon serves — external API clients, Code sessions, in-app Chat — with
|
|
@@ -65,7 +65,17 @@ function availableBackends(tag = LLAMA_BUILD) {
|
|
|
65
65
|
if (a === "arm64") return [def("cpu", "CPU", `llama-${tag}-bin-win-cpu-arm64.zip`)];
|
|
66
66
|
return [
|
|
67
67
|
def("cuda", "CUDA (NVIDIA)", `llama-${tag}-bin-win-cuda-${CUDA_VER}-x64.zip`, `cudart-llama-bin-win-cuda-${CUDA_VER}-x64.zip`),
|
|
68
|
-
|
|
68
|
+
// Upstream has renamed this archive at least once (`*-bin-win-hip-radeon-x64.zip` →
|
|
69
|
+
// `*-bin-win-rocm-<toolkit-ver>-x64.zip`, GitHub #220) without any deprecation window,
|
|
70
|
+
// so the literal name below is only a fallback label — assetPatterns resolves the
|
|
71
|
+
// real filename from the release's own asset list at download time and survives the
|
|
72
|
+
// next rename too.
|
|
73
|
+
{
|
|
74
|
+
id: "rocm",
|
|
75
|
+
label: "ROCm / HIP (AMD Radeon)",
|
|
76
|
+
assets: [`llama-${tag}-bin-win-hip-radeon-x64.zip`],
|
|
77
|
+
assetPatterns: [/^llama-.+-bin-win-(?:hip-radeon|rocm-[\d.]+)-x64\.zip$/i]
|
|
78
|
+
},
|
|
69
79
|
def("sycl", "SYCL (Intel)", `llama-${tag}-bin-win-sycl-x64.zip`),
|
|
70
80
|
def("vulkan", "Vulkan (any GPU)", `llama-${tag}-bin-win-vulkan-x64.zip`),
|
|
71
81
|
def("cpu", "CPU", `llama-${tag}-bin-win-cpu-x64.zip`)
|
|
@@ -236,12 +246,30 @@ async function provisionBackend(enginesRoot, backend, tag, onProgress, signal) {
|
|
|
236
246
|
}
|
|
237
247
|
mkdirSync(destDir, { recursive: true });
|
|
238
248
|
const parts = backend.assets.length;
|
|
249
|
+
const tmpPaths = [];
|
|
239
250
|
try {
|
|
240
251
|
for (let i = 0; i < parts; i++) {
|
|
241
|
-
const asset = backend.assets[i];
|
|
242
252
|
const part = i + 1;
|
|
243
|
-
const
|
|
244
|
-
|
|
253
|
+
const pattern = backend.assetPatterns?.[i];
|
|
254
|
+
let assetName = backend.assets[i];
|
|
255
|
+
let url;
|
|
256
|
+
if (backend.downloadBaseUrl) {
|
|
257
|
+
url = `${backend.downloadBaseUrl}/${assetName}`;
|
|
258
|
+
} else {
|
|
259
|
+
const repo = backend.repo ?? REPO;
|
|
260
|
+
const releaseTag = backend.releaseTag ?? tag;
|
|
261
|
+
if (pattern) {
|
|
262
|
+
const releaseAssets = await releaseAssetsForTag(repo, releaseTag, signal);
|
|
263
|
+
const found = releaseAssets.find((a) => pattern.test(a.name));
|
|
264
|
+
if (!found) throw new Error(`no release asset matching ${pattern} in ${repo}@${releaseTag}`);
|
|
265
|
+
assetName = found.name;
|
|
266
|
+
url = found.browser_download_url;
|
|
267
|
+
} else {
|
|
268
|
+
url = `https://github.com/${repo}/releases/download/${releaseTag}/${assetName}`;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
const tmp = join(enginesRoot, assetName);
|
|
272
|
+
tmpPaths.push(tmp);
|
|
245
273
|
onProgress?.({ phase: "downloading", pct: 0, part, parts });
|
|
246
274
|
await downloadFile(url, tmp, (p) => onProgress?.({ ...p, part, parts }), signal);
|
|
247
275
|
onProgress?.({ phase: "extracting", pct: -1, part, parts });
|
|
@@ -249,7 +277,7 @@ async function provisionBackend(enginesRoot, backend, tag, onProgress, signal) {
|
|
|
249
277
|
rmSync(tmp, { force: true });
|
|
250
278
|
}
|
|
251
279
|
} catch (e) {
|
|
252
|
-
for (const
|
|
280
|
+
for (const tmp of tmpPaths) rmSync(tmp, { force: true });
|
|
253
281
|
rmSync(destDir, { recursive: true, force: true });
|
|
254
282
|
throw e;
|
|
255
283
|
}
|
|
@@ -347,6 +375,16 @@ async function latestBuildTagRelease(repo, signal) {
|
|
|
347
375
|
}
|
|
348
376
|
return best;
|
|
349
377
|
}
|
|
378
|
+
async function releaseAssetsForTag(repo, tag, signal) {
|
|
379
|
+
const res = await fetch(`https://api.github.com/repos/${repo}/releases/tags/${encodeURIComponent(tag)}`, {
|
|
380
|
+
headers: githubHeaders(),
|
|
381
|
+
signal
|
|
382
|
+
});
|
|
383
|
+
if (isRateLimited(res)) throw new GithubRateLimitError(repo);
|
|
384
|
+
if (!res.ok) throw new Error(`could not query ${repo} release ${tag}: HTTP ${res.status}`);
|
|
385
|
+
const data = await res.json();
|
|
386
|
+
return data.assets ?? [];
|
|
387
|
+
}
|
|
350
388
|
async function latestCommitSha(repo, branch = "", signal) {
|
|
351
389
|
const ref = branch.trim() ? encodeURIComponent(branch.trim()) : "HEAD";
|
|
352
390
|
const res = await fetch(`https://api.github.com/repos/${repo}/commits/${ref}`, {
|
package/dist/cli.js
CHANGED
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
recommendBackendId,
|
|
44
44
|
reconcileTailscale,
|
|
45
45
|
setGithubTokenProvider
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-Y3TMLJQD.js";
|
|
47
47
|
|
|
48
48
|
// src/util/hide-console-windows.ts
|
|
49
49
|
import { ChildProcess } from "child_process";
|
|
@@ -22376,6 +22376,67 @@ function mergeUsage(sys, samples) {
|
|
|
22376
22376
|
};
|
|
22377
22377
|
});
|
|
22378
22378
|
}
|
|
22379
|
+
var WHOLE_DISK_RE = /^(?:sd[a-z]+|vd[a-z]+|xvd[a-z]+|nvme\d+n\d+|mmcblk\d+)$/;
|
|
22380
|
+
function parseDiskstats(raw) {
|
|
22381
|
+
let sectorsRead = 0;
|
|
22382
|
+
let sectorsWritten = 0;
|
|
22383
|
+
let matched = false;
|
|
22384
|
+
for (const line of raw.split("\n")) {
|
|
22385
|
+
const f2 = line.trim().split(/\s+/);
|
|
22386
|
+
if (f2.length < 10) continue;
|
|
22387
|
+
if (!WHOLE_DISK_RE.test(f2[2])) continue;
|
|
22388
|
+
const r = Number(f2[5]);
|
|
22389
|
+
const w = Number(f2[9]);
|
|
22390
|
+
if (!Number.isFinite(r) || !Number.isFinite(w)) continue;
|
|
22391
|
+
sectorsRead += r;
|
|
22392
|
+
sectorsWritten += w;
|
|
22393
|
+
matched = true;
|
|
22394
|
+
}
|
|
22395
|
+
return matched ? { sectorsRead, sectorsWritten } : null;
|
|
22396
|
+
}
|
|
22397
|
+
var SECTOR_BYTES = 512;
|
|
22398
|
+
function diskstatsRate(prev, prevAtMs, cur, curAtMs) {
|
|
22399
|
+
if (!prev || !cur) return null;
|
|
22400
|
+
const elapsedS = (curAtMs - prevAtMs) / 1e3;
|
|
22401
|
+
if (elapsedS <= 0) return null;
|
|
22402
|
+
const readMBps = (cur.sectorsRead - prev.sectorsRead) * SECTOR_BYTES / 1e6 / elapsedS;
|
|
22403
|
+
const writeMBps = (cur.sectorsWritten - prev.sectorsWritten) * SECTOR_BYTES / 1e6 / elapsedS;
|
|
22404
|
+
if (readMBps < 0 || writeMBps < 0) return null;
|
|
22405
|
+
return { readMBps, writeMBps, combined: false };
|
|
22406
|
+
}
|
|
22407
|
+
function parseWindowsDiskSample(line) {
|
|
22408
|
+
let j;
|
|
22409
|
+
try {
|
|
22410
|
+
j = JSON.parse(line);
|
|
22411
|
+
} catch {
|
|
22412
|
+
return null;
|
|
22413
|
+
}
|
|
22414
|
+
if (typeof j.readBps !== "number" || typeof j.writeBps !== "number") return null;
|
|
22415
|
+
return { readMBps: j.readBps / 1e6, writeMBps: j.writeBps / 1e6, combined: false };
|
|
22416
|
+
}
|
|
22417
|
+
var IOSTAT_COLUMNS_PER_DISK = 3;
|
|
22418
|
+
var IOSTAT_MBPS_COLUMN = 2;
|
|
22419
|
+
function parseMacIostat(text) {
|
|
22420
|
+
let newestTotalMBps = null;
|
|
22421
|
+
for (const line of text.split("\n")) {
|
|
22422
|
+
const total = sumDiskThroughput(line);
|
|
22423
|
+
if (total !== null) newestTotalMBps = total;
|
|
22424
|
+
}
|
|
22425
|
+
if (newestTotalMBps === null) return null;
|
|
22426
|
+
return { readMBps: newestTotalMBps, writeMBps: null, combined: true };
|
|
22427
|
+
}
|
|
22428
|
+
function sumDiskThroughput(line) {
|
|
22429
|
+
const trimmed = line.trim();
|
|
22430
|
+
if (!trimmed) return null;
|
|
22431
|
+
const columns = trimmed.split(/\s+/).map(Number);
|
|
22432
|
+
if (columns.length % IOSTAT_COLUMNS_PER_DISK !== 0) return null;
|
|
22433
|
+
if (!columns.every((c) => Number.isFinite(c))) return null;
|
|
22434
|
+
let totalMBps = 0;
|
|
22435
|
+
for (let i = IOSTAT_MBPS_COLUMN; i < columns.length; i += IOSTAT_COLUMNS_PER_DISK) {
|
|
22436
|
+
totalMBps += columns[i];
|
|
22437
|
+
}
|
|
22438
|
+
return totalMBps;
|
|
22439
|
+
}
|
|
22379
22440
|
|
|
22380
22441
|
// src/sysinfo/usage.ts
|
|
22381
22442
|
var SAMPLE_MS = 1e3;
|
|
@@ -22416,6 +22477,61 @@ function createLatchingReader(kind, sample, hooks = {}) {
|
|
|
22416
22477
|
}
|
|
22417
22478
|
};
|
|
22418
22479
|
}
|
|
22480
|
+
function createStreamingReader(kind, command, args, parseLine) {
|
|
22481
|
+
let child = null;
|
|
22482
|
+
let latest2 = null;
|
|
22483
|
+
let buf = "";
|
|
22484
|
+
let dead = false;
|
|
22485
|
+
return {
|
|
22486
|
+
kind,
|
|
22487
|
+
start() {
|
|
22488
|
+
if (child) return;
|
|
22489
|
+
try {
|
|
22490
|
+
child = spawn8(command, args, {
|
|
22491
|
+
windowsHide: true,
|
|
22492
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
22493
|
+
});
|
|
22494
|
+
} catch {
|
|
22495
|
+
dead = true;
|
|
22496
|
+
return;
|
|
22497
|
+
}
|
|
22498
|
+
child.stdout?.setEncoding("utf8");
|
|
22499
|
+
child.stdout?.on("data", (chunk) => {
|
|
22500
|
+
buf += chunk;
|
|
22501
|
+
if (buf.length > 1e6) buf = buf.slice(-1e5);
|
|
22502
|
+
for (; ; ) {
|
|
22503
|
+
const nl = buf.indexOf("\n");
|
|
22504
|
+
if (nl < 0) break;
|
|
22505
|
+
const line = buf.slice(0, nl).trim();
|
|
22506
|
+
buf = buf.slice(nl + 1);
|
|
22507
|
+
if (!line) continue;
|
|
22508
|
+
const parsed = parseLine(line);
|
|
22509
|
+
if (parsed !== null) latest2 = parsed;
|
|
22510
|
+
}
|
|
22511
|
+
});
|
|
22512
|
+
child.on("error", () => {
|
|
22513
|
+
dead = true;
|
|
22514
|
+
child = null;
|
|
22515
|
+
});
|
|
22516
|
+
child.on("exit", () => {
|
|
22517
|
+
child = null;
|
|
22518
|
+
});
|
|
22519
|
+
},
|
|
22520
|
+
// Returns null until the first sample lands (~1.65 s for the WDDM counter stream). That is
|
|
22521
|
+
// "not ready", not a failure — which is exactly why this reader is not wrapped in
|
|
22522
|
+
// createLatchingReader: the latch would trip during the normal warm-up.
|
|
22523
|
+
read: async () => dead ? null : latest2,
|
|
22524
|
+
stop() {
|
|
22525
|
+
try {
|
|
22526
|
+
child?.kill();
|
|
22527
|
+
} catch {
|
|
22528
|
+
}
|
|
22529
|
+
child = null;
|
|
22530
|
+
latest2 = null;
|
|
22531
|
+
buf = "";
|
|
22532
|
+
}
|
|
22533
|
+
};
|
|
22534
|
+
}
|
|
22419
22535
|
function nvidiaReader() {
|
|
22420
22536
|
return createLatchingReader(
|
|
22421
22537
|
"nvidia",
|
|
@@ -22493,65 +22609,98 @@ var WDDM_STREAM_PS = [
|
|
|
22493
22609
|
"}"
|
|
22494
22610
|
].join("\n");
|
|
22495
22611
|
function wddmReader() {
|
|
22496
|
-
|
|
22497
|
-
|
|
22498
|
-
|
|
22612
|
+
return createStreamingReader(
|
|
22613
|
+
"wddm",
|
|
22614
|
+
"powershell",
|
|
22615
|
+
["-NoProfile", "-NonInteractive", "-Command", WDDM_STREAM_PS],
|
|
22616
|
+
(line) => {
|
|
22617
|
+
const parsed = parseWddmSample(line);
|
|
22618
|
+
return parsed.length > 0 ? parsed : null;
|
|
22619
|
+
}
|
|
22620
|
+
);
|
|
22621
|
+
}
|
|
22622
|
+
function nullReader() {
|
|
22623
|
+
return { kind: "null", start: () => {
|
|
22624
|
+
}, read: async () => null, stop: () => {
|
|
22625
|
+
} };
|
|
22626
|
+
}
|
|
22627
|
+
var DISK_STREAM_PS = [
|
|
22628
|
+
"$ErrorActionPreference='SilentlyContinue'",
|
|
22629
|
+
"$c=@('\\PhysicalDisk(_Total)\\Disk Read Bytes/sec','\\PhysicalDisk(_Total)\\Disk Write Bytes/sec')",
|
|
22630
|
+
"Get-Counter -Counter $c -SampleInterval 1 -Continuous | ForEach-Object {",
|
|
22631
|
+
"$r=$null;$w=$null",
|
|
22632
|
+
"foreach($s in $_.CounterSamples){",
|
|
22633
|
+
"$p=$s.Path.ToLower()",
|
|
22634
|
+
"if($p -like '*read bytes*'){$r=[double]$s.CookedValue}",
|
|
22635
|
+
"elseif($p -like '*write bytes*'){$w=[double]$s.CookedValue}}",
|
|
22636
|
+
"Write-Output (ConvertTo-Json -Compress -InputObject @{readBps=$r;writeBps=$w})",
|
|
22637
|
+
"}"
|
|
22638
|
+
].join("\n");
|
|
22639
|
+
function windowsDiskReader() {
|
|
22640
|
+
return createStreamingReader(
|
|
22641
|
+
"windows-disk",
|
|
22642
|
+
"powershell",
|
|
22643
|
+
["-NoProfile", "-NonInteractive", "-Command", DISK_STREAM_PS],
|
|
22644
|
+
parseWindowsDiskSample
|
|
22645
|
+
);
|
|
22646
|
+
}
|
|
22647
|
+
function linuxDiskReader() {
|
|
22648
|
+
let prev = null;
|
|
22649
|
+
let prevAtMs = 0;
|
|
22499
22650
|
let dead = false;
|
|
22500
22651
|
return {
|
|
22501
|
-
kind: "
|
|
22652
|
+
kind: "linux-diskstats",
|
|
22502
22653
|
start() {
|
|
22503
|
-
|
|
22654
|
+
prev = null;
|
|
22655
|
+
prevAtMs = 0;
|
|
22656
|
+
dead = false;
|
|
22657
|
+
},
|
|
22658
|
+
read: async () => {
|
|
22659
|
+
if (dead) return null;
|
|
22504
22660
|
try {
|
|
22505
|
-
|
|
22506
|
-
|
|
22507
|
-
|
|
22508
|
-
|
|
22661
|
+
const cur = parseDiskstats(readFileSync15("/proc/diskstats", "utf8"));
|
|
22662
|
+
const now = Date.now();
|
|
22663
|
+
const rate = diskstatsRate(prev, prevAtMs, cur, now);
|
|
22664
|
+
prev = cur;
|
|
22665
|
+
prevAtMs = now;
|
|
22666
|
+
return rate;
|
|
22509
22667
|
} catch {
|
|
22510
22668
|
dead = true;
|
|
22511
|
-
return;
|
|
22669
|
+
return null;
|
|
22512
22670
|
}
|
|
22513
|
-
child.stdout?.setEncoding("utf8");
|
|
22514
|
-
child.stdout?.on("data", (chunk) => {
|
|
22515
|
-
buf += chunk;
|
|
22516
|
-
if (buf.length > 1e6) buf = buf.slice(-1e5);
|
|
22517
|
-
for (; ; ) {
|
|
22518
|
-
const nl = buf.indexOf("\n");
|
|
22519
|
-
if (nl < 0) break;
|
|
22520
|
-
const line = buf.slice(0, nl).trim();
|
|
22521
|
-
buf = buf.slice(nl + 1);
|
|
22522
|
-
if (!line) continue;
|
|
22523
|
-
const parsed = parseWddmSample(line);
|
|
22524
|
-
if (parsed.length > 0) latest2 = parsed;
|
|
22525
|
-
}
|
|
22526
|
-
});
|
|
22527
|
-
child.on("error", () => {
|
|
22528
|
-
dead = true;
|
|
22529
|
-
child = null;
|
|
22530
|
-
});
|
|
22531
|
-
child.on("exit", () => {
|
|
22532
|
-
child = null;
|
|
22533
|
-
});
|
|
22534
22671
|
},
|
|
22535
|
-
// Returns null until the first sample lands (~1.65 s). That is "not ready", not a failure —
|
|
22536
|
-
// which is exactly why this reader is not wrapped in createLatchingReader: the latch would
|
|
22537
|
-
// trip during the normal warm-up.
|
|
22538
|
-
read: async () => dead ? null : latest2,
|
|
22539
22672
|
stop() {
|
|
22540
|
-
|
|
22541
|
-
|
|
22542
|
-
} catch {
|
|
22543
|
-
}
|
|
22544
|
-
child = null;
|
|
22545
|
-
latest2 = null;
|
|
22546
|
-
buf = "";
|
|
22673
|
+
prev = null;
|
|
22674
|
+
prevAtMs = 0;
|
|
22547
22675
|
}
|
|
22548
22676
|
};
|
|
22549
22677
|
}
|
|
22550
|
-
function
|
|
22678
|
+
function createLiveIostatParser() {
|
|
22679
|
+
let seenFirstDataRow = false;
|
|
22680
|
+
return (line) => {
|
|
22681
|
+
const sample = parseMacIostat(line);
|
|
22682
|
+
if (!sample) return null;
|
|
22683
|
+
if (!seenFirstDataRow) {
|
|
22684
|
+
seenFirstDataRow = true;
|
|
22685
|
+
return null;
|
|
22686
|
+
}
|
|
22687
|
+
return sample;
|
|
22688
|
+
};
|
|
22689
|
+
}
|
|
22690
|
+
function darwinDiskReader() {
|
|
22691
|
+
return createStreamingReader("darwin-iostat", "iostat", ["-d", "-w", "1"], createLiveIostatParser());
|
|
22692
|
+
}
|
|
22693
|
+
function nullDiskReader() {
|
|
22551
22694
|
return { kind: "null", start: () => {
|
|
22552
22695
|
}, read: async () => null, stop: () => {
|
|
22553
22696
|
} };
|
|
22554
22697
|
}
|
|
22698
|
+
function pickDiskReader() {
|
|
22699
|
+
if (process.platform === "win32") return windowsDiskReader();
|
|
22700
|
+
if (process.platform === "linux") return linuxDiskReader();
|
|
22701
|
+
if (process.platform === "darwin") return darwinDiskReader();
|
|
22702
|
+
return nullDiskReader();
|
|
22703
|
+
}
|
|
22555
22704
|
function pickReader(sys) {
|
|
22556
22705
|
const gpus = sys.gpus ?? [];
|
|
22557
22706
|
if (gpus.length === 0) return nullReader();
|
|
@@ -22563,6 +22712,8 @@ function pickReader(sys) {
|
|
|
22563
22712
|
}
|
|
22564
22713
|
var reader = null;
|
|
22565
22714
|
var injected = null;
|
|
22715
|
+
var diskReader = null;
|
|
22716
|
+
var injectedDisk = null;
|
|
22566
22717
|
var timer = null;
|
|
22567
22718
|
var idleTimer = null;
|
|
22568
22719
|
var latest = null;
|
|
@@ -22574,10 +22725,15 @@ function startLoop() {
|
|
|
22574
22725
|
running = true;
|
|
22575
22726
|
prevCpu = null;
|
|
22576
22727
|
reader = injected ?? pickReader(getSysInfo());
|
|
22728
|
+
diskReader = injectedDisk ?? pickDiskReader();
|
|
22577
22729
|
try {
|
|
22578
22730
|
reader.start();
|
|
22579
22731
|
} catch {
|
|
22580
22732
|
}
|
|
22733
|
+
try {
|
|
22734
|
+
diskReader.start();
|
|
22735
|
+
} catch {
|
|
22736
|
+
}
|
|
22581
22737
|
timer = setInterval(() => void tick2(), SAMPLE_MS);
|
|
22582
22738
|
timer.unref?.();
|
|
22583
22739
|
}
|
|
@@ -22599,6 +22755,12 @@ async function tick2() {
|
|
|
22599
22755
|
} catch {
|
|
22600
22756
|
samples = null;
|
|
22601
22757
|
}
|
|
22758
|
+
let disk = null;
|
|
22759
|
+
try {
|
|
22760
|
+
disk = diskReader ? await diskReader.read() : null;
|
|
22761
|
+
} catch {
|
|
22762
|
+
disk = null;
|
|
22763
|
+
}
|
|
22602
22764
|
latest = {
|
|
22603
22765
|
cpuPct,
|
|
22604
22766
|
ram: {
|
|
@@ -22606,6 +22768,7 @@ async function tick2() {
|
|
|
22606
22768
|
totalMb: Math.round(os2.totalmem() / 1e6)
|
|
22607
22769
|
},
|
|
22608
22770
|
gpus: mergeUsage(getSysInfo(), samples),
|
|
22771
|
+
disk,
|
|
22609
22772
|
sampledAt: Date.now()
|
|
22610
22773
|
};
|
|
22611
22774
|
return latest;
|
|
@@ -22629,8 +22792,13 @@ function stopUsageMonitor() {
|
|
|
22629
22792
|
reader?.stop();
|
|
22630
22793
|
} catch {
|
|
22631
22794
|
}
|
|
22795
|
+
try {
|
|
22796
|
+
diskReader?.stop();
|
|
22797
|
+
} catch {
|
|
22798
|
+
}
|
|
22632
22799
|
}
|
|
22633
22800
|
reader = null;
|
|
22801
|
+
diskReader = null;
|
|
22634
22802
|
latest = null;
|
|
22635
22803
|
prevCpu = null;
|
|
22636
22804
|
running = false;
|
|
@@ -26564,7 +26732,7 @@ function registerRemoteApi(app2, d) {
|
|
|
26564
26732
|
if (!provider || !REMOTE_PROVIDERS.includes(provider)) {
|
|
26565
26733
|
return c.json({ error: { code: "bad_request", message: "Unknown provider." } }, 400);
|
|
26566
26734
|
}
|
|
26567
|
-
const { makeProvider: makeProvider2 } = await import("./factory-
|
|
26735
|
+
const { makeProvider: makeProvider2 } = await import("./factory-NOUUQICH.js");
|
|
26568
26736
|
const state = await makeProvider2(provider, d).preflight();
|
|
26569
26737
|
if (d.telemetry && (state.kind === "unavailable" || state.kind === "needs-setup")) {
|
|
26570
26738
|
emit(d.telemetry, remoteAccessPreflightFailed, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./radix-B7FN0WwE.js";import{b as W,u as $,r as b}from"./vendor-C1I6euDx.js";import{u as G,d as H,e as Y,f as J,g as U,a as z,B as C,t as j,c as q,b as h,A as _}from"./index-DWD1Hz6g.js";import{f as V}from"./chat-api-CCZfNFmH.js";import{f as X,a as Z}from"./agent-api-1EptCITO.js";import{P as B}from"./personas-FTKXYi_z.js";import{C as ee}from"./chevron-left-irxTskG3.js";import{R as te}from"./rotate-ccw-CYnZI5-z.js";import{T as se}from"./trash-2-B4G2scm5.js";import{C as ne}from"./chevron-right-BxDhzUZl.js";import"./dropdown-menu-Be7l1fxe.js";const ae=()=>({name:"",description:"",systemPrompt:"",skillIds:[],tools:[]});function oe(s){const d=[],x=new Map;for(const n of s){const a=/^mcp__([^_]+(?:_[^_]+)*)__/.exec(n.name);if(!a){d.push(n);continue}const i=a[1],p=/^\[([^\]]+)\]/.exec(n.description),c=p?p[1]:i.replace(/_/g," ");x.has(i)||x.set(i,{key:i,label:c,tools:[]}),x.get(i).tools.push(n)}return{builtin:d,groups:[...x.values()].sort((n,a)=>n.label.localeCompare(a.label))}}function le(s){return s.replace(/^mcp__[^_]+(?:_[^_]+)*__/,"")}function re(s){return s.replace(/^\[[^\]]+\]\s*/,"")}function D({tool:s,checked:d,onToggle:x}){return e.jsxs("label",{className:"flex cursor-pointer items-start gap-2 text-[12px]",children:[e.jsx("input",{type:"checkbox",className:"mt-0.5",checked:d,onChange:x}),e.jsxs("span",{className:"flex flex-col",children:[e.jsx("span",{className:"font-mono text-ink",children:le(s.name)}),s.description&&e.jsx("span",{className:"text-faint",children:re(s.description)})]})]})}function ie({group:s,selected:d,onToggleAll:x,onToggleOne:n}){const[a,i]=b.useState(!1),p=s.tools.map(l=>l.name),c=p.filter(l=>d.has(l)).length,o=c===p.length,g=c>0&&!o,u=b.useRef(null);return b.useEffect(()=>{u.current&&(u.current.indeterminate=g)},[g]),e.jsxs("div",{className:"rounded-md border border-border",children:[e.jsxs("div",{className:"flex items-center gap-2 px-2.5 py-2",children:[e.jsx("input",{ref:u,type:"checkbox",checked:o,onChange:()=>x(p,!o)}),e.jsxs("button",{type:"button",onClick:()=>{j("agents","toggle_agent_tool_group"),i(l=>!l)},className:"flex flex-1 items-center gap-1.5 text-left text-[13px] text-ink",children:[e.jsx(ne,{size:12,className:q("shrink-0 text-faint transition-transform",a&&"rotate-90")}),s.label,e.jsxs("span",{className:"text-[11px] text-faint",children:["(",c,"/",p.length,")"]})]})]}),a&&e.jsx("div",{className:"flex flex-col gap-1.5 border-t border-border px-3 py-2 pl-9",children:s.tools.map(l=>e.jsx(D,{tool:l,checked:d.has(l.name),onToggle:()=>n(l.name)},l.name))})]})}function ce({tools:s,selected:d,onChange:x}){const n=new Set(d),{builtin:a,groups:i}=oe(s),p=o=>x(n.has(o)?d.filter(g=>g!==o):[...d,o]),c=(o,g)=>{const u=d.filter(l=>!o.includes(l));x(g?[...u,...o]:u)};return s.length===0?e.jsx("p",{className:"text-[12px] text-faint",children:"No tools available yet."}):e.jsxs("div",{className:"flex flex-col gap-2",children:[a.length>0&&e.jsx("div",{className:"flex flex-col gap-2 rounded-md border border-border bg-panel-2 p-3",children:a.map(o=>e.jsx(D,{tool:o,checked:n.has(o.name),onToggle:()=>p(o.name)},o.name))}),i.map(o=>e.jsx(ie,{group:o,selected:n,onToggleAll:c,onToggleOne:p},o.key))]})}function je(){const{agentId:s="new"}=W(),d=$(),x=G(),n=s==="new",a=!n&&B.some(t=>t.id===s),i=a?B.find(t=>t.id===s):void 0,p=H(),c=!n&&!a?(p.data??[]).find(t=>t.id===s):void 0,o=Y(),g=J(),u=U(),l=a?g.data?.[s]:void 0,I=z({queryKey:Z.list(),queryFn:X,staleTime:0}),k=I.data??[],w=z({queryKey:["available-tools"],queryFn:V}),N=w.data??[],[m,f]=b.useState(ae()),[S,T]=b.useState(!1),[A,P]=b.useState(!1),[L,R]=b.useState(!1),[E,Q]=b.useState("skills");n&&!S&&(k.length||N.length)&&(f(t=>({...t,skillIds:k.map(r=>r.id),tools:N.map(r=>r.name)})),T(!0)),!n&&!a&&!S&&c&&(f({name:c.name,description:c.description,systemPrompt:c.systemPrompt,skillIds:c.skillIds,tools:c.tools}),T(!0)),a&&!S&&i&&g.isSuccess&&(k.length||N.length)&&(f({name:l?.name??i.name,description:l?.description??i.description,systemPrompt:l?.systemPrompt??i.systemPrompt,skillIds:l?.skillIds??k.map(t=>t.id),tools:l?.tools??N.map(t=>t.name)}),T(!0));const y=()=>{j("agents","back_to_agents"),d("/customize")},O=t=>f(r=>({...r,skillIds:r.skillIds.includes(t)?r.skillIds.filter(v=>v!==t):[...r.skillIds,t]})),F=()=>{if(!m.name.trim()){h.error("Name is required.");return}P(!0);const t={name:m.name.trim(),description:m.description.trim(),systemPrompt:m.systemPrompt,skillIds:m.skillIds,tools:m.tools};if(a){u.save.mutate({id:s,override:t},{onSuccess:()=>{h.success("Agent saved."),y()},onError:v=>{h.error(v instanceof _?v.message:"Could not save agent."),P(!1)}});return}const r={onSuccess:()=>{x.invalidateQueries({queryKey:["chat-agents"]}),h.success(n?"Agent created.":"Agent saved."),y()},onError:v=>{h.error(v instanceof _?v.message:"Could not save agent."),P(!1)}};n?o.add.mutate(t,r):o.update.mutate({id:s,patch:t},r)},K=()=>{u.reset.mutate(s,{onSuccess:()=>{h.success("Reset to default."),i&&f({name:i.name,description:i.description,systemPrompt:i.systemPrompt,skillIds:k.map(t=>t.id),tools:N.map(t=>t.name)})},onError:t=>h.error(t instanceof _?t.message:"Could not reset agent.")})},M=()=>{o.remove.mutate(s,{onSuccess:()=>{h.success("Agent deleted."),y()},onError:t=>h.error(t instanceof _?t.message:"Could not delete agent.")})};return!n&&!a&&p.isSuccess&&!c?e.jsxs("div",{className:"flex w-full flex-col items-center gap-3 px-8 py-16",children:[e.jsx("p",{className:"text-[14px] text-muted",children:"That agent no longer exists."}),e.jsx(C,{size:"sm",variant:"outline",onClick:y,children:"Back to agents"})]}):e.jsxs("div",{className:"flex w-full max-w-4xl flex-col gap-5 px-4 py-6 md:px-8",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("button",{type:"button",onClick:y,className:"text-faint hover:text-ink",title:"Back to agents",children:e.jsx(ee,{size:18})}),e.jsx("span",{className:"text-[15px] font-medium text-ink",children:n?"New agent":a?l?"Edit agent (modified built-in)":"Edit agent (built-in)":"Edit agent"}),e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[a&&e.jsxs(C,{size:"sm",variant:"outline",onClick:()=>{j("agents","reset_agent_to_default"),K()},disabled:u.reset.isPending,children:[e.jsx(te,{size:13})," Reset to default"]}),e.jsx(C,{size:"sm",variant:"outline",onClick:y,children:"Cancel"}),e.jsx(C,{size:"sm",onClick:()=>{j("agents","save_agent"),F()},disabled:A||!m.name.trim(),children:A?"Saving…":"Save"})]})]}),a&&e.jsx("p",{className:"rounded-md border border-border bg-panel px-3 py-2 text-[12px] text-muted",children:"Built-in agents can be edited in place — Reset to default discards your changes and restores TurboLLM's original prompt and access."}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("label",{className:"text-[12px] font-medium text-muted",children:"Name"}),e.jsx("input",{className:"rounded-md border border-border bg-bg px-3 py-1.5 text-[13px] text-ink outline-none focus:border-accent placeholder:text-faint",placeholder:"Release Notes Writer",value:m.name,onChange:t=>f(r=>({...r,name:t.target.value}))})]}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("label",{className:"text-[12px] font-medium text-muted",children:"Description"}),e.jsx("input",{className:"rounded-md border border-border bg-bg px-3 py-1.5 text-[13px] text-ink outline-none focus:border-accent placeholder:text-faint",placeholder:"What this agent is for, in one line",value:m.description,onChange:t=>f(r=>({...r,description:t.target.value}))})]}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("label",{className:"text-[12px] font-medium text-muted",children:"System prompt"}),e.jsx("textarea",{className:"min-h-[160px] resize-y rounded-md border border-border bg-bg px-3 py-2 font-mono text-[12px] leading-relaxed text-ink outline-none focus:border-accent placeholder:text-faint",placeholder:"You are…",value:m.systemPrompt,onChange:t=>f(r=>({...r,systemPrompt:t.target.value}))})]}),e.jsxs("div",{className:"flex flex-col gap-2.5",children:[e.jsx("div",{className:"inline-flex w-fit rounded-md border border-border p-0.5",children:["skills","tools"].map(t=>e.jsx("button",{type:"button",onClick:()=>{j("agents","switch_agent_form_tab"),Q(t)},className:q("rounded px-3 py-1.5 text-[13px] font-medium transition-colors",E===t?"bg-accent/12 text-accent":"text-muted hover:text-ink"),children:t==="skills"?`Skills (${m.skillIds.length})`:`Tools (${m.tools.length})`},t))}),E==="skills"?I.isLoading?e.jsx("p",{className:"text-[12px] text-faint",children:"Loading…"}):k.length===0?e.jsx("p",{className:"text-[12px] text-faint",children:"No skills yet — create one under Customize → Skills."}):e.jsx("div",{className:"flex flex-col gap-2 rounded-md border border-border bg-panel-2 p-3",children:k.map(t=>e.jsxs("label",{className:"flex cursor-pointer items-start gap-2 text-[13px]",children:[e.jsx("input",{type:"checkbox",className:"mt-0.5",checked:m.skillIds.includes(t.id),onChange:()=>O(t.id)}),e.jsxs("span",{className:"flex flex-col",children:[e.jsx("span",{className:"text-ink",children:t.name}),t.description&&e.jsx("span",{className:"text-[12px] text-muted",children:t.description})]})]},t.id))}):w.isLoading?e.jsx("p",{className:"text-[12px] text-faint",children:"Loading…"}):e.jsx(ce,{tools:N,selected:m.tools,onChange:t=>f(r=>({...r,tools:t}))})]}),!n&&!a&&(L?e.jsxs("div",{className:"flex items-center gap-2 self-start rounded-md border border-border bg-panel p-2 text-[12px]",children:[e.jsx("span",{className:"flex-1 text-muted",children:"Delete this agent?"}),e.jsx("button",{type:"button",onClick:()=>{j("agents","delete_agent"),M()},className:"rounded px-2 py-1 text-[color:var(--err)] hover:bg-[color:color-mix(in_srgb,var(--err)_12%,transparent)]",children:"Delete"}),e.jsx("button",{type:"button",onClick:()=>{j("agents","cancel_delete_agent"),R(!1)},className:"rounded px-2 py-1 text-faint hover:text-ink",children:"Cancel"})]}):e.jsxs("button",{type:"button",onClick:()=>R(!0),className:"flex items-center gap-1.5 self-start text-[12px] text-faint hover:text-[color:var(--err)]",children:[e.jsx(se,{size:13})," Delete agent"]}))]})}export{je as AgentEditPage};
|
|
1
|
+
import{j as e}from"./radix-B7FN0WwE.js";import{b as W,u as $,r as b}from"./vendor-C1I6euDx.js";import{u as G,d as H,e as Y,f as J,g as U,a as z,B as C,t as j,c as q,b as h,A as _}from"./index-CfwXVQIu.js";import{f as V}from"./chat-api-BspgdIew.js";import{f as X,a as Z}from"./agent-api-CeGvce9t.js";import{P as B}from"./personas-FTKXYi_z.js";import{C as ee}from"./chevron-left-yPpon0Zo.js";import{R as te}from"./rotate-ccw-DmG7PkUG.js";import{T as se}from"./trash-2-WYWL4BUK.js";import{C as ne}from"./chevron-right-qwzlPkv4.js";import"./dropdown-menu-HI5N3Rmt.js";const ae=()=>({name:"",description:"",systemPrompt:"",skillIds:[],tools:[]});function oe(s){const d=[],x=new Map;for(const n of s){const a=/^mcp__([^_]+(?:_[^_]+)*)__/.exec(n.name);if(!a){d.push(n);continue}const i=a[1],p=/^\[([^\]]+)\]/.exec(n.description),c=p?p[1]:i.replace(/_/g," ");x.has(i)||x.set(i,{key:i,label:c,tools:[]}),x.get(i).tools.push(n)}return{builtin:d,groups:[...x.values()].sort((n,a)=>n.label.localeCompare(a.label))}}function le(s){return s.replace(/^mcp__[^_]+(?:_[^_]+)*__/,"")}function re(s){return s.replace(/^\[[^\]]+\]\s*/,"")}function D({tool:s,checked:d,onToggle:x}){return e.jsxs("label",{className:"flex cursor-pointer items-start gap-2 text-[12px]",children:[e.jsx("input",{type:"checkbox",className:"mt-0.5",checked:d,onChange:x}),e.jsxs("span",{className:"flex flex-col",children:[e.jsx("span",{className:"font-mono text-ink",children:le(s.name)}),s.description&&e.jsx("span",{className:"text-faint",children:re(s.description)})]})]})}function ie({group:s,selected:d,onToggleAll:x,onToggleOne:n}){const[a,i]=b.useState(!1),p=s.tools.map(l=>l.name),c=p.filter(l=>d.has(l)).length,o=c===p.length,g=c>0&&!o,u=b.useRef(null);return b.useEffect(()=>{u.current&&(u.current.indeterminate=g)},[g]),e.jsxs("div",{className:"rounded-md border border-border",children:[e.jsxs("div",{className:"flex items-center gap-2 px-2.5 py-2",children:[e.jsx("input",{ref:u,type:"checkbox",checked:o,onChange:()=>x(p,!o)}),e.jsxs("button",{type:"button",onClick:()=>{j("agents","toggle_agent_tool_group"),i(l=>!l)},className:"flex flex-1 items-center gap-1.5 text-left text-[13px] text-ink",children:[e.jsx(ne,{size:12,className:q("shrink-0 text-faint transition-transform",a&&"rotate-90")}),s.label,e.jsxs("span",{className:"text-[11px] text-faint",children:["(",c,"/",p.length,")"]})]})]}),a&&e.jsx("div",{className:"flex flex-col gap-1.5 border-t border-border px-3 py-2 pl-9",children:s.tools.map(l=>e.jsx(D,{tool:l,checked:d.has(l.name),onToggle:()=>n(l.name)},l.name))})]})}function ce({tools:s,selected:d,onChange:x}){const n=new Set(d),{builtin:a,groups:i}=oe(s),p=o=>x(n.has(o)?d.filter(g=>g!==o):[...d,o]),c=(o,g)=>{const u=d.filter(l=>!o.includes(l));x(g?[...u,...o]:u)};return s.length===0?e.jsx("p",{className:"text-[12px] text-faint",children:"No tools available yet."}):e.jsxs("div",{className:"flex flex-col gap-2",children:[a.length>0&&e.jsx("div",{className:"flex flex-col gap-2 rounded-md border border-border bg-panel-2 p-3",children:a.map(o=>e.jsx(D,{tool:o,checked:n.has(o.name),onToggle:()=>p(o.name)},o.name))}),i.map(o=>e.jsx(ie,{group:o,selected:n,onToggleAll:c,onToggleOne:p},o.key))]})}function je(){const{agentId:s="new"}=W(),d=$(),x=G(),n=s==="new",a=!n&&B.some(t=>t.id===s),i=a?B.find(t=>t.id===s):void 0,p=H(),c=!n&&!a?(p.data??[]).find(t=>t.id===s):void 0,o=Y(),g=J(),u=U(),l=a?g.data?.[s]:void 0,I=z({queryKey:Z.list(),queryFn:X,staleTime:0}),k=I.data??[],w=z({queryKey:["available-tools"],queryFn:V}),N=w.data??[],[m,f]=b.useState(ae()),[S,T]=b.useState(!1),[A,P]=b.useState(!1),[L,R]=b.useState(!1),[E,Q]=b.useState("skills");n&&!S&&(k.length||N.length)&&(f(t=>({...t,skillIds:k.map(r=>r.id),tools:N.map(r=>r.name)})),T(!0)),!n&&!a&&!S&&c&&(f({name:c.name,description:c.description,systemPrompt:c.systemPrompt,skillIds:c.skillIds,tools:c.tools}),T(!0)),a&&!S&&i&&g.isSuccess&&(k.length||N.length)&&(f({name:l?.name??i.name,description:l?.description??i.description,systemPrompt:l?.systemPrompt??i.systemPrompt,skillIds:l?.skillIds??k.map(t=>t.id),tools:l?.tools??N.map(t=>t.name)}),T(!0));const y=()=>{j("agents","back_to_agents"),d("/customize")},O=t=>f(r=>({...r,skillIds:r.skillIds.includes(t)?r.skillIds.filter(v=>v!==t):[...r.skillIds,t]})),F=()=>{if(!m.name.trim()){h.error("Name is required.");return}P(!0);const t={name:m.name.trim(),description:m.description.trim(),systemPrompt:m.systemPrompt,skillIds:m.skillIds,tools:m.tools};if(a){u.save.mutate({id:s,override:t},{onSuccess:()=>{h.success("Agent saved."),y()},onError:v=>{h.error(v instanceof _?v.message:"Could not save agent."),P(!1)}});return}const r={onSuccess:()=>{x.invalidateQueries({queryKey:["chat-agents"]}),h.success(n?"Agent created.":"Agent saved."),y()},onError:v=>{h.error(v instanceof _?v.message:"Could not save agent."),P(!1)}};n?o.add.mutate(t,r):o.update.mutate({id:s,patch:t},r)},K=()=>{u.reset.mutate(s,{onSuccess:()=>{h.success("Reset to default."),i&&f({name:i.name,description:i.description,systemPrompt:i.systemPrompt,skillIds:k.map(t=>t.id),tools:N.map(t=>t.name)})},onError:t=>h.error(t instanceof _?t.message:"Could not reset agent.")})},M=()=>{o.remove.mutate(s,{onSuccess:()=>{h.success("Agent deleted."),y()},onError:t=>h.error(t instanceof _?t.message:"Could not delete agent.")})};return!n&&!a&&p.isSuccess&&!c?e.jsxs("div",{className:"flex w-full flex-col items-center gap-3 px-8 py-16",children:[e.jsx("p",{className:"text-[14px] text-muted",children:"That agent no longer exists."}),e.jsx(C,{size:"sm",variant:"outline",onClick:y,children:"Back to agents"})]}):e.jsxs("div",{className:"flex w-full max-w-4xl flex-col gap-5 px-4 py-6 md:px-8",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("button",{type:"button",onClick:y,className:"text-faint hover:text-ink",title:"Back to agents",children:e.jsx(ee,{size:18})}),e.jsx("span",{className:"text-[15px] font-medium text-ink",children:n?"New agent":a?l?"Edit agent (modified built-in)":"Edit agent (built-in)":"Edit agent"}),e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[a&&e.jsxs(C,{size:"sm",variant:"outline",onClick:()=>{j("agents","reset_agent_to_default"),K()},disabled:u.reset.isPending,children:[e.jsx(te,{size:13})," Reset to default"]}),e.jsx(C,{size:"sm",variant:"outline",onClick:y,children:"Cancel"}),e.jsx(C,{size:"sm",onClick:()=>{j("agents","save_agent"),F()},disabled:A||!m.name.trim(),children:A?"Saving…":"Save"})]})]}),a&&e.jsx("p",{className:"rounded-md border border-border bg-panel px-3 py-2 text-[12px] text-muted",children:"Built-in agents can be edited in place — Reset to default discards your changes and restores TurboLLM's original prompt and access."}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("label",{className:"text-[12px] font-medium text-muted",children:"Name"}),e.jsx("input",{className:"rounded-md border border-border bg-bg px-3 py-1.5 text-[13px] text-ink outline-none focus:border-accent placeholder:text-faint",placeholder:"Release Notes Writer",value:m.name,onChange:t=>f(r=>({...r,name:t.target.value}))})]}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("label",{className:"text-[12px] font-medium text-muted",children:"Description"}),e.jsx("input",{className:"rounded-md border border-border bg-bg px-3 py-1.5 text-[13px] text-ink outline-none focus:border-accent placeholder:text-faint",placeholder:"What this agent is for, in one line",value:m.description,onChange:t=>f(r=>({...r,description:t.target.value}))})]}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("label",{className:"text-[12px] font-medium text-muted",children:"System prompt"}),e.jsx("textarea",{className:"min-h-[160px] resize-y rounded-md border border-border bg-bg px-3 py-2 font-mono text-[12px] leading-relaxed text-ink outline-none focus:border-accent placeholder:text-faint",placeholder:"You are…",value:m.systemPrompt,onChange:t=>f(r=>({...r,systemPrompt:t.target.value}))})]}),e.jsxs("div",{className:"flex flex-col gap-2.5",children:[e.jsx("div",{className:"inline-flex w-fit rounded-md border border-border p-0.5",children:["skills","tools"].map(t=>e.jsx("button",{type:"button",onClick:()=>{j("agents","switch_agent_form_tab"),Q(t)},className:q("rounded px-3 py-1.5 text-[13px] font-medium transition-colors",E===t?"bg-accent/12 text-accent":"text-muted hover:text-ink"),children:t==="skills"?`Skills (${m.skillIds.length})`:`Tools (${m.tools.length})`},t))}),E==="skills"?I.isLoading?e.jsx("p",{className:"text-[12px] text-faint",children:"Loading…"}):k.length===0?e.jsx("p",{className:"text-[12px] text-faint",children:"No skills yet — create one under Customize → Skills."}):e.jsx("div",{className:"flex flex-col gap-2 rounded-md border border-border bg-panel-2 p-3",children:k.map(t=>e.jsxs("label",{className:"flex cursor-pointer items-start gap-2 text-[13px]",children:[e.jsx("input",{type:"checkbox",className:"mt-0.5",checked:m.skillIds.includes(t.id),onChange:()=>O(t.id)}),e.jsxs("span",{className:"flex flex-col",children:[e.jsx("span",{className:"text-ink",children:t.name}),t.description&&e.jsx("span",{className:"text-[12px] text-muted",children:t.description})]})]},t.id))}):w.isLoading?e.jsx("p",{className:"text-[12px] text-faint",children:"Loading…"}):e.jsx(ce,{tools:N,selected:m.tools,onChange:t=>f(r=>({...r,tools:t}))})]}),!n&&!a&&(L?e.jsxs("div",{className:"flex items-center gap-2 self-start rounded-md border border-border bg-panel p-2 text-[12px]",children:[e.jsx("span",{className:"flex-1 text-muted",children:"Delete this agent?"}),e.jsx("button",{type:"button",onClick:()=>{j("agents","delete_agent"),M()},className:"rounded px-2 py-1 text-[color:var(--err)] hover:bg-[color:color-mix(in_srgb,var(--err)_12%,transparent)]",children:"Delete"}),e.jsx("button",{type:"button",onClick:()=>{j("agents","cancel_delete_agent"),R(!1)},className:"rounded px-2 py-1 text-faint hover:text-ink",children:"Cancel"})]}):e.jsxs("button",{type:"button",onClick:()=>R(!0),className:"flex items-center gap-1.5 self-start text-[12px] text-faint hover:text-[color:var(--err)]",children:[e.jsx(se,{size:13})," Delete agent"]}))]})}export{je as AgentEditPage};
|