turbollm 1.11.0 → 1.11.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.
- package/README.md +3 -0
- package/dist/cli.js +163 -21
- package/dist/webdist/assets/AgentEditPage-D5ccnu5s.js +1 -0
- package/dist/webdist/assets/{ChatScreen-DWR0twnC.js → ChatScreen-BygO8zb3.js} +15 -15
- package/dist/webdist/assets/CodeComposer-BTpMVTCA.js +1 -0
- package/dist/webdist/assets/CodeHomeScreen-Cz7tsGIS.js +1 -0
- package/dist/webdist/assets/{CodeSessionScreen-CwBa11Jt.js → CodeSessionScreen-CFIAgEJ7.js} +12 -12
- package/dist/webdist/assets/{CustomizeScreen-CD-WTBXb.js → CustomizeScreen-7zLa19h5.js} +1 -1
- package/dist/webdist/assets/{DeveloperScreen-CESuUPIA.js → DeveloperScreen-e8_tLsWt.js} +1 -1
- package/dist/webdist/assets/{EnginesScreen-BhdKIPyX.js → EnginesScreen-hn6IM67U.js} +2 -2
- package/dist/webdist/assets/ModelDetailDialog-DN-kl63r.js +1 -0
- package/dist/webdist/assets/ModelLoadMenu-Dgy2n0qW.js +1 -0
- package/dist/webdist/assets/{ModelsScreen-m-cbkQfg.js → ModelsScreen-COQU83v_.js} +2 -2
- package/dist/webdist/assets/OnboardingScreen-BcjUSBAv.js +1 -0
- package/dist/webdist/assets/RoutineEditPage-BtYITioy.js +1 -0
- package/dist/webdist/assets/RoutinesPanel-DnnVr9g2.js +1 -0
- package/dist/webdist/assets/SettingsScreen-0NoDCta7.js +2 -0
- package/dist/webdist/assets/SidebarResizeHandle-DCZXIwhU.js +2 -0
- package/dist/webdist/assets/{SkillEditPage-BPMWlPxr.js → SkillEditPage-B157ySq9.js} +1 -1
- package/dist/webdist/assets/{TokensScreen-C78YBwfC.js → TokensScreen-DoYPjv6Y.js} +1 -1
- package/dist/webdist/assets/{ToolApprovalBar-D6Usabbc.js → ToolApprovalBar-ChYJChYS.js} +4 -4
- package/dist/webdist/assets/WorkspaceScreen-BrA4DSov.js +1 -0
- package/dist/webdist/assets/{abnfDiagram-N423BO3Z-EMmaHj8K.js → abnfDiagram-N423BO3Z-YE0PLBtD.js} +1 -1
- package/dist/webdist/assets/{agent-api-Vpc7M2SN.js → agent-api-DyPUCnyd.js} +1 -1
- package/dist/webdist/assets/{alert-dialog-RuoeJJC-.js → alert-dialog-mb66t64A.js} +1 -1
- package/dist/webdist/assets/{arc-BHeddvY-.js → arc-D6tB7EyD.js} +1 -1
- package/dist/webdist/assets/{architectureDiagram-T3A2C74G-B9vPWlm9.js → architectureDiagram-T3A2C74G-CC_g3uHG.js} +1 -1
- package/dist/webdist/assets/{arrow-left-QxWpxvpD.js → arrow-left-B0kOOTXf.js} +1 -1
- package/dist/webdist/assets/{badge-WQ1wLWtz.js → badge-BaPl3cu1.js} +1 -1
- package/dist/webdist/assets/{blockDiagram-VBNYF7ZC-DF9hv8Mn.js → blockDiagram-VBNYF7ZC-CDFisfPP.js} +1 -1
- package/dist/webdist/assets/{bot-BkUld4bs.js → bot-DQc34hdo.js} +1 -1
- package/dist/webdist/assets/{c4Diagram-5PPSVZJV-DiyHHtjq.js → c4Diagram-5PPSVZJV-Df9WlHJi.js} +1 -1
- package/dist/webdist/assets/channel-rIJvIL9_.js +1 -0
- package/dist/webdist/assets/chat-api-B7cm_Kjj.js +3 -0
- package/dist/webdist/assets/{chat-queries-RLSOlOWo.js → chat-queries-vBDT6raC.js} +1 -1
- package/dist/webdist/assets/chevron-down-D3qQII2-.js +1 -0
- package/dist/webdist/assets/{chevron-left-CP9IFIJY.js → chevron-left-BQ3TyvUR.js} +1 -1
- package/dist/webdist/assets/{chevron-right-DrIMoQSz.js → chevron-right-C1TzfDRc.js} +1 -1
- package/dist/webdist/assets/{chunk-2GRJ4B5K-CCSTGpfU.js → chunk-2GRJ4B5K--fTNBTKb.js} +1 -1
- package/dist/webdist/assets/{chunk-2Q5K7J3B-DhLcfa9a.js → chunk-2Q5K7J3B-BE2H2UHk.js} +1 -1
- package/dist/webdist/assets/{chunk-5RXB4S5H-DS_Jjker.js → chunk-5RXB4S5H-C-ps6IJo.js} +1 -1
- package/dist/webdist/assets/{chunk-5VM5RSS4-DR8jriPd.js → chunk-5VM5RSS4-Dr6Y-wsq.js} +1 -1
- package/dist/webdist/assets/{chunk-6Q2QTUOP-CvvshdRt.js → chunk-6Q2QTUOP-CFP_W3le.js} +1 -1
- package/dist/webdist/assets/{chunk-GF5L2VYU-Bn_W4FqO.js → chunk-GF5L2VYU-eS8r3XDQ.js} +1 -1
- package/dist/webdist/assets/{chunk-JWPE2WC7-BbyR5jPI.js → chunk-JWPE2WC7-CnHOI6Vb.js} +1 -1
- package/dist/webdist/assets/{chunk-KBJHAD2P-CapiPaai.js → chunk-KBJHAD2P-DjKuoeJv.js} +1 -1
- package/dist/webdist/assets/{chunk-RYQCIY6F-o0Eobs4I.js → chunk-RYQCIY6F-BCZSATDq.js} +1 -1
- package/dist/webdist/assets/{chunk-XXDRQBXY-DnfM_6_z.js → chunk-XXDRQBXY-6vDQpKbX.js} +1 -1
- package/dist/webdist/assets/{circle-check-Dfy4urT3.js → circle-check-CayQ1Kmr.js} +1 -1
- package/dist/webdist/assets/{circle-x-CTrNBFyk.js → circle-x-DBL77ehg.js} +1 -1
- package/dist/webdist/assets/classDiagram-JCYQIIEL-CKHNwlA2.js +1 -0
- package/dist/webdist/assets/classDiagram-v2-OCEON4UE-CKHNwlA2.js +1 -0
- package/dist/webdist/assets/{common-D3KIhI5Z.js → common-COkt_JGo.js} +1 -1
- package/dist/webdist/assets/{cose-bilkent-JH36ORCC-CVGwTg6K.js → cose-bilkent-JH36ORCC-CPMWY99B.js} +1 -1
- package/dist/webdist/assets/{cynefin-VYW2F7L2-B_cdEt0j.js → cynefin-VYW2F7L2-DCemwV3Z.js} +1 -1
- package/dist/webdist/assets/{cynefinDiagram-MW4NZA55-D6Bq1Hb9.js → cynefinDiagram-MW4NZA55-B8HcUCjZ.js} +1 -1
- package/dist/webdist/assets/{dagre-VZM6K2ZE-BZBXLl5P.js → dagre-VZM6K2ZE-BC6lGXyw.js} +1 -1
- package/dist/webdist/assets/{diagram-7IWD3JNH-CfaI5HQ5.js → diagram-7IWD3JNH-CQSNxirf.js} +1 -1
- package/dist/webdist/assets/{diagram-B4RE2ZJO-CHTmK73T.js → diagram-B4RE2ZJO-D6Ot6ZYA.js} +1 -1
- package/dist/webdist/assets/{diagram-LBJQPF4R-Cv1djbM6.js → diagram-LBJQPF4R-D775f1Jb.js} +1 -1
- package/dist/webdist/assets/{diagram-Q27KOJAE-wH1umxXP.js → diagram-Q27KOJAE-aedYX_I3.js} +1 -1
- package/dist/webdist/assets/{diagram-UB23O5K3-DjVjVgky.js → diagram-UB23O5K3-DyKXvxFs.js} +1 -1
- package/dist/webdist/assets/dropdown-menu-Co-9JBK7.js +1 -0
- package/dist/webdist/assets/{ebnfDiagram-BXEA7PRR-CnP6v0OA.js → ebnfDiagram-BXEA7PRR-Dmyl6hgX.js} +1 -1
- package/dist/webdist/assets/{erDiagram-JOGREHBK-Bxvus2yH.js → erDiagram-JOGREHBK-DQ61Ftq2.js} +1 -1
- package/dist/webdist/assets/{external-link-BYxejPiV.js → external-link-DeGazJd7.js} +1 -1
- package/dist/webdist/assets/file-text-BqSocdvg.js +1 -0
- package/dist/webdist/assets/{flowDiagram-UKHOOZJN-Cs1rV3tb.js → flowDiagram-UKHOOZJN-DpF0SMmj.js} +1 -1
- package/dist/webdist/assets/{folder-input-BtJHHiyW.js → folder-input-fLAI3sbE.js} +1 -1
- package/dist/webdist/assets/{folder-plus-Ch-KIy_j.js → folder-plus-kUhRq8Qs.js} +1 -1
- package/dist/webdist/assets/{ganttDiagram-PKOTCBZU-DbKmBS-m.js → ganttDiagram-PKOTCBZU-C9hM2RtH.js} +1 -1
- package/dist/webdist/assets/{git-branch-C0tnpEBn.js → git-branch-BLvbsQlx.js} +1 -1
- package/dist/webdist/assets/{gitGraphDiagram-DS77QQ5N-XiTtBrMy.js → gitGraphDiagram-DS77QQ5N-F-m07GU8.js} +1 -1
- package/dist/webdist/assets/{index-DgjAtL-b.js → index-Djd745uq.js} +2 -2
- package/dist/webdist/assets/{infoDiagram-6WML65LV-VAFHBPFv.js → infoDiagram-6WML65LV-SU_VZ3kP.js} +1 -1
- package/dist/webdist/assets/{ishikawaDiagram-WSZJBQD7-CltvpCC_.js → ishikawaDiagram-WSZJBQD7-CPGrHUJl.js} +1 -1
- package/dist/webdist/assets/{journeyDiagram-NVQOT4AX-B8O_4rAi.js → journeyDiagram-NVQOT4AX-xSn5t7m_.js} +1 -1
- package/dist/webdist/assets/{kanban-definition-27J2QSJJ-PuuqAhDK.js → kanban-definition-27J2QSJJ-BP6v9V-b.js} +1 -1
- package/dist/webdist/assets/{linear-BzcDsYCl.js → linear-CrWjOgAX.js} +1 -1
- package/dist/webdist/assets/{lock-NjhtB3l7.js → lock-CMnk_C6j.js} +1 -1
- package/dist/webdist/assets/{mermaid.core--ItM_Tuo.js → mermaid.core-Daad9FCu.js} +4 -4
- package/dist/webdist/assets/{mindmap-definition-FAOFIHXS-DA4CwvE8.js → mindmap-definition-FAOFIHXS-BdQNGzcB.js} +1 -1
- package/dist/webdist/assets/{pegDiagram-VL7TDLO6-pcbWVCJ3.js → pegDiagram-VL7TDLO6-BVO3lisg.js} +1 -1
- package/dist/webdist/assets/{pencil-C7Mm5Xtr.js → pencil-CLqNgcwe.js} +1 -1
- package/dist/webdist/assets/{personas-DUC47oth.js → personas-Bdrl3tL6.js} +2 -1
- package/dist/webdist/assets/{pieDiagram-7S7Q4E2Y-BY35jaW3.js → pieDiagram-7S7Q4E2Y-I0avJ0HP.js} +1 -1
- package/dist/webdist/assets/{plus-DvEO8E95.js → plus-CZ50K8Az.js} +1 -1
- package/dist/webdist/assets/{quadrantDiagram-CIZ2JOQS-C5mpyBRe.js → quadrantDiagram-CIZ2JOQS-BoKPRmFq.js} +1 -1
- package/dist/webdist/assets/{railroadDiagram-AXF67PYL-DWTf-dRS.js → railroadDiagram-AXF67PYL-nuYQFWlg.js} +1 -1
- package/dist/webdist/assets/{refresh-cw-BATeQPJY.js → refresh-cw-ZKuYnoI-.js} +1 -1
- package/dist/webdist/assets/{requirementDiagram-LRYGKXZP-DBow0Bqr.js → requirementDiagram-LRYGKXZP-BdsVsDe6.js} +1 -1
- package/dist/webdist/assets/{rocket-90T43z1Z.js → rocket-DWM7Gy7e.js} +1 -1
- package/dist/webdist/assets/{rotate-ccw-C7pm2Mke.js → rotate-ccw-Dl2CDY8F.js} +1 -1
- package/dist/webdist/assets/{sankeyDiagram-W5VNT64P-Y3Ppkoun.js → sankeyDiagram-W5VNT64P-oCUC-z0Q.js} +1 -1
- package/dist/webdist/assets/{sequenceDiagram-SI44F4Z6-CHYIu9uX.js → sequenceDiagram-SI44F4Z6-E17XGC6k.js} +1 -1
- package/dist/webdist/assets/{sizeCapture-X5ZJPWSS-B2aHWrTS.js → sizeCapture-X5ZJPWSS-B3ZZ8soS.js} +1 -1
- package/dist/webdist/assets/{skeleton-BvAwq7sP.js → skeleton-B2R1iGLZ.js} +1 -1
- package/dist/webdist/assets/{sliders-horizontal-DfmwaGs9.js → sliders-horizontal-S1QDbdoj.js} +1 -1
- package/dist/webdist/assets/{sparkles-CLTAYDRV.js → sparkles-C1UduBZm.js} +1 -1
- package/dist/webdist/assets/{star-CGSbYOmP.js → star-6fg60gkG.js} +1 -1
- package/dist/webdist/assets/{stateDiagram-OKZ733FA-COcaEWBl.js → stateDiagram-OKZ733FA-uJ7BcjMS.js} +1 -1
- package/dist/webdist/assets/stateDiagram-v2-UEYNNEHI-C03mcgmI.js +1 -0
- package/dist/webdist/assets/{swimlanes-SLNWSIFB-B5uq0ZSN.js → swimlanes-SLNWSIFB-C5Rg25iw.js} +2 -2
- package/dist/webdist/assets/swimlanesDiagram-ULZ7WXOC-Cnm-o6w8.js +8 -0
- package/dist/webdist/assets/{switch-CndaFrl5.js → switch-_T-NWlJj.js} +1 -1
- package/dist/webdist/assets/{terminal-C6Twoyfk.js → terminal-jZn2njs8.js} +1 -1
- package/dist/webdist/assets/{timeline-definition-Z64GVDOM-CfEDs9k-.js → timeline-definition-Z64GVDOM-DCgYtPRm.js} +1 -1
- package/dist/webdist/assets/{trash-2-CtpXI0P6.js → trash-2-C5UxcfNn.js} +1 -1
- package/dist/webdist/assets/{triangle-alert-wgQzTmmK.js → triangle-alert-BLYFYhrL.js} +1 -1
- package/dist/webdist/assets/{useIsDesktop-C28eAfaZ.js → useIsDesktop-Db8d_FwF.js} +1 -1
- package/dist/webdist/assets/{vennDiagram-T6HMQDX7-CjjfGXNg.js → vennDiagram-T6HMQDX7-Bu0txarq.js} +1 -1
- package/dist/webdist/assets/{vram-Bz1RMnmc.js → vram-BW-GKnZ2.js} +1 -1
- package/dist/webdist/assets/{wardleyDiagram-T6FBY63Y--seBEPmq.js → wardleyDiagram-T6FBY63Y-LfdOSJGM.js} +1 -1
- package/dist/webdist/assets/{wrench-CLtGGoX0.js → wrench-R5NYyfgk.js} +1 -1
- package/dist/webdist/assets/{xychartDiagram-ELKLHX3M-CbkgQrTE.js → xychartDiagram-ELKLHX3M-CQSLgZgd.js} +1 -1
- package/dist/webdist/index.html +1 -1
- package/package.json +1 -1
- package/dist/webdist/assets/AgentEditPage-Crb8pCTs.js +0 -1
- package/dist/webdist/assets/CodeComposer-DTUjWlAE.js +0 -1
- package/dist/webdist/assets/CodeHomeScreen-CXfPIHBq.js +0 -1
- package/dist/webdist/assets/ModelDetailDialog-D5TNFKk6.js +0 -1
- package/dist/webdist/assets/ModelLoadMenu-BbBx7ruU.js +0 -1
- package/dist/webdist/assets/OnboardingScreen-CloBv6v8.js +0 -1
- package/dist/webdist/assets/RoutineEditPage-CIFrprR0.js +0 -1
- package/dist/webdist/assets/RoutinesPanel-DuCSvkpH.js +0 -1
- package/dist/webdist/assets/SettingsScreen-CSHExY0c.js +0 -2
- package/dist/webdist/assets/SidebarResizeHandle-DPHLGOYS.js +0 -2
- package/dist/webdist/assets/WorkspaceScreen-D4VRoaRA.js +0 -1
- package/dist/webdist/assets/channel-Dp-qf202.js +0 -1
- package/dist/webdist/assets/chat-api-DgmaYhDI.js +0 -3
- package/dist/webdist/assets/classDiagram-JCYQIIEL-7lq6N49Q.js +0 -1
- package/dist/webdist/assets/classDiagram-v2-OCEON4UE-7lq6N49Q.js +0 -1
- package/dist/webdist/assets/dropdown-menu-DtzQnzDC.js +0 -1
- package/dist/webdist/assets/file-text-BFFqF1Q-.js +0 -1
- package/dist/webdist/assets/stateDiagram-v2-UEYNNEHI-DuyS45WN.js +0 -1
- package/dist/webdist/assets/swimlanesDiagram-ULZ7WXOC-C4aR5PY8.js +0 -8
package/README.md
CHANGED
|
@@ -293,6 +293,9 @@ the detail:
|
|
|
293
293
|
from Settings → Memory, and turning the toggle off stops new chats from seeing it immediately.
|
|
294
294
|
- **Thinking-budget control** — a graduated slider, not just on/off: cap reasoning to a specific
|
|
295
295
|
token count, disable it entirely, or leave it unlimited. Works in Chat and Code alike.
|
|
296
|
+
- **Reasoning-effort control** for models whose own chat template supports it (e.g. Qwen3.8) —
|
|
297
|
+
an Off/Low/Medium/xhigh slider swaps in automatically in place of the thinking-budget one,
|
|
298
|
+
detected per model.
|
|
296
299
|
|
|
297
300
|
</details>
|
|
298
301
|
|
package/dist/cli.js
CHANGED
|
@@ -626,6 +626,35 @@ function setModelProfile(cfg2, modelKey, engineId, profile) {
|
|
|
626
626
|
;
|
|
627
627
|
(cfg2.modelProfiles[modelKey] ??= {})[engineId] = { profile, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
628
628
|
}
|
|
629
|
+
function migrateModelKey(cfg2, oldKey, newKey) {
|
|
630
|
+
if (oldKey === newKey) return false;
|
|
631
|
+
let moved = false;
|
|
632
|
+
if (cfg2.modelProfiles[oldKey] && !cfg2.modelProfiles[newKey]) {
|
|
633
|
+
cfg2.modelProfiles[newKey] = cfg2.modelProfiles[oldKey];
|
|
634
|
+
delete cfg2.modelProfiles[oldKey];
|
|
635
|
+
moved = true;
|
|
636
|
+
}
|
|
637
|
+
if (cfg2.modelPresets[oldKey] && !cfg2.modelPresets[newKey]) {
|
|
638
|
+
cfg2.modelPresets[newKey] = cfg2.modelPresets[oldKey];
|
|
639
|
+
delete cfg2.modelPresets[oldKey];
|
|
640
|
+
moved = true;
|
|
641
|
+
}
|
|
642
|
+
if (cfg2.lastPresetId[oldKey] && !cfg2.lastPresetId[newKey]) {
|
|
643
|
+
cfg2.lastPresetId[newKey] = cfg2.lastPresetId[oldKey];
|
|
644
|
+
delete cfg2.lastPresetId[oldKey];
|
|
645
|
+
moved = true;
|
|
646
|
+
}
|
|
647
|
+
if (cfg2.benchResults[oldKey] && !cfg2.benchResults[newKey]) {
|
|
648
|
+
cfg2.benchResults[newKey] = { ...cfg2.benchResults[oldKey], modelKey: newKey };
|
|
649
|
+
delete cfg2.benchResults[oldKey];
|
|
650
|
+
moved = true;
|
|
651
|
+
}
|
|
652
|
+
if (cfg2.lastLoaded.modelKey === oldKey) {
|
|
653
|
+
cfg2.lastLoaded = { ...cfg2.lastLoaded, modelKey: newKey };
|
|
654
|
+
moved = true;
|
|
655
|
+
}
|
|
656
|
+
return moved;
|
|
657
|
+
}
|
|
629
658
|
function deleteModelProfile(cfg2, modelKey, engineId) {
|
|
630
659
|
const byEngine = cfg2.modelProfiles[modelKey];
|
|
631
660
|
if (!byEngine) return;
|
|
@@ -4405,6 +4434,12 @@ function needsExtraPass(content) {
|
|
|
4405
4434
|
return stripThinkingBlocks(content).trim() === "";
|
|
4406
4435
|
}
|
|
4407
4436
|
|
|
4437
|
+
// src/chat/reasoning-effort.ts
|
|
4438
|
+
var VALID = /* @__PURE__ */ new Set(["off", "low", "medium", "xhigh"]);
|
|
4439
|
+
function parseReasoningEffort(value) {
|
|
4440
|
+
return typeof value === "string" && VALID.has(value) ? value : void 0;
|
|
4441
|
+
}
|
|
4442
|
+
|
|
4408
4443
|
// src/tools/research-referee.ts
|
|
4409
4444
|
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
4410
4445
|
"a",
|
|
@@ -6509,6 +6544,7 @@ var SessionAuthRegistry = class {
|
|
|
6509
6544
|
sessionToToken = /* @__PURE__ */ new Map();
|
|
6510
6545
|
tokenToSession = /* @__PURE__ */ new Map();
|
|
6511
6546
|
sessionThinkingBudget = /* @__PURE__ */ new Map();
|
|
6547
|
+
sessionReasoningEffort = /* @__PURE__ */ new Map();
|
|
6512
6548
|
/** Mint a token for a Code session — idempotent: returns the SAME token on every call for a
|
|
6513
6549
|
* given session (a reconnect/remount must never invalidate the CLI's already-running auth). */
|
|
6514
6550
|
mint(codeSessionId) {
|
|
@@ -6547,6 +6583,20 @@ var SessionAuthRegistry = class {
|
|
|
6547
6583
|
if (!sessionId) return null;
|
|
6548
6584
|
return this.sessionThinkingBudget.get(sessionId) ?? null;
|
|
6549
6585
|
}
|
|
6586
|
+
/** Same override mechanism as setThinkingBudget, for reasoning_effort — see that method's
|
|
6587
|
+
* doc comment. Already validated by the caller (parseReasoningEffort); this registry never
|
|
6588
|
+
* re-validates, same as setThinkingBudget trusts its own caller's int coercion. */
|
|
6589
|
+
setReasoningEffort(codeSessionId, effort) {
|
|
6590
|
+
if (effort === null) this.sessionReasoningEffort.delete(codeSessionId);
|
|
6591
|
+
else this.sessionReasoningEffort.set(codeSessionId, effort);
|
|
6592
|
+
}
|
|
6593
|
+
/** The reasoning-effort override for whichever session `token` belongs to, or null when the
|
|
6594
|
+
* token is unrecognized or no override has been set. */
|
|
6595
|
+
getReasoningEffortForToken(token) {
|
|
6596
|
+
const sessionId = this.tokenToSession.get(token);
|
|
6597
|
+
if (!sessionId) return null;
|
|
6598
|
+
return this.sessionReasoningEffort.get(sessionId) ?? null;
|
|
6599
|
+
}
|
|
6550
6600
|
};
|
|
6551
6601
|
var sessionAuth = new SessionAuthRegistry();
|
|
6552
6602
|
|
|
@@ -9063,7 +9113,7 @@ ${content}` : b.docContext : content;
|
|
|
9063
9113
|
...images.map((url) => ({ type: "image_url", image_url: { url } }))
|
|
9064
9114
|
] : fullContent;
|
|
9065
9115
|
engineMessages.push({ role: "user", content: userContent });
|
|
9066
|
-
await runGeneration(d, stream, { convId, conv, engineMessages, assistantMsg, ms, target, ac, thinkingBudget: b.thinkingBudget ?? -1, userText: content, isCodeAuthorized });
|
|
9116
|
+
await runGeneration(d, stream, { convId, conv, engineMessages, assistantMsg, ms, target, ac, thinkingBudget: b.thinkingBudget ?? -1, reasoningEffort: parseReasoningEffort(b.reasoningEffort), userText: content, isCodeAuthorized });
|
|
9067
9117
|
});
|
|
9068
9118
|
});
|
|
9069
9119
|
app2.post("/api/v1/conversations/:id/continue", async (c) => {
|
|
@@ -9102,7 +9152,7 @@ ${m.reasoning}
|
|
|
9102
9152
|
${m.content}` : m.content;
|
|
9103
9153
|
engineMessages.push({ role: m.role, content });
|
|
9104
9154
|
}
|
|
9105
|
-
await runGeneration(d, stream, { convId, conv, engineMessages, assistantMsg, ms, target, ac, thinkingBudget: b.thinkingBudget ?? -1, isCodeAuthorized });
|
|
9155
|
+
await runGeneration(d, stream, { convId, conv, engineMessages, assistantMsg, ms, target, ac, thinkingBudget: b.thinkingBudget ?? -1, reasoningEffort: parseReasoningEffort(b.reasoningEffort), isCodeAuthorized });
|
|
9106
9156
|
});
|
|
9107
9157
|
});
|
|
9108
9158
|
app2.post("/api/v1/chat/stop", async (c) => {
|
|
@@ -9321,7 +9371,7 @@ function reportChatBenchResult(d, ms, stats) {
|
|
|
9321
9371
|
}
|
|
9322
9372
|
async function runGeneration(d, stream, ctx) {
|
|
9323
9373
|
const { db: db2 } = d;
|
|
9324
|
-
const { convId, conv, assistantMsg, ms, target, ac, thinkingBudget } = ctx;
|
|
9374
|
+
const { convId, conv, assistantMsg, ms, target, ac, thinkingBudget, reasoningEffort } = ctx;
|
|
9325
9375
|
const convS = conv.sampling ?? {};
|
|
9326
9376
|
const engineKind = d.registry.active()?.kind ?? "";
|
|
9327
9377
|
const repeatPenaltyKey = engineKind === "vllm" || engineKind === "sglang" || engineKind === "mlx-vlm" ? "repetition_penalty" : "repeat_penalty";
|
|
@@ -9427,6 +9477,12 @@ After reviewing the search results, include a confidence assessment on a line by
|
|
|
9427
9477
|
reqBody.thinking_budget_tokens = thinkingBudget;
|
|
9428
9478
|
}
|
|
9429
9479
|
if (conv.preserveThinking) templateKwargs.preserve_thinking = true;
|
|
9480
|
+
if (reasoningEffort === "off") {
|
|
9481
|
+
reqBody.thinking_budget_tokens = 0;
|
|
9482
|
+
templateKwargs.enable_thinking = false;
|
|
9483
|
+
} else if (reasoningEffort) {
|
|
9484
|
+
templateKwargs.reasoning_effort = reasoningEffort;
|
|
9485
|
+
}
|
|
9430
9486
|
if (Object.keys(templateKwargs).length) reqBody.chat_template_kwargs = templateKwargs;
|
|
9431
9487
|
const toolsSupported = engineKind !== "vllm" && engineKind !== "sglang" && toolDefs.length > 0;
|
|
9432
9488
|
if (toolsSupported) reqBody.tools = toolDefs;
|
|
@@ -9672,6 +9728,12 @@ After reviewing the search results, include a confidence assessment on a line by
|
|
|
9672
9728
|
reqBody.thinking_budget_tokens = thinkingBudget;
|
|
9673
9729
|
}
|
|
9674
9730
|
if (conv.preserveThinking) templateKwargs.preserve_thinking = true;
|
|
9731
|
+
if (reasoningEffort === "off") {
|
|
9732
|
+
reqBody.thinking_budget_tokens = 0;
|
|
9733
|
+
templateKwargs.enable_thinking = false;
|
|
9734
|
+
} else if (reasoningEffort) {
|
|
9735
|
+
templateKwargs.reasoning_effort = reasoningEffort;
|
|
9736
|
+
}
|
|
9675
9737
|
if (Object.keys(templateKwargs).length) reqBody.chat_template_kwargs = templateKwargs;
|
|
9676
9738
|
const res = await fetch(`${target}/v1/chat/completions`, {
|
|
9677
9739
|
method: "POST",
|
|
@@ -10755,7 +10817,7 @@ function pickPrefillProgress(slots) {
|
|
|
10755
10817
|
return { processed, total, pct };
|
|
10756
10818
|
}
|
|
10757
10819
|
async function runCodeSession(params) {
|
|
10758
|
-
const { d, convId, sessionId, repoRoot, mode, thinkingBudget, task: rawTask, signal, sink } = params;
|
|
10820
|
+
const { d, convId, sessionId, repoRoot, mode, thinkingBudget, reasoningEffort, task: rawTask, signal, sink } = params;
|
|
10759
10821
|
const ms = d.manager.status();
|
|
10760
10822
|
if (ms.state !== "running" || !ms.model) throw new Error("model_not_loaded");
|
|
10761
10823
|
const target = d.manager.target();
|
|
@@ -11175,6 +11237,20 @@ async function runCodeSession(params) {
|
|
|
11175
11237
|
chat_template_kwargs: { ...payload.chat_template_kwargs ?? {}, enable_thinking: false }
|
|
11176
11238
|
};
|
|
11177
11239
|
}
|
|
11240
|
+
if (reasoningEffort === "off") {
|
|
11241
|
+
return {
|
|
11242
|
+
...payload,
|
|
11243
|
+
thinking_budget_tokens: 0,
|
|
11244
|
+
chat_template_kwargs: { ...payload.chat_template_kwargs ?? {}, enable_thinking: false }
|
|
11245
|
+
};
|
|
11246
|
+
}
|
|
11247
|
+
if (reasoningEffort) {
|
|
11248
|
+
return {
|
|
11249
|
+
...payload,
|
|
11250
|
+
...thinkingBudget > 0 ? { thinking_budget_tokens: thinkingBudget } : {},
|
|
11251
|
+
chat_template_kwargs: { ...payload.chat_template_kwargs ?? {}, reasoning_effort: reasoningEffort }
|
|
11252
|
+
};
|
|
11253
|
+
}
|
|
11178
11254
|
if (thinkingBudget > 0) {
|
|
11179
11255
|
return { ...payload, thinking_budget_tokens: thinkingBudget };
|
|
11180
11256
|
}
|
|
@@ -11913,7 +11989,7 @@ var CodeRunManager = class {
|
|
|
11913
11989
|
enqueue(sessionId, params) {
|
|
11914
11990
|
const s = this.ensure(sessionId, params.convId, params.repoRoot);
|
|
11915
11991
|
const willQueue = s.active !== null;
|
|
11916
|
-
s.queue.push({ task: params.task, userMsgId: params.userMsgId, thinkingBudget: params.thinkingBudget ?? -1, kind: params.kind ?? "followUp" });
|
|
11992
|
+
s.queue.push({ task: params.task, userMsgId: params.userMsgId, thinkingBudget: params.thinkingBudget ?? -1, reasoningEffort: params.reasoningEffort, kind: params.kind ?? "followUp" });
|
|
11917
11993
|
this.emitQueue(sessionId);
|
|
11918
11994
|
void this.pump(sessionId);
|
|
11919
11995
|
return { queued: willQueue };
|
|
@@ -12043,6 +12119,7 @@ var CodeRunManager = class {
|
|
|
12043
12119
|
repoRoot: s.repoRoot,
|
|
12044
12120
|
mode,
|
|
12045
12121
|
thinkingBudget: turn.thinkingBudget,
|
|
12122
|
+
reasoningEffort: turn.reasoningEffort,
|
|
12046
12123
|
task: turn.task,
|
|
12047
12124
|
signal: ac.signal,
|
|
12048
12125
|
sink,
|
|
@@ -12747,7 +12824,8 @@ function parseGguf(path) {
|
|
|
12747
12824
|
else if (key.endsWith(".nextn_predict_layers")) m.nextnLayers = readNumberOrMax(r, t);
|
|
12748
12825
|
else if (key === "tokenizer.chat_template") {
|
|
12749
12826
|
m.hasChatTemplate = true;
|
|
12750
|
-
skipValue(r, t);
|
|
12827
|
+
const template = t === T_STRING ? String(readScalar(r, t)) : (skipValue(r, t), "");
|
|
12828
|
+
if (template.includes("reasoning_effort")) m.reasoningEffort = true;
|
|
12751
12829
|
} else {
|
|
12752
12830
|
skipValue(r, t);
|
|
12753
12831
|
}
|
|
@@ -12765,6 +12843,7 @@ function parseGguf(path) {
|
|
|
12765
12843
|
expertCount: m.expertCount ?? 0,
|
|
12766
12844
|
nextnLayers: m.nextnLayers ?? 0,
|
|
12767
12845
|
hasChatTemplate: m.hasChatTemplate ?? false,
|
|
12846
|
+
reasoningEffort: m.reasoningEffort ?? false,
|
|
12768
12847
|
slidingWindow: m.slidingWindow ?? 0,
|
|
12769
12848
|
slidingWindowPattern: m.slidingWindowPattern ?? [],
|
|
12770
12849
|
headDimSwa: keyLengthSwa ?? valueLengthSwa ?? 0,
|
|
@@ -12779,15 +12858,15 @@ function parseGguf(path) {
|
|
|
12779
12858
|
}
|
|
12780
12859
|
}
|
|
12781
12860
|
function quantFromName(filename) {
|
|
12782
|
-
const
|
|
12783
|
-
if (
|
|
12861
|
+
const matches = [...filename.matchAll(/(?:^|[-_. ])(I?Q\d(?:_[A-Za-z0-9]+)*|BF16|F16|F32)(?=$|[-_. ])/gi)];
|
|
12862
|
+
if (matches.length > 0) return matches[matches.length - 1][1].toUpperCase();
|
|
12784
12863
|
const apex = filename.match(/APEX(?:-[A-Za-z0-9]+){0,3}?-(I-)?(NANO|MINI|COMPACT|BALANCED|QUALITY)(?=\.|$|-)/i);
|
|
12785
12864
|
if (apex) return `APEX-${apex[1] ? "I-" : ""}${apex[2].toUpperCase()}`;
|
|
12786
12865
|
return "?";
|
|
12787
12866
|
}
|
|
12788
12867
|
|
|
12789
12868
|
// src/models/scanner.ts
|
|
12790
|
-
var CACHE_VERSION =
|
|
12869
|
+
var CACHE_VERSION = 6;
|
|
12791
12870
|
function attentionLayoutOf(meta) {
|
|
12792
12871
|
const a = meta ?? {};
|
|
12793
12872
|
const out = {};
|
|
@@ -12854,6 +12933,9 @@ var Scanner = class {
|
|
|
12854
12933
|
lastScanAt = "";
|
|
12855
12934
|
cache = /* @__PURE__ */ new Map();
|
|
12856
12935
|
cachePath;
|
|
12936
|
+
// [legacyKey, key] pairs discovered during the CURRENT rescan — see the comment in `entryFor`
|
|
12937
|
+
// for why these are batched into one config write instead of applied as they're found.
|
|
12938
|
+
pendingKeyMigrations = [];
|
|
12857
12939
|
list() {
|
|
12858
12940
|
return { models: this.entries, scanning: this.scanning, lastScanAt: this.lastScanAt };
|
|
12859
12941
|
}
|
|
@@ -12912,11 +12994,18 @@ var Scanner = class {
|
|
|
12912
12994
|
if (existsSync19(d)) walk(d, scan);
|
|
12913
12995
|
await tick();
|
|
12914
12996
|
}
|
|
12997
|
+
this.pendingKeyMigrations = [];
|
|
12915
12998
|
const gguf = await this.build(scan.ggufs);
|
|
12916
12999
|
const mlx = scan.mlxDirs.map((dir) => mlxEntryFor(dir));
|
|
12917
13000
|
this.entries = [...gguf, ...mlx].sort((a, b) => a.name.localeCompare(b.name));
|
|
12918
13001
|
this.lastScanAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
12919
13002
|
this.saveCache();
|
|
13003
|
+
if (this.pendingKeyMigrations.length > 0) {
|
|
13004
|
+
const pairs = this.pendingKeyMigrations;
|
|
13005
|
+
this.store.update((cfg2) => {
|
|
13006
|
+
for (const [oldKey, newKey] of pairs) migrateModelKey(cfg2, oldKey, newKey);
|
|
13007
|
+
});
|
|
13008
|
+
}
|
|
12920
13009
|
} finally {
|
|
12921
13010
|
this.scanning = false;
|
|
12922
13011
|
}
|
|
@@ -12986,12 +13075,16 @@ var Scanner = class {
|
|
|
12986
13075
|
}
|
|
12987
13076
|
}
|
|
12988
13077
|
const fileName = basename2(path);
|
|
12989
|
-
const quant = meta?.quant ||
|
|
13078
|
+
const quant = quantFromName(fileName) !== "?" ? quantFromName(fileName) : meta?.quant || "?";
|
|
12990
13079
|
const name = meta?.name || cleanName(fileName);
|
|
12991
13080
|
const vision = mmprojPath !== null;
|
|
12992
13081
|
const arch2 = meta?.arch ?? "unknown";
|
|
13082
|
+
const key = `${name.toLowerCase()}|${quant}|${sizeBytes}`;
|
|
13083
|
+
const legacyQuant = meta?.quant || quantFromName(fileName);
|
|
13084
|
+
const legacyKey = `${name.toLowerCase()}|${legacyQuant}|${sizeBytes}`;
|
|
13085
|
+
if (legacyKey !== key) this.pendingKeyMigrations.push([legacyKey, key]);
|
|
12993
13086
|
return {
|
|
12994
|
-
key
|
|
13087
|
+
key,
|
|
12995
13088
|
name,
|
|
12996
13089
|
path,
|
|
12997
13090
|
dir,
|
|
@@ -13015,6 +13108,7 @@ var Scanner = class {
|
|
|
13015
13108
|
mmprojPath: vision ? mmprojPath : null,
|
|
13016
13109
|
mmprojSizeBytes: vision ? mmprojSizeBytes : 0,
|
|
13017
13110
|
hasChatTemplate: meta?.hasChatTemplate ?? false,
|
|
13111
|
+
reasoningEffort: meta?.reasoningEffort ?? false,
|
|
13018
13112
|
embedding: isEmbeddingModel(arch2, fileName),
|
|
13019
13113
|
incomplete,
|
|
13020
13114
|
parseError,
|
|
@@ -13107,6 +13201,7 @@ function mlxEntryFor(dir) {
|
|
|
13107
13201
|
let sizeBytes = 0;
|
|
13108
13202
|
let mtimeMs = 0;
|
|
13109
13203
|
let hasChatTemplate = false;
|
|
13204
|
+
let reasoningEffort = false;
|
|
13110
13205
|
try {
|
|
13111
13206
|
for (const n of readdirSync7(dir)) {
|
|
13112
13207
|
const lower = n.toLowerCase();
|
|
@@ -13117,7 +13212,11 @@ function mlxEntryFor(dir) {
|
|
|
13117
13212
|
}
|
|
13118
13213
|
}
|
|
13119
13214
|
const tc = join23(dir, "tokenizer_config.json");
|
|
13120
|
-
|
|
13215
|
+
const tcText = existsSync19(tc) ? readFileSync8(tc, "utf8") : "";
|
|
13216
|
+
const jinjaPath = join23(dir, "chat_template.jinja");
|
|
13217
|
+
const jinjaText = existsSync19(jinjaPath) ? readFileSync8(jinjaPath, "utf8") : "";
|
|
13218
|
+
hasChatTemplate = tcText.includes("chat_template") || jinjaText !== "";
|
|
13219
|
+
reasoningEffort = tcText.includes("reasoning_effort") || jinjaText.includes("reasoning_effort");
|
|
13121
13220
|
} catch {
|
|
13122
13221
|
}
|
|
13123
13222
|
let incomplete = false;
|
|
@@ -13162,6 +13261,7 @@ function mlxEntryFor(dir) {
|
|
|
13162
13261
|
mmprojPath: null,
|
|
13163
13262
|
mmprojSizeBytes: 0,
|
|
13164
13263
|
hasChatTemplate,
|
|
13264
|
+
reasoningEffort,
|
|
13165
13265
|
embedding: isEmbeddingModel(arch2, basename2(dir)),
|
|
13166
13266
|
incomplete,
|
|
13167
13267
|
parseError,
|
|
@@ -15868,9 +15968,20 @@ function spillMb(baselineSharedMb, loadedSharedMb) {
|
|
|
15868
15968
|
if (baselineSharedMb === null || loadedSharedMb === null) return null;
|
|
15869
15969
|
return Math.max(0, loadedSharedMb - baselineSharedMb);
|
|
15870
15970
|
}
|
|
15871
|
-
|
|
15971
|
+
var SPILL_PROXIMITY_MB = 1024;
|
|
15972
|
+
var SPILL_FLOOR_CAP_MB = 2048;
|
|
15973
|
+
function isSpilling(spill, vramAbsMb, budgetMb, floorMb = null, pooled = false) {
|
|
15872
15974
|
if (spill === null) return false;
|
|
15873
|
-
|
|
15975
|
+
const floor = pooled ? 0 : Math.min(floorMb ?? 0, SPILL_FLOOR_CAP_MB);
|
|
15976
|
+
if (spill - floor <= SPILL_TOLERANCE_MB) return false;
|
|
15977
|
+
if (!pooled && vramAbsMb !== null && budgetMb > 0 && vramAbsMb < budgetMb - SPILL_PROXIMITY_MB) return false;
|
|
15978
|
+
return true;
|
|
15979
|
+
}
|
|
15980
|
+
function spillFloor(floorMb, spill, vramAbsMb, budgetMb, pooled = false) {
|
|
15981
|
+
if (pooled || spill === null || vramAbsMb === null || budgetMb <= 0) return floorMb;
|
|
15982
|
+
if (vramAbsMb >= budgetMb - SPILL_PROXIMITY_MB) return floorMb;
|
|
15983
|
+
const learned = floorMb === null ? spill : Math.min(floorMb, spill);
|
|
15984
|
+
return Math.min(learned, SPILL_FLOOR_CAP_MB);
|
|
15874
15985
|
}
|
|
15875
15986
|
|
|
15876
15987
|
// src/api/path-utils.ts
|
|
@@ -17145,6 +17256,8 @@ var BenchRunner = class {
|
|
|
17145
17256
|
if (base2.nglFit) return this.benchAt(entry, sys, base2, caps, results, "auto-fit");
|
|
17146
17257
|
let bestNgl = 0;
|
|
17147
17258
|
const budgetMb = gpuBudgetMb(sys, base2);
|
|
17259
|
+
let spillFloorMb = null;
|
|
17260
|
+
const pooled = sys.gpus.length > 1 && base2.gpu.splitMode !== "none";
|
|
17148
17261
|
if (sys.gpus.length > 0) {
|
|
17149
17262
|
const hi0 = entry.blockCount > 0 ? entry.blockCount : 99;
|
|
17150
17263
|
let lo = 0, hi = hi0;
|
|
@@ -17155,7 +17268,8 @@ var BenchRunner = class {
|
|
|
17155
17268
|
const probe2 = await this.probeVram(entry, sys, { ...base2, ngl: mid }, caps);
|
|
17156
17269
|
this.pushProbe(results, base2, "ngl", mid, probe2);
|
|
17157
17270
|
await this.settleGpu(sys);
|
|
17158
|
-
|
|
17271
|
+
spillFloorMb = spillFloor(spillFloorMb, probe2.spillMb, probe2.vramAbsMb, budgetMb, pooled);
|
|
17272
|
+
const verdict = probeVerdict(probe2, budgetMb, headroomMb, spillFloorMb, pooled);
|
|
17159
17273
|
if (verdict.decision === "fits") {
|
|
17160
17274
|
bestNgl = mid;
|
|
17161
17275
|
lo = mid + 1;
|
|
@@ -17169,7 +17283,7 @@ var BenchRunner = class {
|
|
|
17169
17283
|
}
|
|
17170
17284
|
if (bestNgl === null) return null;
|
|
17171
17285
|
let found = await this.benchAt(entry, sys, { ...base2, ngl: bestNgl }, caps, results, `ngl=${bestNgl}`);
|
|
17172
|
-
if (found && isSpilling(found.cand.spillMb) && bestNgl > 0) {
|
|
17286
|
+
if (found && isSpilling(found.cand.spillMb, found.cand.vramAbsMb, budgetMb, spillFloorMb, pooled) && bestNgl > 0) {
|
|
17173
17287
|
this.emit(`ngl=${bestNgl} spilled ${Math.round(found.cand.spillMb)} MB once actually generating (the load-only probe could not see this) \u2014 retrying at ngl=${bestNgl - 1}`);
|
|
17174
17288
|
const safer = await this.benchAt(entry, sys, { ...base2, ngl: bestNgl - 1 }, caps, results, `ngl=${bestNgl - 1} (spill backoff)`);
|
|
17175
17289
|
if (safer) {
|
|
@@ -17204,13 +17318,16 @@ var BenchRunner = class {
|
|
|
17204
17318
|
const budgetMb = gpuBudgetMb(sys, base2);
|
|
17205
17319
|
let lo = 0, hi = maxN;
|
|
17206
17320
|
let bestN = null;
|
|
17321
|
+
let spillFloorMb = null;
|
|
17322
|
+
const pooled = sys.gpus.length > 1 && base2.gpu.splitMode !== "none";
|
|
17207
17323
|
while (lo <= hi && !this.cancelled && Date.now() <= this.deadline) {
|
|
17208
17324
|
const mid = Math.floor((lo + hi) / 2);
|
|
17209
17325
|
this.state = { ...this.state, step: `KV ${base2.kvTypeK}: probing nCpuMoe=${mid} (range ${lo}\u2013${hi})\u2026`, candidates: results };
|
|
17210
17326
|
const probe2 = await this.probeVram(entry, sys, { ...base2, nCpuMoe: mid }, caps);
|
|
17211
17327
|
this.pushProbe(results, base2, "nCpuMoe", mid, probe2);
|
|
17212
17328
|
await this.settleGpu(sys);
|
|
17213
|
-
|
|
17329
|
+
spillFloorMb = spillFloor(spillFloorMb, probe2.spillMb, probe2.vramAbsMb, budgetMb, pooled);
|
|
17330
|
+
const verdict = probeVerdict(probe2, budgetMb, headroomMb, spillFloorMb, pooled);
|
|
17214
17331
|
if (verdict.decision === "fits") {
|
|
17215
17332
|
bestN = mid;
|
|
17216
17333
|
hi = mid - 1;
|
|
@@ -17238,7 +17355,7 @@ var BenchRunner = class {
|
|
|
17238
17355
|
}
|
|
17239
17356
|
if (n < maxN) this.emit(`nCpuMoe=${n} failed to bench (${results[results.length - 1]?.outcome ?? "crash"}) \u2014 retrying at nCpuMoe=${n + 1}`);
|
|
17240
17357
|
}
|
|
17241
|
-
if (found && isSpilling(found.cand.spillMb) && foundN < maxN) {
|
|
17358
|
+
if (found && isSpilling(found.cand.spillMb, found.cand.vramAbsMb, budgetMb, spillFloorMb, pooled) && foundN < maxN) {
|
|
17242
17359
|
this.emit(`nCpuMoe=${foundN} spilled ${Math.round(found.cand.spillMb)} MB once actually generating (the load-only probe could not see this) \u2014 retrying at nCpuMoe=${foundN + 1}`);
|
|
17243
17360
|
const safer = await this.benchAt(entry, sys, { ...base2, nCpuMoe: foundN + 1 }, caps, results, `nCpuMoe=${foundN + 1} (spill backoff)`);
|
|
17244
17361
|
if (safer) {
|
|
@@ -17929,9 +18046,9 @@ function pickKvQuants(baseKv, kvTypes) {
|
|
|
17929
18046
|
for (const t of [baseKv, ...QUALITY_KV]) if (supported(t) && !out.includes(t)) out.push(t);
|
|
17930
18047
|
return out;
|
|
17931
18048
|
}
|
|
17932
|
-
function probeVerdict(probe2, budgetMb, headroomMb) {
|
|
18049
|
+
function probeVerdict(probe2, budgetMb, headroomMb, spillFloorMb = null, pooled = false) {
|
|
17933
18050
|
if (probe2.outcome === "oom") return { decision: "offload-more", reason: "oom" };
|
|
17934
|
-
if (isSpilling(probe2.spillMb)) {
|
|
18051
|
+
if (isSpilling(probe2.spillMb, probe2.vramAbsMb, budgetMb, spillFloorMb, pooled)) {
|
|
17935
18052
|
return { decision: "offload-more", reason: "spill", shortfallMb: probe2.spillMb };
|
|
17936
18053
|
}
|
|
17937
18054
|
if (overHeadroom(probe2.vramAbsMb, budgetMb, headroomMb)) {
|
|
@@ -24682,6 +24799,15 @@ function registerCodeRoutes(app2, d, codeRuns) {
|
|
|
24682
24799
|
sessionAuth.setThinkingBudget(run.id, tokens === -1 ? null : tokens);
|
|
24683
24800
|
return c.json({ ok: true, tokens });
|
|
24684
24801
|
});
|
|
24802
|
+
app2.patch("/api/v1/code/sessions/:id/reasoning-effort", async (c) => {
|
|
24803
|
+
const id = c.req.param("id");
|
|
24804
|
+
const run = db2.getAgentRun(id);
|
|
24805
|
+
if (!run) return err8(c, 404, "not_found", "Session not found.");
|
|
24806
|
+
const b = await body8(c);
|
|
24807
|
+
const effort = parseReasoningEffort(b.effort) ?? null;
|
|
24808
|
+
sessionAuth.setReasoningEffort(run.id, effort);
|
|
24809
|
+
return c.json({ ok: true, effort });
|
|
24810
|
+
});
|
|
24685
24811
|
app2.get("/api/v1/code/sessions/:id/last-usage", (c) => {
|
|
24686
24812
|
const id = c.req.param("id");
|
|
24687
24813
|
const run = db2.getAgentRun(id);
|
|
@@ -24930,7 +25056,7 @@ function registerCodeRoutes(app2, d, codeRuns) {
|
|
|
24930
25056
|
userMsgId = lastUser.id;
|
|
24931
25057
|
task = contextFilesBlock(lastUser.textAttachments) + lastUser.content;
|
|
24932
25058
|
}
|
|
24933
|
-
const enqueueParams = { convId: run.convId, repoRoot: agentCwd(run), task, userMsgId, thinkingBudget: b.thinkingBudget };
|
|
25059
|
+
const enqueueParams = { convId: run.convId, repoRoot: agentCwd(run), task, userMsgId, thinkingBudget: b.thinkingBudget, reasoningEffort: parseReasoningEffort(b.reasoningEffort) };
|
|
24934
25060
|
if (kind === "steer") {
|
|
24935
25061
|
const { steered, queued: queued2 } = await runs.steer(id, enqueueParams);
|
|
24936
25062
|
return c.json({ ok: true, queued: queued2, steered, userMessageId: userMsgId }, 202);
|
|
@@ -25856,6 +25982,15 @@ function registerGateway(app2, d, opts = {}) {
|
|
|
25856
25982
|
const requestOrigin = new URL(c.req.url).origin;
|
|
25857
25983
|
const guidance = req.tools?.length ? applyAgentGuidance(req, requestOrigin) : null;
|
|
25858
25984
|
const oaiBody = mapToOpenAI(req);
|
|
25985
|
+
if (anthropicCodeSessionId) {
|
|
25986
|
+
const effortOverride = sessionAuth.getReasoningEffortForToken(anthropicToken);
|
|
25987
|
+
if (effortOverride === "off") {
|
|
25988
|
+
oaiBody.thinking_budget_tokens = 0;
|
|
25989
|
+
oaiBody.chat_template_kwargs = { ...oaiBody.chat_template_kwargs ?? {}, enable_thinking: false };
|
|
25990
|
+
} else if (effortOverride !== null) {
|
|
25991
|
+
oaiBody.chat_template_kwargs = { ...oaiBody.chat_template_kwargs ?? {}, reasoning_effort: effortOverride };
|
|
25992
|
+
}
|
|
25993
|
+
}
|
|
25859
25994
|
if (guidance?.forceTextOnly) oaiBody.tool_choice = "none";
|
|
25860
25995
|
const oaiAlias = engineModelAlias(d.registry.active()?.kind ?? "", d.manager.currentOpts()?.modelPath);
|
|
25861
25996
|
if (oaiAlias) oaiBody.model = oaiAlias;
|
|
@@ -26102,6 +26237,13 @@ function registerGateway(app2, d, opts = {}) {
|
|
|
26102
26237
|
if (override > 0) parsedBody.thinking_budget_tokens = override;
|
|
26103
26238
|
else delete parsedBody.thinking_budget_tokens;
|
|
26104
26239
|
}
|
|
26240
|
+
const effortOverride = sessionAuth.getReasoningEffortForToken(chatToken);
|
|
26241
|
+
if (effortOverride === "off") {
|
|
26242
|
+
parsedBody.thinking_budget_tokens = 0;
|
|
26243
|
+
parsedBody.chat_template_kwargs = { ...parsedBody.chat_template_kwargs ?? {}, enable_thinking: false };
|
|
26244
|
+
} else if (effortOverride !== null) {
|
|
26245
|
+
parsedBody.chat_template_kwargs = { ...parsedBody.chat_template_kwargs ?? {}, reasoning_effort: effortOverride };
|
|
26246
|
+
}
|
|
26105
26247
|
}
|
|
26106
26248
|
if (parsedBody?.stream === true && parsedBody.stream_options === void 0) {
|
|
26107
26249
|
parsedBody.stream_options = { include_usage: true };
|
|
@@ -0,0 +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-Djd745uq.js";import{f as V}from"./chat-api-B7cm_Kjj.js";import{f as X,a as Z}from"./agent-api-DyPUCnyd.js";import{P as B}from"./personas-Bdrl3tL6.js";import{C as ee}from"./chevron-left-BQ3TyvUR.js";import{R as te}from"./rotate-ccw-Dl2CDY8F.js";import{T as se}from"./trash-2-C5UxcfNn.js";import{C as ne}from"./chevron-right-C1TzfDRc.js";import"./dropdown-menu-Co-9JBK7.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};
|