turbollm 1.13.1 → 1.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -2
- package/dist/{chunk-TIH3B2GZ.js → chunk-HQ76BEUS.js} +200 -196
- package/dist/chunk-Y3TMLJQD.js +1114 -0
- package/dist/cli.js +3729 -2958
- package/dist/code-routes.js +1 -1
- package/dist/code-run-manager.js +1 -1
- package/dist/factory-NOUUQICH.js +7 -0
- package/dist/webdist/assets/{AgentEditPage-Dym1KyqX.js → AgentEditPage-8XwklBCN.js} +1 -1
- package/dist/webdist/assets/{ChatScreen-BcdP2zdp.js → ChatScreen-BG-gWo8i.js} +17 -17
- package/dist/webdist/assets/CodeComposer-Bui_gqhF.js +1 -0
- package/dist/webdist/assets/CodeHomeScreen-CEaCj3je.js +1 -0
- package/dist/webdist/assets/{CodeSessionScreen-BOQ6KoV7.js → CodeSessionScreen-DUTkKMNW.js} +2 -2
- package/dist/webdist/assets/CustomizeScreen-ze18T4hb.js +4 -0
- package/dist/webdist/assets/{EnginesScreen-DsXKQBdB.js → EnginesScreen-CmJVhifa.js} +10 -10
- package/dist/webdist/assets/HardwareSection-63UUvSMO.js +1 -0
- package/dist/webdist/assets/{ModelDetailDialog-BXITKheg.js → ModelDetailDialog-C2lnCsw6.js} +1 -1
- package/dist/webdist/assets/{ModelLoadMenu-BA07PQdL.js → ModelLoadMenu-D0bpk6p2.js} +1 -1
- package/dist/webdist/assets/{ModelsScreen-B9Lfop2U.js → ModelsScreen-DYSvF-AP.js} +2 -2
- package/dist/webdist/assets/OnboardingScreen-Bti1XKVZ.js +1 -0
- package/dist/webdist/assets/RoutineEditPage-Dytik45T.js +1 -0
- package/dist/webdist/assets/RoutinesPanel-CK2_OmGj.js +1 -0
- package/dist/webdist/assets/SettingsScreen-qcB-Wlhm.js +2 -0
- package/dist/webdist/assets/{SidebarResizeHandle-DVs8SGko.js → SidebarResizeHandle-C6DzzA0i.js} +2 -2
- package/dist/webdist/assets/{SkillEditPage-DTIwnb5M.js → SkillEditPage-BoVodeSt.js} +1 -1
- package/dist/webdist/assets/{ToolApprovalBar-C1Za_m4h.js → ToolApprovalBar-CkVy2BpV.js} +3 -3
- package/dist/webdist/assets/WorkspaceScreen-BzYimITz.js +1 -0
- package/dist/webdist/assets/{abnfDiagram-N423BO3Z-CVyB7CsQ.js → abnfDiagram-N423BO3Z-BsFZfp7v.js} +1 -1
- package/dist/webdist/assets/{agent-api-mKI2ziy1.js → agent-api-CeGvce9t.js} +1 -1
- package/dist/webdist/assets/alert-dialog-Crc_A3Jz.js +1 -0
- package/dist/webdist/assets/{arc-vy1HbZG7.js → arc-DBKAh_3p.js} +1 -1
- package/dist/webdist/assets/{architectureDiagram-T3A2C74G-CMd1GRSg.js → architectureDiagram-T3A2C74G-DF2Iau9y.js} +1 -1
- package/dist/webdist/assets/{blockDiagram-VBNYF7ZC-C0TDSyYW.js → blockDiagram-VBNYF7ZC-EIM7OH8W.js} +1 -1
- package/dist/webdist/assets/{c4Diagram-5PPSVZJV-M6Gw1tuY.js → c4Diagram-5PPSVZJV-DfTJQH_y.js} +1 -1
- package/dist/webdist/assets/channel-BF2z4CLG.js +1 -0
- package/dist/webdist/assets/chat-api-BspgdIew.js +3 -0
- package/dist/webdist/assets/chat-queries-dQVxfOyx.js +1 -0
- package/dist/webdist/assets/{chevron-down-Cr8PyXv0.js → chevron-down-DNeXZ14t.js} +1 -1
- package/dist/webdist/assets/{chevron-left-BWp4EppC.js → chevron-left-yPpon0Zo.js} +1 -1
- package/dist/webdist/assets/{chevron-right-BNTB7WiI.js → chevron-right-qwzlPkv4.js} +1 -1
- package/dist/webdist/assets/{chunk-2GRJ4B5K-BtJnPm_X.js → chunk-2GRJ4B5K-g8WkdrcJ.js} +1 -1
- package/dist/webdist/assets/{chunk-2Q5K7J3B-CUF6QQ1A.js → chunk-2Q5K7J3B-DiSXrpfm.js} +1 -1
- package/dist/webdist/assets/{chunk-5RXB4S5H-BtKyDHvg.js → chunk-5RXB4S5H--rX8NQES.js} +1 -1
- package/dist/webdist/assets/{chunk-5VM5RSS4-D1I4GKUh.js → chunk-5VM5RSS4-D0bbkNOA.js} +1 -1
- package/dist/webdist/assets/{chunk-6Q2QTUOP-CuhRlIbl.js → chunk-6Q2QTUOP-CyjvDHy7.js} +1 -1
- package/dist/webdist/assets/{chunk-GF5L2VYU-DXuYLaz3.js → chunk-GF5L2VYU-DBsZFyHH.js} +1 -1
- package/dist/webdist/assets/{chunk-JWPE2WC7-CXyw7def.js → chunk-JWPE2WC7-BJX8rZY8.js} +1 -1
- package/dist/webdist/assets/{chunk-KBJHAD2P-DTxBuz43.js → chunk-KBJHAD2P-CzHI537O.js} +1 -1
- package/dist/webdist/assets/{chunk-RYQCIY6F-CJNSzYoP.js → chunk-RYQCIY6F-DcQ5BoLP.js} +1 -1
- package/dist/webdist/assets/{chunk-XXDRQBXY-DEVi8OYy.js → chunk-XXDRQBXY-DwaqNMb3.js} +1 -1
- package/dist/webdist/assets/{circle-check-tPHpKH4i.js → circle-check-Brhy4Orf.js} +1 -1
- package/dist/webdist/assets/{circle-x-BtZB2fZ7.js → circle-x-BvhAr_O9.js} +1 -1
- package/dist/webdist/assets/classDiagram-JCYQIIEL-D-pqoTab.js +1 -0
- package/dist/webdist/assets/classDiagram-v2-OCEON4UE-D-pqoTab.js +1 -0
- package/dist/webdist/assets/collapsible-Bg5PA5Nz.js +1 -0
- package/dist/webdist/assets/{cose-bilkent-JH36ORCC-BFcCFhIi.js → cose-bilkent-JH36ORCC-DT2idxjo.js} +1 -1
- package/dist/webdist/assets/{cynefin-VYW2F7L2-BYQiVIyh.js → cynefin-VYW2F7L2-9kVBD_9a.js} +1 -1
- package/dist/webdist/assets/{cynefinDiagram-MW4NZA55-BkQKk_25.js → cynefinDiagram-MW4NZA55-CTix7oEO.js} +1 -1
- package/dist/webdist/assets/{dagre-VZM6K2ZE-rsfyi456.js → dagre-VZM6K2ZE-DbRB_1Ng.js} +1 -1
- package/dist/webdist/assets/{diagram-7IWD3JNH-C0DN8V1H.js → diagram-7IWD3JNH-ClCpikH_.js} +1 -1
- package/dist/webdist/assets/{diagram-B4RE2ZJO-VrZw1kLY.js → diagram-B4RE2ZJO-wQlXyd4e.js} +1 -1
- package/dist/webdist/assets/{diagram-LBJQPF4R-BcYKBexW.js → diagram-LBJQPF4R-zgM6REwi.js} +1 -1
- package/dist/webdist/assets/{diagram-Q27KOJAE-CXS9VQM1.js → diagram-Q27KOJAE-DvIssBlm.js} +1 -1
- package/dist/webdist/assets/{diagram-UB23O5K3-o3LA6b9f.js → diagram-UB23O5K3-DdQiF9NE.js} +1 -1
- package/dist/webdist/assets/{dropdown-menu-BdlxlOvr.js → dropdown-menu-HI5N3Rmt.js} +1 -1
- package/dist/webdist/assets/{ebnfDiagram-BXEA7PRR-CeVCgeJ0.js → ebnfDiagram-BXEA7PRR-CpSxEGTe.js} +1 -1
- package/dist/webdist/assets/{erDiagram-JOGREHBK-DNDqb-7g.js → erDiagram-JOGREHBK-BrhRHXD4.js} +1 -1
- package/dist/webdist/assets/{file-text-ClQSSMFI.js → file-text-Cx83fgk0.js} +1 -1
- package/dist/webdist/assets/{flowDiagram-UKHOOZJN-6Y0STfYO.js → flowDiagram-UKHOOZJN-CIxMbmNO.js} +1 -1
- package/dist/webdist/assets/{folder-input-BPVoURwk.js → folder-input-BN5lzecG.js} +1 -1
- package/dist/webdist/assets/{folder-plus-C6qdRRE1.js → folder-plus-B-imiY57.js} +1 -1
- package/dist/webdist/assets/{ganttDiagram-PKOTCBZU-DEKJRLOu.js → ganttDiagram-PKOTCBZU-CiO9YNNt.js} +1 -1
- package/dist/webdist/assets/{git-branch-CGm1i_Eb.js → git-branch-BY-pdlSo.js} +1 -1
- package/dist/webdist/assets/{gitGraphDiagram-DS77QQ5N-x2UJFG-U.js → gitGraphDiagram-DS77QQ5N-Dz_fBDX6.js} +1 -1
- package/dist/webdist/assets/globe-FB3s-Kjz.js +1 -0
- package/dist/webdist/assets/index-A9e9aiYI.css +1 -0
- package/dist/webdist/assets/{index-DzbdV438.js → index-Bs1-t0Ft.js} +1 -1
- package/dist/webdist/assets/index-CfwXVQIu.js +14 -0
- package/dist/webdist/assets/{infoDiagram-6WML65LV-C6C1bGzu.js → infoDiagram-6WML65LV-BP9JLl_M.js} +1 -1
- package/dist/webdist/assets/{ishikawaDiagram-WSZJBQD7-CZVmvAx3.js → ishikawaDiagram-WSZJBQD7-CeBpQALC.js} +1 -1
- package/dist/webdist/assets/{journeyDiagram-NVQOT4AX-CJ2qLlRG.js → journeyDiagram-NVQOT4AX-Cnn5M1YO.js} +1 -1
- package/dist/webdist/assets/{kanban-definition-27J2QSJJ-C1j9o0ks.js → kanban-definition-27J2QSJJ-BMnM-8zj.js} +1 -1
- package/dist/webdist/assets/{linear-DXj2WKUc.js → linear-ontMFf7q.js} +1 -1
- package/dist/webdist/assets/{lock-BI2ZVie9.js → lock-CVTYolJH.js} +1 -1
- package/dist/webdist/assets/{mermaid.core-Zn6MPOtK.js → mermaid.core-BX4U-c4C.js} +4 -4
- package/dist/webdist/assets/{mindmap-definition-FAOFIHXS-CDJMKx24.js → mindmap-definition-FAOFIHXS-D55lobOz.js} +1 -1
- package/dist/webdist/assets/{monitor-DY9e5ORA.js → monitor-BVyi9riP.js} +1 -1
- package/dist/webdist/assets/{pegDiagram-VL7TDLO6-DDIE3L3w.js → pegDiagram-VL7TDLO6-BE11XRQ7.js} +1 -1
- package/dist/webdist/assets/{pencil-Db1lkam5.js → pencil-xiVy9lBH.js} +1 -1
- package/dist/webdist/assets/{pieDiagram-7S7Q4E2Y-9-_Vzadf.js → pieDiagram-7S7Q4E2Y-BMHDg8ys.js} +1 -1
- package/dist/webdist/assets/{quadrantDiagram-CIZ2JOQS-DVFOD-B7.js → quadrantDiagram-CIZ2JOQS-2sqR5qXm.js} +1 -1
- package/dist/webdist/assets/radix-B7FN0WwE.js +41 -0
- package/dist/webdist/assets/{railroadDiagram-AXF67PYL-DaK1Lf9k.js → railroadDiagram-AXF67PYL-CrA2ZKhq.js} +1 -1
- package/dist/webdist/assets/{refresh-cw-ClWNeewb.js → refresh-cw-BGipAyiS.js} +1 -1
- package/dist/webdist/assets/{remote-failure-CVQYekAL.js → remote-failure-CGk8OyjK.js} +1 -1
- package/dist/webdist/assets/{requirementDiagram-LRYGKXZP-RXJrMu9j.js → requirementDiagram-LRYGKXZP-RlYw_SgL.js} +1 -1
- package/dist/webdist/assets/{rocket-BE4Peice.js → rocket-DHnkfnhQ.js} +1 -1
- package/dist/webdist/assets/{rotate-ccw-C2s6i5Jp.js → rotate-ccw-DmG7PkUG.js} +1 -1
- package/dist/webdist/assets/{sankeyDiagram-W5VNT64P-CFE9sU4S.js → sankeyDiagram-W5VNT64P-B61EFr-D.js} +1 -1
- package/dist/webdist/assets/{sequenceDiagram-SI44F4Z6-DZkMg137.js → sequenceDiagram-SI44F4Z6-Cj4e2tXy.js} +1 -1
- package/dist/webdist/assets/sheet-DFCO49jw.js +1 -0
- package/dist/webdist/assets/{sizeCapture-X5ZJPWSS-NHtmoElu.js → sizeCapture-X5ZJPWSS-CYyUy4Qg.js} +1 -1
- package/dist/webdist/assets/{skeleton-CVFgYJeZ.js → skeleton-DVrIPwv0.js} +1 -1
- package/dist/webdist/assets/{sliders-horizontal-lnE2U8Ng.js → sliders-horizontal-DQYu0jQs.js} +1 -1
- package/dist/webdist/assets/{sparkles-DDdOhO-u.js → sparkles-DKoUw0Ra.js} +1 -1
- package/dist/webdist/assets/{star-DK9AFk2h.js → star-EY1hsb1g.js} +1 -1
- package/dist/webdist/assets/{stateDiagram-OKZ733FA-qeV-WNNN.js → stateDiagram-OKZ733FA-CIAre6fb.js} +1 -1
- package/dist/webdist/assets/stateDiagram-v2-UEYNNEHI-c4H1EbPk.js +1 -0
- package/dist/webdist/assets/{swimlanes-SLNWSIFB-Dn2032Qm.js → swimlanes-SLNWSIFB-DGZBf-GQ.js} +2 -2
- package/dist/webdist/assets/swimlanesDiagram-ULZ7WXOC-C9AdErpx.js +8 -0
- package/dist/webdist/assets/{switch-C8TDmk4o.js → switch-CXoaYXdG.js} +1 -1
- package/dist/webdist/assets/{terminal-B8Cu2_ni.js → terminal-BrWVclQ0.js} +1 -1
- package/dist/webdist/assets/{timeline-definition-Z64GVDOM-CeOxLPuW.js → timeline-definition-Z64GVDOM-mu5ti0bv.js} +1 -1
- package/dist/webdist/assets/{trash-2-2wk4VHfQ.js → trash-2-WYWL4BUK.js} +1 -1
- package/dist/webdist/assets/{vennDiagram-T6HMQDX7-BzQXbsSd.js → vennDiagram-T6HMQDX7-OxY1RaKm.js} +1 -1
- package/dist/webdist/assets/{wardleyDiagram-T6FBY63Y-ZnmHNIut.js → wardleyDiagram-T6FBY63Y-BtG14vOo.js} +1 -1
- package/dist/webdist/assets/{wrench-Cfgbkzi3.js → wrench-D_MLSbdw.js} +1 -1
- package/dist/webdist/assets/{xychartDiagram-ELKLHX3M-ByHBwPv5.js → xychartDiagram-ELKLHX3M-DeNO3ZVS.js} +1 -1
- package/dist/webdist/index.html +3 -3
- package/package.json +1 -1
- package/dist/webdist/assets/CodeComposer-BCxQ5mSO.js +0 -1
- package/dist/webdist/assets/CodeHomeScreen-DvHCATzs.js +0 -1
- package/dist/webdist/assets/CustomizeScreen-BwMOTrmg.js +0 -4
- package/dist/webdist/assets/HardwareSection-DXHuVSsh.js +0 -1
- package/dist/webdist/assets/OnboardingScreen-CdCJbHnx.js +0 -1
- package/dist/webdist/assets/RoutineEditPage-B-Q_NK95.js +0 -1
- package/dist/webdist/assets/RoutinesPanel-DElOj8Dh.js +0 -1
- package/dist/webdist/assets/SettingsScreen-CbRWiTC9.js +0 -2
- package/dist/webdist/assets/WorkspaceScreen-CjXZkcXT.js +0 -1
- package/dist/webdist/assets/alert-dialog-a5ByK8bb.js +0 -1
- package/dist/webdist/assets/channel-Co0osRum.js +0 -1
- package/dist/webdist/assets/chat-api-u48Gn8_q.js +0 -3
- package/dist/webdist/assets/chat-queries-C2eUqnQe.js +0 -1
- package/dist/webdist/assets/classDiagram-JCYQIIEL-Cd9CRK17.js +0 -1
- package/dist/webdist/assets/classDiagram-v2-OCEON4UE-Cd9CRK17.js +0 -1
- package/dist/webdist/assets/collapsible-BEf-vk0G.js +0 -1
- package/dist/webdist/assets/common-D2Aax55A.js +0 -1
- package/dist/webdist/assets/index-CKu-FGKB.js +0 -14
- package/dist/webdist/assets/index-jjD6-DKX.css +0 -1
- package/dist/webdist/assets/radix-mRz26PwR.js +0 -41
- package/dist/webdist/assets/sheet-65Zlup1V.js +0 -1
- package/dist/webdist/assets/stateDiagram-v2-UEYNNEHI-D8QiIhoF.js +0 -1
- package/dist/webdist/assets/swimlanesDiagram-ULZ7WXOC-CtjO7H8G.js +0 -8
package/README.md
CHANGED
|
@@ -299,6 +299,12 @@ the detail:
|
|
|
299
299
|
set per link — use models only, run a server, or full control — optionally pinned to specific
|
|
300
300
|
models, and revocable at any time from the host. Not yet verified against a real two-machine
|
|
301
301
|
setup, so it stays behind Settings → Experimental.
|
|
302
|
+
- **Remote access** *(experimental, off by default)* — expose TurboLLM to the internet through
|
|
303
|
+
Cloudflare (Quick or Named tunnel), Tailscale (Serve or Funnel), ngrok, or your own reverse
|
|
304
|
+
proxy, from Settings → Network & sharing. Enabling it mints a capability-scoped access token —
|
|
305
|
+
restrict it to chat-only, or also allow loading/unloading models — instead of exposing your
|
|
306
|
+
regular API key, with a live status chip and one-click stop. Not yet verified
|
|
307
|
+
against real Cloudflare/Tailscale/ngrok accounts, so it stays behind Settings → Experimental.
|
|
302
308
|
- **Thinking-budget control** — a graduated slider, not just on/off: cap reasoning to a specific
|
|
303
309
|
token count, disable it entirely, or leave it unlimited. Works in Chat and Code alike.
|
|
304
310
|
- **Reasoning-effort control** for models whose own chat template supports it (e.g. Qwen3.8) —
|
|
@@ -437,8 +443,9 @@ connected); **Remove** undoes it.
|
|
|
437
443
|
|
|
438
444
|
- A **persistent bottom strip** on every screen shows real-time CPU, RAM, GPU and VRAM — values
|
|
439
445
|
and percentages — pulled from `nvidia-smi`, WDDM counters, `rocm-smi`, AMD sysfs, `ioreg`,
|
|
440
|
-
or `/proc` on Linux. Clicking the bar opens detailed gauges and sparklines in Settings → System
|
|
441
|
-
|
|
446
|
+
or `/proc` on Linux. Clicking the bar opens detailed gauges and sparklines in Settings → System,
|
|
447
|
+
including live **disk I/O** (read/write MB/s) and a **shared/spilled VRAM** figure that shows
|
|
448
|
+
when a discrete GPU has spilled into system memory. Toggle it off entirely from Settings → General.
|
|
442
449
|
- **Engines → Monitor** puts the live engine log and those same hardware gauges on one
|
|
443
450
|
always-visible split screen, plus a second, LM Studio-style **developer request log**: every
|
|
444
451
|
completion the daemon serves — external API clients, Code sessions, in-app Chat — with
|
|
@@ -12,11 +12,19 @@ import { EventEmitter as EventEmitter2 } from "events";
|
|
|
12
12
|
// src/chat/chat-routes.ts
|
|
13
13
|
import { streamSSE } from "hono/streaming";
|
|
14
14
|
|
|
15
|
+
// src/auth.ts
|
|
16
|
+
import { createHash, randomBytes, randomUUID } from "crypto";
|
|
17
|
+
import { getConnInfo } from "@hono/node-server/conninfo";
|
|
18
|
+
|
|
19
|
+
// src/remote/access-jwt.ts
|
|
20
|
+
import { createPublicKey, createVerify, verify as cryptoVerify } from "crypto";
|
|
21
|
+
var JWKS_TTL_MS = 60 * 6e4;
|
|
22
|
+
|
|
15
23
|
// src/net.ts
|
|
16
24
|
import { networkInterfaces } from "os";
|
|
17
25
|
|
|
18
26
|
// src/config/config.ts
|
|
19
|
-
import { randomUUID } from "crypto";
|
|
27
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
20
28
|
import { cpSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
|
|
21
29
|
import { homedir } from "os";
|
|
22
30
|
import { dirname, join } from "path";
|
|
@@ -34,194 +42,6 @@ function parseReasoningEffort(value) {
|
|
|
34
42
|
return ALIASES.get(value);
|
|
35
43
|
}
|
|
36
44
|
|
|
37
|
-
// src/tools/approval-gate.ts
|
|
38
|
-
var pending = /* @__PURE__ */ new Map();
|
|
39
|
-
function waitForToolApproval(key, signal) {
|
|
40
|
-
return new Promise((resolvePromise) => {
|
|
41
|
-
const onAbort = () => {
|
|
42
|
-
pending.delete(key);
|
|
43
|
-
resolvePromise("deny");
|
|
44
|
-
};
|
|
45
|
-
const cleanup = () => {
|
|
46
|
-
signal.removeEventListener("abort", onAbort);
|
|
47
|
-
};
|
|
48
|
-
pending.set(key, {
|
|
49
|
-
resolve: (decision) => {
|
|
50
|
-
cleanup();
|
|
51
|
-
resolvePromise(decision);
|
|
52
|
-
},
|
|
53
|
-
cleanup
|
|
54
|
-
});
|
|
55
|
-
if (signal.aborted) {
|
|
56
|
-
onAbort();
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// src/agents/skills.ts
|
|
64
|
-
import { join as join2 } from "path";
|
|
65
|
-
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, rmSync, readdirSync } from "fs";
|
|
66
|
-
var BUILTIN_SKILLS = [
|
|
67
|
-
{
|
|
68
|
-
id: "filesystem",
|
|
69
|
-
name: "Filesystem",
|
|
70
|
-
description: "Read files, list directories, glob patterns within the agent's workspace.",
|
|
71
|
-
instructions: "You can read files and explore directories. Use read_file to read file contents, list_dir to explore, and glob to find files. Always work within your allowed paths.",
|
|
72
|
-
tools: ["read_file", "list_dir", "glob"],
|
|
73
|
-
builtin: true
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
id: "web",
|
|
77
|
-
name: "Web",
|
|
78
|
-
description: "Search the web and fetch URLs for research.",
|
|
79
|
-
instructions: "You can search the web using web_search and fetch URLs with fetch_url. Use these to gather current information and research topics.",
|
|
80
|
-
tools: ["web_search", "fetch_url"],
|
|
81
|
-
builtin: true
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
id: "code",
|
|
85
|
-
name: "Code",
|
|
86
|
-
description: "Execute code for computation and data processing.",
|
|
87
|
-
instructions: "You can run code using run_code. Code execution runs unattended \u2014 ensure your code is correct before running.",
|
|
88
|
-
tools: ["run_code"],
|
|
89
|
-
builtin: true
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
id: "task-tracking",
|
|
93
|
-
name: "Task Tracking",
|
|
94
|
-
description: "Track progress on a task and declare completion.",
|
|
95
|
-
instructions: "You can track your progress with update_doc and declare a task complete with complete_task. Update the working doc regularly to maintain a clear record of what's done and what's left.",
|
|
96
|
-
tools: ["update_doc", "complete_task"],
|
|
97
|
-
builtin: true
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
id: "compose",
|
|
101
|
-
name: "Compose",
|
|
102
|
-
description: "Delegate work to other agents via call_agent.",
|
|
103
|
-
instructions: "You can call other agents using call_agent. Use this to delegate specialized sub-tasks to agents with different capabilities.",
|
|
104
|
-
tools: ["call_agent"],
|
|
105
|
-
builtin: true
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
id: "skill-creator",
|
|
109
|
-
name: "Skill Creator",
|
|
110
|
-
description: "Save a reusable skill distilled from this conversation.",
|
|
111
|
-
instructions: 'Do NOT proactively mention, suggest, or save skills. ONLY when the user EXPLICITLY asks to create or save a skill from this conversation (e.g. "make a skill out of this", "save this as a skill"), call the save_skill tool \u2014 it writes a SKILL.md into the shared library in the background. Never use any external memory, knowledge-graph, or note tool to store skills.',
|
|
112
|
-
tools: ["save_skill"],
|
|
113
|
-
builtin: true
|
|
114
|
-
}
|
|
115
|
-
];
|
|
116
|
-
function toSkillMd(skill) {
|
|
117
|
-
const fm = [`name: ${skill.name}`, `description: ${oneLine(skill.description)}`];
|
|
118
|
-
if (skill.tools.length) fm.push(`tools: ${skill.tools.join(", ")}`);
|
|
119
|
-
return `---
|
|
120
|
-
${fm.join("\n")}
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
${skill.instructions.trim()}
|
|
124
|
-
`;
|
|
125
|
-
}
|
|
126
|
-
function fromSkillMd(id, raw) {
|
|
127
|
-
const text = raw.replace(/^/, "").replace(/\r\n/g, "\n");
|
|
128
|
-
const m = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/.exec(text);
|
|
129
|
-
if (!m) return null;
|
|
130
|
-
const meta = {};
|
|
131
|
-
for (const line of m[1].split("\n")) {
|
|
132
|
-
const c = line.indexOf(":");
|
|
133
|
-
if (c < 0) continue;
|
|
134
|
-
meta[line.slice(0, c).trim().toLowerCase()] = unquote(line.slice(c + 1).trim());
|
|
135
|
-
}
|
|
136
|
-
const name = meta.name?.trim();
|
|
137
|
-
const instructions = m[2].trim();
|
|
138
|
-
if (!name || !instructions) return null;
|
|
139
|
-
const tools = meta.tools ? meta.tools.split(",").map((t) => unquote(t.trim())).filter(Boolean) : [];
|
|
140
|
-
return { id, name, description: meta.description ?? "", instructions, tools, builtin: false };
|
|
141
|
-
}
|
|
142
|
-
function unquote(s) {
|
|
143
|
-
return s.replace(/^["']|["']$/g, "").trim();
|
|
144
|
-
}
|
|
145
|
-
function oneLine(s) {
|
|
146
|
-
return s.replace(/\s*\n\s*/g, " ").trim();
|
|
147
|
-
}
|
|
148
|
-
var SkillStore = class {
|
|
149
|
-
constructor(dataDir) {
|
|
150
|
-
this.dataDir = dataDir;
|
|
151
|
-
}
|
|
152
|
-
dataDir;
|
|
153
|
-
get skillsDir() {
|
|
154
|
-
return join2(this.dataDir, "skills");
|
|
155
|
-
}
|
|
156
|
-
list() {
|
|
157
|
-
const skills = [...BUILTIN_SKILLS];
|
|
158
|
-
const idSet = new Set(skills.map((s) => s.id));
|
|
159
|
-
if (!existsSync2(this.skillsDir)) return skills;
|
|
160
|
-
for (const e of readdirSync(this.skillsDir, { withFileTypes: true })) {
|
|
161
|
-
let skill = null;
|
|
162
|
-
let id = "";
|
|
163
|
-
if (e.isDirectory()) {
|
|
164
|
-
id = e.name;
|
|
165
|
-
const md = join2(this.skillsDir, e.name, "SKILL.md");
|
|
166
|
-
if (existsSync2(md)) skill = this.loadMd(id, md);
|
|
167
|
-
} else if (e.isFile() && e.name.endsWith(".json")) {
|
|
168
|
-
id = e.name.slice(0, -5);
|
|
169
|
-
skill = this.loadJson(join2(this.skillsDir, e.name), id);
|
|
170
|
-
}
|
|
171
|
-
if (!skill || !id || idSet.has(id)) continue;
|
|
172
|
-
idSet.add(id);
|
|
173
|
-
skills.push(skill);
|
|
174
|
-
}
|
|
175
|
-
return skills;
|
|
176
|
-
}
|
|
177
|
-
/** Only the user-created (non-builtin) skills, for injection + the library UI. */
|
|
178
|
-
userSkills() {
|
|
179
|
-
return this.list().filter((s) => !s.builtin);
|
|
180
|
-
}
|
|
181
|
-
get(id) {
|
|
182
|
-
return this.list().find((s) => s.id === id);
|
|
183
|
-
}
|
|
184
|
-
has(id) {
|
|
185
|
-
return isValidSkillId(id) && existsSync2(join2(this.skillsDir, id, "SKILL.md"));
|
|
186
|
-
}
|
|
187
|
-
write(skill) {
|
|
188
|
-
if (!isValidSkillId(skill.id)) throw new Error(`Invalid skill id: ${skill.id}`);
|
|
189
|
-
const dir = join2(this.skillsDir, skill.id);
|
|
190
|
-
mkdirSync2(dir, { recursive: true });
|
|
191
|
-
writeFileSync2(join2(dir, "SKILL.md"), toSkillMd(skill), "utf8");
|
|
192
|
-
}
|
|
193
|
-
delete(id) {
|
|
194
|
-
if (!isValidSkillId(id)) return;
|
|
195
|
-
rmSync(join2(this.skillsDir, id), { recursive: true, force: true });
|
|
196
|
-
const legacy = join2(this.skillsDir, `${id}.json`);
|
|
197
|
-
if (existsSync2(legacy)) rmSync(legacy);
|
|
198
|
-
}
|
|
199
|
-
loadMd(id, path) {
|
|
200
|
-
try {
|
|
201
|
-
return fromSkillMd(id, readFileSync2(path, "utf8"));
|
|
202
|
-
} catch {
|
|
203
|
-
return null;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
loadJson(path, id) {
|
|
207
|
-
try {
|
|
208
|
-
const data = JSON.parse(readFileSync2(path, "utf8"));
|
|
209
|
-
if (!data.name || typeof data.name !== "string") return null;
|
|
210
|
-
if (!data.instructions || typeof data.instructions !== "string") return null;
|
|
211
|
-
return { id, name: data.name, description: data.description || "", instructions: data.instructions, tools: Array.isArray(data.tools) ? data.tools : [], builtin: false };
|
|
212
|
-
} catch {
|
|
213
|
-
return null;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
};
|
|
217
|
-
function isValidSkillId(id) {
|
|
218
|
-
return typeof id === "string" && /^[a-z0-9-]{1,64}$/.test(id);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// src/agents/distiller.ts
|
|
222
|
-
import { readFileSync as readFileSync3, readdirSync as readdirSync2, statSync, existsSync as existsSync3 } from "fs";
|
|
223
|
-
import { join as join3 } from "path";
|
|
224
|
-
|
|
225
45
|
// src/engines/compat.ts
|
|
226
46
|
var ENGINE_MODEL_ALIAS = "default_model";
|
|
227
47
|
var RAPID_MLX_MODEL_ALIAS = "default";
|
|
@@ -257,7 +77,7 @@ async function proxyStream(remote, path, init, signal, fetchImpl = fetch) {
|
|
|
257
77
|
}
|
|
258
78
|
|
|
259
79
|
// src/observability/request-log.ts
|
|
260
|
-
import { randomUUID as
|
|
80
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
261
81
|
function requestLogConfig(d) {
|
|
262
82
|
return d.store.snapshot().requestLog ?? { enabled: false, captureBodies: false, maxEntries: 500 };
|
|
263
83
|
}
|
|
@@ -476,9 +296,193 @@ function callChatUpstream(upstream, body, signal, fetchImpl = fetch, d) {
|
|
|
476
296
|
);
|
|
477
297
|
}
|
|
478
298
|
|
|
479
|
-
// src/
|
|
480
|
-
|
|
481
|
-
|
|
299
|
+
// src/tools/approval-gate.ts
|
|
300
|
+
var pending = /* @__PURE__ */ new Map();
|
|
301
|
+
function waitForToolApproval(key, signal) {
|
|
302
|
+
return new Promise((resolvePromise) => {
|
|
303
|
+
const onAbort = () => {
|
|
304
|
+
pending.delete(key);
|
|
305
|
+
resolvePromise("deny");
|
|
306
|
+
};
|
|
307
|
+
const cleanup = () => {
|
|
308
|
+
signal.removeEventListener("abort", onAbort);
|
|
309
|
+
};
|
|
310
|
+
pending.set(key, {
|
|
311
|
+
resolve: (decision) => {
|
|
312
|
+
cleanup();
|
|
313
|
+
resolvePromise(decision);
|
|
314
|
+
},
|
|
315
|
+
cleanup
|
|
316
|
+
});
|
|
317
|
+
if (signal.aborted) {
|
|
318
|
+
onAbort();
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// src/agents/skills.ts
|
|
326
|
+
import { join as join2 } from "path";
|
|
327
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, rmSync, readdirSync } from "fs";
|
|
328
|
+
var BUILTIN_SKILLS = [
|
|
329
|
+
{
|
|
330
|
+
id: "filesystem",
|
|
331
|
+
name: "Filesystem",
|
|
332
|
+
description: "Read files, list directories, glob patterns within the agent's workspace.",
|
|
333
|
+
instructions: "You can read files and explore directories. Use read_file to read file contents, list_dir to explore, and glob to find files. Always work within your allowed paths.",
|
|
334
|
+
tools: ["read_file", "list_dir", "glob"],
|
|
335
|
+
builtin: true
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
id: "web",
|
|
339
|
+
name: "Web",
|
|
340
|
+
description: "Search the web and fetch URLs for research.",
|
|
341
|
+
instructions: "You can search the web using web_search and fetch URLs with fetch_url. Use these to gather current information and research topics.",
|
|
342
|
+
tools: ["web_search", "fetch_url"],
|
|
343
|
+
builtin: true
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
id: "code",
|
|
347
|
+
name: "Code",
|
|
348
|
+
description: "Execute code for computation and data processing.",
|
|
349
|
+
instructions: "You can run code using run_code. Code execution runs unattended \u2014 ensure your code is correct before running.",
|
|
350
|
+
tools: ["run_code"],
|
|
351
|
+
builtin: true
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
id: "task-tracking",
|
|
355
|
+
name: "Task Tracking",
|
|
356
|
+
description: "Track progress on a task and declare completion.",
|
|
357
|
+
instructions: "You can track your progress with update_doc and declare a task complete with complete_task. Update the working doc regularly to maintain a clear record of what's done and what's left.",
|
|
358
|
+
tools: ["update_doc", "complete_task"],
|
|
359
|
+
builtin: true
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
id: "compose",
|
|
363
|
+
name: "Compose",
|
|
364
|
+
description: "Delegate work to other agents via call_agent.",
|
|
365
|
+
instructions: "You can call other agents using call_agent. Use this to delegate specialized sub-tasks to agents with different capabilities.",
|
|
366
|
+
tools: ["call_agent"],
|
|
367
|
+
builtin: true
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
id: "skill-creator",
|
|
371
|
+
name: "Skill Creator",
|
|
372
|
+
description: "Save a reusable skill distilled from this conversation.",
|
|
373
|
+
instructions: 'Do NOT proactively mention, suggest, or save skills. ONLY when the user EXPLICITLY asks to create or save a skill from this conversation (e.g. "make a skill out of this", "save this as a skill"), call the save_skill tool \u2014 it writes a SKILL.md into the shared library in the background. Never use any external memory, knowledge-graph, or note tool to store skills.',
|
|
374
|
+
tools: ["save_skill"],
|
|
375
|
+
builtin: true
|
|
376
|
+
}
|
|
377
|
+
];
|
|
378
|
+
function toSkillMd(skill) {
|
|
379
|
+
const fm = [`name: ${skill.name}`, `description: ${oneLine(skill.description)}`];
|
|
380
|
+
if (skill.tools.length) fm.push(`tools: ${skill.tools.join(", ")}`);
|
|
381
|
+
return `---
|
|
382
|
+
${fm.join("\n")}
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
${skill.instructions.trim()}
|
|
386
|
+
`;
|
|
387
|
+
}
|
|
388
|
+
function fromSkillMd(id, raw) {
|
|
389
|
+
const text = raw.replace(/^/, "").replace(/\r\n/g, "\n");
|
|
390
|
+
const m = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/.exec(text);
|
|
391
|
+
if (!m) return null;
|
|
392
|
+
const meta = {};
|
|
393
|
+
for (const line of m[1].split("\n")) {
|
|
394
|
+
const c = line.indexOf(":");
|
|
395
|
+
if (c < 0) continue;
|
|
396
|
+
meta[line.slice(0, c).trim().toLowerCase()] = unquote(line.slice(c + 1).trim());
|
|
397
|
+
}
|
|
398
|
+
const name = meta.name?.trim();
|
|
399
|
+
const instructions = m[2].trim();
|
|
400
|
+
if (!name || !instructions) return null;
|
|
401
|
+
const tools = meta.tools ? meta.tools.split(",").map((t) => unquote(t.trim())).filter(Boolean) : [];
|
|
402
|
+
return { id, name, description: meta.description ?? "", instructions, tools, builtin: false };
|
|
403
|
+
}
|
|
404
|
+
function unquote(s) {
|
|
405
|
+
return s.replace(/^["']|["']$/g, "").trim();
|
|
406
|
+
}
|
|
407
|
+
function oneLine(s) {
|
|
408
|
+
return s.replace(/\s*\n\s*/g, " ").trim();
|
|
409
|
+
}
|
|
410
|
+
var SkillStore = class {
|
|
411
|
+
constructor(dataDir) {
|
|
412
|
+
this.dataDir = dataDir;
|
|
413
|
+
}
|
|
414
|
+
dataDir;
|
|
415
|
+
get skillsDir() {
|
|
416
|
+
return join2(this.dataDir, "skills");
|
|
417
|
+
}
|
|
418
|
+
list() {
|
|
419
|
+
const skills = [...BUILTIN_SKILLS];
|
|
420
|
+
const idSet = new Set(skills.map((s) => s.id));
|
|
421
|
+
if (!existsSync2(this.skillsDir)) return skills;
|
|
422
|
+
for (const e of readdirSync(this.skillsDir, { withFileTypes: true })) {
|
|
423
|
+
let skill = null;
|
|
424
|
+
let id = "";
|
|
425
|
+
if (e.isDirectory()) {
|
|
426
|
+
id = e.name;
|
|
427
|
+
const md = join2(this.skillsDir, e.name, "SKILL.md");
|
|
428
|
+
if (existsSync2(md)) skill = this.loadMd(id, md);
|
|
429
|
+
} else if (e.isFile() && e.name.endsWith(".json")) {
|
|
430
|
+
id = e.name.slice(0, -5);
|
|
431
|
+
skill = this.loadJson(join2(this.skillsDir, e.name), id);
|
|
432
|
+
}
|
|
433
|
+
if (!skill || !id || idSet.has(id)) continue;
|
|
434
|
+
idSet.add(id);
|
|
435
|
+
skills.push(skill);
|
|
436
|
+
}
|
|
437
|
+
return skills;
|
|
438
|
+
}
|
|
439
|
+
/** Only the user-created (non-builtin) skills, for injection + the library UI. */
|
|
440
|
+
userSkills() {
|
|
441
|
+
return this.list().filter((s) => !s.builtin);
|
|
442
|
+
}
|
|
443
|
+
get(id) {
|
|
444
|
+
return this.list().find((s) => s.id === id);
|
|
445
|
+
}
|
|
446
|
+
has(id) {
|
|
447
|
+
return isValidSkillId(id) && existsSync2(join2(this.skillsDir, id, "SKILL.md"));
|
|
448
|
+
}
|
|
449
|
+
write(skill) {
|
|
450
|
+
if (!isValidSkillId(skill.id)) throw new Error(`Invalid skill id: ${skill.id}`);
|
|
451
|
+
const dir = join2(this.skillsDir, skill.id);
|
|
452
|
+
mkdirSync2(dir, { recursive: true });
|
|
453
|
+
writeFileSync2(join2(dir, "SKILL.md"), toSkillMd(skill), "utf8");
|
|
454
|
+
}
|
|
455
|
+
delete(id) {
|
|
456
|
+
if (!isValidSkillId(id)) return;
|
|
457
|
+
rmSync(join2(this.skillsDir, id), { recursive: true, force: true });
|
|
458
|
+
const legacy = join2(this.skillsDir, `${id}.json`);
|
|
459
|
+
if (existsSync2(legacy)) rmSync(legacy);
|
|
460
|
+
}
|
|
461
|
+
loadMd(id, path) {
|
|
462
|
+
try {
|
|
463
|
+
return fromSkillMd(id, readFileSync2(path, "utf8"));
|
|
464
|
+
} catch {
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
loadJson(path, id) {
|
|
469
|
+
try {
|
|
470
|
+
const data = JSON.parse(readFileSync2(path, "utf8"));
|
|
471
|
+
if (!data.name || typeof data.name !== "string") return null;
|
|
472
|
+
if (!data.instructions || typeof data.instructions !== "string") return null;
|
|
473
|
+
return { id, name: data.name, description: data.description || "", instructions: data.instructions, tools: Array.isArray(data.tools) ? data.tools : [], builtin: false };
|
|
474
|
+
} catch {
|
|
475
|
+
return null;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
function isValidSkillId(id) {
|
|
480
|
+
return typeof id === "string" && /^[a-z0-9-]{1,64}$/.test(id);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// src/agents/distiller.ts
|
|
484
|
+
import { readFileSync as readFileSync3, readdirSync as readdirSync2, statSync, existsSync as existsSync3 } from "fs";
|
|
485
|
+
import { join as join3 } from "path";
|
|
482
486
|
|
|
483
487
|
// src/engines/download.ts
|
|
484
488
|
import { createWriteStream, existsSync as existsSync4, mkdirSync as mkdirSync3, readdirSync as readdirSync3, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
@@ -1597,7 +1601,7 @@ import {
|
|
|
1597
1601
|
SettingsManager,
|
|
1598
1602
|
isEditToolResult
|
|
1599
1603
|
} from "@earendil-works/pi-coding-agent";
|
|
1600
|
-
import { estimateTokens, calculateContextTokens } from "@earendil-works/pi-coding-agent";
|
|
1604
|
+
import { estimateTokens as estimateTokens2, calculateContextTokens } from "@earendil-works/pi-coding-agent";
|
|
1601
1605
|
|
|
1602
1606
|
// src/code/robust-bash.ts
|
|
1603
1607
|
import { access as fsAccess } from "fs/promises";
|
|
@@ -3274,12 +3278,12 @@ ${lines.join("\n")}${more}]`
|
|
|
3274
3278
|
if (lastUsage) {
|
|
3275
3279
|
contextUsed = calculateContextTokens(lastUsage);
|
|
3276
3280
|
for (let i = lastUsageIdx + 1; i < session.messages.length; i++) {
|
|
3277
|
-
contextUsed +=
|
|
3281
|
+
contextUsed += estimateTokens2(session.messages[i]);
|
|
3278
3282
|
}
|
|
3279
3283
|
} else {
|
|
3280
3284
|
contextUsed = 0;
|
|
3281
3285
|
for (const m of session.messages) {
|
|
3282
|
-
contextUsed +=
|
|
3286
|
+
contextUsed += estimateTokens2(m);
|
|
3283
3287
|
}
|
|
3284
3288
|
}
|
|
3285
3289
|
}
|