turbollm 1.11.9 → 1.12.0
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 +1 -1
- package/dist/cli.js +130 -26
- package/dist/webdist/assets/{AgentEditPage-Cfbfakkc.js → AgentEditPage-Cl9VgfYt.js} +1 -1
- package/dist/webdist/assets/{ChatScreen-CYggEGs5.js → ChatScreen-D0JIgp7C.js} +1 -1
- package/dist/webdist/assets/{CodeComposer-CPq9MB0A.js → CodeComposer-Cqtowy4i.js} +1 -1
- package/dist/webdist/assets/{CodeHomeScreen-DJd7UNqS.js → CodeHomeScreen-fGeu4-IS.js} +1 -1
- package/dist/webdist/assets/{CodeSessionScreen-DANRbQym.js → CodeSessionScreen-CqBDC3e4.js} +1 -1
- package/dist/webdist/assets/{CustomizeScreen-BHsYmBrR.js → CustomizeScreen-BTzZdj7z.js} +1 -1
- package/dist/webdist/assets/{DeveloperScreen-C_m-yLRt.js → DeveloperScreen-D40_GOxu.js} +1 -1
- package/dist/webdist/assets/{EnginesScreen-WNm64lCr.js → EnginesScreen-CPKMB1MS.js} +1 -1
- package/dist/webdist/assets/ModelDetailDialog-PySMSzRc.js +1 -0
- package/dist/webdist/assets/{ModelLoadMenu-BoD8vGEb.js → ModelLoadMenu-BgkEIVli.js} +1 -1
- package/dist/webdist/assets/{ModelsScreen-B1eaJCK_.js → ModelsScreen-Bi_cdOOR.js} +1 -1
- package/dist/webdist/assets/{OnboardingScreen-Dp2_T3xE.js → OnboardingScreen-BVyp58am.js} +1 -1
- package/dist/webdist/assets/{RoutineEditPage-_ego0aCV.js → RoutineEditPage-BtL6uHNS.js} +1 -1
- package/dist/webdist/assets/{RoutinesPanel-DHwZQ9Gk.js → RoutinesPanel-Bb0LP98-.js} +1 -1
- package/dist/webdist/assets/{SettingsScreen-DbKvB_mp.js → SettingsScreen-Dsz1JZPU.js} +1 -1
- package/dist/webdist/assets/{SidebarResizeHandle-Bc3QBs84.js → SidebarResizeHandle-B9IvMWnc.js} +1 -1
- package/dist/webdist/assets/{SkillEditPage-CwGusPDb.js → SkillEditPage-zPuoTSEK.js} +1 -1
- package/dist/webdist/assets/{TokensScreen-UaGvsqtF.js → TokensScreen-DGfd8Z_h.js} +1 -1
- package/dist/webdist/assets/{ToolApprovalBar-Chx2y-tr.js → ToolApprovalBar-CjF6OSEN.js} +3 -3
- package/dist/webdist/assets/WorkspaceScreen-BvQS-6fo.js +1 -0
- package/dist/webdist/assets/{abnfDiagram-N423BO3Z-iiGkfE9c.js → abnfDiagram-N423BO3Z-BHtFnGEG.js} +1 -1
- package/dist/webdist/assets/{agent-api-CmhXBBT6.js → agent-api-C-qZrrYO.js} +1 -1
- package/dist/webdist/assets/{alert-dialog-B7ASyTxr.js → alert-dialog-CjxDGiZR.js} +1 -1
- package/dist/webdist/assets/{arc-CitM3TjF.js → arc-CxTBdZ4R.js} +1 -1
- package/dist/webdist/assets/{architectureDiagram-T3A2C74G-B81sGCwi.js → architectureDiagram-T3A2C74G-7PcBBjT5.js} +1 -1
- package/dist/webdist/assets/{arrow-left-Cx0V34bU.js → arrow-left-B6hlnKUy.js} +1 -1
- package/dist/webdist/assets/{badge-BJPgZflb.js → badge-DUS8w956.js} +1 -1
- package/dist/webdist/assets/{blockDiagram-VBNYF7ZC-StpQormu.js → blockDiagram-VBNYF7ZC-yJQM294Z.js} +1 -1
- package/dist/webdist/assets/{bot-XI_iobdp.js → bot-92SGv3lK.js} +1 -1
- package/dist/webdist/assets/{c4Diagram-5PPSVZJV-Csa8aK4v.js → c4Diagram-5PPSVZJV-DGo_IrnA.js} +1 -1
- package/dist/webdist/assets/channel-B6B2Q5Vd.js +1 -0
- package/dist/webdist/assets/{chat-api-Zyxy4wka.js → chat-api-DUobixOH.js} +1 -1
- package/dist/webdist/assets/{chat-queries-DIm_a9NN.js → chat-queries-DIGUy3mB.js} +1 -1
- package/dist/webdist/assets/{chevron-down-BWfjeD2C.js → chevron-down-Cg4gkXkY.js} +1 -1
- package/dist/webdist/assets/{chevron-left-CBtdrcDZ.js → chevron-left-CRkSrIuw.js} +1 -1
- package/dist/webdist/assets/{chevron-right-DRLCoDa8.js → chevron-right-D6YKa1nw.js} +1 -1
- package/dist/webdist/assets/{chunk-2GRJ4B5K-2MKQX9Og.js → chunk-2GRJ4B5K-4BRNCKh4.js} +1 -1
- package/dist/webdist/assets/{chunk-2Q5K7J3B-B_27rm1N.js → chunk-2Q5K7J3B-VVErlkzz.js} +1 -1
- package/dist/webdist/assets/{chunk-5RXB4S5H-BlhTP0-3.js → chunk-5RXB4S5H-BdrEcHfH.js} +1 -1
- package/dist/webdist/assets/{chunk-5VM5RSS4-C7IJCBfZ.js → chunk-5VM5RSS4-B7ZoD7jT.js} +1 -1
- package/dist/webdist/assets/{chunk-6Q2QTUOP-Bj14OW8u.js → chunk-6Q2QTUOP-CZboDQFa.js} +1 -1
- package/dist/webdist/assets/{chunk-GF5L2VYU-aT8ppbPL.js → chunk-GF5L2VYU-Bxfejn_T.js} +1 -1
- package/dist/webdist/assets/{chunk-JWPE2WC7-Bt4dl9CN.js → chunk-JWPE2WC7-CR53ctin.js} +1 -1
- package/dist/webdist/assets/{chunk-KBJHAD2P-J4coc1ol.js → chunk-KBJHAD2P-CI9fYV8V.js} +1 -1
- package/dist/webdist/assets/{chunk-RYQCIY6F-Dv_7Q2hX.js → chunk-RYQCIY6F-CEka5LWj.js} +1 -1
- package/dist/webdist/assets/{chunk-XXDRQBXY-zQnucktD.js → chunk-XXDRQBXY-B6ToGKiT.js} +1 -1
- package/dist/webdist/assets/{circle-check-loUJak9B.js → circle-check-NUkbKKsX.js} +1 -1
- package/dist/webdist/assets/{circle-x-Bgnj4qQZ.js → circle-x-BI2C2Gpz.js} +1 -1
- package/dist/webdist/assets/classDiagram-JCYQIIEL-Nr9H5qaY.js +1 -0
- package/dist/webdist/assets/classDiagram-v2-OCEON4UE-Nr9H5qaY.js +1 -0
- package/dist/webdist/assets/{common-B5JH_OFR.js → common-BDUb2Jp_.js} +1 -1
- package/dist/webdist/assets/{cose-bilkent-JH36ORCC-CvYv-f5s.js → cose-bilkent-JH36ORCC-n-mMCinT.js} +1 -1
- package/dist/webdist/assets/{cynefin-VYW2F7L2-DVwHpekX.js → cynefin-VYW2F7L2--M6hM_u0.js} +1 -1
- package/dist/webdist/assets/{cynefinDiagram-MW4NZA55-BcdPKvtX.js → cynefinDiagram-MW4NZA55-C1WV5_wf.js} +1 -1
- package/dist/webdist/assets/{dagre-VZM6K2ZE-4sSe5M8W.js → dagre-VZM6K2ZE-BrvE8li2.js} +1 -1
- package/dist/webdist/assets/{diagram-7IWD3JNH-COLSWeIR.js → diagram-7IWD3JNH-BAtvwqyn.js} +1 -1
- package/dist/webdist/assets/{diagram-B4RE2ZJO-ER5prsGm.js → diagram-B4RE2ZJO-DIvlrS5g.js} +1 -1
- package/dist/webdist/assets/{diagram-LBJQPF4R-FfvD4Hay.js → diagram-LBJQPF4R-BzTddnYn.js} +1 -1
- package/dist/webdist/assets/{diagram-Q27KOJAE-DnwPL2tG.js → diagram-Q27KOJAE-U-iZs4DE.js} +1 -1
- package/dist/webdist/assets/{diagram-UB23O5K3-B6lZME5q.js → diagram-UB23O5K3-CaFGOdAj.js} +1 -1
- package/dist/webdist/assets/{dropdown-menu-DRRO0ftt.js → dropdown-menu-D5Vf7U3W.js} +1 -1
- package/dist/webdist/assets/{ebnfDiagram-BXEA7PRR-DLx8zqdK.js → ebnfDiagram-BXEA7PRR-WEkh8Cpp.js} +1 -1
- package/dist/webdist/assets/{erDiagram-JOGREHBK-DdSmD2ix.js → erDiagram-JOGREHBK-DIPsvu0C.js} +1 -1
- package/dist/webdist/assets/{external-link-dolckdL9.js → external-link-DuVH0_sU.js} +1 -1
- package/dist/webdist/assets/{file-text-BJHbdxSm.js → file-text-B8I_V3Ev.js} +1 -1
- package/dist/webdist/assets/{flowDiagram-UKHOOZJN-C71SbKr7.js → flowDiagram-UKHOOZJN-D0Il5rli.js} +1 -1
- package/dist/webdist/assets/{folder-input-ubj-7_tQ.js → folder-input-n_yC89H9.js} +1 -1
- package/dist/webdist/assets/{folder-plus-Bz7B7UnH.js → folder-plus-CC1f-3oh.js} +1 -1
- package/dist/webdist/assets/{ganttDiagram-PKOTCBZU-C5doF3y3.js → ganttDiagram-PKOTCBZU-8KyY9Pa4.js} +1 -1
- package/dist/webdist/assets/{git-branch-CNpNkvMr.js → git-branch-CQA2JECJ.js} +1 -1
- package/dist/webdist/assets/{gitGraphDiagram-DS77QQ5N-iCuj4BOQ.js → gitGraphDiagram-DS77QQ5N-DnwR5_g_.js} +1 -1
- package/dist/webdist/assets/{index-D0Emka7d.js → index-hEBbEVm0.js} +2 -2
- package/dist/webdist/assets/{infoDiagram-6WML65LV-CVbutaQs.js → infoDiagram-6WML65LV-B4Ao9xBO.js} +1 -1
- package/dist/webdist/assets/{ishikawaDiagram-WSZJBQD7-CZyy_met.js → ishikawaDiagram-WSZJBQD7-BIH-3xyR.js} +1 -1
- package/dist/webdist/assets/{journeyDiagram-NVQOT4AX-BIwZvXA4.js → journeyDiagram-NVQOT4AX-CB7VA190.js} +1 -1
- package/dist/webdist/assets/{kanban-definition-27J2QSJJ-DOERNBKz.js → kanban-definition-27J2QSJJ-t0MLGJxS.js} +1 -1
- package/dist/webdist/assets/{linear-Bf8xCMRw.js → linear-C2UcHtLH.js} +1 -1
- package/dist/webdist/assets/{link-queries-DBf0L0p4.js → link-queries-Dd_UY0A-.js} +1 -1
- package/dist/webdist/assets/{lock-CnmBV2sW.js → lock-BaRe3TFE.js} +1 -1
- package/dist/webdist/assets/{mermaid.core-DcQR7vsm.js → mermaid.core-Do_AkPs7.js} +4 -4
- package/dist/webdist/assets/{mindmap-definition-FAOFIHXS-C3T3OIGM.js → mindmap-definition-FAOFIHXS-C0FjLEZb.js} +1 -1
- package/dist/webdist/assets/{monitor-Dj5hVZG9.js → monitor-nPLFkAL-.js} +1 -1
- package/dist/webdist/assets/{pegDiagram-VL7TDLO6-J5nkSsO9.js → pegDiagram-VL7TDLO6-DMP_1SBp.js} +1 -1
- package/dist/webdist/assets/{pencil-CJDKBSrc.js → pencil-DIAK3lkm.js} +1 -1
- package/dist/webdist/assets/{personas-CeAQ6niU.js → personas-Dkq9JD72.js} +1 -1
- package/dist/webdist/assets/{pieDiagram-7S7Q4E2Y-2RGDZc8u.js → pieDiagram-7S7Q4E2Y-RG_slaJ2.js} +1 -1
- package/dist/webdist/assets/{plus-CtCCCtT9.js → plus-Cd2hb3vG.js} +1 -1
- package/dist/webdist/assets/{quadrantDiagram-CIZ2JOQS-DsYpj2qg.js → quadrantDiagram-CIZ2JOQS-6wV3EG0F.js} +1 -1
- package/dist/webdist/assets/{railroadDiagram-AXF67PYL-DvObbGSI.js → railroadDiagram-AXF67PYL-flgltuTY.js} +1 -1
- package/dist/webdist/assets/{refresh-cw-Qd40C8Nj.js → refresh-cw-MAW86aWv.js} +1 -1
- package/dist/webdist/assets/{remote-failure-B7wlj-_A.js → remote-failure-DTP9EDi2.js} +1 -1
- package/dist/webdist/assets/{requirementDiagram-LRYGKXZP-CdeOzUDb.js → requirementDiagram-LRYGKXZP-CXpi-87D.js} +1 -1
- package/dist/webdist/assets/{rocket-D2AvWWtP.js → rocket-B5uDLuGn.js} +1 -1
- package/dist/webdist/assets/{rotate-ccw-BpPatpxx.js → rotate-ccw-DVWlxS6M.js} +1 -1
- package/dist/webdist/assets/{sankeyDiagram-W5VNT64P-DVrYRLqU.js → sankeyDiagram-W5VNT64P-C50KvAmS.js} +1 -1
- package/dist/webdist/assets/{sequenceDiagram-SI44F4Z6-BZAK6xg6.js → sequenceDiagram-SI44F4Z6-CsT039Tm.js} +1 -1
- package/dist/webdist/assets/{sizeCapture-X5ZJPWSS-BHOY8h1t.js → sizeCapture-X5ZJPWSS-BImTTCUc.js} +1 -1
- package/dist/webdist/assets/{skeleton-C1KITEIJ.js → skeleton-DnvNxbj8.js} +1 -1
- package/dist/webdist/assets/{sliders-horizontal-D48--I0k.js → sliders-horizontal-DsS2Uee5.js} +1 -1
- package/dist/webdist/assets/{sparkles-DDOla5js.js → sparkles-BU19nV47.js} +1 -1
- package/dist/webdist/assets/{star-B2buMvXV.js → star-DcvDKUjt.js} +1 -1
- package/dist/webdist/assets/{stateDiagram-OKZ733FA-VUJTdkvj.js → stateDiagram-OKZ733FA-Go1nImaV.js} +1 -1
- package/dist/webdist/assets/stateDiagram-v2-UEYNNEHI-CNOImueL.js +1 -0
- package/dist/webdist/assets/{swimlanes-SLNWSIFB-MjxXyCvR.js → swimlanes-SLNWSIFB-D8aYBeg_.js} +2 -2
- package/dist/webdist/assets/swimlanesDiagram-ULZ7WXOC-u93o-5nq.js +8 -0
- package/dist/webdist/assets/{switch-Cs9dlnwb.js → switch-DRDUQUBQ.js} +1 -1
- package/dist/webdist/assets/{terminal-CiOZKaJb.js → terminal-BaGcFc0D.js} +1 -1
- package/dist/webdist/assets/{timeline-definition-Z64GVDOM-Bw8Iivgn.js → timeline-definition-Z64GVDOM-BCYicvUs.js} +1 -1
- package/dist/webdist/assets/{trash-2-DbQqCHSH.js → trash-2-dTSieVsH.js} +1 -1
- package/dist/webdist/assets/{triangle-alert-Buguln0S.js → triangle-alert-BQok4bN-.js} +1 -1
- package/dist/webdist/assets/{useIsDesktop-BdbkbmUH.js → useIsDesktop-D7McLbCu.js} +1 -1
- package/dist/webdist/assets/{vennDiagram-T6HMQDX7-UptwMBTb.js → vennDiagram-T6HMQDX7-BvWE6mUb.js} +1 -1
- package/dist/webdist/assets/{wardleyDiagram-T6FBY63Y-DBzcNfG5.js → wardleyDiagram-T6FBY63Y-DId8SDFX.js} +1 -1
- package/dist/webdist/assets/{wrench-ByDKNN2K.js → wrench-wnE0c5Ir.js} +1 -1
- package/dist/webdist/assets/{xychartDiagram-ELKLHX3M-DrO-tWl0.js → xychartDiagram-ELKLHX3M-DAFHE1Oy.js} +1 -1
- package/dist/webdist/index.html +1 -1
- package/package.json +1 -1
- package/dist/webdist/assets/ModelDetailDialog-CCmZhT_-.js +0 -1
- package/dist/webdist/assets/WorkspaceScreen-a7V07mMZ.js +0 -1
- package/dist/webdist/assets/channel-DS6QHRxP.js +0 -1
- package/dist/webdist/assets/classDiagram-JCYQIIEL-DmMoUKDN.js +0 -1
- package/dist/webdist/assets/classDiagram-v2-OCEON4UE-DmMoUKDN.js +0 -1
- package/dist/webdist/assets/stateDiagram-v2-UEYNNEHI-DslkN__b.js +0 -1
- package/dist/webdist/assets/swimlanesDiagram-ULZ7WXOC-CQoli8MP.js +0 -8
package/README.md
CHANGED
|
@@ -208,7 +208,7 @@ the detail:
|
|
|
208
208
|
- **Full load-parameter UI**, a superset of what other tools expose: context length, GPU offload
|
|
209
209
|
(`-ngl`), **MoE CPU-offload (`--n-cpu-moe`)**, parallel slots, **independent K and V cache-quant
|
|
210
210
|
type** (incl. low-bit on supporting forks), CPU threads, flash attention, **speculative decoding
|
|
211
|
-
(NextN / MTP / draft, with a configurable draft min/max window)**, a **pinned engine port** per
|
|
211
|
+
(NextN / MTP / draft / DFlash, with a configurable draft min/max window)**, a **pinned engine port** per
|
|
212
212
|
model, and a **custom/raw flags** field for anything not exposed as its own control.
|
|
213
213
|
- **Copy the exact launch command** for a loaded model — runs the same config standalone with
|
|
214
214
|
llama.cpp/the fork directly, no TurboLLM required.
|
package/dist/cli.js
CHANGED
|
@@ -2637,9 +2637,12 @@ function detectKvTypes(helpText, hasCacheTypeFlag) {
|
|
|
2637
2637
|
return kvTypes;
|
|
2638
2638
|
}
|
|
2639
2639
|
function parseEnumList(blockText) {
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2640
|
+
let raw = /allowed values:\s*([\s\S]+)/i.exec(blockText)?.[1] ?? /(?:^|[ \t])\[([^\]\n]+)\]/.exec(blockText)?.[1];
|
|
2641
|
+
if (!raw) {
|
|
2642
|
+
const braceMatch = /(?:^|[ \t])\{([^}]+)\}/.exec(blockText);
|
|
2643
|
+
const parenMatch = /(?:^|[ \t])\(([^)|]+)\)/.exec(blockText);
|
|
2644
|
+
raw = braceMatch?.[1] ?? parenMatch?.[1];
|
|
2645
|
+
}
|
|
2643
2646
|
if (!raw) return [];
|
|
2644
2647
|
const values = raw.split(/[,|]/).map((s) => s.trim()).filter((s) => /^[a-z][a-z0-9_-]*$/i.test(s));
|
|
2645
2648
|
return values.length >= 2 ? values : [];
|
|
@@ -2648,7 +2651,7 @@ function classifyFlag(flagName, helpText) {
|
|
|
2648
2651
|
const escaped = flagName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2649
2652
|
const ALIAS = "-{1,2}[a-zA-Z][a-zA-Z0-9-]*";
|
|
2650
2653
|
const re = new RegExp(
|
|
2651
|
-
`(?:^|\\n)[ \\t]*(?:${ALIAS}[ \\t]*,[ \\t]*)*${escaped}(?![-a-zA-Z0-9])(?:[ \\t]*,[ \\t]*${ALIAS})*( *)(\\S+)?([\\s\\S]
|
|
2654
|
+
`(?:^|\\n)[ \\t]*(?:${ALIAS}[ \\t]*,[ \\t]*)*${escaped}(?![-a-zA-Z0-9])(?:[ \\t]*,[ \\t]*${ALIAS})*( *)(\\S+)?([\\s\\S]+?)(?=\\n\\s*\\(default|\\n[ \\t]*${ALIAS}|\\n\\n|$)`,
|
|
2652
2655
|
"i"
|
|
2653
2656
|
);
|
|
2654
2657
|
const m = re.exec(helpText);
|
|
@@ -2656,11 +2659,24 @@ function classifyFlag(flagName, helpText) {
|
|
|
2656
2659
|
const gap = m[1] ?? "";
|
|
2657
2660
|
const placeholder = m[2] ?? "";
|
|
2658
2661
|
const block = m[3] ?? "";
|
|
2659
|
-
const
|
|
2662
|
+
const nextFlagLine = block.match(/\n[ \t]*-{1,2}[a-zA-Z][a-zA-Z0-9-]*/);
|
|
2663
|
+
const ownBlock = nextFlagLine ? block.slice(0, nextFlagLine.index) : block;
|
|
2664
|
+
const scanText = placeholder + "\n" + ownBlock;
|
|
2665
|
+
const enumValues = parseEnumList(scanText);
|
|
2660
2666
|
if (enumValues.length > 0) return { name: flagName, kind: "enum", enumValues };
|
|
2667
|
+
const bracket = parseEnumBrackets(scanText);
|
|
2668
|
+
if (bracket.length > 0) return { name: flagName, kind: "enum", enumValues: bracket };
|
|
2661
2669
|
if (gap.length !== 1 || !placeholder) return { name: flagName, kind: "boolean" };
|
|
2662
2670
|
return { name: flagName, kind: "valued" };
|
|
2663
2671
|
}
|
|
2672
|
+
function parseEnumBrackets(blockText) {
|
|
2673
|
+
const braceMatch = /(?:^|[ \t])\{([^}]+)\}/.exec(blockText);
|
|
2674
|
+
const parenMatch = /(?:^|[ \t])\(([^)|]+)\)/.exec(blockText);
|
|
2675
|
+
const raw = braceMatch?.[1] ?? parenMatch?.[1];
|
|
2676
|
+
if (!raw) return [];
|
|
2677
|
+
const values = raw.split(/[|,]/).map((s) => s.trim()).filter((s) => /^[a-z][a-z0-9_-]*$/i.test(s));
|
|
2678
|
+
return values.length >= 2 ? values : [];
|
|
2679
|
+
}
|
|
2664
2680
|
function firstNonEmptyLine(s) {
|
|
2665
2681
|
for (const ln of s.split("\n")) {
|
|
2666
2682
|
const t = ln.trim();
|
|
@@ -2887,9 +2903,11 @@ function suggestEngineName(binPath, version2) {
|
|
|
2887
2903
|
|
|
2888
2904
|
// src/engines/build-runner.ts
|
|
2889
2905
|
var execFileP8 = promisify8(execFile10);
|
|
2906
|
+
function chooseEngineName(name, priorName) {
|
|
2907
|
+
return name ?? priorName ?? "";
|
|
2908
|
+
}
|
|
2890
2909
|
function buildDirName(repoUrl, branch, commit) {
|
|
2891
|
-
const
|
|
2892
|
-
const repo = last.replace(/\.git$/i, "").trim() || "engine";
|
|
2910
|
+
const repo = normRepoUrl(repoUrl) || "engine";
|
|
2893
2911
|
const b = (branch ?? "").trim();
|
|
2894
2912
|
const sha = (commit ?? "").trim();
|
|
2895
2913
|
const raw = sha ? `${repo}-${sha.slice(0, 12)}` : b ? `${repo}-${b}` : repo;
|
|
@@ -2900,7 +2918,7 @@ function sameRepo(a, b) {
|
|
|
2900
2918
|
return na !== "" && na === normRepoUrl(b);
|
|
2901
2919
|
}
|
|
2902
2920
|
function normRepoUrl(s) {
|
|
2903
|
-
return (s ?? "").trim().toLowerCase().replace(/^https?:\/\//, "").replace(/^github\.com\//, "").replace(
|
|
2921
|
+
return (s ?? "").trim().toLowerCase().replace(/^https?:\/\//, "").replace(/^github\.com\//, "").replace(/\/+$/, "").replace(/\.git$/, "");
|
|
2904
2922
|
}
|
|
2905
2923
|
function sourceBuildBinary(enginesRoot, repoUrl, branch, commit) {
|
|
2906
2924
|
const root = join13(enginesRoot, "build", buildDirName(repoUrl, branch, commit));
|
|
@@ -3662,7 +3680,11 @@ function customSourceKey(s) {
|
|
|
3662
3680
|
}
|
|
3663
3681
|
function isStaleCapabilities(flags, flagInfo) {
|
|
3664
3682
|
if (flags.includes("--spec-type") && !flags.some((f2) => f2.startsWith("spec-type:"))) return true;
|
|
3665
|
-
|
|
3683
|
+
const removed = ["--draft-max", "--draft-min", "--draft", "--draft-n", "--draft-n-min"];
|
|
3684
|
+
const successor = ["--spec-draft-n-max", "--spec-draft-n-min"];
|
|
3685
|
+
const hasRemoved = removed.some((f2) => flags.includes(f2));
|
|
3686
|
+
const hasSuccessor = successor.some((f2) => flags.includes(f2));
|
|
3687
|
+
if (hasRemoved && hasSuccessor) return true;
|
|
3666
3688
|
if (flagInfo === void 0) return true;
|
|
3667
3689
|
return false;
|
|
3668
3690
|
}
|
|
@@ -3830,7 +3852,7 @@ var modelLoad = defineEvent({
|
|
|
3830
3852
|
batchSize: f.int({ optional: true }),
|
|
3831
3853
|
uBatchSize: f.int({ optional: true }),
|
|
3832
3854
|
cacheReuse: f.int(),
|
|
3833
|
-
speculative: f.enum(["off", "mtp", "nextn", "draft"]),
|
|
3855
|
+
speculative: f.enum(["off", "mtp", "nextn", "draft", "dflash"]),
|
|
3834
3856
|
contextOverflow: f.enum(["shift", "keep"]),
|
|
3835
3857
|
nKeep: f.int(),
|
|
3836
3858
|
ropeScalingType: f.enum(["none", "linear", "yarn"]),
|
|
@@ -5617,7 +5639,11 @@ async function withPinnedModel(deps2, pinnedModel, fn) {
|
|
|
5617
5639
|
return { outcome: "ran" };
|
|
5618
5640
|
}
|
|
5619
5641
|
const swapResult = await deps2.modelRouter.loadExplicit(pinnedModel);
|
|
5620
|
-
if ("status" in swapResult)
|
|
5642
|
+
if ("status" in swapResult) {
|
|
5643
|
+
if (swapResult.message.includes("ComfyUI is rendering"))
|
|
5644
|
+
return { outcome: "skip-comfyui-busy" };
|
|
5645
|
+
return { outcome: "skip-load-failed", message: swapResult.message };
|
|
5646
|
+
}
|
|
5621
5647
|
try {
|
|
5622
5648
|
await fn();
|
|
5623
5649
|
} finally {
|
|
@@ -8474,6 +8500,10 @@ function finalizeSwapOutcome(d, runId, swap, ranStatus) {
|
|
|
8474
8500
|
d.db.updateRoutineRun(runId, { status: "skipped", skipReason: "model_busy", endedAt });
|
|
8475
8501
|
return "skipped";
|
|
8476
8502
|
}
|
|
8503
|
+
if (swap.outcome === "skip-comfyui-busy") {
|
|
8504
|
+
d.db.updateRoutineRun(runId, { status: "skipped", skipReason: "comfyui_busy", endedAt });
|
|
8505
|
+
return "skipped";
|
|
8506
|
+
}
|
|
8477
8507
|
d.db.updateRoutineRun(runId, { status: "errored", error: swap.message, endedAt });
|
|
8478
8508
|
return "errored";
|
|
8479
8509
|
}
|
|
@@ -9098,7 +9128,7 @@ function estimateVramPerGpu(p, m, sys) {
|
|
|
9098
9128
|
const blocks = m.blockCount > 0 ? m.blockCount : 1;
|
|
9099
9129
|
const sizeMb = m.sizeBytes / 1e6;
|
|
9100
9130
|
const perLayerMb = sizeMb * GPU_WEIGHT_FRACTION / blocks;
|
|
9101
|
-
const residentLayers =
|
|
9131
|
+
const residentLayers = Math.max(0, Math.min(p.ngl, blocks));
|
|
9102
9132
|
const nCpuMoe = m.moe ? Math.max(0, Math.min(p.nCpuMoe, blocks)) : 0;
|
|
9103
9133
|
const layers = new Array(n).fill(0);
|
|
9104
9134
|
if (p.gpu?.splitMode === "none" || n === 1) {
|
|
@@ -9305,6 +9335,10 @@ function profileToArgs(p, m, caps, cores = 0, sys, binPath) {
|
|
|
9305
9335
|
if (specType) a.push("--spec-type", "draft");
|
|
9306
9336
|
a.push("--model-draft", p.draftModelPath);
|
|
9307
9337
|
specActive = true;
|
|
9338
|
+
} else if (p.speculative === "dflash" && p.draftModelPath && specType && specAccepts("draft-dflash") && has("--spec-draft-model")) {
|
|
9339
|
+
a.push("--spec-type", "draft-dflash");
|
|
9340
|
+
a.push("--spec-draft-model", p.draftModelPath);
|
|
9341
|
+
specActive = true;
|
|
9308
9342
|
}
|
|
9309
9343
|
if (specActive) {
|
|
9310
9344
|
if (has("--draft-max")) a.push("--draft-max", String(p.draftMax ?? 16));
|
|
@@ -10816,6 +10850,7 @@ import {
|
|
|
10816
10850
|
SettingsManager,
|
|
10817
10851
|
isEditToolResult
|
|
10818
10852
|
} from "@earendil-works/pi-coding-agent";
|
|
10853
|
+
import { estimateTokens, calculateContextTokens } from "@earendil-works/pi-coding-agent";
|
|
10819
10854
|
|
|
10820
10855
|
// src/code/robust-bash.ts
|
|
10821
10856
|
import { access as fsAccess } from "fs/promises";
|
|
@@ -12574,7 +12609,35 @@ ${lines.join("\n")}${more}]`
|
|
|
12574
12609
|
}
|
|
12575
12610
|
const finalText = session.getLastAssistantText() ?? "";
|
|
12576
12611
|
const stats = session.getSessionStats();
|
|
12577
|
-
|
|
12612
|
+
let contextUsed;
|
|
12613
|
+
if (stats.contextUsage?.tokens != null) {
|
|
12614
|
+
contextUsed = stats.contextUsage.tokens;
|
|
12615
|
+
} else {
|
|
12616
|
+
let lastUsage;
|
|
12617
|
+
let lastUsageIdx = -1;
|
|
12618
|
+
for (let i = session.messages.length - 1; i >= 0; i--) {
|
|
12619
|
+
const m = session.messages[i];
|
|
12620
|
+
if (m.role === "assistant" && "usage" in m) {
|
|
12621
|
+
const u = m.usage;
|
|
12622
|
+
if (u && calculateContextTokens(u) > 0) {
|
|
12623
|
+
lastUsage = u;
|
|
12624
|
+
lastUsageIdx = i;
|
|
12625
|
+
break;
|
|
12626
|
+
}
|
|
12627
|
+
}
|
|
12628
|
+
}
|
|
12629
|
+
if (lastUsage) {
|
|
12630
|
+
contextUsed = calculateContextTokens(lastUsage);
|
|
12631
|
+
for (let i = lastUsageIdx + 1; i < session.messages.length; i++) {
|
|
12632
|
+
contextUsed += estimateTokens(session.messages[i]);
|
|
12633
|
+
}
|
|
12634
|
+
} else {
|
|
12635
|
+
contextUsed = 0;
|
|
12636
|
+
for (const m of session.messages) {
|
|
12637
|
+
contextUsed += estimateTokens(m);
|
|
12638
|
+
}
|
|
12639
|
+
}
|
|
12640
|
+
}
|
|
12578
12641
|
const contextMax = stats.contextUsage?.contextWindow ?? contextWindow;
|
|
12579
12642
|
const usage = foldTurnUsage(stats.tokens, { promptMsTotal, genMsTotal, ttftMs, totalMs: Date.now() - turnStartedAt });
|
|
12580
12643
|
session.dispose();
|
|
@@ -12674,7 +12737,10 @@ async function compactCodeSession(params) {
|
|
|
12674
12737
|
compactionUpToMessageId: upToMessageId,
|
|
12675
12738
|
compactionTokensBefore: result.tokensBefore
|
|
12676
12739
|
});
|
|
12677
|
-
|
|
12740
|
+
const summaryTokens = Math.ceil(result.summary.length / 4);
|
|
12741
|
+
const ctxUsed = compactionSettings.keepRecentTokens + summaryTokens;
|
|
12742
|
+
d.db.setCodeSessionCtxUsed(sessionId, ctxUsed);
|
|
12743
|
+
return { summary: result.summary, upToMessageId, tokensBefore: result.tokensBefore, ctxUsed };
|
|
12678
12744
|
}
|
|
12679
12745
|
async function lookbackPreCompactionHistory(params) {
|
|
12680
12746
|
const { d, convId, sessionId, repoRoot, question, signal } = params;
|
|
@@ -15318,6 +15384,10 @@ var ConversationStore = class {
|
|
|
15318
15384
|
`);
|
|
15319
15385
|
this.db.exec(`PRAGMA user_version = 48;`);
|
|
15320
15386
|
}
|
|
15387
|
+
if (v < 49) {
|
|
15388
|
+
if (!this.hasColumn("api_usage", "ctx_used")) this.db.exec(`ALTER TABLE api_usage ADD COLUMN ctx_used INTEGER DEFAULT 0;`);
|
|
15389
|
+
this.db.exec(`PRAGMA user_version = 49;`);
|
|
15390
|
+
}
|
|
15321
15391
|
}
|
|
15322
15392
|
listConversations(q, kind = "all") {
|
|
15323
15393
|
if (q) {
|
|
@@ -15688,8 +15758,8 @@ var ConversationStore = class {
|
|
|
15688
15758
|
recordApiUsage(rec) {
|
|
15689
15759
|
const rate = (v) => v != null && Number.isFinite(v) && v > 0 ? v : null;
|
|
15690
15760
|
this.db.prepare(`
|
|
15691
|
-
INSERT INTO api_usage (id, created_at, source, model_key, prompt_tokens, gen_tokens, code_session_id, duration_ms, prompt_tps, gen_tps, harness)
|
|
15692
|
-
VALUES ($id, $createdAt, $source, $modelKey, $promptTokens, $genTokens, $codeSessionId, $durationMs, $promptTps, $genTps, $harness)
|
|
15761
|
+
INSERT INTO api_usage (id, created_at, source, model_key, prompt_tokens, gen_tokens, code_session_id, duration_ms, prompt_tps, gen_tps, harness, ctx_used)
|
|
15762
|
+
VALUES ($id, $createdAt, $source, $modelKey, $promptTokens, $genTokens, $codeSessionId, $durationMs, $promptTps, $genTps, $harness, $ctxUsed)
|
|
15693
15763
|
`).run({
|
|
15694
15764
|
$id: randomUUID6(),
|
|
15695
15765
|
$createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -15701,9 +15771,40 @@ var ConversationStore = class {
|
|
|
15701
15771
|
$durationMs: rec.durationMs != null && Number.isFinite(rec.durationMs) ? Math.max(0, Math.floor(rec.durationMs)) : null,
|
|
15702
15772
|
$promptTps: rate(rec.promptTps),
|
|
15703
15773
|
$genTps: rate(rec.genTps),
|
|
15704
|
-
$harness: rec.harness ?? null
|
|
15774
|
+
$harness: rec.harness ?? null,
|
|
15775
|
+
$ctxUsed: Math.max(0, Math.floor(rec.promptTokens) || 0)
|
|
15705
15776
|
});
|
|
15706
15777
|
}
|
|
15778
|
+
/** Lower the current context size for a Code session after /compact, so the ctx gauge
|
|
15779
|
+
* reflects post-compaction reality (ADR-386). Updates the row with the MAX ctx_used
|
|
15780
|
+
* to the new value — this is what allows /compact to lower the ring's frozen ceiling.
|
|
15781
|
+
* If no row exists yet (fresh session compacted before first gateway request), creates one. */
|
|
15782
|
+
setCodeSessionCtxUsed(codeSessionId, ctxUsed) {
|
|
15783
|
+
const maxRow = this.db.prepare(`
|
|
15784
|
+
SELECT id FROM api_usage
|
|
15785
|
+
WHERE code_session_id = $codeSessionId AND ctx_used = (
|
|
15786
|
+
SELECT MAX(ctx_used) FROM api_usage WHERE code_session_id = $codeSessionId
|
|
15787
|
+
)
|
|
15788
|
+
LIMIT 1
|
|
15789
|
+
`).get({ $codeSessionId: codeSessionId });
|
|
15790
|
+
if (maxRow) {
|
|
15791
|
+
this.db.prepare(`
|
|
15792
|
+
UPDATE api_usage SET ctx_used = $ctxUsed, prompt_tokens = $promptTokens, created_at = $createdAt
|
|
15793
|
+
WHERE id = $id
|
|
15794
|
+
`).run({ $ctxUsed: ctxUsed, $promptTokens: ctxUsed, $createdAt: (/* @__PURE__ */ new Date()).toISOString(), $id: maxRow.id });
|
|
15795
|
+
} else {
|
|
15796
|
+
this.db.prepare(`
|
|
15797
|
+
INSERT INTO api_usage (id, created_at, source, prompt_tokens, gen_tokens, code_session_id, ctx_used)
|
|
15798
|
+
VALUES ($id, $createdAt, 'compact', $promptTokens, 0, $codeSessionId, $ctxUsed)
|
|
15799
|
+
`).run({
|
|
15800
|
+
$id: randomUUID6(),
|
|
15801
|
+
$createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
15802
|
+
$promptTokens: ctxUsed,
|
|
15803
|
+
$codeSessionId: codeSessionId,
|
|
15804
|
+
$ctxUsed: ctxUsed
|
|
15805
|
+
});
|
|
15806
|
+
}
|
|
15807
|
+
}
|
|
15707
15808
|
/** The session's own gateway-request stats (ADR-284, revised twice — founder-reported "ctx
|
|
15708
15809
|
* fill jumps between full and empty in the same session", then a review pass on that same fix
|
|
15709
15810
|
* catching that it had gone on to freeze the LAST-TURN stats too). Two different questions,
|
|
@@ -15737,14 +15838,14 @@ var ConversationStore = class {
|
|
|
15737
15838
|
* non-terminal-agent one). */
|
|
15738
15839
|
getLastApiUsageForSession(codeSessionId) {
|
|
15739
15840
|
const row = this.db.prepare(`
|
|
15740
|
-
SELECT prompt_tokens, gen_tokens, duration_ms, prompt_tps, gen_tps FROM api_usage
|
|
15841
|
+
SELECT prompt_tokens, gen_tokens, duration_ms, prompt_tps, gen_tps, ctx_used FROM api_usage
|
|
15741
15842
|
WHERE code_session_id = $codeSessionId
|
|
15742
15843
|
ORDER BY created_at DESC LIMIT 1
|
|
15743
15844
|
`).get({ $codeSessionId: codeSessionId });
|
|
15744
15845
|
if (!row) return null;
|
|
15745
15846
|
const ctxUsed = this.db.prepare(`
|
|
15746
|
-
SELECT MAX(
|
|
15747
|
-
`).get({ $codeSessionId: codeSessionId }).
|
|
15847
|
+
SELECT MAX(ctx_used) as maxCtxUsed FROM api_usage WHERE code_session_id = $codeSessionId
|
|
15848
|
+
`).get({ $codeSessionId: codeSessionId }).maxCtxUsed;
|
|
15748
15849
|
const seconds = row.duration_ms != null && row.duration_ms > 0 ? row.duration_ms / 1e3 : null;
|
|
15749
15850
|
return {
|
|
15750
15851
|
ctxUsed,
|
|
@@ -22506,7 +22607,10 @@ var ALL = [
|
|
|
22506
22607
|
support: "stable",
|
|
22507
22608
|
// llama.cpp expands into the backend sub-picker (existing UI); it has no single
|
|
22508
22609
|
// install endpoint of its own.
|
|
22509
|
-
installEndpoint: ""
|
|
22610
|
+
installEndpoint: "",
|
|
22611
|
+
// Its installed state comes from the separate backend-build detection (LlamaCppBackendRows),
|
|
22612
|
+
// not the generic sourceRepo match below — see the field's own doc comment (ADR-388).
|
|
22613
|
+
excludeFromSourceMatch: true
|
|
22510
22614
|
},
|
|
22511
22615
|
{
|
|
22512
22616
|
// Upstream publishes NO Linux CUDA prebuilt (download.ts availableBackends() — Linux
|
|
@@ -24501,11 +24605,11 @@ function registerApi(app2, d) {
|
|
|
24501
24605
|
installed2 = existsSync26(llamafileBinPath(enginesRoot));
|
|
24502
24606
|
enabled = regEngines.some((x) => x.kind === "llamafile");
|
|
24503
24607
|
}
|
|
24504
|
-
const srcEng = regEngines.find(
|
|
24608
|
+
const srcEng = e.excludeFromSourceMatch ? void 0 : regEngines.find(
|
|
24505
24609
|
(x) => sameRepo(x.sourceRepo, e.homepage) && (x.sourceCommit ?? "") === (e.sourceCommit ?? "") && (x.sourcePatchUrl ?? "") === (e.patchUrl ?? "")
|
|
24506
24610
|
);
|
|
24507
24611
|
let sourceBinPath = srcEng?.binPath;
|
|
24508
|
-
if (!srcEng) sourceBinPath = sourceBuildBinary(enginesRoot, e.homepage, void 0, e.sourceCommit) ?? void 0;
|
|
24612
|
+
if (!srcEng && !e.excludeFromSourceMatch) sourceBinPath = sourceBuildBinary(enginesRoot, e.homepage, void 0, e.sourceCommit) ?? void 0;
|
|
24509
24613
|
const sourceBuilt = !!srcEng || !!sourceBinPath;
|
|
24510
24614
|
if (srcEng) {
|
|
24511
24615
|
installed2 = true;
|
|
@@ -24604,7 +24708,7 @@ function registerApi(app2, d) {
|
|
|
24604
24708
|
} catch {
|
|
24605
24709
|
}
|
|
24606
24710
|
}
|
|
24607
|
-
const eng = (await d.registry.add(prior?.name
|
|
24711
|
+
const eng = (await d.registry.add(chooseEngineName(name, prior?.name), out.binPath, {
|
|
24608
24712
|
sourceRepo: repoUrl,
|
|
24609
24713
|
sourceBranch: branch,
|
|
24610
24714
|
sourceCommit: commit,
|
|
@@ -31148,14 +31252,14 @@ import { streamSSE as streamSSE5 } from "hono/streaming";
|
|
|
31148
31252
|
// src/ext/context-limit.ts
|
|
31149
31253
|
var CHARS_PER_TOKEN2 = 3.5;
|
|
31150
31254
|
var REPLY_HEADROOM = 512;
|
|
31151
|
-
function
|
|
31255
|
+
function estimateTokens2(messages) {
|
|
31152
31256
|
let chars = 0;
|
|
31153
31257
|
for (const m of messages) chars += m.content.length + m.role.length + 4;
|
|
31154
31258
|
return Math.ceil(chars / CHARS_PER_TOKEN2);
|
|
31155
31259
|
}
|
|
31156
31260
|
function checkContextFits(d, messages) {
|
|
31157
31261
|
const limit = d.manager.status().model?.ctx ?? 0;
|
|
31158
|
-
const estimated =
|
|
31262
|
+
const estimated = estimateTokens2(messages);
|
|
31159
31263
|
if (!limit) return { fits: true, estimated, limit: 0 };
|
|
31160
31264
|
return { fits: estimated + REPLY_HEADROOM <= limit, estimated, limit };
|
|
31161
31265
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./radix-B0YBjihE.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-D0Emka7d.js";import{f as V}from"./chat-api-Zyxy4wka.js";import{f as X,a as Z}from"./agent-api-CmhXBBT6.js";import{P as B}from"./personas-CeAQ6niU.js";import{C as ee}from"./chevron-left-CBtdrcDZ.js";import{R as te}from"./rotate-ccw-BpPatpxx.js";import{T as se}from"./trash-2-DbQqCHSH.js";import{C as ne}from"./chevron-right-DRLCoDa8.js";import"./dropdown-menu-DRRO0ftt.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-B0YBjihE.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-hEBbEVm0.js";import{f as V}from"./chat-api-DUobixOH.js";import{f as X,a as Z}from"./agent-api-C-qZrrYO.js";import{P as B}from"./personas-Dkq9JD72.js";import{C as ee}from"./chevron-left-CRkSrIuw.js";import{R as te}from"./rotate-ccw-DVWlxS6M.js";import{T as se}from"./trash-2-dTSieVsH.js";import{C as ne}from"./chevron-right-D6YKa1nw.js";import"./dropdown-menu-D5Vf7U3W.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};
|