turbollm 1.7.1 → 1.7.2
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 -3
- package/bin/turbollm.mjs +29 -25
- package/dist/cli.js +98 -13
- package/dist/webdist/assets/{AgentsScreen-BToQ_CZg.js → AgentsScreen-sMeMB3IQ.js} +1 -1
- package/dist/webdist/assets/{ChatScreen-B4T7fIcx.js → ChatScreen-rXB7PrWJ.js} +1 -1
- package/dist/webdist/assets/{CustomizeScreen-IL-QlVq2.js → CustomizeScreen-BBwvtk28.js} +1 -1
- package/dist/webdist/assets/DeveloperScreen-fXV-qXB5.js +1 -0
- package/dist/webdist/assets/{EnginesScreen-GZYaJJNx.js → EnginesScreen-CrmYzhio.js} +1 -1
- package/dist/webdist/assets/{MessageBubble-DG7ZWPCw.js → MessageBubble-COuZ8jTd.js} +3 -3
- package/dist/webdist/assets/{ModelDetailDialog-DhCCmMnp.js → ModelDetailDialog-Dlt5uF3h.js} +1 -1
- package/dist/webdist/assets/{ModelDirs-D0d7xetP.js → ModelDirs-BYN-DmHL.js} +1 -1
- package/dist/webdist/assets/{ModelsScreen-Bl0OP-BY.js → ModelsScreen-DncNvsj6.js} +1 -1
- package/dist/webdist/assets/{SettingsScreen-DXy_TCXo.js → SettingsScreen-DXX3r4Ep.js} +1 -1
- package/dist/webdist/assets/{arc-DVrcAJc9.js → arc-BrQAHE5c.js} +1 -1
- package/dist/webdist/assets/{architectureDiagram-3BPJPVTR-BaL05OA8.js → architectureDiagram-3BPJPVTR-DzOwDk0E.js} +1 -1
- package/dist/webdist/assets/{arrow-left-nmoUPZoB.js → arrow-left-Dp4XRnbs.js} +1 -1
- package/dist/webdist/assets/{blockDiagram-GPEHLZMM-D8aCVMG0.js → blockDiagram-GPEHLZMM-Cbs2lNCh.js} +1 -1
- package/dist/webdist/assets/{c4Diagram-AAUBKEIU-Bpj96pxf.js → c4Diagram-AAUBKEIU-BAull9Yv.js} +1 -1
- package/dist/webdist/assets/channel-Bt5-ol5R.js +1 -0
- package/dist/webdist/assets/check-jMeH6YsH.js +1 -0
- package/dist/webdist/assets/{chevron-down-DgTSOyZG.js → chevron-down-C5ZMFCtb.js} +1 -1
- package/dist/webdist/assets/{chevron-right-BshRZEvM.js → chevron-right-DNVnXbZ1.js} +1 -1
- package/dist/webdist/assets/{chunk-2J33WTMH-DA6mFoN-.js → chunk-2J33WTMH-B38k4sJL.js} +1 -1
- package/dist/webdist/assets/{chunk-4BX2VUAB-B_fmKUNu.js → chunk-4BX2VUAB-VxAkYvb7.js} +1 -1
- package/dist/webdist/assets/{chunk-55IACEB6-3cWMWgYr.js → chunk-55IACEB6-CAz9ZWyR.js} +1 -1
- package/dist/webdist/assets/{chunk-727SXJPM-Cwb5Sv7F.js → chunk-727SXJPM-CvLX5ghS.js} +1 -1
- package/dist/webdist/assets/{chunk-AQP2D5EJ-7QIg1x7-.js → chunk-AQP2D5EJ-CZ0fsnc1.js} +1 -1
- package/dist/webdist/assets/{chunk-FMBD7UC4-D_Qfl5Jc.js → chunk-FMBD7UC4-tjHz_yw8.js} +1 -1
- package/dist/webdist/assets/{chunk-ND2GUHAM-pgqeq7NP.js → chunk-ND2GUHAM-DVSh5E5_.js} +1 -1
- package/dist/webdist/assets/{chunk-QZHKN3VN-EUqDaxxx.js → chunk-QZHKN3VN-D1rUM2SU.js} +1 -1
- package/dist/webdist/assets/{circle-check-Dey3SdiG.js → circle-check-qnghY_qF.js} +1 -1
- package/dist/webdist/assets/{circle-x-M54_eiYo.js → circle-x-FM28MwOL.js} +1 -1
- package/dist/webdist/assets/classDiagram-4FO5ZUOK-jfnUpxOr.js +1 -0
- package/dist/webdist/assets/classDiagram-v2-Q7XG4LA2-jfnUpxOr.js +1 -0
- package/dist/webdist/assets/{common-Dn21s6g5.js → common-BD4Wa3KL.js} +1 -1
- package/dist/webdist/assets/{copy-button-D6JkFOO9.js → copy-button-DypRNkqI.js} +1 -1
- package/dist/webdist/assets/{cose-bilkent-S5V4N54A-BzxdTTj-.js → cose-bilkent-S5V4N54A-DIUqY7o2.js} +1 -1
- package/dist/webdist/assets/{dagre-BM42HDAG-YQn0mFsV.js → dagre-BM42HDAG-BzTcsgZ1.js} +1 -1
- package/dist/webdist/assets/{diagram-2AECGRRQ-DtSRGaVH.js → diagram-2AECGRRQ-DanHH-W_.js} +1 -1
- package/dist/webdist/assets/{diagram-5GNKFQAL-Dko3hF44.js → diagram-5GNKFQAL-DQ5sWHUL.js} +1 -1
- package/dist/webdist/assets/{diagram-KO2AKTUF-CQAm-tYF.js → diagram-KO2AKTUF-Jqr_pLwu.js} +1 -1
- package/dist/webdist/assets/{diagram-LMA3HP47-gz5BqFhM.js → diagram-LMA3HP47-BZ89-cp0.js} +1 -1
- package/dist/webdist/assets/{diagram-OG6HWLK6-BqsSoNIn.js → diagram-OG6HWLK6-cidBc5qa.js} +1 -1
- package/dist/webdist/assets/{dialog-B_Yd5di3.js → dialog-3hyZ9j4e.js} +1 -1
- package/dist/webdist/assets/{erDiagram-TEJ5UH35-D8rPsHw-.js → erDiagram-TEJ5UH35-DEAKZN7b.js} +1 -1
- package/dist/webdist/assets/{flowDiagram-I6XJVG4X-DhGWyp50.js → flowDiagram-I6XJVG4X-Cyx8gMzN.js} +1 -1
- package/dist/webdist/assets/{ganttDiagram-6RSMTGT7-WEinw7mP.js → ganttDiagram-6RSMTGT7-CqXYW44d.js} +1 -1
- package/dist/webdist/assets/{gitGraphDiagram-PVQCEYII-BJ-BzBFO.js → gitGraphDiagram-PVQCEYII-0dv_zKYA.js} +1 -1
- package/dist/webdist/assets/{index-C-xjjrht.js → index-CriwC5VH.js} +2 -2
- package/dist/webdist/assets/{infoDiagram-5YYISTIA-BA9oHMe2.js → infoDiagram-5YYISTIA-PxeM6E3u.js} +1 -1
- package/dist/webdist/assets/{ishikawaDiagram-YF4QCWOH-BJ5McdEJ.js → ishikawaDiagram-YF4QCWOH-BnNdTjj1.js} +1 -1
- package/dist/webdist/assets/{journeyDiagram-JHISSGLW-Bu6WJyQy.js → journeyDiagram-JHISSGLW-D3AHUGxz.js} +1 -1
- package/dist/webdist/assets/{kanban-definition-UN3LZRKU-C_Y8cJ9D.js → kanban-definition-UN3LZRKU-YARl6SUt.js} +1 -1
- package/dist/webdist/assets/{linear-BssoHTW-.js → linear-CMEhaWGh.js} +1 -1
- package/dist/webdist/assets/{mermaid.core-C331Qhyf.js → mermaid.core-Dfl2pPvv.js} +4 -4
- package/dist/webdist/assets/{mindmap-definition-RKZ34NQL-B6NCYWu3.js → mindmap-definition-RKZ34NQL-BojWC6jk.js} +1 -1
- package/dist/webdist/assets/{pencil-bwNY7waZ.js → pencil-CS33zp9q.js} +1 -1
- package/dist/webdist/assets/{personas-C_q63e_2.js → personas-CzcXp8zg.js} +1 -1
- package/dist/webdist/assets/{pieDiagram-4H26LBE5-CV23vNlv.js → pieDiagram-4H26LBE5-cjsdMtJJ.js} +1 -1
- package/dist/webdist/assets/{plus-12BmUfjg.js → plus-BO3vGy6f.js} +1 -1
- package/dist/webdist/assets/{quadrantDiagram-W4KKPZXB-DxWTWFL7.js → quadrantDiagram-W4KKPZXB-DYVcgQuL.js} +1 -1
- package/dist/webdist/assets/{refresh-cw-Cl7RshCH.js → refresh-cw-Cco9RapO.js} +1 -1
- package/dist/webdist/assets/{requirementDiagram-4Y6WPE33-DRRulwpq.js → requirementDiagram-4Y6WPE33-Dkj58nhB.js} +1 -1
- package/dist/webdist/assets/{sankeyDiagram-5OEKKPKP-BTBSg_uE.js → sankeyDiagram-5OEKKPKP-l3GwUuNl.js} +1 -1
- package/dist/webdist/assets/{save-YXge1rTt.js → save-CSISNMk8.js} +1 -1
- package/dist/webdist/assets/{sequenceDiagram-3UESZ5HK-HiTl9dyH.js → sequenceDiagram-3UESZ5HK-CWj1Dplo.js} +1 -1
- package/dist/webdist/assets/{skeleton-BMhnZFjx.js → skeleton-CBRf-twG.js} +1 -1
- package/dist/webdist/assets/{stateDiagram-AJRCARHV-SGw6a8ke.js → stateDiagram-AJRCARHV-zbnPRcoE.js} +1 -1
- package/dist/webdist/assets/stateDiagram-v2-BHNVJYJU-Ukx8AVKZ.js +1 -0
- package/dist/webdist/assets/{timeline-definition-PNZ67QCA-B_X3zBz0.js → timeline-definition-PNZ67QCA-C_zAo1WZ.js} +1 -1
- package/dist/webdist/assets/{trash-2-BNQkpp4n.js → trash-2-DJmVqx0w.js} +1 -1
- package/dist/webdist/assets/{vennDiagram-CIIHVFJN-C8ibsbKD.js → vennDiagram-CIIHVFJN-DxfcocQu.js} +1 -1
- package/dist/webdist/assets/{vram-D4ttIJVy.js → vram-Dn53zt7R.js} +1 -1
- package/dist/webdist/assets/{wardley-L42UT6IY-ClFBGt2Y.js → wardley-L42UT6IY-BnZ8BinJ.js} +1 -1
- package/dist/webdist/assets/{wardleyDiagram-YWT4CUSO-1iaMKpVQ.js → wardleyDiagram-YWT4CUSO-DMk9z7hr.js} +1 -1
- package/dist/webdist/assets/{wrench-Chhk_zTw.js → wrench-Di5WLTz2.js} +1 -1
- package/dist/webdist/assets/{xychartDiagram-2RQKCTM6-FIIVikoF.js → xychartDiagram-2RQKCTM6-BUtTPXPF.js} +1 -1
- package/dist/webdist/index.html +1 -1
- package/package.json +2 -2
- package/dist/webdist/assets/DeveloperScreen-DN-FWjXV.js +0 -1
- package/dist/webdist/assets/channel-M9YFYffr.js +0 -1
- package/dist/webdist/assets/check-CD6cKVwJ.js +0 -1
- package/dist/webdist/assets/classDiagram-4FO5ZUOK-BtQ5UIn2.js +0 -1
- package/dist/webdist/assets/classDiagram-v2-Q7XG4LA2-BtQ5UIn2.js +0 -1
- package/dist/webdist/assets/stateDiagram-v2-BHNVJYJU-C7Pv9LnA.js +0 -1
package/README.md
CHANGED
|
@@ -446,7 +446,7 @@ Use `--config <file>` to point at an alternate config (its directory becomes the
|
|
|
446
446
|
|
|
447
447
|
## Requirements
|
|
448
448
|
|
|
449
|
-
- **Node.js 22 or newer** — enforced at startup with a clear message. <https://nodejs.org>
|
|
449
|
+
- **Node.js 22.13.0 or newer** — enforced at startup with a clear message. <https://nodejs.org>
|
|
450
450
|
- **Windows, macOS, or Linux.**
|
|
451
451
|
- A GPU is recommended but **not required** — a CPU build is provisioned as a fallback.
|
|
452
452
|
- On Windows, the first time the auto-downloaded `llama-server` runs, SmartScreen/Defender may
|
|
@@ -492,7 +492,7 @@ Prefer Open WebUI's chat breadth? It works great pointed at TurboLLM's OpenAI en
|
|
|
492
492
|
|
|
493
493
|
## Troubleshooting
|
|
494
494
|
|
|
495
|
-
- **`TurboLLM requires Node.js 22 or newer`** — upgrade Node: <https://nodejs.org>.
|
|
495
|
+
- **`TurboLLM requires Node.js 22.13.0 or newer`** — upgrade Node: <https://nodejs.org>.
|
|
496
496
|
- **Model won't load / OOM** — pick a smaller quant (the VRAM verdict warns you), lower GPU
|
|
497
497
|
offload, or close other GPU apps. Failures surface in the Engines screen with the engine log.
|
|
498
498
|
- **Windows Defender / SmartScreen prompt** — that's the upstream `llama-server` binary on
|
|
@@ -519,7 +519,7 @@ node dist/cli.js --port 6996
|
|
|
519
519
|
Frontend hot-reload: `cd web && npm run dev` (proxies `/api` and `/v1` to the daemon on
|
|
520
520
|
:6996).
|
|
521
521
|
|
|
522
|
-
**Stack:** Node ≥22 · TypeScript · Hono · `node:sqlite` · tsup — and a React 19 + Tailwind v4 +
|
|
522
|
+
**Stack:** Node ≥22.13 · TypeScript · Hono · `node:sqlite` · tsup — and a React 19 + Tailwind v4 +
|
|
523
523
|
shadcn/ui frontend. One TypeScript codebase, shipped as an npm package.
|
|
524
524
|
|
|
525
525
|
---
|
package/bin/turbollm.mjs
CHANGED
|
@@ -1,25 +1,29 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// Hand-written launcher shim — NOT bundled by tsup. It runs before the bundled
|
|
3
|
-
// daemon (dist/cli.js) loads, so it can do two things that must happen before
|
|
4
|
-
// node:sqlite is imported (the bundle hoists that import, emitting an experimental
|
|
5
|
-
// warning that PowerShell renders as a scary red error block on every run):
|
|
6
|
-
// 1. Guard the Node version with a friendly message (node:sqlite needs Node 22+
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Hand-written launcher shim — NOT bundled by tsup. It runs before the bundled
|
|
3
|
+
// daemon (dist/cli.js) loads, so it can do two things that must happen before
|
|
4
|
+
// node:sqlite is imported (the bundle hoists that import, emitting an experimental
|
|
5
|
+
// warning that PowerShell renders as a scary red error block on every run):
|
|
6
|
+
// 1. Guard the Node version with a friendly message (node:sqlite needs Node 22.13+ —
|
|
7
|
+
// that's when node:sqlite became available WITHOUT the --experimental-sqlite flag;
|
|
8
|
+
// on 22.5.0-22.12.x it's registered only behind that flag, so importing it bare
|
|
9
|
+
// throws ERR_UNKNOWN_BUILTIN_MODULE: "No such built-in module: node:sqlite"
|
|
10
|
+
// (GitHub #40) even though `node -v` reports 22.x).
|
|
11
|
+
// 2. Register a 'warning' filter that swallows the node:sqlite experimental notice
|
|
12
|
+
// while still printing every other warning.
|
|
13
|
+
// Then it hands off to the real CLI via dynamic import (same process; argv intact).
|
|
14
|
+
const [major, minor] = process.versions.node.split('.').map(Number)
|
|
15
|
+
if (major < 22 || (major === 22 && minor < 13)) {
|
|
16
|
+
process.stderr.write(
|
|
17
|
+
`TurboLLM requires Node.js 22.13.0 or newer (needs node:sqlite unflagged).\n` +
|
|
18
|
+
`You are running Node.js ${process.versions.node}.\n` +
|
|
19
|
+
`Please upgrade: https://nodejs.org\n`,
|
|
20
|
+
)
|
|
21
|
+
process.exit(1)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
process.on('warning', (w) => {
|
|
25
|
+
if (w.name === 'ExperimentalWarning' && /SQLite/i.test(w.message)) return
|
|
26
|
+
process.stderr.write(`${w.stack ?? `${w.name}: ${w.message}`}\n`)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
await import('../dist/cli.js')
|
package/dist/cli.js
CHANGED
|
@@ -1946,7 +1946,7 @@ async function probe(bin) {
|
|
|
1946
1946
|
const m = RE_VERSION.exec(combined);
|
|
1947
1947
|
let version2 = m ? m[1].trim() : trimLen(firstNonEmptyLine(v.out), 100);
|
|
1948
1948
|
if (!version2) version2 = "unknown";
|
|
1949
|
-
const flags =
|
|
1949
|
+
const flags = extractFlags(h.out);
|
|
1950
1950
|
const kvTypes = flags.includes("--cache-type-k") ? [...KNOWN_KV] : ["f16"];
|
|
1951
1951
|
if (combined.toLowerCase().includes("turbo")) kvTypes.push("turbo2", "turbo3", "turbo4");
|
|
1952
1952
|
const ENUM_RE = /--spec-type\s+(\[[^\]\n]+\]|[a-z][a-z0-9_-]*(?:[,|][a-z0-9_-]+)+)/gi;
|
|
@@ -1982,6 +1982,14 @@ function detectFormat(bin) {
|
|
|
1982
1982
|
function osLabel(fmt) {
|
|
1983
1983
|
return fmt === "pe" ? "Windows" : fmt === "macho" ? "macOS" : "Linux";
|
|
1984
1984
|
}
|
|
1985
|
+
function extractFlags(helpText) {
|
|
1986
|
+
const flagSet = /* @__PURE__ */ new Set();
|
|
1987
|
+
for (const line of helpText.split("\n")) {
|
|
1988
|
+
if (/\bhas been removed\b/i.test(line)) continue;
|
|
1989
|
+
for (const f of line.match(RE_FLAG) ?? []) flagSet.add(f);
|
|
1990
|
+
}
|
|
1991
|
+
return [...flagSet].sort();
|
|
1992
|
+
}
|
|
1985
1993
|
function firstNonEmptyLine(s) {
|
|
1986
1994
|
for (const ln of s.split("\n")) {
|
|
1987
1995
|
const t = ln.trim();
|
|
@@ -2264,9 +2272,8 @@ var Registry = class {
|
|
|
2264
2272
|
* e.g. one with `--spec-type` but no captured `spec-type:<value>` entries, so
|
|
2265
2273
|
* NextN/MTP gating has the data it needs without a manual re-probe. */
|
|
2266
2274
|
async ensureProbed() {
|
|
2267
|
-
const stale = (e) => e.capabilities.flags.includes("--spec-type") && !e.capabilities.flags.some((f) => f.startsWith("spec-type:"));
|
|
2268
2275
|
for (const e of this.list().engines) {
|
|
2269
|
-
if (e.version && !
|
|
2276
|
+
if (e.version && !isStaleCapabilities(e.capabilities.flags)) continue;
|
|
2270
2277
|
try {
|
|
2271
2278
|
await this.reprobe(e.id);
|
|
2272
2279
|
} catch {
|
|
@@ -2274,6 +2281,11 @@ var Registry = class {
|
|
|
2274
2281
|
}
|
|
2275
2282
|
}
|
|
2276
2283
|
};
|
|
2284
|
+
function isStaleCapabilities(flags) {
|
|
2285
|
+
if (flags.includes("--spec-type") && !flags.some((f) => f.startsWith("spec-type:"))) return true;
|
|
2286
|
+
if (["--draft-max", "--draft-min", "--draft", "--draft-n", "--draft-n-min"].some((f) => flags.includes(f))) return true;
|
|
2287
|
+
return false;
|
|
2288
|
+
}
|
|
2277
2289
|
|
|
2278
2290
|
// src/engines/provision-state.ts
|
|
2279
2291
|
var ProvisionState = class {
|
|
@@ -3900,9 +3912,12 @@ function profileToArgs(p, m, caps, cores = 0) {
|
|
|
3900
3912
|
if (specType) a.push("--spec-type", "mtp");
|
|
3901
3913
|
a.push("--mtp-head", p.mtpHeadPath);
|
|
3902
3914
|
specActive = true;
|
|
3903
|
-
} else if (p.speculative === "nextn" && specType
|
|
3915
|
+
} else if (p.speculative === "nextn" && specType) {
|
|
3904
3916
|
const nextnVal = ["nextn", "draft-mtp"].find((v) => specAccepts(v));
|
|
3905
|
-
if (nextnVal) {
|
|
3917
|
+
if (nextnVal === "draft-mtp") {
|
|
3918
|
+
a.push("--spec-type", nextnVal);
|
|
3919
|
+
specActive = true;
|
|
3920
|
+
} else if (nextnVal === "nextn" && has("--model-draft")) {
|
|
3906
3921
|
a.push("--spec-type", nextnVal, "--model-draft", m.path);
|
|
3907
3922
|
specActive = true;
|
|
3908
3923
|
}
|
|
@@ -3911,8 +3926,12 @@ function profileToArgs(p, m, caps, cores = 0) {
|
|
|
3911
3926
|
a.push("--model-draft", p.draftModelPath);
|
|
3912
3927
|
specActive = true;
|
|
3913
3928
|
}
|
|
3914
|
-
if (specActive
|
|
3915
|
-
|
|
3929
|
+
if (specActive) {
|
|
3930
|
+
if (has("--draft-max")) a.push("--draft-max", String(p.draftMax ?? 16));
|
|
3931
|
+
else if (has("--spec-draft-n-max")) a.push("--spec-draft-n-max", String(p.draftMax ?? 16));
|
|
3932
|
+
if (has("--draft-min")) a.push("--draft-min", String(p.draftMin ?? 1));
|
|
3933
|
+
else if (has("--spec-draft-n-min")) a.push("--spec-draft-n-min", String(p.draftMin ?? 1));
|
|
3934
|
+
}
|
|
3916
3935
|
if (p.sampling.temp !== 0.8 && has("--temp")) a.push("--temp", String(p.sampling.temp));
|
|
3917
3936
|
if (p.sampling.topP !== 0.95 && has("--top-p")) a.push("--top-p", String(p.sampling.topP));
|
|
3918
3937
|
if (p.sampling.topK !== 40 && has("--top-k")) a.push("--top-k", String(p.sampling.topK));
|
|
@@ -5396,7 +5415,7 @@ var BenchRunner = class {
|
|
|
5396
5415
|
const saved = getModelProfile(this.store.snapshot(), modelKey, active?.id ?? "*");
|
|
5397
5416
|
const defaults = this.store.snapshot().modelDefaults;
|
|
5398
5417
|
const resolved = resolveProfile(entry, sys, saved, base2, defaults);
|
|
5399
|
-
const baseProfile =
|
|
5418
|
+
const baseProfile = resolved;
|
|
5400
5419
|
const headroomMb = this.store.snapshot().vramHeadroomMb;
|
|
5401
5420
|
const results = [];
|
|
5402
5421
|
let best = null;
|
|
@@ -12356,6 +12375,7 @@ function registerApi(app2, d) {
|
|
|
12356
12375
|
const base2 = `http://${host2}:${port2}`;
|
|
12357
12376
|
const ms = d.manager.status();
|
|
12358
12377
|
const modelName = ms.state === "running" ? ms.model?.name ?? "local" : "local";
|
|
12378
|
+
const modelKey = ms.state === "running" ? ms.model?.key ?? modelName : modelName;
|
|
12359
12379
|
let apiKey = "not-needed-on-localhost";
|
|
12360
12380
|
if (lanBind) {
|
|
12361
12381
|
const keyName = `cli-${cli}`;
|
|
@@ -12374,7 +12394,7 @@ function registerApi(app2, d) {
|
|
|
12374
12394
|
});
|
|
12375
12395
|
apiKey = full;
|
|
12376
12396
|
}
|
|
12377
|
-
return c.json(buildConnectSnippets(cli, base2, apiKey, modelName));
|
|
12397
|
+
return c.json(buildConnectSnippets(cli, base2, apiKey, modelName, modelKey));
|
|
12378
12398
|
});
|
|
12379
12399
|
}
|
|
12380
12400
|
function overlayModel(e, d, lastTpsMap) {
|
|
@@ -12613,7 +12633,7 @@ function getLanIp() {
|
|
|
12613
12633
|
}
|
|
12614
12634
|
return "127.0.0.1";
|
|
12615
12635
|
}
|
|
12616
|
-
function buildConnectSnippets(cli, base2, apiKey, modelName) {
|
|
12636
|
+
function buildConnectSnippets(cli, base2, apiKey, modelName, modelKey = modelName) {
|
|
12617
12637
|
switch (cli) {
|
|
12618
12638
|
case "claude-code":
|
|
12619
12639
|
return {
|
|
@@ -12642,6 +12662,11 @@ function buildConnectSnippets(cli, base2, apiKey, modelName) {
|
|
|
12642
12662
|
cli,
|
|
12643
12663
|
title: "opencode",
|
|
12644
12664
|
steps: [
|
|
12665
|
+
{
|
|
12666
|
+
label: "Quickest \u2014 one command (ships with TurboLLM)",
|
|
12667
|
+
snippet: `turbollm launch opencode`,
|
|
12668
|
+
lang: "bash"
|
|
12669
|
+
},
|
|
12645
12670
|
{
|
|
12646
12671
|
label: "Merge into ~/.config/opencode/opencode.json",
|
|
12647
12672
|
snippet: JSON.stringify(
|
|
@@ -12669,6 +12694,11 @@ function buildConnectSnippets(cli, base2, apiKey, modelName) {
|
|
|
12669
12694
|
cli,
|
|
12670
12695
|
title: "Kilo Code",
|
|
12671
12696
|
steps: [
|
|
12697
|
+
{
|
|
12698
|
+
label: "Quickest \u2014 one command (ships with TurboLLM)",
|
|
12699
|
+
snippet: `turbollm launch kilo`,
|
|
12700
|
+
lang: "bash"
|
|
12701
|
+
},
|
|
12672
12702
|
{
|
|
12673
12703
|
label: "Add to ~/.config/kilo/kilo.jsonc providers array",
|
|
12674
12704
|
snippet: JSON.stringify(
|
|
@@ -12687,6 +12717,61 @@ function buildConnectSnippets(cli, base2, apiKey, modelName) {
|
|
|
12687
12717
|
}
|
|
12688
12718
|
]
|
|
12689
12719
|
};
|
|
12720
|
+
case "openclaw":
|
|
12721
|
+
return {
|
|
12722
|
+
cli,
|
|
12723
|
+
title: "openclaw",
|
|
12724
|
+
steps: [
|
|
12725
|
+
{
|
|
12726
|
+
label: "Quickest \u2014 one command (ships with TurboLLM)",
|
|
12727
|
+
snippet: `turbollm launch openclaw`,
|
|
12728
|
+
lang: "bash"
|
|
12729
|
+
},
|
|
12730
|
+
{
|
|
12731
|
+
label: "Merge into ~/.config/openclaw/openclaw.json",
|
|
12732
|
+
snippet: JSON.stringify(
|
|
12733
|
+
{
|
|
12734
|
+
models: {
|
|
12735
|
+
providers: {
|
|
12736
|
+
turbollm: {
|
|
12737
|
+
baseUrl: `${base2}/v1`,
|
|
12738
|
+
apiKey: apiKey !== "not-needed-on-localhost" ? apiKey : "not-required",
|
|
12739
|
+
api: "openai-completions",
|
|
12740
|
+
models: [{ id: modelKey, name: modelName }]
|
|
12741
|
+
}
|
|
12742
|
+
}
|
|
12743
|
+
},
|
|
12744
|
+
agents: { defaults: { model: { primary: `turbollm/${modelKey}` } } }
|
|
12745
|
+
},
|
|
12746
|
+
null,
|
|
12747
|
+
2
|
|
12748
|
+
),
|
|
12749
|
+
lang: "json"
|
|
12750
|
+
}
|
|
12751
|
+
]
|
|
12752
|
+
};
|
|
12753
|
+
case "hermes":
|
|
12754
|
+
return {
|
|
12755
|
+
cli,
|
|
12756
|
+
title: "Hermes Agent",
|
|
12757
|
+
steps: [
|
|
12758
|
+
{
|
|
12759
|
+
label: "Quickest \u2014 one command (ships with TurboLLM)",
|
|
12760
|
+
snippet: `turbollm launch hermes`,
|
|
12761
|
+
lang: "bash"
|
|
12762
|
+
},
|
|
12763
|
+
{
|
|
12764
|
+
label: "PowerShell",
|
|
12765
|
+
snippet: `hermes config set model.provider custom; hermes config set model.base_url ${base2}/v1; hermes config set model.default "${modelKey}"`,
|
|
12766
|
+
lang: "powershell"
|
|
12767
|
+
},
|
|
12768
|
+
{
|
|
12769
|
+
label: "bash / zsh",
|
|
12770
|
+
snippet: `hermes config set model.provider custom && hermes config set model.base_url ${base2}/v1 && hermes config set model.default "${modelKey}"`,
|
|
12771
|
+
lang: "bash"
|
|
12772
|
+
}
|
|
12773
|
+
]
|
|
12774
|
+
};
|
|
12690
12775
|
case "qwen":
|
|
12691
12776
|
return {
|
|
12692
12777
|
cli,
|
|
@@ -13661,10 +13746,10 @@ try {
|
|
|
13661
13746
|
version = JSON.parse(readFileSync12(pkgPath, "utf8")).version ?? version;
|
|
13662
13747
|
} catch {
|
|
13663
13748
|
}
|
|
13664
|
-
var nodeMajor =
|
|
13665
|
-
if (nodeMajor < 22) {
|
|
13749
|
+
var [nodeMajor, nodeMinor] = process.versions.node.split(".").map(Number);
|
|
13750
|
+
if (nodeMajor < 22 || nodeMajor === 22 && nodeMinor < 13) {
|
|
13666
13751
|
process.stderr.write(
|
|
13667
|
-
`TurboLLM requires Node.js 22 or newer.
|
|
13752
|
+
`TurboLLM requires Node.js 22.13.0 or newer.
|
|
13668
13753
|
You are running Node.js ${process.versions.node}.
|
|
13669
13754
|
Please upgrade: https://nodejs.org
|
|
13670
13755
|
`
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as e}from"./radix-BY-fjzwm.js";import{r as u}from"./vendor-W5GIuFcv.js";import{c as w,d as k,A as T,u as v,L as h,e as S,a as b,f as C,g as q,X as A}from"./index-
|
|
1
|
+
import{j as e}from"./radix-BY-fjzwm.js";import{r as u}from"./vendor-W5GIuFcv.js";import{c as w,d as k,A as T,u as v,L as h,e as S,a as b,f as C,g as q,X as A}from"./index-CriwC5VH.js";import{P as N}from"./plus-BO3vGy6f.js";import{C as y}from"./circle-x-FM28MwOL.js";import{C as O}from"./circle-check-qnghY_qF.js";import{W as E}from"./wrench-Di5WLTz2.js";const _=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}]],D=w("circle-dot",_);const L=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 6v6l4 2",key:"mmk7yg"}]],P=w("clock",L),p={all:["agent-runs"],list:()=>[...p.all,"list"],detail:t=>[...p.all,"detail",t]};async function g(t,a){const l={Accept:"application/json",...k(),...a?.headers??{}},i=await fetch(t,{...a,headers:l});if(i.status===204)return;const r=await i.text(),o=r?JSON.parse(r):void 0;if(!i.ok){const d=o;throw new T(d?.error?.code??"http_error",d?.error?.message??`Request failed with status ${i.status}.`,i.status)}return o}async function $(){return g("/api/v1/agents/runs")}async function I(t){return g(`/api/v1/agents/runs/${t}`)}async function Q(t){return g("/api/v1/agents/runs",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}async function K(t){await g(`/api/v1/agents/runs/${t}`,{method:"DELETE"})}async function*F(t,a=0,l){const i=`/api/v1/agents/runs/${t}/stream?fromSeq=${a}`,r=await fetch(i,{headers:{Accept:"text/event-stream",...k()},signal:l});if(!r.ok||!r.body)throw new Error(`Stream error: ${r.status}`);const o=r.body.getReader(),d=new TextDecoder;let m="";try{for(;;){const{done:s,value:x}=await o.read();if(s)break;m+=d.decode(x,{stream:!0});const c=m.split(`
|
|
2
2
|
`);m=c.pop()??"";let n="message";for(const f of c){if(f.startsWith("event: ")){n=f.slice(7).trim();continue}if(f.startsWith("data: ")){const j=f.slice(6).trim();if(j==="[DONE]")return;try{const R=JSON.parse(j);if(yield{event:n,data:R},n==="done"||n==="error")return}catch{}n="message"}}}}finally{o.cancel()}}const J={queued:e.jsx(P,{size:12}),running:e.jsx(h,{size:12,className:"animate-spin"}),done:e.jsx(O,{size:12}),failed:e.jsx(y,{size:12}),cancelled:e.jsx(y,{size:12}),interrupted:e.jsx(y,{size:12})},M={queued:"text-muted",running:"text-accent",done:"text-green-500",failed:"text-red-500",cancelled:"text-muted",interrupted:"text-orange-500"};function z({status:t}){return e.jsxs("span",{className:b("flex items-center gap-1 text-[11px] capitalize",M[t]),children:[J[t],t]})}function W(t){const a=Date.now()-new Date(t).getTime();return a<6e4?"just now":a<36e5?`${Math.floor(a/6e4)}m ago`:a<864e5?`${Math.floor(a/36e5)}h ago`:new Date(t).toLocaleDateString()}const U=[{id:"web_search",label:"Web search",hint:"Search the web (needs a provider configured in Settings)"},{id:"fetch_url",label:"Fetch URL",hint:"Read the contents of a web page"},{id:"run_code",label:"Run code",hint:"Execute JS in a sandbox — no mid-run confirmation, opt in only if you trust the task"}];function B({onClose:t,onCreated:a}){const[l,i]=u.useState(""),[r,o]=u.useState(""),[d,m]=u.useState({web_search:!0,fetch_url:!0,run_code:!1}),s=C(),x=n=>m(f=>({...f,[n]:!f[n]})),c=q({mutationFn:()=>Q({title:l.slice(0,60)||"Agent run",systemPrompt:r||void 0,userMessage:l,allowedTools:Object.entries(d).filter(([,n])=>n).map(([n])=>n)}),onSuccess:n=>{s.invalidateQueries({queryKey:p.list()}),a(n.id),t()}});return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40",onClick:t,children:e.jsxs("div",{className:"w-full max-w-lg rounded-xl border border-border bg-panel p-5 shadow-xl",onClick:n=>n.stopPropagation(),children:[e.jsxs("div",{className:"mb-4 flex items-center justify-between",children:[e.jsx("h2",{className:"text-[15px] font-semibold",children:"New agent run"}),e.jsx("button",{type:"button",onClick:t,className:"text-faint hover:text-ink",children:e.jsx(A,{size:16})})]}),e.jsx("label",{className:"mb-1 block text-[12px] text-muted",children:"Task"}),e.jsx("textarea",{autoFocus:!0,value:l,onChange:n=>i(n.target.value),placeholder:"Describe what the agent should do…",rows:4,className:"mb-3 w-full resize-none rounded-lg border border-border bg-input px-3 py-2 text-[13px] text-ink placeholder:text-faint focus:border-accent focus:outline-none"}),e.jsxs("label",{className:"mb-1 block text-[12px] text-muted",children:["System prompt ",e.jsx("span",{className:"text-faint",children:"(optional)"})]}),e.jsx("textarea",{value:r,onChange:n=>o(n.target.value),placeholder:"You are a helpful assistant…",rows:2,className:"mb-4 w-full resize-none rounded-lg border border-border bg-input px-3 py-2 text-[13px] text-ink placeholder:text-faint focus:border-accent focus:outline-none"}),e.jsx("label",{className:"mb-1.5 block text-[12px] text-muted",children:"Tools"}),e.jsx("div",{className:"mb-4 space-y-1.5",children:U.map(n=>e.jsxs("label",{className:"flex cursor-pointer items-start gap-2 rounded-lg border border-border px-2.5 py-2 hover:bg-panel-2",children:[e.jsx("input",{type:"checkbox",checked:d[n.id],onChange:()=>x(n.id),className:"mt-0.5 accent-[var(--accent)]"}),e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:"block text-[13px] font-medium text-ink",children:n.label}),e.jsx("span",{className:"block text-[11px] leading-snug text-faint",children:n.hint})]})]},n.id))}),e.jsxs("div",{className:"flex items-center justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:t,className:"rounded-lg px-3 py-1.5 text-[13px] text-muted hover:text-ink",children:"Cancel"}),e.jsxs("button",{type:"button",disabled:!l.trim()||c.isPending,onClick:()=>c.mutate(),className:"flex items-center gap-1.5 rounded-lg bg-accent px-3 py-1.5 text-[13px] font-medium text-white disabled:opacity-50",children:[c.isPending?e.jsx(h,{size:13,className:"animate-spin"}):e.jsx(S,{size:13}),"Run agent"]})]}),c.isError&&e.jsx("p",{className:"mt-2 text-[12px]",style:{color:"var(--err)"},children:c.error.message})]})})}function X({call:t}){const[a,l]=u.useState(!1),i=typeof t.args?.query=="string"?t.args.query:typeof t.args?.url=="string"?t.args.url:JSON.stringify(t.args??{});return e.jsxs("div",{className:"w-full max-w-[85%] rounded-lg border border-border bg-panel px-2.5 py-1.5 text-[12px]",children:[e.jsxs("button",{type:"button",onClick:()=>l(r=>!r),className:"flex w-full items-center gap-1.5 text-left text-muted hover:text-ink",children:[e.jsx(E,{size:12,className:"shrink-0 text-accent"}),e.jsx("span",{className:"font-medium text-ink",children:t.name}),e.jsx("span",{className:"truncate text-faint",children:i})]}),a&&e.jsx("pre",{className:"mt-1.5 max-h-48 overflow-auto whitespace-pre-wrap break-words rounded bg-panel-2 p-2 text-[11px] text-muted",children:t.result})]})}function H({run:t}){const a=C(),l=u.useRef(null),[i,r]=u.useState(""),o=u.useRef(null),d=q({mutationFn:()=>K(t.id),onSuccess:()=>{a.invalidateQueries({queryKey:p.list()})}});u.useEffect(()=>{if(t.status!=="running"&&t.status!=="queued")return;const s=new AbortController;l.current=s;let x="";return(async()=>{try{for await(const c of F(t.id,0,s.signal))if(c.event==="delta")x+=c.data.delta,r(x);else if(c.event==="done"||c.event==="error"){r(""),a.invalidateQueries({queryKey:p.detail(t.id)}),a.invalidateQueries({queryKey:p.list()});break}}catch{}})(),()=>{s.abort(),l.current=null}},[t.id,t.status,a]),u.useEffect(()=>{o.current?.scrollIntoView({behavior:"smooth"})},[i,t.messages?.length]);const m=t.messages??[];return e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-border px-4 py-2.5",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[14px] font-medium text-ink",children:t.title}),e.jsx(z,{status:t.status})]}),(t.status==="running"||t.status==="queued")&&e.jsx("button",{type:"button",onClick:()=>d.mutate(),className:"rounded-lg border border-border px-3 py-1 text-[12px] text-muted transition-colors hover:border-red-400 hover:text-red-500",children:d.isPending?e.jsx(h,{size:12,className:"inline animate-spin"}):"Cancel"})]}),e.jsxs("div",{className:"flex-1 space-y-3 overflow-y-auto p-4",children:[m.map(s=>e.jsxs("div",{className:b("flex flex-col gap-1.5",s.role==="user"?"items-end":"items-start"),children:[s.toolCalls?.map(x=>e.jsx(X,{call:x},x.id)),(s.content||s.role==="user"||t.status==="running")&&e.jsx("div",{className:b("max-w-[85%] rounded-xl px-3 py-2 text-[13px] leading-relaxed",s.role==="user"?"bg-accent/15 text-ink":"bg-panel-2 text-ink"),children:e.jsx("p",{className:"whitespace-pre-wrap break-words",children:s.content||(s.role==="assistant"&&t.status==="running"?"…":"")})})]},s.id)),i&&e.jsx("div",{className:"flex gap-2",children:e.jsx("div",{className:"max-w-[85%] rounded-xl bg-panel-2 px-3 py-2 text-[13px] leading-relaxed text-ink",children:e.jsx("p",{className:"whitespace-pre-wrap break-words",children:i})})}),t.error&&e.jsxs("div",{className:"rounded-lg bg-red-500/10 px-3 py-2 text-[12px] text-red-500",children:["Error: ",t.error]}),e.jsx("div",{ref:o})]})]})}function ne(){const[t,a]=u.useState(null),[l,i]=u.useState(!1),r=v({queryKey:p.list(),queryFn:$,refetchInterval:s=>(s.state.data??[]).some(n=>n.status==="queued"||n.status==="running")?3e3:!1}),o=v({queryKey:p.detail(t??""),queryFn:()=>I(t),enabled:!!t,refetchInterval:s=>{const x=s.state.data;return x?.status==="queued"||x?.status==="running"?5e3:!1}}),d=r.data??[],m=o.data;return e.jsxs("div",{className:"flex h-full",children:[e.jsxs("div",{className:"flex w-64 shrink-0 flex-col border-r border-border",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-border px-3 py-2.5",children:[e.jsx("span",{className:"text-[13px] font-semibold text-ink",children:"Agents"}),e.jsxs("button",{type:"button",title:"New agent run",onClick:()=>i(!0),className:"flex items-center gap-1 rounded-lg bg-accent px-2 py-1 text-[11px] font-medium text-white transition-opacity hover:opacity-90",children:[e.jsx(N,{size:11})," New"]})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto",children:[r.isLoading&&e.jsx("div",{className:"flex h-20 items-center justify-center",children:e.jsx(h,{size:16,className:"animate-spin text-faint"})}),d.length===0&&!r.isLoading&&e.jsxs("div",{className:"px-4 py-8 text-center",children:[e.jsx(S,{size:28,className:"mx-auto mb-2 text-faint"}),e.jsx("p",{className:"text-[12px] text-muted",children:"No agent runs yet."}),e.jsx("p",{className:"mt-0.5 text-[11px] text-faint",children:"Click “New” to start one."})]}),d.map(s=>e.jsxs("button",{type:"button",onClick:()=>a(s.id),className:b("w-full border-b border-border px-3 py-2.5 text-left transition-colors hover:bg-panel-2",t===s.id&&"bg-panel-2"),children:[e.jsx("p",{className:"mb-0.5 truncate text-[13px] font-medium text-ink",children:s.title}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(z,{status:s.status}),e.jsx("span",{className:"text-[10px] text-faint",children:W(s.createdAt)})]})]},s.id))]})]}),e.jsx("div",{className:"flex min-w-0 flex-1 flex-col",children:t?o.isLoading?e.jsx("div",{className:"flex h-full items-center justify-center",children:e.jsx(h,{size:20,className:"animate-spin text-faint"})}):m?e.jsx(H,{run:m}):null:e.jsxs("div",{className:"flex h-full flex-col items-center justify-center text-center",children:[e.jsx(D,{size:32,className:"mb-3 text-faint"}),e.jsx("p",{className:"text-[14px] font-medium text-ink",children:"Select a run"}),e.jsx("p",{className:"mt-1 text-[12px] text-muted",children:"or create a new agent run to get started"}),e.jsxs("button",{type:"button",onClick:()=>i(!0),className:"mt-4 flex items-center gap-1.5 rounded-lg bg-accent px-3 py-1.5 text-[13px] font-medium text-white hover:opacity-90",children:[e.jsx(N,{size:13})," New agent run"]})]})}),l&&e.jsx(B,{onClose:()=>i(!1),onCreated:s=>{a(s),r.refetch()}})]})}export{ne as AgentsScreen};
|