turbollm 1.12.0 → 1.12.1

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.
Files changed (129) hide show
  1. package/dist/cli.js +36 -39
  2. package/dist/webdist/.omc/state/agent-replay-d4811781-2640-44e0-8399-662ec162ff43.jsonl +10 -0
  3. package/dist/webdist/.omc/state/subagent-tracking.json +7 -0
  4. package/dist/webdist/assets/{AgentEditPage-Cl9VgfYt.js → AgentEditPage-B9mKK6Ob.js} +1 -1
  5. package/dist/webdist/assets/{ChatScreen-D0JIgp7C.js → ChatScreen-DLD1CDS1.js} +1 -1
  6. package/dist/webdist/assets/{CodeComposer-Cqtowy4i.js → CodeComposer-DHE_iTkC.js} +1 -1
  7. package/dist/webdist/assets/{CodeHomeScreen-fGeu4-IS.js → CodeHomeScreen-6CKrrrZ5.js} +1 -1
  8. package/dist/webdist/assets/{CodeSessionScreen-CqBDC3e4.js → CodeSessionScreen-JUpzeYHF.js} +1 -1
  9. package/dist/webdist/assets/{CustomizeScreen-BTzZdj7z.js → CustomizeScreen-C7f4ZRSa.js} +1 -1
  10. package/dist/webdist/assets/{DeveloperScreen-D40_GOxu.js → DeveloperScreen-n6gJC3-E.js} +1 -1
  11. package/dist/webdist/assets/{EnginesScreen-CPKMB1MS.js → EnginesScreen-BWRix4d7.js} +1 -1
  12. package/dist/webdist/assets/ModelDetailDialog-BdPGMTTz.js +1 -0
  13. package/dist/webdist/assets/{ModelLoadMenu-BgkEIVli.js → ModelLoadMenu-D3zo79dw.js} +1 -1
  14. package/dist/webdist/assets/ModelsScreen-7AJUC2wa.js +2 -0
  15. package/dist/webdist/assets/{OnboardingScreen-BVyp58am.js → OnboardingScreen-CGbbx6bS.js} +1 -1
  16. package/dist/webdist/assets/{RoutineEditPage-BtL6uHNS.js → RoutineEditPage-Dd_snYdQ.js} +1 -1
  17. package/dist/webdist/assets/{RoutinesPanel-Bb0LP98-.js → RoutinesPanel-5M00XOUM.js} +1 -1
  18. package/dist/webdist/assets/{SettingsScreen-Dsz1JZPU.js → SettingsScreen-B489HDiC.js} +1 -1
  19. package/dist/webdist/assets/{SidebarResizeHandle-B9IvMWnc.js → SidebarResizeHandle-B0wgsZJ6.js} +1 -1
  20. package/dist/webdist/assets/{SkillEditPage-zPuoTSEK.js → SkillEditPage-CVYFfzLc.js} +1 -1
  21. package/dist/webdist/assets/{TokensScreen-DGfd8Z_h.js → TokensScreen-CQ4m20pP.js} +1 -1
  22. package/dist/webdist/assets/{ToolApprovalBar-CjF6OSEN.js → ToolApprovalBar-B2nX56dI.js} +3 -3
  23. package/dist/webdist/assets/WorkspaceScreen-RLGQrw5_.js +1 -0
  24. package/dist/webdist/assets/{abnfDiagram-N423BO3Z-BHtFnGEG.js → abnfDiagram-N423BO3Z-DoOYvhD1.js} +1 -1
  25. package/dist/webdist/assets/{agent-api-C-qZrrYO.js → agent-api-BAMDY8-v.js} +1 -1
  26. package/dist/webdist/assets/{alert-dialog-CjxDGiZR.js → alert-dialog-rMeq-XIF.js} +1 -1
  27. package/dist/webdist/assets/{arc-CxTBdZ4R.js → arc-BmVPVvg0.js} +1 -1
  28. package/dist/webdist/assets/{architectureDiagram-T3A2C74G-7PcBBjT5.js → architectureDiagram-T3A2C74G-Bh4HLM3j.js} +1 -1
  29. package/dist/webdist/assets/{arrow-left-B6hlnKUy.js → arrow-left-Bawx_G0m.js} +1 -1
  30. package/dist/webdist/assets/{badge-DUS8w956.js → badge-BK8Xn6K3.js} +1 -1
  31. package/dist/webdist/assets/{blockDiagram-VBNYF7ZC-yJQM294Z.js → blockDiagram-VBNYF7ZC-D4dEMw56.js} +1 -1
  32. package/dist/webdist/assets/{bot-92SGv3lK.js → bot-DmBk_i45.js} +1 -1
  33. package/dist/webdist/assets/{c4Diagram-5PPSVZJV-DGo_IrnA.js → c4Diagram-5PPSVZJV-cnPwu_pX.js} +1 -1
  34. package/dist/webdist/assets/channel-BoFujHnv.js +1 -0
  35. package/dist/webdist/assets/{chat-api-DUobixOH.js → chat-api-Bgrb0rnf.js} +1 -1
  36. package/dist/webdist/assets/{chat-queries-DIGUy3mB.js → chat-queries-zz2ch8OT.js} +1 -1
  37. package/dist/webdist/assets/{chevron-down-Cg4gkXkY.js → chevron-down-CNDC69O9.js} +1 -1
  38. package/dist/webdist/assets/{chevron-left-CRkSrIuw.js → chevron-left-CxvUI3ck.js} +1 -1
  39. package/dist/webdist/assets/{chevron-right-D6YKa1nw.js → chevron-right-CpdnK5S2.js} +1 -1
  40. package/dist/webdist/assets/{chunk-2GRJ4B5K-4BRNCKh4.js → chunk-2GRJ4B5K-CtDLA9D7.js} +1 -1
  41. package/dist/webdist/assets/{chunk-2Q5K7J3B-VVErlkzz.js → chunk-2Q5K7J3B-CclvIDBO.js} +1 -1
  42. package/dist/webdist/assets/{chunk-5RXB4S5H-BdrEcHfH.js → chunk-5RXB4S5H-DFYQzU9L.js} +1 -1
  43. package/dist/webdist/assets/{chunk-5VM5RSS4-B7ZoD7jT.js → chunk-5VM5RSS4-CGpXaRvE.js} +1 -1
  44. package/dist/webdist/assets/{chunk-6Q2QTUOP-CZboDQFa.js → chunk-6Q2QTUOP-CI7s7JEA.js} +1 -1
  45. package/dist/webdist/assets/{chunk-GF5L2VYU-Bxfejn_T.js → chunk-GF5L2VYU-y-SeWQKo.js} +1 -1
  46. package/dist/webdist/assets/{chunk-JWPE2WC7-CR53ctin.js → chunk-JWPE2WC7-BvVsBdrN.js} +1 -1
  47. package/dist/webdist/assets/{chunk-KBJHAD2P-CI9fYV8V.js → chunk-KBJHAD2P-CUc-YWns.js} +1 -1
  48. package/dist/webdist/assets/{chunk-RYQCIY6F-CEka5LWj.js → chunk-RYQCIY6F-CABY0N-y.js} +1 -1
  49. package/dist/webdist/assets/{chunk-XXDRQBXY-B6ToGKiT.js → chunk-XXDRQBXY-ChEtYkzy.js} +1 -1
  50. package/dist/webdist/assets/{circle-check-NUkbKKsX.js → circle-check-D-vn9nY2.js} +1 -1
  51. package/dist/webdist/assets/{circle-x-BI2C2Gpz.js → circle-x-BcnmRVTe.js} +1 -1
  52. package/dist/webdist/assets/classDiagram-JCYQIIEL-CWuM4mUX.js +1 -0
  53. package/dist/webdist/assets/classDiagram-v2-OCEON4UE-CWuM4mUX.js +1 -0
  54. package/dist/webdist/assets/{common-BDUb2Jp_.js → common-xWkNwbHY.js} +1 -1
  55. package/dist/webdist/assets/{cose-bilkent-JH36ORCC-n-mMCinT.js → cose-bilkent-JH36ORCC-CJpKH0B3.js} +1 -1
  56. package/dist/webdist/assets/{cynefin-VYW2F7L2--M6hM_u0.js → cynefin-VYW2F7L2-B97tFXrq.js} +1 -1
  57. package/dist/webdist/assets/{cynefinDiagram-MW4NZA55-C1WV5_wf.js → cynefinDiagram-MW4NZA55-CTmmk7Xt.js} +1 -1
  58. package/dist/webdist/assets/{dagre-VZM6K2ZE-BrvE8li2.js → dagre-VZM6K2ZE-BMkcnGJJ.js} +1 -1
  59. package/dist/webdist/assets/{diagram-7IWD3JNH-BAtvwqyn.js → diagram-7IWD3JNH-DxA708mT.js} +1 -1
  60. package/dist/webdist/assets/{diagram-B4RE2ZJO-DIvlrS5g.js → diagram-B4RE2ZJO-Bkjy34TD.js} +1 -1
  61. package/dist/webdist/assets/{diagram-LBJQPF4R-BzTddnYn.js → diagram-LBJQPF4R-BorjsNJT.js} +1 -1
  62. package/dist/webdist/assets/{diagram-Q27KOJAE-U-iZs4DE.js → diagram-Q27KOJAE-hW5SDR9k.js} +1 -1
  63. package/dist/webdist/assets/{diagram-UB23O5K3-CaFGOdAj.js → diagram-UB23O5K3-c07HJJ5p.js} +1 -1
  64. package/dist/webdist/assets/{dropdown-menu-D5Vf7U3W.js → dropdown-menu-CaecUWTU.js} +1 -1
  65. package/dist/webdist/assets/{ebnfDiagram-BXEA7PRR-WEkh8Cpp.js → ebnfDiagram-BXEA7PRR-CvgAWjhG.js} +1 -1
  66. package/dist/webdist/assets/{erDiagram-JOGREHBK-DIPsvu0C.js → erDiagram-JOGREHBK-C66LM90T.js} +1 -1
  67. package/dist/webdist/assets/{external-link-DuVH0_sU.js → external-link-NvytYVfT.js} +1 -1
  68. package/dist/webdist/assets/{file-text-B8I_V3Ev.js → file-text-BsC3M8zz.js} +1 -1
  69. package/dist/webdist/assets/{flowDiagram-UKHOOZJN-D0Il5rli.js → flowDiagram-UKHOOZJN-BcXu-_m9.js} +1 -1
  70. package/dist/webdist/assets/{folder-input-n_yC89H9.js → folder-input-B5dvV2Rt.js} +1 -1
  71. package/dist/webdist/assets/{folder-plus-CC1f-3oh.js → folder-plus-CfgNM2Bq.js} +1 -1
  72. package/dist/webdist/assets/{ganttDiagram-PKOTCBZU-8KyY9Pa4.js → ganttDiagram-PKOTCBZU-DtorJ7JE.js} +1 -1
  73. package/dist/webdist/assets/{git-branch-CQA2JECJ.js → git-branch-BRH6t3pJ.js} +1 -1
  74. package/dist/webdist/assets/{gitGraphDiagram-DS77QQ5N-DnwR5_g_.js → gitGraphDiagram-DS77QQ5N-krn_sqdS.js} +1 -1
  75. package/dist/webdist/assets/index-B2S9teij.css +1 -0
  76. package/dist/webdist/assets/{index-hEBbEVm0.js → index-C9ZXfFYo.js} +2 -2
  77. package/dist/webdist/assets/{infoDiagram-6WML65LV-B4Ao9xBO.js → infoDiagram-6WML65LV-DdSRJqp_.js} +1 -1
  78. package/dist/webdist/assets/{ishikawaDiagram-WSZJBQD7-BIH-3xyR.js → ishikawaDiagram-WSZJBQD7-CXU7wA7v.js} +1 -1
  79. package/dist/webdist/assets/{journeyDiagram-NVQOT4AX-CB7VA190.js → journeyDiagram-NVQOT4AX-CIzJLnh4.js} +1 -1
  80. package/dist/webdist/assets/{kanban-definition-27J2QSJJ-t0MLGJxS.js → kanban-definition-27J2QSJJ-D7PciwFU.js} +1 -1
  81. package/dist/webdist/assets/{linear-C2UcHtLH.js → linear-DJzOvrgv.js} +1 -1
  82. package/dist/webdist/assets/{link-queries-Dd_UY0A-.js → link-queries-BfuN5xQI.js} +1 -1
  83. package/dist/webdist/assets/{lock-BaRe3TFE.js → lock-BpNNUDlH.js} +1 -1
  84. package/dist/webdist/assets/{mermaid.core-Do_AkPs7.js → mermaid.core-DEfoMsry.js} +4 -4
  85. package/dist/webdist/assets/{mindmap-definition-FAOFIHXS-C0FjLEZb.js → mindmap-definition-FAOFIHXS-B-p8gHME.js} +1 -1
  86. package/dist/webdist/assets/{monitor-nPLFkAL-.js → monitor-3-JqrGh0.js} +1 -1
  87. package/dist/webdist/assets/{pegDiagram-VL7TDLO6-DMP_1SBp.js → pegDiagram-VL7TDLO6-CVN-UtZ2.js} +1 -1
  88. package/dist/webdist/assets/{pencil-DIAK3lkm.js → pencil-CLBnFmc5.js} +1 -1
  89. package/dist/webdist/assets/{pieDiagram-7S7Q4E2Y-RG_slaJ2.js → pieDiagram-7S7Q4E2Y-Cyowg7jU.js} +1 -1
  90. package/dist/webdist/assets/{plus-Cd2hb3vG.js → plus-BsBN79CH.js} +1 -1
  91. package/dist/webdist/assets/{quadrantDiagram-CIZ2JOQS-6wV3EG0F.js → quadrantDiagram-CIZ2JOQS-CLEre7Bo.js} +1 -1
  92. package/dist/webdist/assets/{railroadDiagram-AXF67PYL-flgltuTY.js → railroadDiagram-AXF67PYL-CstFYJPW.js} +1 -1
  93. package/dist/webdist/assets/{refresh-cw-MAW86aWv.js → refresh-cw-DHnSGytz.js} +1 -1
  94. package/dist/webdist/assets/{remote-failure-DTP9EDi2.js → remote-failure-DQsv9RYM.js} +1 -1
  95. package/dist/webdist/assets/{requirementDiagram-LRYGKXZP-CXpi-87D.js → requirementDiagram-LRYGKXZP-BVS10AjP.js} +1 -1
  96. package/dist/webdist/assets/{rocket-B5uDLuGn.js → rocket-0CLawS4F.js} +1 -1
  97. package/dist/webdist/assets/{rotate-ccw-DVWlxS6M.js → rotate-ccw-kHM_pFpt.js} +1 -1
  98. package/dist/webdist/assets/{sankeyDiagram-W5VNT64P-C50KvAmS.js → sankeyDiagram-W5VNT64P-DWg6hEFJ.js} +1 -1
  99. package/dist/webdist/assets/{sequenceDiagram-SI44F4Z6-CsT039Tm.js → sequenceDiagram-SI44F4Z6-CPe4ECQK.js} +1 -1
  100. package/dist/webdist/assets/{sizeCapture-X5ZJPWSS-BImTTCUc.js → sizeCapture-X5ZJPWSS-tYK0sN8k.js} +1 -1
  101. package/dist/webdist/assets/{skeleton-DnvNxbj8.js → skeleton-1pxWnguF.js} +1 -1
  102. package/dist/webdist/assets/{sliders-horizontal-DsS2Uee5.js → sliders-horizontal-CJnL4ema.js} +1 -1
  103. package/dist/webdist/assets/{sparkles-BU19nV47.js → sparkles-CtVbnpZt.js} +1 -1
  104. package/dist/webdist/assets/{star-DcvDKUjt.js → star-BWg7n83j.js} +1 -1
  105. package/dist/webdist/assets/{stateDiagram-OKZ733FA-Go1nImaV.js → stateDiagram-OKZ733FA-DdMFYbZ9.js} +1 -1
  106. package/dist/webdist/assets/stateDiagram-v2-UEYNNEHI-Pg2RCR6-.js +1 -0
  107. package/dist/webdist/assets/{swimlanes-SLNWSIFB-D8aYBeg_.js → swimlanes-SLNWSIFB-DgWqKJOe.js} +2 -2
  108. package/dist/webdist/assets/swimlanesDiagram-ULZ7WXOC-D-HgKzxH.js +8 -0
  109. package/dist/webdist/assets/{switch-DRDUQUBQ.js → switch-ChtEKTkl.js} +1 -1
  110. package/dist/webdist/assets/{terminal-BaGcFc0D.js → terminal-BksEQh4H.js} +1 -1
  111. package/dist/webdist/assets/{timeline-definition-Z64GVDOM-BCYicvUs.js → timeline-definition-Z64GVDOM-CrwOPdAi.js} +1 -1
  112. package/dist/webdist/assets/{trash-2-dTSieVsH.js → trash-2-BXZkODa0.js} +1 -1
  113. package/dist/webdist/assets/{triangle-alert-BQok4bN-.js → triangle-alert-tsQmbLn8.js} +1 -1
  114. package/dist/webdist/assets/{useIsDesktop-D7McLbCu.js → useIsDesktop-BKLpQjiw.js} +1 -1
  115. package/dist/webdist/assets/{vennDiagram-T6HMQDX7-BvWE6mUb.js → vennDiagram-T6HMQDX7-B7_yA6Pn.js} +1 -1
  116. package/dist/webdist/assets/{wardleyDiagram-T6FBY63Y-DId8SDFX.js → wardleyDiagram-T6FBY63Y-CImMUYg_.js} +1 -1
  117. package/dist/webdist/assets/{wrench-wnE0c5Ir.js → wrench-CuSXx_Zn.js} +1 -1
  118. package/dist/webdist/assets/{xychartDiagram-ELKLHX3M-DAFHE1Oy.js → xychartDiagram-ELKLHX3M-B2wGD83d.js} +1 -1
  119. package/dist/webdist/index.html +2 -2
  120. package/package.json +1 -1
  121. package/dist/webdist/assets/ModelDetailDialog-PySMSzRc.js +0 -1
  122. package/dist/webdist/assets/ModelsScreen-Bi_cdOOR.js +0 -2
  123. package/dist/webdist/assets/WorkspaceScreen-BvQS-6fo.js +0 -1
  124. package/dist/webdist/assets/channel-B6B2Q5Vd.js +0 -1
  125. package/dist/webdist/assets/classDiagram-JCYQIIEL-Nr9H5qaY.js +0 -1
  126. package/dist/webdist/assets/classDiagram-v2-OCEON4UE-Nr9H5qaY.js +0 -1
  127. package/dist/webdist/assets/index-D44YD6EJ.css +0 -1
  128. package/dist/webdist/assets/stateDiagram-v2-UEYNNEHI-CNOImueL.js +0 -1
  129. package/dist/webdist/assets/swimlanesDiagram-ULZ7WXOC-u93o-5nq.js +0 -8
package/dist/cli.js CHANGED
@@ -4636,7 +4636,20 @@ import { EventEmitter as EventEmitter2 } from "events";
4636
4636
 
4637
4637
  // src/chat/chat-routes.ts
4638
4638
  import { streamSSE } from "hono/streaming";
4639
+
4640
+ // src/net.ts
4639
4641
  import { networkInterfaces } from "os";
4642
+ var VIRTUAL_ADAPTER_NAME = /^(vEthernet|Loopback|Virtual|VMware|VirtualBox|Hyper-V|Docker|WSL|Tailscale|ZeroTier|Npcap|TAP-|PPP|Bluetooth)/i;
4643
+ function getLanIp() {
4644
+ const candidates = [];
4645
+ for (const [name, ifaces] of Object.entries(networkInterfaces())) {
4646
+ for (const iface of ifaces ?? []) {
4647
+ if (iface.family === "IPv4" && !iface.internal) candidates.push({ name, address: iface.address });
4648
+ }
4649
+ }
4650
+ const real = candidates.find((c) => !VIRTUAL_ADAPTER_NAME.test(c.name));
4651
+ return (real ?? candidates[0])?.address ?? null;
4652
+ }
4640
4653
 
4641
4654
  // src/chat/parser.ts
4642
4655
  var THINK_OPEN = "<think>";
@@ -10176,14 +10189,7 @@ function importOpenAiMessages(c, db2, messages, titleField, modelField) {
10176
10189
  return c.json({ id: newConv.id }, 201);
10177
10190
  }
10178
10191
  function getLanIpForShare() {
10179
- const nets = networkInterfaces();
10180
- for (const ifaces of Object.values(nets)) {
10181
- if (!ifaces) continue;
10182
- for (const iface of ifaces) {
10183
- if (iface.family === "IPv4" && !iface.internal) return iface.address;
10184
- }
10185
- }
10186
- return "127.0.0.1";
10192
+ return getLanIp() ?? "127.0.0.1";
10187
10193
  }
10188
10194
  function reportChatBenchResult(d, ms, stats) {
10189
10195
  try {
@@ -13824,7 +13830,7 @@ var EMBED_ARCHS = /* @__PURE__ */ new Set([
13824
13830
  "xlm-roberta",
13825
13831
  "electra"
13826
13832
  ]);
13827
- var EMBED_FILE_RE = /\b(bge[-_]|nomic[-_]embed|all[-_]minilm|e5[-_]|gte[-_]|stella[-_]embed|jina[-_]embed|mxbai[-_]embed)\b/i;
13833
+ var EMBED_FILE_RE = /\b(bge[-_]|nomic[-_]embed|all[-_]minilm|e5[-_]|gte[-_]|stella[-_]embed|jina[-_]embed|mxbai[-_]embed|embed(ding)?)\b/i;
13828
13834
  function isEmbeddingModel(arch2, name) {
13829
13835
  return EMBED_ARCHS.has(arch2.toLowerCase()) || EMBED_FILE_RE.test(name);
13830
13836
  }
@@ -20016,12 +20022,12 @@ var ModelRouter = class {
20016
20022
  * skipped. Callers are responsible for their OWN idle-vs-busy decision before calling this
20017
20023
  * (see routines/model-swap.ts) — this method has no opinion on whether now is a safe time to
20018
20024
  * swap, only on HOW to swap once that's decided. */
20019
- async loadExplicit(modelKey) {
20025
+ async loadExplicit(modelKey, overrides) {
20020
20026
  const remote = this.resolveRemote(modelKey);
20021
20027
  if (remote) return remote;
20022
20028
  const entry = this.resolveEntry(modelKey);
20023
20029
  if (!entry) return { status: 503, message: `No model matching '${modelKey}' found. Add one in TurboLLM.` };
20024
- return this.withSwapLock(() => this.doLoad(entry));
20030
+ return this.withSwapLock(() => this.doLoad(entry, overrides));
20025
20031
  }
20026
20032
  /** Acquire the SAME swap-serialization queue `route()` uses, then run `fn` exclusively with
20027
20033
  * respect to any other swap (manual or auto). `route()` itself is just this wrapping
@@ -20084,7 +20090,7 @@ var ModelRouter = class {
20084
20090
  return keys;
20085
20091
  }
20086
20092
  // ── internal ──────────────────────────────────────────────────────────────
20087
- async doLoad(entry) {
20093
+ async doLoad(entry, overrides) {
20088
20094
  {
20089
20095
  const ms = this.manager.status();
20090
20096
  if (ms.state === "running" && ms.model && this.keysMatch(ms.model.key, entry)) {
@@ -20107,7 +20113,7 @@ var ModelRouter = class {
20107
20113
  if (!engineAcceptsFormat(active.kind, entry.format)) {
20108
20114
  return { status: 503, message: `Active engine cannot load model format '${entry.format}'.` };
20109
20115
  }
20110
- const opts = this.buildOpts(entry, active);
20116
+ const opts = this.buildOpts(entry, active, overrides);
20111
20117
  if (!opts) return { status: 503, message: "Model is incomplete or unreadable." };
20112
20118
  const keepN = Math.max(1, this.store.snapshot().gateway.keepN);
20113
20119
  const needsNewSlot = entry.embedding || this.chatSlotCount() < keepN;
@@ -20245,13 +20251,13 @@ var ModelRouter = class {
20245
20251
  keysMatch(loadedKey, entry) {
20246
20252
  return loadedKey === entry.key || loadedKey === entry.path;
20247
20253
  }
20248
- buildOpts(entry, engine) {
20254
+ buildOpts(entry, engine, overrides) {
20249
20255
  if (entry.incomplete || entry.parseError) return null;
20250
20256
  const cfg2 = this.store.snapshot();
20251
20257
  const sys = getSysInfo();
20252
20258
  if (entry.format !== "gguf") {
20253
20259
  const savedProfile = getModelProfile(cfg2, entry.key, engine.id);
20254
- const profile2 = resolveProfile(entry, sys, savedProfile, void 0, cfg2.modelDefaults);
20260
+ const profile2 = resolveProfile(entry, sys, savedProfile, overrides, cfg2.modelDefaults);
20255
20261
  return {
20256
20262
  engine,
20257
20263
  model: { key: entry.key, name: entry.name, quant: entry.quant, ctx: entry.nativeCtx, vision: entry.vision },
@@ -20264,7 +20270,7 @@ var ModelRouter = class {
20264
20270
  };
20265
20271
  }
20266
20272
  const saved = getModelProfile(cfg2, entry.key, engine.id);
20267
- const profile = resolveProfile(entry, sys, saved, void 0, cfg2.modelDefaults);
20273
+ const profile = resolveProfile(entry, sys, saved, overrides, cfg2.modelDefaults);
20268
20274
  const extraArgs = engine.kind === "koboldcpp" ? koboldcppProfileToArgs(profile, sys.gpus[0]?.vendor ?? "unknown", sys.gpus.length > 0) : profileToArgs(profile, entry, engine.capabilities, sys.cores, sys, engine.binPath);
20269
20275
  return {
20270
20276
  engine,
@@ -22501,7 +22507,7 @@ __all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
22501
22507
 
22502
22508
  // src/api/routes.ts
22503
22509
  import { randomUUID as randomUUID11 } from "crypto";
22504
- import { homedir as homedir4, networkInterfaces as networkInterfaces2 } from "os";
22510
+ import { homedir as homedir4 } from "os";
22505
22511
 
22506
22512
  // src/config/config-bounds.ts
22507
22513
  var CONFIG_BOUNDS = {
@@ -24076,9 +24082,6 @@ async function startEngine(c, d, b) {
24076
24082
  const active = d.registry.active();
24077
24083
  if (!active) return err4(c, 409, "no_active_engine", "Register and select an engine first.");
24078
24084
  if (d.comfy?.isBlocked()) return err4(c, 409, "comfyui_busy", "ComfyUI is rendering \u2014 model loading is paused until its queue finishes.");
24079
- d.bench.cancel();
24080
- abortAllInFlightChats();
24081
- await d.bench.waitIdle();
24082
24085
  const cfg2 = d.store.snapshot();
24083
24086
  const sys = getSysInfo();
24084
24087
  let key = b.modelKey ?? "";
@@ -24101,6 +24104,13 @@ async function startEngine(c, d, b) {
24101
24104
  `${engineLabel} cannot load models with an audio tower \u2014 the audio encoder ${certainty} due to an upstream mlx-vlm bug in the sanitizer for these architectures. Switch to the MLX engine instead.`
24102
24105
  );
24103
24106
  }
24107
+ if (entry.embedding) {
24108
+ void d.modelRouter.loadExplicit(entry.key, b.profileOverrides).catch((e) => console.warn(`engine load failed: ${e}`));
24109
+ return c.json({ ok: true }, 202);
24110
+ }
24111
+ d.bench.cancel();
24112
+ abortAllInFlightChats();
24113
+ await d.bench.waitIdle();
24104
24114
  let opts2;
24105
24115
  if (entry.format !== "gguf") {
24106
24116
  const savedProfile = getModelProfile(cfg2, entry.key, active.id);
@@ -24145,6 +24155,9 @@ async function startEngine(c, d, b) {
24145
24155
  name = cfg2.devModel.label;
24146
24156
  }
24147
24157
  if (!modelPath) return err4(c, 409, "no_such_model", "No model specified. Pick one from the Models screen.");
24158
+ d.bench.cancel();
24159
+ abortAllInFlightChats();
24160
+ await d.bench.waitIdle();
24148
24161
  const opts = { engine: active, model: deriveModel(modelPath, name, extra), modelPath, extraArgs: extra };
24149
24162
  void d.modelRouter.withSwapLock(() => d.manager.load(opts, { beforeStart: () => d.comfy?.freeComfyUIBeforeLoad() ?? Promise.resolve() })).then(() => d.modelRouter.markPrimaryLoaded()).catch((e) => console.warn(`engine load failed: ${e}`));
24150
24163
  return c.json({ ok: true }, 202);
@@ -25605,7 +25618,7 @@ function registerApi(app2, d) {
25605
25618
  const cfg2 = d.store.snapshot();
25606
25619
  return c.json({
25607
25620
  lanBind: cfg2.daemon.lanBind,
25608
- lanUrl: `http://${getLanIp()}:${cfg2.daemon.port}`,
25621
+ lanUrl: `http://${getLanIp() ?? "127.0.0.1"}:${cfg2.daemon.port}`,
25609
25622
  hasApiKey: cfg2.apiKeys.length > 0,
25610
25623
  requireApiKey: cfg2.daemon.requireApiKey,
25611
25624
  isHost: isLocalRequest(c, d)
@@ -25775,7 +25788,7 @@ function registerApi(app2, d) {
25775
25788
  const cli = c.req.param("cli");
25776
25789
  const cfg2 = d.store.snapshot();
25777
25790
  const { port: port2, lanBind } = cfg2.daemon;
25778
- const host2 = lanBind ? getLanIp() : "127.0.0.1";
25791
+ const host2 = lanBind ? getLanIp() ?? "127.0.0.1" : "127.0.0.1";
25779
25792
  const base2 = `http://${host2}:${port2}`;
25780
25793
  const ms = d.manager.status();
25781
25794
  const modelName = ms.state === "running" ? ms.model?.name ?? "local" : "local";
@@ -26093,16 +26106,6 @@ function listWindowsDrives() {
26093
26106
  }
26094
26107
  return drives;
26095
26108
  }
26096
- function getLanIp() {
26097
- const nets = networkInterfaces2();
26098
- for (const ifaces of Object.values(nets)) {
26099
- if (!ifaces) continue;
26100
- for (const iface of ifaces) {
26101
- if (iface.family === "IPv4" && !iface.internal) return iface.address;
26102
- }
26103
- }
26104
- return "127.0.0.1";
26105
- }
26106
26109
  function buildConnectSnippets(cli, base2, apiKey, modelName, modelKey = modelName) {
26107
26110
  switch (cli) {
26108
26111
  case "claude-code":
@@ -26266,7 +26269,6 @@ function buildConnectSnippets(cli, base2, apiKey, modelName, modelKey = modelNam
26266
26269
 
26267
26270
  // src/api/link-admin-routes.ts
26268
26271
  import { randomUUID as randomUUID12 } from "crypto";
26269
- import { networkInterfaces as networkInterfaces3 } from "os";
26270
26272
 
26271
26273
  // src/link/link-state.ts
26272
26274
  function nextStatus(current, probe2) {
@@ -27238,12 +27240,7 @@ function remoteFailure(c, rec, probe2) {
27238
27240
  );
27239
27241
  }
27240
27242
  function lanHost() {
27241
- for (const iface of Object.values(networkInterfaces3())) {
27242
- for (const a of iface ?? []) {
27243
- if (a.family === "IPv4" && !a.internal) return a.address;
27244
- }
27245
- }
27246
- return "localhost";
27243
+ return getLanIp() ?? "localhost";
27247
27244
  }
27248
27245
 
27249
27246
  // src/chat/chat-agent-routes.ts
@@ -0,0 +1,10 @@
1
+ {"t":0,"agent":"a0686ab","agent_type":"unknown","event":"agent_stop","success":true}
2
+ {"t":0,"agent":"a0686ab","agent_type":"unknown","event":"agent_stop","success":true}
3
+ {"t":0,"agent":"a0686ab","agent_type":"unknown","event":"agent_stop","success":true}
4
+ {"t":0,"agent":"a0686ab","agent_type":"unknown","event":"agent_stop","success":true}
5
+ {"t":0,"agent":"a0686ab","agent_type":"unknown","event":"agent_stop","success":true}
6
+ {"t":0,"agent":"a0686ab","agent_type":"unknown","event":"agent_stop","success":true}
7
+ {"t":0,"agent":"a0686ab","agent_type":"unknown","event":"agent_stop","success":true}
8
+ {"t":0,"agent":"a0686ab","agent_type":"unknown","event":"agent_stop","success":true}
9
+ {"t":0,"agent":"a0686ab","agent_type":"unknown","event":"agent_stop","success":true}
10
+ {"t":0,"agent":"a0686ab","agent_type":"unknown","event":"agent_stop","success":true}
@@ -0,0 +1,7 @@
1
+ {
2
+ "agents": [],
3
+ "total_spawned": 0,
4
+ "total_completed": 0,
5
+ "total_failed": 0,
6
+ "last_updated": "2026-09-01T14:34:13.310Z"
7
+ }
@@ -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-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};
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-C9ZXfFYo.js";import{f as V}from"./chat-api-Bgrb0rnf.js";import{f as X,a as Z}from"./agent-api-BAMDY8-v.js";import{P as B}from"./personas-Dkq9JD72.js";import{C as ee}from"./chevron-left-CxvUI3ck.js";import{R as te}from"./rotate-ccw-kHM_pFpt.js";import{T as se}from"./trash-2-BXZkODa0.js";import{C as ne}from"./chevron-right-CpdnK5S2.js";import"./dropdown-menu-CaecUWTU.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};