turbollm 1.12.2 → 1.12.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/dist/{chunk-H67DVIQT.js → chunk-5IU2DOOW.js} +2 -1
- package/dist/cli.js +180 -31
- package/dist/{distiller-76UGFCA4.js → distiller-3S34HCI6.js} +1 -1
- package/dist/webdist/assets/{AgentEditPage-DC5b8GLz.js → AgentEditPage-CE4lxy1g.js} +1 -1
- package/dist/webdist/assets/{ChatScreen-_trAuOm4.js → ChatScreen-BWZFrPkm.js} +1 -1
- package/dist/webdist/assets/{CodeComposer-N7JTyzpl.js → CodeComposer-53_HhRBK.js} +1 -1
- package/dist/webdist/assets/{CodeHomeScreen-CY7CTv_Q.js → CodeHomeScreen-D1alRzQa.js} +1 -1
- package/dist/webdist/assets/{CodeSessionScreen-tx2s3iWr.js → CodeSessionScreen-p9tPPoVe.js} +2 -2
- package/dist/webdist/assets/{CustomizeScreen-BUiEu5vl.js → CustomizeScreen-CebO4Kif.js} +1 -1
- package/dist/webdist/assets/{DeveloperScreen-JAV1WwIi.js → DeveloperScreen-CI5WYmmt.js} +1 -1
- package/dist/webdist/assets/EnginesScreen-DjzBXrbU.js +8 -0
- package/dist/webdist/assets/ModelDetailDialog-CriVmDMu.js +1 -0
- package/dist/webdist/assets/{ModelLoadMenu-8zL_YHxh.js → ModelLoadMenu-yzCvMZFM.js} +1 -1
- package/dist/webdist/assets/{ModelsScreen-Cse1wZKp.js → ModelsScreen-BLosszVi.js} +1 -1
- package/dist/webdist/assets/{OnboardingScreen-DNUgdieT.js → OnboardingScreen-1Eh4MMsz.js} +1 -1
- package/dist/webdist/assets/{RoutineEditPage-Dkt04QR1.js → RoutineEditPage-BBptNINr.js} +1 -1
- package/dist/webdist/assets/{RoutinesPanel-iULR-iL1.js → RoutinesPanel-DA1e-FlT.js} +1 -1
- package/dist/webdist/assets/{SettingsScreen-CQXDBVEu.js → SettingsScreen-CE211J25.js} +1 -1
- package/dist/webdist/assets/{SidebarResizeHandle-Bx_x_ICv.js → SidebarResizeHandle-BS9E0P8t.js} +2 -2
- package/dist/webdist/assets/{SkillEditPage-BKrXTpY3.js → SkillEditPage-CswptEm0.js} +1 -1
- package/dist/webdist/assets/{TokensScreen-DTazcqcy.js → TokensScreen-DqX7R08T.js} +1 -1
- package/dist/webdist/assets/{ToolApprovalBar-DDgGZOxI.js → ToolApprovalBar-Ctxtcdk_.js} +3 -3
- package/dist/webdist/assets/WorkspaceScreen-82kXmjux.js +1 -0
- package/dist/webdist/assets/{abnfDiagram-N423BO3Z-h22xWhjH.js → abnfDiagram-N423BO3Z-wYX3XzEU.js} +1 -1
- package/dist/webdist/assets/{agent-api-BXUf3UuJ.js → agent-api-CNgD3AG5.js} +1 -1
- package/dist/webdist/assets/alert-dialog-DtFUjjf-.js +1 -0
- package/dist/webdist/assets/{arc-BSvZ7mxZ.js → arc-CAVYLnrV.js} +1 -1
- package/dist/webdist/assets/{architectureDiagram-T3A2C74G-D840pkTs.js → architectureDiagram-T3A2C74G-B-ep8-Wc.js} +1 -1
- package/dist/webdist/assets/{arrow-left-tnJKNvU8.js → arrow-left-BUyjb-eA.js} +1 -1
- package/dist/webdist/assets/{badge-HTozgaNk.js → badge-fTl4lUnO.js} +1 -1
- package/dist/webdist/assets/{blockDiagram-VBNYF7ZC-DlvennNB.js → blockDiagram-VBNYF7ZC-C_yOS3Cn.js} +1 -1
- package/dist/webdist/assets/{bot-BEKBqPcU.js → bot-DjnxX6n5.js} +1 -1
- package/dist/webdist/assets/{c4Diagram-5PPSVZJV-CneJCPhz.js → c4Diagram-5PPSVZJV-yQy5pOFU.js} +1 -1
- package/dist/webdist/assets/channel-CMLjxq8A.js +1 -0
- package/dist/webdist/assets/{chat-api-B_SlDoXA.js → chat-api-Cm7puych.js} +1 -1
- package/dist/webdist/assets/{chat-queries-CxkwlyLc.js → chat-queries-flf3EhI8.js} +1 -1
- package/dist/webdist/assets/{chevron-down-DfzNO8NY.js → chevron-down-BMj_J4Z6.js} +1 -1
- package/dist/webdist/assets/{chevron-left-DHH-nnSd.js → chevron-left-CcApbuPp.js} +1 -1
- package/dist/webdist/assets/{chevron-right-DnT71PVy.js → chevron-right-DcT_N4lU.js} +1 -1
- package/dist/webdist/assets/{chunk-2GRJ4B5K-DfGpb0ih.js → chunk-2GRJ4B5K-DGiFq5-O.js} +1 -1
- package/dist/webdist/assets/{chunk-2Q5K7J3B-CbNbsgTh.js → chunk-2Q5K7J3B-D3EdskXA.js} +1 -1
- package/dist/webdist/assets/{chunk-5RXB4S5H-Bc_97P9Q.js → chunk-5RXB4S5H-BidckIKz.js} +1 -1
- package/dist/webdist/assets/{chunk-5VM5RSS4-Dc1cXgV2.js → chunk-5VM5RSS4-DOxfljEH.js} +1 -1
- package/dist/webdist/assets/{chunk-6Q2QTUOP-CdFOJa-e.js → chunk-6Q2QTUOP-DAYq99TW.js} +1 -1
- package/dist/webdist/assets/{chunk-GF5L2VYU-D3PC0Vtx.js → chunk-GF5L2VYU-CRAn0Eq3.js} +1 -1
- package/dist/webdist/assets/{chunk-JWPE2WC7-BPW77F2i.js → chunk-JWPE2WC7-DHQMj5yT.js} +1 -1
- package/dist/webdist/assets/{chunk-KBJHAD2P-BHXAIZXB.js → chunk-KBJHAD2P-CVzZvxJP.js} +1 -1
- package/dist/webdist/assets/{chunk-RYQCIY6F-CrnPyqjW.js → chunk-RYQCIY6F-BmrJERxa.js} +1 -1
- package/dist/webdist/assets/{chunk-XXDRQBXY-Bv9q4UGg.js → chunk-XXDRQBXY-DEZG0EV3.js} +1 -1
- package/dist/webdist/assets/{circle-check-BgrXRJTZ.js → circle-check-BNjlHnHh.js} +1 -1
- package/dist/webdist/assets/{circle-x-CYZSobXW.js → circle-x-DV1nLTK3.js} +1 -1
- package/dist/webdist/assets/classDiagram-JCYQIIEL-BaxaaW6h.js +1 -0
- package/dist/webdist/assets/classDiagram-v2-OCEON4UE-BaxaaW6h.js +1 -0
- package/dist/webdist/assets/collapsible-DDR_RndG.js +1 -0
- package/dist/webdist/assets/{common-C48Zd9_u.js → common-CaQP3vin.js} +1 -1
- package/dist/webdist/assets/{cose-bilkent-JH36ORCC-B9I1Xo2f.js → cose-bilkent-JH36ORCC-Bq5B3ICk.js} +1 -1
- package/dist/webdist/assets/{cynefin-VYW2F7L2-Djx9Q5Zl.js → cynefin-VYW2F7L2-DZle68dV.js} +1 -1
- package/dist/webdist/assets/{cynefinDiagram-MW4NZA55-egTrJ3T2.js → cynefinDiagram-MW4NZA55-CfM3dACl.js} +1 -1
- package/dist/webdist/assets/{dagre-VZM6K2ZE-ClfYLjT5.js → dagre-VZM6K2ZE-DnxnfNsU.js} +1 -1
- package/dist/webdist/assets/{diagram-7IWD3JNH-C-AaXLmL.js → diagram-7IWD3JNH-j2-QzJMm.js} +1 -1
- package/dist/webdist/assets/{diagram-B4RE2ZJO-5ZsOP19O.js → diagram-B4RE2ZJO-b38UCmx1.js} +1 -1
- package/dist/webdist/assets/{diagram-LBJQPF4R-BAa7bkkY.js → diagram-LBJQPF4R-CdkW-WA-.js} +1 -1
- package/dist/webdist/assets/{diagram-Q27KOJAE-HarfGeNl.js → diagram-Q27KOJAE-B0R9y_o4.js} +1 -1
- package/dist/webdist/assets/{diagram-UB23O5K3-CvSFCTH8.js → diagram-UB23O5K3-ChZYNuxT.js} +1 -1
- package/dist/webdist/assets/{dropdown-menu-BOUsiJco.js → dropdown-menu-CzL84hjo.js} +1 -1
- package/dist/webdist/assets/{ebnfDiagram-BXEA7PRR-CD94llbm.js → ebnfDiagram-BXEA7PRR-Df2n-V3W.js} +1 -1
- package/dist/webdist/assets/{erDiagram-JOGREHBK-iSGYBlqE.js → erDiagram-JOGREHBK-CJwWpaRB.js} +1 -1
- package/dist/webdist/assets/{external-link-c_B7G__W.js → external-link-Bqgcz-GW.js} +1 -1
- package/dist/webdist/assets/{file-text-BMSTQeV2.js → file-text-CAqmQYG6.js} +1 -1
- package/dist/webdist/assets/{flowDiagram-UKHOOZJN-CfRmhZIc.js → flowDiagram-UKHOOZJN-Bd94ldad.js} +1 -1
- package/dist/webdist/assets/{folder-input-BtE_5cPV.js → folder-input-dy5PCMy4.js} +1 -1
- package/dist/webdist/assets/{folder-plus-CFn90Mxi.js → folder-plus-YR4wA8PT.js} +1 -1
- package/dist/webdist/assets/{ganttDiagram-PKOTCBZU-DoQkfMfx.js → ganttDiagram-PKOTCBZU-DYeYOb2A.js} +1 -1
- package/dist/webdist/assets/{git-branch-ojL3vNiD.js → git-branch-BZWrq5B1.js} +1 -1
- package/dist/webdist/assets/{gitGraphDiagram-DS77QQ5N-DsvnFgBc.js → gitGraphDiagram-DS77QQ5N-CvZdup4u.js} +1 -1
- package/dist/webdist/assets/{index-CSavhRGL.js → index-4QuGA7c6.js} +10 -10
- package/dist/webdist/assets/{index-glXD6BQc.js → index-B-lM0jtZ.js} +1 -1
- package/dist/webdist/assets/index-D4C8JIlz.css +1 -0
- package/dist/webdist/assets/{infoDiagram-6WML65LV-mDSA5sHn.js → infoDiagram-6WML65LV-jwAgJ0e9.js} +1 -1
- package/dist/webdist/assets/{ishikawaDiagram-WSZJBQD7-B5Yq0JqB.js → ishikawaDiagram-WSZJBQD7-BEdaiV3h.js} +1 -1
- package/dist/webdist/assets/{journeyDiagram-NVQOT4AX-5jpV1XZE.js → journeyDiagram-NVQOT4AX-CdVLYVhh.js} +1 -1
- package/dist/webdist/assets/{kanban-definition-27J2QSJJ-Cuyvwopj.js → kanban-definition-27J2QSJJ-DT-DsTQr.js} +1 -1
- package/dist/webdist/assets/{linear-DqzYFlqe.js → linear-BrxtevgR.js} +1 -1
- package/dist/webdist/assets/{link-queries-R-5RNwSV.js → link-queries-C3HTfth1.js} +1 -1
- package/dist/webdist/assets/{lock-BMvhGs4r.js → lock-zeDOBniP.js} +1 -1
- package/dist/webdist/assets/{mermaid.core-BSsGYq_y.js → mermaid.core-B9NxJSlE.js} +4 -4
- package/dist/webdist/assets/{mindmap-definition-FAOFIHXS-bGoQuSrf.js → mindmap-definition-FAOFIHXS-BPQfqoP2.js} +1 -1
- package/dist/webdist/assets/{monitor-BgsqLI--.js → monitor-BDzPa5YN.js} +1 -1
- package/dist/webdist/assets/{pegDiagram-VL7TDLO6-BSfifu-4.js → pegDiagram-VL7TDLO6-CR4mTeP-.js} +1 -1
- package/dist/webdist/assets/{pencil-CMc0BVmG.js → pencil-BtEhdGP-.js} +1 -1
- package/dist/webdist/assets/{personas-CKCwxU6o.js → personas-BK5wc_P3.js} +1 -1
- package/dist/webdist/assets/{pieDiagram-7S7Q4E2Y-DFMcMGg7.js → pieDiagram-7S7Q4E2Y-DPD5scZh.js} +1 -1
- package/dist/webdist/assets/{plus-5OMKNJj_.js → plus-D3Tv9cim.js} +1 -1
- package/dist/webdist/assets/{quadrantDiagram-CIZ2JOQS-BRQ2ESFh.js → quadrantDiagram-CIZ2JOQS-DsESOJc6.js} +1 -1
- package/dist/webdist/assets/{radix-B0YBjihE.js → radix-DW4bWMkB.js} +1 -1
- package/dist/webdist/assets/{railroadDiagram-AXF67PYL-DPodM5Aj.js → railroadDiagram-AXF67PYL-U15r6DjT.js} +1 -1
- package/dist/webdist/assets/{refresh-cw-ZKW14GBQ.js → refresh-cw-BemgDv3Q.js} +1 -1
- package/dist/webdist/assets/{remote-failure-nVuOLb4V.js → remote-failure-Ddau3S9z.js} +1 -1
- package/dist/webdist/assets/{requirementDiagram-LRYGKXZP-DWCCxYHs.js → requirementDiagram-LRYGKXZP-DDeRZQ__.js} +1 -1
- package/dist/webdist/assets/{rocket-fYq9X9BT.js → rocket-Uil5x1E9.js} +1 -1
- package/dist/webdist/assets/{rotate-ccw-g_DuozeG.js → rotate-ccw-Bar4GXPb.js} +1 -1
- package/dist/webdist/assets/{sankeyDiagram-W5VNT64P-DrI6xZpj.js → sankeyDiagram-W5VNT64P-BMTSd4xI.js} +1 -1
- package/dist/webdist/assets/{sequenceDiagram-SI44F4Z6-BrlRaYxD.js → sequenceDiagram-SI44F4Z6-DdMCm5jm.js} +1 -1
- package/dist/webdist/assets/{sizeCapture-X5ZJPWSS-BWkHzhyu.js → sizeCapture-X5ZJPWSS-2IYIZrFi.js} +1 -1
- package/dist/webdist/assets/skeleton-MlF2228j.js +1 -0
- package/dist/webdist/assets/{sliders-horizontal-ePjH5qK0.js → sliders-horizontal-DFahpoGu.js} +1 -1
- package/dist/webdist/assets/{sparkles-CshkhEsq.js → sparkles-BYaOifNR.js} +1 -1
- package/dist/webdist/assets/{star-ENKV_riY.js → star-HYST5DWB.js} +1 -1
- package/dist/webdist/assets/{stateDiagram-OKZ733FA-T_6O5IHv.js → stateDiagram-OKZ733FA-DgPdyEyJ.js} +1 -1
- package/dist/webdist/assets/stateDiagram-v2-UEYNNEHI-Bi2zf8yv.js +1 -0
- package/dist/webdist/assets/{swimlanes-SLNWSIFB-Bmme-2xD.js → swimlanes-SLNWSIFB-CxbQXrF7.js} +2 -2
- package/dist/webdist/assets/swimlanesDiagram-ULZ7WXOC-DvkgZzhL.js +8 -0
- package/dist/webdist/assets/{switch-BtGEUEC2.js → switch-VYcKekwB.js} +1 -1
- package/dist/webdist/assets/{terminal-C_QOTYmG.js → terminal-BXEMsYi1.js} +1 -1
- package/dist/webdist/assets/{timeline-definition-Z64GVDOM-B3fBfREF.js → timeline-definition-Z64GVDOM-BN25-Wyy.js} +1 -1
- package/dist/webdist/assets/{trash-2-B__gvkzD.js → trash-2-BNwq5WtQ.js} +1 -1
- package/dist/webdist/assets/{triangle-alert-BbhRFFB2.js → triangle-alert-DTK5P852.js} +1 -1
- package/dist/webdist/assets/useIsDesktop-DAdBFmSY.js +1 -0
- package/dist/webdist/assets/{vennDiagram-T6HMQDX7-DnVI7ph_.js → vennDiagram-T6HMQDX7-Cmn8MOEp.js} +1 -1
- package/dist/webdist/assets/{wardleyDiagram-T6FBY63Y-CY4YnfZL.js → wardleyDiagram-T6FBY63Y-AS3obg9i.js} +1 -1
- package/dist/webdist/assets/{wrench-WKNRyiMt.js → wrench-B5967UE3.js} +1 -1
- package/dist/webdist/assets/{xychartDiagram-ELKLHX3M-DgqvW4os.js → xychartDiagram-ELKLHX3M-puQ_9bb2.js} +1 -1
- package/dist/webdist/index.html +3 -3
- package/package.json +1 -1
- package/dist/webdist/.omc/state/agent-replay-d4811781-2640-44e0-8399-662ec162ff43.jsonl +0 -10
- package/dist/webdist/.omc/state/subagent-tracking.json +0 -7
- package/dist/webdist/assets/EnginesScreen-CL-rA9uX.js +0 -8
- package/dist/webdist/assets/ModelDetailDialog-B_-j8TNF.js +0 -1
- package/dist/webdist/assets/WorkspaceScreen-DpkSZQhK.js +0 -1
- package/dist/webdist/assets/alert-dialog-hkwXUo0d.js +0 -1
- package/dist/webdist/assets/channel-ZaF9JSkw.js +0 -1
- package/dist/webdist/assets/classDiagram-JCYQIIEL-CjrbKhLT.js +0 -1
- package/dist/webdist/assets/classDiagram-v2-OCEON4UE-CjrbKhLT.js +0 -1
- package/dist/webdist/assets/collapsible-BEzntcAR.js +0 -1
- package/dist/webdist/assets/index-B2S9teij.css +0 -1
- package/dist/webdist/assets/skeleton-Bv8b9m3J.js +0 -1
- package/dist/webdist/assets/stateDiagram-v2-UEYNNEHI-97ixhjGa.js +0 -1
- package/dist/webdist/assets/swimlanesDiagram-ULZ7WXOC-BxJRyIBv.js +0 -8
- package/dist/webdist/assets/useIsDesktop-Do2taDTq.js +0 -1
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
engineModelAlias,
|
|
9
9
|
engineRejectsAudioModel,
|
|
10
10
|
evaluateVariant
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-5IU2DOOW.js";
|
|
12
12
|
import {
|
|
13
13
|
requiresShell,
|
|
14
14
|
resolveExecutable
|
|
@@ -708,6 +708,15 @@ import { Readable } from "stream";
|
|
|
708
708
|
import { pipeline } from "stream/promises";
|
|
709
709
|
import { promisify } from "util";
|
|
710
710
|
var execFileP = promisify(execFile);
|
|
711
|
+
function githubHeaders(extra) {
|
|
712
|
+
const base2 = {
|
|
713
|
+
Accept: "application/vnd.github+json",
|
|
714
|
+
"User-Agent": "turbollm"
|
|
715
|
+
};
|
|
716
|
+
const token = process.env.GITHUB_TOKEN?.trim();
|
|
717
|
+
if (token) base2["Authorization"] = `Bearer ${token}`;
|
|
718
|
+
return { ...base2, ...extra };
|
|
719
|
+
}
|
|
711
720
|
function stripMacOsQuarantine(dir) {
|
|
712
721
|
if (process.platform !== "darwin") return;
|
|
713
722
|
try {
|
|
@@ -717,6 +726,7 @@ function stripMacOsQuarantine(dir) {
|
|
|
717
726
|
}
|
|
718
727
|
var LLAMA_BUILD = "b9608";
|
|
719
728
|
var REPO = "ggml-org/llama.cpp";
|
|
729
|
+
var ANDROID_REPO = "mohitsoni48/TurboLLM";
|
|
720
730
|
var CUDA_VER = "13.3";
|
|
721
731
|
var serverBin = process.platform === "win32" ? "llama-server.exe" : "llama-server";
|
|
722
732
|
var plat = () => process.platform;
|
|
@@ -750,7 +760,15 @@ function availableBackends(tag = LLAMA_BUILD) {
|
|
|
750
760
|
return a === "arm64" ? list.filter((b) => b.id === "vulkan" || b.id === "cpu") : list;
|
|
751
761
|
}
|
|
752
762
|
if (plat() === "android") {
|
|
753
|
-
return [
|
|
763
|
+
return [
|
|
764
|
+
{
|
|
765
|
+
id: "cpu",
|
|
766
|
+
label: "CPU",
|
|
767
|
+
assets: [`llama-${tag}-bin-android-${a}.tar.gz`],
|
|
768
|
+
repo: ANDROID_REPO,
|
|
769
|
+
releaseTag: `android-${tag}`
|
|
770
|
+
}
|
|
771
|
+
];
|
|
754
772
|
}
|
|
755
773
|
throw new Error(`unsupported platform: ${plat()}/${process.arch}`);
|
|
756
774
|
}
|
|
@@ -903,7 +921,7 @@ async function provisionBackend(enginesRoot, backend, tag, onProgress, signal) {
|
|
|
903
921
|
const asset = backend.assets[i];
|
|
904
922
|
const part = i + 1;
|
|
905
923
|
const tmp = join2(enginesRoot, asset);
|
|
906
|
-
const url = `https://github.com/${REPO}/releases/download/${tag}/${asset}`;
|
|
924
|
+
const url = `https://github.com/${backend.repo ?? REPO}/releases/download/${backend.releaseTag ?? tag}/${asset}`;
|
|
907
925
|
onProgress?.({ phase: "downloading", pct: 0, part, parts });
|
|
908
926
|
await downloadFile(url, tmp, (p) => onProgress?.({ ...p, part, parts }), signal);
|
|
909
927
|
onProgress?.({ phase: "extracting", pct: -1, part, parts });
|
|
@@ -967,7 +985,7 @@ function pickReleaseAsset(assets, platform = process.platform, archStr = process
|
|
|
967
985
|
async function latestGithubRelease(repo, signal) {
|
|
968
986
|
const apiUrl = `https://api.github.com/repos/${repo}/releases/latest`;
|
|
969
987
|
const res = await fetch(apiUrl, {
|
|
970
|
-
headers:
|
|
988
|
+
headers: githubHeaders(),
|
|
971
989
|
signal
|
|
972
990
|
});
|
|
973
991
|
if (!res.ok) throw new Error(`could not query ${repo} releases: HTTP ${res.status}`);
|
|
@@ -980,7 +998,7 @@ async function latestReleaseTag(repo, signal) {
|
|
|
980
998
|
async function latestCommitSha(repo, branch = "", signal) {
|
|
981
999
|
const ref = branch.trim() ? encodeURIComponent(branch.trim()) : "HEAD";
|
|
982
1000
|
const res = await fetch(`https://api.github.com/repos/${repo}/commits/${ref}`, {
|
|
983
|
-
headers:
|
|
1001
|
+
headers: githubHeaders(),
|
|
984
1002
|
signal
|
|
985
1003
|
});
|
|
986
1004
|
if (!res.ok) throw new Error(`could not query ${repo} commits: HTTP ${res.status}`);
|
|
@@ -990,7 +1008,7 @@ async function latestCommitSha(repo, branch = "", signal) {
|
|
|
990
1008
|
async function turboquantAssetUrl(repo, platform = process.platform, archStr = process.arch, signal) {
|
|
991
1009
|
if (platform === "win32") return null;
|
|
992
1010
|
const res = await fetch(`https://api.github.com/repos/${repo}/releases?per_page=100`, {
|
|
993
|
-
headers:
|
|
1011
|
+
headers: githubHeaders(),
|
|
994
1012
|
signal
|
|
995
1013
|
});
|
|
996
1014
|
if (!res.ok) throw new Error(`could not query ${repo} releases: HTTP ${res.status}`);
|
|
@@ -2528,6 +2546,12 @@ import { randomUUID as randomUUID2 } from "crypto";
|
|
|
2528
2546
|
import { execFile as execFile8 } from "child_process";
|
|
2529
2547
|
import { closeSync, existsSync as existsSync12, openSync, readSync, statSync as statSync2 } from "fs";
|
|
2530
2548
|
import { dirname as dirname3 } from "path";
|
|
2549
|
+
function probeEnv(bin) {
|
|
2550
|
+
if (process.platform === "win32") return void 0;
|
|
2551
|
+
const dir = dirname3(bin);
|
|
2552
|
+
const existing = process.env.LD_LIBRARY_PATH;
|
|
2553
|
+
return { ...process.env, LD_LIBRARY_PATH: existing ? `${dir}:${existing}` : dir };
|
|
2554
|
+
}
|
|
2531
2555
|
var ProbeError = class extends Error {
|
|
2532
2556
|
constructor(code, msg2) {
|
|
2533
2557
|
super(msg2);
|
|
@@ -2548,7 +2572,7 @@ function runCaptured(bin, arg) {
|
|
|
2548
2572
|
return new Promise((resolve6) => {
|
|
2549
2573
|
try {
|
|
2550
2574
|
const timeoutMs = process.platform === "darwin" ? 6e4 : 15e3;
|
|
2551
|
-
execFile8(bin, [arg], { cwd: dirname3(bin), timeout: timeoutMs, windowsHide: true, maxBuffer: 4 * 1024 * 1024 }, (error, stdout, stderr) => {
|
|
2575
|
+
execFile8(bin, [arg], { cwd: dirname3(bin), env: probeEnv(bin), timeout: timeoutMs, windowsHide: true, maxBuffer: 4 * 1024 * 1024 }, (error, stdout, stderr) => {
|
|
2552
2576
|
resolve6({ out: (stdout || "") + (stderr || ""), err: error });
|
|
2553
2577
|
});
|
|
2554
2578
|
} catch (e) {
|
|
@@ -2587,13 +2611,7 @@ async function probe(bin) {
|
|
|
2587
2611
|
const flags = extractFlags(h.out);
|
|
2588
2612
|
const kvTypes = detectKvTypes(h.out, flags.includes("--cache-type-k"));
|
|
2589
2613
|
const flagInfo = flags.map((f2) => classifyFlag(f2, h.out));
|
|
2590
|
-
const
|
|
2591
|
-
for (const m2 of h.out.matchAll(ENUM_RE)) {
|
|
2592
|
-
for (const v2 of m2[1].replace(/[[\]]/g, "").split(/[,|]/)) {
|
|
2593
|
-
const t = v2.trim();
|
|
2594
|
-
if (t) flags.push(`spec-type:${t}`);
|
|
2595
|
-
}
|
|
2596
|
-
}
|
|
2614
|
+
for (const t of extractSpecTypeValues(h.out)) flags.push(`spec-type:${t}`);
|
|
2597
2615
|
return { version: version2, capabilities: { kvTypes, flags: [...new Set(flags)].sort(), flagInfo } };
|
|
2598
2616
|
}
|
|
2599
2617
|
function detectFormat(bin) {
|
|
@@ -2636,6 +2654,24 @@ function detectKvTypes(helpText, hasCacheTypeFlag) {
|
|
|
2636
2654
|
}
|
|
2637
2655
|
return kvTypes;
|
|
2638
2656
|
}
|
|
2657
|
+
function extractSpecTypeValues(helpText) {
|
|
2658
|
+
const values = /* @__PURE__ */ new Set();
|
|
2659
|
+
const ENUM_RE = /--spec-type\s+(\[[^\]\n]+\]|[a-z][a-z0-9_-]*(?:[,|][a-z0-9_-]+)+)/gi;
|
|
2660
|
+
for (const m of helpText.matchAll(ENUM_RE)) {
|
|
2661
|
+
for (const v of m[1].replace(/[[\]]/g, "").split(/[,|]/)) {
|
|
2662
|
+
const t = v.trim();
|
|
2663
|
+
if (t) values.add(t);
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
const TYPES_LINE_RE = /--spec-type\b[\s\S]{0,400}?\r?\n[ \t]*types:\s*([a-z0-9_][a-z0-9_, -]*)/gi;
|
|
2667
|
+
for (const m of helpText.matchAll(TYPES_LINE_RE)) {
|
|
2668
|
+
for (const v of m[1].split(",")) {
|
|
2669
|
+
const t = v.trim();
|
|
2670
|
+
if (t) values.add(t);
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
return [...values];
|
|
2674
|
+
}
|
|
2639
2675
|
function parseEnumList(blockText) {
|
|
2640
2676
|
let raw = /allowed values:\s*([\s\S]+)/i.exec(blockText)?.[1] ?? /(?:^|[ \t])\[([^\]\n]+)\]/.exec(blockText)?.[1];
|
|
2641
2677
|
if (!raw) {
|
|
@@ -2868,10 +2904,14 @@ async function checkGcc(env) {
|
|
|
2868
2904
|
}
|
|
2869
2905
|
async function checkBuildPrereqs(toolchainDirs = []) {
|
|
2870
2906
|
const platform = process.platform;
|
|
2871
|
-
if (platform !== "win32" && platform !== "linux" && platform !== "darwin") {
|
|
2907
|
+
if (platform !== "win32" && platform !== "linux" && platform !== "darwin" && platform !== "android") {
|
|
2872
2908
|
return { supported: false, os: "other", tools: [], packageManager: null };
|
|
2873
2909
|
}
|
|
2874
2910
|
const env = buildEnv(toolchainDirs);
|
|
2911
|
+
if (platform === "android") {
|
|
2912
|
+
const tools2 = await Promise.all([checkGit(env), checkCmake(env), checkGcc(env)]);
|
|
2913
|
+
return { supported: true, os: "android", tools: tools2, packageManager: null };
|
|
2914
|
+
}
|
|
2875
2915
|
const [tools, packageManager] = await Promise.all([
|
|
2876
2916
|
platform === "darwin" ? Promise.all([checkGit(env), checkCmake(env), checkGcc(env)]) : platform === "win32" ? Promise.all([checkGit(env), checkCmake(env), checkCuda(env), checkMsvc(env)]) : Promise.all([checkGit(env), checkCmake(env), checkCuda(env), checkGcc(env)]),
|
|
2877
2917
|
detectPackageManager(env)
|
|
@@ -2895,6 +2935,7 @@ function withInstallCommands(tools, pm) {
|
|
|
2895
2935
|
var CMAKE_CONFIGURE_ARGS = ["-DGGML_CUDA=ON", "-DCMAKE_BUILD_TYPE=Release", "-DCMAKE_CUDA_FLAGS=-allow-unsupported-compiler"];
|
|
2896
2936
|
var CMAKE_CONFIGURE_ARGS_MACOS = ["-DGGML_METAL=ON", "-DCMAKE_BUILD_TYPE=Release"];
|
|
2897
2937
|
var CMAKE_CONFIGURE_ARGS_MACOS_CPU = ["-DGGML_METAL=OFF", "-DCMAKE_BUILD_TYPE=Release"];
|
|
2938
|
+
var CMAKE_CONFIGURE_ARGS_ANDROID = ["-DCMAKE_BUILD_TYPE=Release"];
|
|
2898
2939
|
var CUDA_RUNTIME_DLL_PREFIXES = ["cudart64_", "cublas64_", "cublaslt64_", "nvrtc64_", "nvrtc-builtins64_", "nvjitlink_"];
|
|
2899
2940
|
var CUDA_RUNTIME_SO_PREFIXES = ["libcudart.so", "libcublas.so", "libcublasLt.so", "libnvrtc.so", "libnvrtc-builtins.so", "libnvJitLink.so"];
|
|
2900
2941
|
|
|
@@ -3297,10 +3338,11 @@ async function runPrereqInstall(req, hooks, signal) {
|
|
|
3297
3338
|
async function runBuild(req, hooks, signal) {
|
|
3298
3339
|
const isWindows = process.platform === "win32";
|
|
3299
3340
|
const isMac = process.platform === "darwin";
|
|
3341
|
+
const isAndroid = process.platform === "android";
|
|
3300
3342
|
const env = { ...buildEnv(req.toolchainDirs), GIT_TERMINAL_PROMPT: "0", GCM_INTERACTIVE: "never" };
|
|
3301
3343
|
hooks.phase("preparing");
|
|
3302
3344
|
const prereqs = await checkBuildPrereqs(req.toolchainDirs);
|
|
3303
|
-
if (!prereqs.supported) throw new Error("In-app build is currently Windows, Linux, or
|
|
3345
|
+
if (!prereqs.supported) throw new Error("In-app build is currently Windows, Linux, macOS, or Android (Termux) only.");
|
|
3304
3346
|
const missing = prereqs.tools.filter((t) => (t.id === "git" || t.id === "cmake" || t.id === "cuda") && !t.found);
|
|
3305
3347
|
if (missing.length > 0) {
|
|
3306
3348
|
const names = missing.map((t) => t.name).join(", ");
|
|
@@ -3318,7 +3360,7 @@ async function runBuild(req, hooks, signal) {
|
|
|
3318
3360
|
}
|
|
3319
3361
|
} else if (!prereqs.tools.some((t) => t.id === "gcc" && t.found)) {
|
|
3320
3362
|
throw new Error(
|
|
3321
|
-
isMac ? "Could not find a C++ compiler. Install the Xcode Command Line Tools (`xcode-select --install`) and retry." : "Could not find a C++ compiler. Install one (e.g. `sudo apt install build-essential` on Debian/Ubuntu) and retry."
|
|
3363
|
+
isMac ? "Could not find a C++ compiler. Install the Xcode Command Line Tools (`xcode-select --install`) and retry." : isAndroid ? "Could not find a C++ compiler. Run `pkg install clang` in Termux and retry." : "Could not find a C++ compiler. Install one (e.g. `sudo apt install build-essential` on Debian/Ubuntu) and retry."
|
|
3322
3364
|
);
|
|
3323
3365
|
}
|
|
3324
3366
|
const buildRoot = join13(req.enginesRoot, "build", buildDirName(req.repoUrl, req.branch, req.commit));
|
|
@@ -3391,7 +3433,7 @@ async function runBuild(req, hooks, signal) {
|
|
|
3391
3433
|
await runStep("cmake", configureArgs, { cwd: buildRoot, env, signal, onLine: captureLog });
|
|
3392
3434
|
}
|
|
3393
3435
|
hooks.phase("compiling");
|
|
3394
|
-
const compileArgs = ["--build", buildSubdir, "-j", "--target", "llama-server"];
|
|
3436
|
+
const compileArgs = ["--build", buildSubdir, "-j", ...isAndroid ? ["2"] : [], "--target", "llama-server"];
|
|
3395
3437
|
if (isWindows) {
|
|
3396
3438
|
const compileBat = join13(buildRoot, "_tllm_build.bat");
|
|
3397
3439
|
writeFileSync4(compileBat, vcvarsBatch(vcvars, compileArgs));
|
|
@@ -3410,7 +3452,8 @@ async function runBuild(req, hooks, signal) {
|
|
|
3410
3452
|
}
|
|
3411
3453
|
const buildLog = [];
|
|
3412
3454
|
try {
|
|
3413
|
-
|
|
3455
|
+
const configureArgs = isMac ? CMAKE_CONFIGURE_ARGS_MACOS : isAndroid ? CMAKE_CONFIGURE_ARGS_ANDROID : linuxCudaArgs;
|
|
3456
|
+
await configureAndCompile(configureArgs, buildLog);
|
|
3414
3457
|
} catch (e) {
|
|
3415
3458
|
if (!isMac || !isIncompleteMetalBackendError(buildLog)) throw e;
|
|
3416
3459
|
hooks.log(
|
|
@@ -3426,7 +3469,7 @@ async function runBuild(req, hooks, signal) {
|
|
|
3426
3469
|
throw new Error("Build finished but no llama-server binary was found in the output \u2014 see the log above.");
|
|
3427
3470
|
}
|
|
3428
3471
|
if (isWindows) copyCudaRuntimeDlls(env, dirname5(binPath), hooks.log);
|
|
3429
|
-
else if (!isMac) copyCudaRuntimeLibs(env, dirname5(binPath), hooks.log);
|
|
3472
|
+
else if (!isMac && !isAndroid) copyCudaRuntimeLibs(env, dirname5(binPath), hooks.log);
|
|
3430
3473
|
return { binPath, commit, buildRoot };
|
|
3431
3474
|
}
|
|
3432
3475
|
|
|
@@ -9488,8 +9531,8 @@ function profileToArgs(p, m, caps, cores = 0, sys, binPath) {
|
|
|
9488
9531
|
a.push("--mtp-head", p.mtpHeadPath);
|
|
9489
9532
|
specActive = true;
|
|
9490
9533
|
} else if (p.speculative === "nextn" && specType) {
|
|
9491
|
-
const nextnVal = ["nextn", "draft-mtp"].find((v) => specAccepts(v));
|
|
9492
|
-
if (nextnVal === "draft-mtp") {
|
|
9534
|
+
const nextnVal = ["nextn", "draft-mtp", "mtp"].find((v) => specAccepts(v));
|
|
9535
|
+
if (nextnVal === "draft-mtp" || nextnVal === "mtp") {
|
|
9493
9536
|
a.push("--spec-type", nextnVal);
|
|
9494
9537
|
specActive = true;
|
|
9495
9538
|
} else if (nextnVal === "nextn" && has("--model-draft")) {
|
|
@@ -9500,10 +9543,14 @@ function profileToArgs(p, m, caps, cores = 0, sys, binPath) {
|
|
|
9500
9543
|
if (specType) a.push("--spec-type", "draft");
|
|
9501
9544
|
a.push("--model-draft", p.draftModelPath);
|
|
9502
9545
|
specActive = true;
|
|
9503
|
-
} else if (p.speculative === "dflash" && p.draftModelPath && specType
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
|
|
9546
|
+
} else if (p.speculative === "dflash" && p.draftModelPath && specType) {
|
|
9547
|
+
const dflashVal = ["draft-dflash", "dflash"].find((v) => specAccepts(v));
|
|
9548
|
+
const draftFlag = has("--spec-draft-model") ? "--spec-draft-model" : has("--model-draft") ? "--model-draft" : null;
|
|
9549
|
+
if (dflashVal && draftFlag) {
|
|
9550
|
+
a.push("--spec-type", dflashVal);
|
|
9551
|
+
a.push(draftFlag, p.draftModelPath);
|
|
9552
|
+
specActive = true;
|
|
9553
|
+
}
|
|
9507
9554
|
}
|
|
9508
9555
|
if (specActive) {
|
|
9509
9556
|
if (has("--draft-max")) a.push("--draft-max", String(p.draftMax ?? 16));
|
|
@@ -22787,7 +22834,11 @@ var ALL = [
|
|
|
22787
22834
|
provision: "github-release",
|
|
22788
22835
|
homepage: "https://github.com/ggml-org/llama.cpp",
|
|
22789
22836
|
repo: "ggml-org/llama.cpp",
|
|
22790
|
-
|
|
22837
|
+
// 'android' included: upstream has no Android prebuilt (Bionic vs. glibc), so on Android
|
|
22838
|
+
// this flows through the same LlamaCppBackendRows UI but availableBackends() (download.ts)
|
|
22839
|
+
// resolves the archive from TurboLLM's OWN cross-compiled releases instead of upstream's —
|
|
22840
|
+
// see ANDROID_REPO there. GitHub #52 item 6 / ADR-390/391.
|
|
22841
|
+
platforms: ["win32", "darwin", "linux", "android"],
|
|
22791
22842
|
support: "stable",
|
|
22792
22843
|
// llama.cpp expands into the backend sub-picker (existing UI); it has no single
|
|
22793
22844
|
// install endpoint of its own.
|
|
@@ -22826,6 +22877,68 @@ var ALL = [
|
|
|
22826
22877
|
}
|
|
22827
22878
|
]
|
|
22828
22879
|
},
|
|
22880
|
+
{
|
|
22881
|
+
// GitHub #52 item 6, "Android out-of-box support". Fallback / advanced path, now that the
|
|
22882
|
+
// main llama.cpp entry above carries a real Android prebuilt (TurboLLM's own NDK cross-
|
|
22883
|
+
// compile, ADR-391): this stays useful for an ABI CI doesn't publish (e.g. armeabi-v7a), a
|
|
22884
|
+
// llama.cpp commit newer than the last CI build, or Termux itself being unavailable/broken
|
|
22885
|
+
// for the hosted download. Building from source inside Termux with Termux's own clang
|
|
22886
|
+
// produces a Bionic-native binary directly, the same "no prebuilt → build it" treatment
|
|
22887
|
+
// ik_llama.cpp already gets below. Termux reports process.platform === 'android' (not
|
|
22888
|
+
// 'linux') — see sysinfo.ts and build-prereqs.ts for the other places that matters.
|
|
22889
|
+
id: "llama.cpp-android-source",
|
|
22890
|
+
name: "llama.cpp (Android / Termux, build from source)",
|
|
22891
|
+
kind: "llama-server",
|
|
22892
|
+
description: "Official llama.cpp, CPU-only, built from source inside Termux \u2014 the advanced/fallback path when the prebuilt above (llama.cpp entry) doesn't fit your device.",
|
|
22893
|
+
provision: "github-release",
|
|
22894
|
+
homepage: "https://github.com/ggml-org/llama.cpp",
|
|
22895
|
+
repo: "ggml-org/llama.cpp",
|
|
22896
|
+
platforms: ["android"],
|
|
22897
|
+
support: "experimental",
|
|
22898
|
+
installEndpoint: "",
|
|
22899
|
+
note: "Run inside Termux (not the Android app store \u2014 get Termux from F-Droid or its GitHub releases). First install the toolchain: `pkg install git cmake clang`. Then use the guided build below. Real-device verified: toolchain install + partial compile confirmed live on a real Android 14 (4KB-page) emulator; a full clean build was not timed to completion in that session (GitHub #52 item 6).",
|
|
22900
|
+
variants: [
|
|
22901
|
+
{
|
|
22902
|
+
id: "llama.cpp-android-source-cpu",
|
|
22903
|
+
label: "CPU \u2014 build from source",
|
|
22904
|
+
repo: "ggml-org/llama.cpp",
|
|
22905
|
+
requires: { platform: ["android"] },
|
|
22906
|
+
stability: "experimental",
|
|
22907
|
+
speed: "baseline",
|
|
22908
|
+
hasPrebuilt: false
|
|
22909
|
+
}
|
|
22910
|
+
]
|
|
22911
|
+
},
|
|
22912
|
+
{
|
|
22913
|
+
// General-purpose build-from-source entry for official llama.cpp — cross-platform,
|
|
22914
|
+
// branch-aware. Unlike llama.cpp-cuda-linux (Linux-only CUDA) and llama.cpp-android-source
|
|
22915
|
+
// (Termux-only CPU), this works on every desktop OS and lets the user pick any branch.
|
|
22916
|
+
// Each branch builds into its own directory and registers as a separate engine
|
|
22917
|
+
// (e.g. Llama-main, Llama-my-feature). The main llama.cpp entry above handles the
|
|
22918
|
+
// prebuilt download path; this is the source-build complement.
|
|
22919
|
+
id: "llama.cpp-source",
|
|
22920
|
+
name: "llama.cpp (Build from Source)",
|
|
22921
|
+
kind: "llama-server",
|
|
22922
|
+
description: "Official llama.cpp, compiled from source on your machine. Pick any branch \u2014 each becomes its own engine.",
|
|
22923
|
+
provision: "github-release",
|
|
22924
|
+
homepage: "https://github.com/ggml-org/llama.cpp",
|
|
22925
|
+
repo: "ggml-org/llama.cpp",
|
|
22926
|
+
platforms: ["win32", "darwin", "linux"],
|
|
22927
|
+
support: "experimental",
|
|
22928
|
+
installEndpoint: "",
|
|
22929
|
+
note: "No prebuilt binary. Select a branch below and TurboLLM clones + compiles it for you. Each branch you build becomes a separate engine (e.g. Llama-main, Llama-my-feature).",
|
|
22930
|
+
variants: [
|
|
22931
|
+
{
|
|
22932
|
+
id: "llama.cpp-source-branch",
|
|
22933
|
+
label: "Build from source",
|
|
22934
|
+
repo: "ggml-org/llama.cpp",
|
|
22935
|
+
requires: {},
|
|
22936
|
+
stability: "experimental",
|
|
22937
|
+
speed: "baseline",
|
|
22938
|
+
hasPrebuilt: false
|
|
22939
|
+
}
|
|
22940
|
+
]
|
|
22941
|
+
},
|
|
22829
22942
|
{
|
|
22830
22943
|
id: "vllm",
|
|
22831
22944
|
name: "vLLM",
|
|
@@ -22956,7 +23069,7 @@ var ALL = [
|
|
|
22956
23069
|
id: "ik_llama.cpp",
|
|
22957
23070
|
name: "ik_llama.cpp",
|
|
22958
23071
|
kind: "llama-server",
|
|
22959
|
-
description: "A llama.cpp fork (ikawrakow) with CPU/GPU performance work
|
|
23072
|
+
description: "A llama.cpp fork (ikawrakow) with CPU/GPU performance work, extra quant types, and adaptive DFlash speculative decoding. Ships llama-server but publishes no prebuilt binaries \u2014 build it, then add your own engine.",
|
|
22960
23073
|
provision: "github-release",
|
|
22961
23074
|
homepage: "https://github.com/ikawrakow/ik_llama.cpp",
|
|
22962
23075
|
repo: "ikawrakow/ik_llama.cpp",
|
|
@@ -24773,6 +24886,7 @@ function registerApi(app2, d) {
|
|
|
24773
24886
|
app2.get("/api/v1/engines/catalog", (c) => {
|
|
24774
24887
|
const regEngines = d.registry.list().engines;
|
|
24775
24888
|
const enginesRoot = join34(d.store.dir(), "engines");
|
|
24889
|
+
const branchParam = (c.req.query("branch") ?? "").trim() || void 0;
|
|
24776
24890
|
const items = catalogForPlatform().map((e) => {
|
|
24777
24891
|
let installed2;
|
|
24778
24892
|
let enabled;
|
|
@@ -24796,11 +24910,13 @@ function registerApi(app2, d) {
|
|
|
24796
24910
|
installed2 = existsSync26(llamafileBinPath(enginesRoot));
|
|
24797
24911
|
enabled = regEngines.some((x) => x.kind === "llamafile");
|
|
24798
24912
|
}
|
|
24913
|
+
const isBranchCapable = !e.sourceCommit && !e.patchUrl;
|
|
24914
|
+
const matchBranch = isBranchCapable ? branchParam ?? "" : void 0;
|
|
24799
24915
|
const srcEng = e.excludeFromSourceMatch ? void 0 : regEngines.find(
|
|
24800
|
-
(x) => sameRepo(x.sourceRepo, e.homepage) && (x.sourceCommit ?? "") === (e.sourceCommit ?? "") && (x.sourcePatchUrl ?? "") === (e.patchUrl ?? "")
|
|
24916
|
+
(x) => sameRepo(x.sourceRepo, e.homepage) && (x.sourceCommit ?? "") === (e.sourceCommit ?? "") && (x.sourcePatchUrl ?? "") === (e.patchUrl ?? "") && (x.sourceBranch ?? "") === (matchBranch ?? "")
|
|
24801
24917
|
);
|
|
24802
24918
|
let sourceBinPath = srcEng?.binPath;
|
|
24803
|
-
if (!srcEng && !e.excludeFromSourceMatch) sourceBinPath = sourceBuildBinary(enginesRoot, e.homepage,
|
|
24919
|
+
if (!srcEng && !e.excludeFromSourceMatch) sourceBinPath = sourceBuildBinary(enginesRoot, e.homepage, matchBranch, e.sourceCommit) ?? void 0;
|
|
24804
24920
|
const sourceBuilt = !!srcEng || !!sourceBinPath;
|
|
24805
24921
|
if (srcEng) {
|
|
24806
24922
|
installed2 = true;
|
|
@@ -24830,6 +24946,39 @@ function registerApi(app2, d) {
|
|
|
24830
24946
|
"/api/v1/build/prereqs",
|
|
24831
24947
|
async (c) => c.json(await checkBuildPrereqs(d.store.snapshot().build.toolchainDirs))
|
|
24832
24948
|
);
|
|
24949
|
+
app2.get("/api/v1/build/git-branches", async (c) => {
|
|
24950
|
+
const raw = (c.req.query("repo") ?? "").trim();
|
|
24951
|
+
if (!raw) return err5(c, 400, "invalid_input", "repo is required.");
|
|
24952
|
+
const repo = normRepoUrl(raw);
|
|
24953
|
+
if (!repo) return err5(c, 400, "invalid_input", "repo must be a valid GitHub repo identifier.");
|
|
24954
|
+
const limit = Math.min(parseInt(c.req.query("limit") ?? "50", 10) || 50, 100);
|
|
24955
|
+
const offset = Math.max(parseInt(c.req.query("offset") ?? "0", 10) || 0, 0);
|
|
24956
|
+
try {
|
|
24957
|
+
const res = await fetch(`https://api.github.com/repos/${repo}/branches?per_page=100`, {
|
|
24958
|
+
headers: githubHeaders()
|
|
24959
|
+
});
|
|
24960
|
+
if (!res.ok) throw new Error(`GitHub API returned HTTP ${res.status}`);
|
|
24961
|
+
const data = await res.json();
|
|
24962
|
+
let defaultBranch = "";
|
|
24963
|
+
try {
|
|
24964
|
+
const info = await fetch(`https://api.github.com/repos/${repo}`, {
|
|
24965
|
+
headers: githubHeaders()
|
|
24966
|
+
});
|
|
24967
|
+
if (info.ok) {
|
|
24968
|
+
const j = await info.json();
|
|
24969
|
+
defaultBranch = j.default_branch ?? "";
|
|
24970
|
+
}
|
|
24971
|
+
} catch {
|
|
24972
|
+
}
|
|
24973
|
+
const names = data.map((b) => b.name);
|
|
24974
|
+
const sorted = defaultBranch ? [defaultBranch, ...names.filter((n) => n !== defaultBranch)] : names;
|
|
24975
|
+
const total = names.length;
|
|
24976
|
+
const page = sorted.slice(offset, offset + limit);
|
|
24977
|
+
return c.json({ total, branches: page });
|
|
24978
|
+
} catch (e) {
|
|
24979
|
+
return err5(c, 503, "offline", `Could not fetch branches for ${repo}: ${e instanceof Error ? e.message : String(e)}`);
|
|
24980
|
+
}
|
|
24981
|
+
});
|
|
24833
24982
|
app2.post("/api/v1/build/run", async (c) => {
|
|
24834
24983
|
if (!isLocalOrAuthenticated(c, d))
|
|
24835
24984
|
return err5(c, 403, "forbidden", "Building an engine requires a valid API key from a non-host device.");
|
|
@@ -27738,7 +27887,7 @@ function registerAgentRoutes(app2, d) {
|
|
|
27738
27887
|
return;
|
|
27739
27888
|
}
|
|
27740
27889
|
if (taskId) d.agentTasks?.step(taskId, "No skill files found \u2014 distilling from the folder\u2026");
|
|
27741
|
-
const { distillSkillsFromFolder } = await import("./distiller-
|
|
27890
|
+
const { distillSkillsFromFolder } = await import("./distiller-3S34HCI6.js");
|
|
27742
27891
|
const distilled = await distillSkillsFromFolder(d, folder, {
|
|
27743
27892
|
max: Math.max(0, SKILL_CAP - store2.userSkills().length),
|
|
27744
27893
|
onProgress: (done, total, file) => {
|
|
@@ -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-CSavhRGL.js";import{f as V}from"./chat-api-B_SlDoXA.js";import{f as X,a as Z}from"./agent-api-BXUf3UuJ.js";import{P as B}from"./personas-CKCwxU6o.js";import{C as ee}from"./chevron-left-DHH-nnSd.js";import{R as te}from"./rotate-ccw-g_DuozeG.js";import{T as se}from"./trash-2-B__gvkzD.js";import{C as ne}from"./chevron-right-DnT71PVy.js";import"./dropdown-menu-BOUsiJco.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-DW4bWMkB.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-4QuGA7c6.js";import{f as V}from"./chat-api-Cm7puych.js";import{f as X,a as Z}from"./agent-api-CNgD3AG5.js";import{P as B}from"./personas-BK5wc_P3.js";import{C as ee}from"./chevron-left-CcApbuPp.js";import{R as te}from"./rotate-ccw-Bar4GXPb.js";import{T as se}from"./trash-2-BNwq5WtQ.js";import{C as ne}from"./chevron-right-DcT_N4lU.js";import"./dropdown-menu-CzL84hjo.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};
|