turbollm 1.7.2 → 1.7.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 +13 -11
- package/dist/chunk-TPYU5ZAX.js +175 -0
- package/dist/cli.js +2124 -1948
- package/dist/distiller-UROKYEBN.js +9 -0
- package/dist/webdist/assets/AgentEditPage-DLuckXeR.js +1 -0
- package/dist/webdist/assets/ChatScreen-BOZjtqGu.js +65 -0
- package/dist/webdist/assets/CustomizeScreen-DoVGTM4C.js +4 -0
- package/dist/webdist/assets/DeveloperScreen-BJ7m4ZxK.js +1 -0
- package/dist/webdist/assets/EnginesScreen-D3b9VNx0.js +7 -0
- package/dist/webdist/assets/{MessageBubble-COuZ8jTd.js → MessageBubble-mJwFfOab.js} +15 -16
- package/dist/webdist/assets/ModelDetailDialog-M2tPWvP4.js +1 -0
- package/dist/webdist/assets/ModelDirs-CaIf1TUh.js +1 -0
- package/dist/webdist/assets/{ModelsScreen-DncNvsj6.js → ModelsScreen--sPDS_sx.js} +2 -2
- package/dist/webdist/assets/SettingsScreen-lBpo_MAD.js +1 -0
- package/dist/webdist/assets/SkillEditPage-B5S9Gtlh.js +1 -0
- package/dist/webdist/assets/WorkspaceScreen-Cpm-gLG1.js +1 -0
- package/dist/webdist/assets/agent-api-B3GXwr4Y.js +1 -0
- package/dist/webdist/assets/{arc-BrQAHE5c.js → arc-CRcL8nar.js} +1 -1
- package/dist/webdist/assets/{architectureDiagram-3BPJPVTR-DzOwDk0E.js → architectureDiagram-3BPJPVTR-BmOKGMd0.js} +1 -1
- package/dist/webdist/assets/{blockDiagram-GPEHLZMM-Cbs2lNCh.js → blockDiagram-GPEHLZMM-C4vusmQ-.js} +1 -1
- package/dist/webdist/assets/{c4Diagram-AAUBKEIU-BAull9Yv.js → c4Diagram-AAUBKEIU-DdY0YXKs.js} +1 -1
- package/dist/webdist/assets/channel-BB6NPD_B.js +1 -0
- package/dist/webdist/assets/chat-api-DrMO_g5m.js +3 -0
- package/dist/webdist/assets/check-BLFw3EpE.js +1 -0
- package/dist/webdist/assets/chevron-left-CfyO2AXW.js +1 -0
- package/dist/webdist/assets/chevron-right--1OIa5uV.js +1 -0
- package/dist/webdist/assets/{chunk-2J33WTMH-B38k4sJL.js → chunk-2J33WTMH-DzCJsNN1.js} +1 -1
- package/dist/webdist/assets/{chunk-4BX2VUAB-VxAkYvb7.js → chunk-4BX2VUAB-BNPfO47j.js} +1 -1
- package/dist/webdist/assets/{chunk-55IACEB6-CAz9ZWyR.js → chunk-55IACEB6-_vELiE2B.js} +1 -1
- package/dist/webdist/assets/{chunk-727SXJPM-CvLX5ghS.js → chunk-727SXJPM-CsQCgUxY.js} +1 -1
- package/dist/webdist/assets/{chunk-AQP2D5EJ-CZ0fsnc1.js → chunk-AQP2D5EJ-G0waQ7sq.js} +1 -1
- package/dist/webdist/assets/{chunk-FMBD7UC4-tjHz_yw8.js → chunk-FMBD7UC4-CkNtvlrw.js} +1 -1
- package/dist/webdist/assets/{chunk-ND2GUHAM-DVSh5E5_.js → chunk-ND2GUHAM-DGnw4n1I.js} +1 -1
- package/dist/webdist/assets/{chunk-QZHKN3VN-D1rUM2SU.js → chunk-QZHKN3VN-BpJ4HH0V.js} +1 -1
- package/dist/webdist/assets/circle-check-ByN99MCf.js +1 -0
- package/dist/webdist/assets/classDiagram-4FO5ZUOK-DwCs4wFr.js +1 -0
- package/dist/webdist/assets/classDiagram-v2-Q7XG4LA2-DwCs4wFr.js +1 -0
- package/dist/webdist/assets/collapsible-B_M28W08.js +1 -0
- package/dist/webdist/assets/{common-BD4Wa3KL.js → common-Cy1uxtS_.js} +1 -1
- package/dist/webdist/assets/{copy-button-DypRNkqI.js → copy-button-DgYGL35x.js} +1 -1
- package/dist/webdist/assets/{cose-bilkent-S5V4N54A-DIUqY7o2.js → cose-bilkent-S5V4N54A-fol9bGNP.js} +1 -1
- package/dist/webdist/assets/{dagre-BM42HDAG-BzTcsgZ1.js → dagre-BM42HDAG-kyg4YiiE.js} +1 -1
- package/dist/webdist/assets/{diagram-2AECGRRQ-DanHH-W_.js → diagram-2AECGRRQ-CK_mQs9l.js} +1 -1
- package/dist/webdist/assets/{diagram-5GNKFQAL-DQ5sWHUL.js → diagram-5GNKFQAL-MBl66jsh.js} +1 -1
- package/dist/webdist/assets/{diagram-KO2AKTUF-Jqr_pLwu.js → diagram-KO2AKTUF-IxjaUqTu.js} +1 -1
- package/dist/webdist/assets/{diagram-LMA3HP47-BZ89-cp0.js → diagram-LMA3HP47-Cc_fuuLo.js} +1 -1
- package/dist/webdist/assets/{diagram-OG6HWLK6-cidBc5qa.js → diagram-OG6HWLK6-DvprGLFT.js} +1 -1
- package/dist/webdist/assets/{dialog-3hyZ9j4e.js → dialog-d6eLRBbl.js} +1 -1
- package/dist/webdist/assets/{erDiagram-TEJ5UH35-DEAKZN7b.js → erDiagram-TEJ5UH35-BEebeQO0.js} +1 -1
- package/dist/webdist/assets/{flowDiagram-I6XJVG4X-Cyx8gMzN.js → flowDiagram-I6XJVG4X--NtrYHee.js} +1 -1
- package/dist/webdist/assets/folder-input-C5Td4Oz0.js +1 -0
- package/dist/webdist/assets/{ganttDiagram-6RSMTGT7-CqXYW44d.js → ganttDiagram-6RSMTGT7-DOx3A2YH.js} +1 -1
- package/dist/webdist/assets/{gitGraphDiagram-PVQCEYII-0dv_zKYA.js → gitGraphDiagram-PVQCEYII-BEY69HKU.js} +1 -1
- package/dist/webdist/assets/index-B8H9eSFq.css +1 -0
- package/dist/webdist/assets/{index-DHmOrvk5.js → index-Tpho8qZ0.js} +1 -1
- package/dist/webdist/assets/index-tVO2x-Rw.js +10 -0
- package/dist/webdist/assets/{infoDiagram-5YYISTIA-PxeM6E3u.js → infoDiagram-5YYISTIA-C4X5I5eI.js} +1 -1
- package/dist/webdist/assets/{ishikawaDiagram-YF4QCWOH-BnNdTjj1.js → ishikawaDiagram-YF4QCWOH-BhUZzSmP.js} +1 -1
- package/dist/webdist/assets/{journeyDiagram-JHISSGLW-D3AHUGxz.js → journeyDiagram-JHISSGLW-R-rmKLZ-.js} +1 -1
- package/dist/webdist/assets/{kanban-definition-UN3LZRKU-YARl6SUt.js → kanban-definition-UN3LZRKU-DUcDGDiT.js} +1 -1
- package/dist/webdist/assets/{linear-CMEhaWGh.js → linear-Cbr5iYFb.js} +1 -1
- package/dist/webdist/assets/{mermaid.core-Dfl2pPvv.js → mermaid.core-DJVxydy1.js} +4 -4
- package/dist/webdist/assets/{mindmap-definition-RKZ34NQL-BojWC6jk.js → mindmap-definition-RKZ34NQL-BSOgl-Cn.js} +1 -1
- package/dist/webdist/assets/pencil-Blh_Q7or.js +1 -0
- package/dist/webdist/assets/personas-Dm0JD8kn.js +305 -0
- package/dist/webdist/assets/{pieDiagram-4H26LBE5-cjsdMtJJ.js → pieDiagram-4H26LBE5-BwQ854zg.js} +1 -1
- package/dist/webdist/assets/plus-D4IwdkJ3.js +1 -0
- package/dist/webdist/assets/{quadrantDiagram-W4KKPZXB-DYVcgQuL.js → quadrantDiagram-W4KKPZXB-BOQGjhZD.js} +1 -1
- package/dist/webdist/assets/{radix-BY-fjzwm.js → radix-DVGeLgPN.js} +2 -2
- package/dist/webdist/assets/{refresh-cw-Cco9RapO.js → refresh-cw-BVSLL9xa.js} +1 -1
- package/dist/webdist/assets/{requirementDiagram-4Y6WPE33-Dkj58nhB.js → requirementDiagram-4Y6WPE33-b3dNYy6K.js} +1 -1
- package/dist/webdist/assets/rotate-ccw-B7QiZxpr.js +1 -0
- package/dist/webdist/assets/{sankeyDiagram-5OEKKPKP-l3GwUuNl.js → sankeyDiagram-5OEKKPKP-C26ntsbR.js} +1 -1
- package/dist/webdist/assets/{save-CSISNMk8.js → save-DI4M5kP-.js} +1 -1
- package/dist/webdist/assets/{sequenceDiagram-3UESZ5HK-CWj1Dplo.js → sequenceDiagram-3UESZ5HK-Bp8i1DIR.js} +1 -1
- package/dist/webdist/assets/{skeleton-CBRf-twG.js → skeleton-D6toQA7p.js} +1 -1
- package/dist/webdist/assets/star-BCxsXqcv.js +1 -0
- package/dist/webdist/assets/{stateDiagram-AJRCARHV-zbnPRcoE.js → stateDiagram-AJRCARHV-CmZpIELB.js} +1 -1
- package/dist/webdist/assets/stateDiagram-v2-BHNVJYJU-CswfYrBO.js +1 -0
- package/dist/webdist/assets/{timeline-definition-PNZ67QCA-C_zAo1WZ.js → timeline-definition-PNZ67QCA-slNuxmat.js} +1 -1
- package/dist/webdist/assets/{trash-2-DJmVqx0w.js → trash-2-DGVXsIsP.js} +1 -1
- package/dist/webdist/assets/{vendor-W5GIuFcv.js → vendor-BE0HADM8.js} +1 -1
- package/dist/webdist/assets/{vennDiagram-CIIHVFJN-DxfcocQu.js → vennDiagram-CIIHVFJN-Lf4xPS3i.js} +1 -1
- package/dist/webdist/assets/{vram-Dn53zt7R.js → vram-DVAmNgRC.js} +1 -1
- package/dist/webdist/assets/{wardley-L42UT6IY-BnZ8BinJ.js → wardley-L42UT6IY-DbEeYkcX.js} +1 -1
- package/dist/webdist/assets/{wardleyDiagram-YWT4CUSO-DMk9z7hr.js → wardleyDiagram-YWT4CUSO-WNGbDcCj.js} +1 -1
- package/dist/webdist/assets/wrench-DzoqtmhJ.js +1 -0
- package/dist/webdist/assets/{xychartDiagram-2RQKCTM6-BUtTPXPF.js → xychartDiagram-2RQKCTM6-D2kBZ8cG.js} +1 -1
- package/dist/webdist/index.html +4 -4
- package/package.json +1 -1
- package/dist/webdist/assets/AgentsScreen-sMeMB3IQ.js +0 -2
- package/dist/webdist/assets/ChatScreen-rXB7PrWJ.js +0 -65
- package/dist/webdist/assets/CustomizeScreen-BBwvtk28.js +0 -4
- package/dist/webdist/assets/DeveloperScreen-fXV-qXB5.js +0 -1
- package/dist/webdist/assets/EnginesScreen-CrmYzhio.js +0 -7
- package/dist/webdist/assets/ModelDetailDialog-Dlt5uF3h.js +0 -1
- package/dist/webdist/assets/ModelDirs-BYN-DmHL.js +0 -1
- package/dist/webdist/assets/SettingsScreen-DXX3r4Ep.js +0 -1
- package/dist/webdist/assets/arrow-left-Dp4XRnbs.js +0 -1
- package/dist/webdist/assets/channel-Bt5-ol5R.js +0 -1
- package/dist/webdist/assets/check-jMeH6YsH.js +0 -1
- package/dist/webdist/assets/chevron-down-C5ZMFCtb.js +0 -1
- package/dist/webdist/assets/chevron-right-DNVnXbZ1.js +0 -1
- package/dist/webdist/assets/circle-check-qnghY_qF.js +0 -1
- package/dist/webdist/assets/circle-x-FM28MwOL.js +0 -1
- package/dist/webdist/assets/classDiagram-4FO5ZUOK-jfnUpxOr.js +0 -1
- package/dist/webdist/assets/classDiagram-v2-Q7XG4LA2-jfnUpxOr.js +0 -1
- package/dist/webdist/assets/collapsible-CwqYFc9v.js +0 -1
- package/dist/webdist/assets/index-B_WtFoLC.css +0 -1
- package/dist/webdist/assets/index-CriwC5VH.js +0 -10
- package/dist/webdist/assets/pencil-CS33zp9q.js +0 -1
- package/dist/webdist/assets/personas-CzcXp8zg.js +0 -75
- package/dist/webdist/assets/plus-BO3vGy6f.js +0 -1
- package/dist/webdist/assets/stateDiagram-v2-BHNVJYJU-Ukx8AVKZ.js +0 -1
- package/dist/webdist/assets/wrench-Di5WLTz2.js +0 -1
package/README.md
CHANGED
|
@@ -196,9 +196,11 @@ the detail:
|
|
|
196
196
|
the model draws when a comparison, trend, or hierarchy is genuinely worth a visual.
|
|
197
197
|
- **Live artifacts** — `html`, `svg`, and `mermaid` replies render as **sandboxed, offline
|
|
198
198
|
previews** shown as an image, with one-click export to **PNG / JPEG / SVG / animated GIF / HTML**.
|
|
199
|
-
- **
|
|
200
|
-
Creative · Research) per conversation, no prompt-wrangling required. The
|
|
201
|
-
produces polished, self-contained, previewable designs by default
|
|
199
|
+
- **Agents** — pick a style (Default · **Designer** · Concise · Detailed · Blunt · Formal · Tutor ·
|
|
200
|
+
Creative · Research · **Lite** · **Code**) per conversation, no prompt-wrangling required. The
|
|
201
|
+
**Designer** persona produces polished, self-contained, previewable designs by default; **Lite**
|
|
202
|
+
strips the hidden prompt to the bare minimum for the fastest responses. See below for editing
|
|
203
|
+
built-ins or creating your own.
|
|
202
204
|
- **Edit, regenerate, delete, copy** any message; **persistent, searchable conversations**
|
|
203
205
|
with rename, delete, and **auto-generated titles**, organized into **drag-resizable,
|
|
204
206
|
collapsible folders** you create/rename/move conversations into.
|
|
@@ -219,17 +221,17 @@ the detail:
|
|
|
219
221
|
</details>
|
|
220
222
|
|
|
221
223
|
<details>
|
|
222
|
-
<summary><strong>🤖
|
|
224
|
+
<summary><strong>🤖 Customize → Agents — edit any built-in, or build your own</strong></summary>
|
|
223
225
|
|
|
224
226
|
<br/>
|
|
225
227
|
|
|
226
|
-
- **
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
228
|
+
- **Edit any built-in agent in place** — system prompt, which shared skills it uses, and which
|
|
229
|
+
tools it may call — with a one-click **Reset** back to the original.
|
|
230
|
+
- **Create your own agent** from scratch: a name, description, and system prompt, plus a
|
|
231
|
+
checklist of which shared skills and which tools it's allowed to use (everything on by
|
|
232
|
+
default). Pick it from the same in-chat agent picker as the built-ins.
|
|
233
|
+
- **MCP tools grouped by server** in the tool checklist — one toggle selects or deselects an
|
|
234
|
+
entire server's tools at once, or expand it to pick individually.
|
|
233
235
|
|
|
234
236
|
</details>
|
|
235
237
|
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/agents/distiller.ts
|
|
4
|
+
import { readFileSync, readdirSync, statSync, existsSync } from "fs";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
|
|
7
|
+
// src/engines/compat.ts
|
|
8
|
+
function engineAcceptsFormat(engineKind, format) {
|
|
9
|
+
if (engineKind === "mlx") return format === "mlx";
|
|
10
|
+
if (engineKind === "vllm") return format === "mlx";
|
|
11
|
+
return format === "gguf";
|
|
12
|
+
}
|
|
13
|
+
var ENGINE_MODEL_ALIAS = "default_model";
|
|
14
|
+
function engineModelAlias(engineKind) {
|
|
15
|
+
return engineKind === "mlx" || engineKind === "vllm" || engineKind === "sglang" ? ENGINE_MODEL_ALIAS : null;
|
|
16
|
+
}
|
|
17
|
+
var VENDOR_DISPLAY = {
|
|
18
|
+
nvidia: "NVIDIA",
|
|
19
|
+
amd: "AMD",
|
|
20
|
+
intel: "Intel",
|
|
21
|
+
apple: "Apple Silicon",
|
|
22
|
+
unknown: "no detected GPU"
|
|
23
|
+
};
|
|
24
|
+
var PLATFORM_DISPLAY = {
|
|
25
|
+
darwin: "macOS",
|
|
26
|
+
win32: "Windows",
|
|
27
|
+
linux: "Linux"
|
|
28
|
+
};
|
|
29
|
+
function platformName(p) {
|
|
30
|
+
return PLATFORM_DISPLAY[p] ?? p;
|
|
31
|
+
}
|
|
32
|
+
function platformReason(allowed) {
|
|
33
|
+
const names = allowed.map(platformName);
|
|
34
|
+
const joined = names.length <= 1 ? names.join("") : `${names.slice(0, -1).join(", ")} & ${names[names.length - 1]}`;
|
|
35
|
+
return `${joined} only`;
|
|
36
|
+
}
|
|
37
|
+
function evaluateVariant(p, r) {
|
|
38
|
+
if (r.platform && !r.platform.includes(p.platform)) {
|
|
39
|
+
return { ok: false, reason: platformReason(r.platform) };
|
|
40
|
+
}
|
|
41
|
+
if (r.arch && !r.arch.includes(p.arch)) {
|
|
42
|
+
return { ok: false, reason: `Needs ${r.arch.join(" / ")}` };
|
|
43
|
+
}
|
|
44
|
+
if (r.gpuVendor && !r.gpuVendor.includes(p.gpuVendor)) {
|
|
45
|
+
const needs = r.gpuVendor.map((v) => VENDOR_DISPLAY[v]).join(" / ");
|
|
46
|
+
const article = /^[NAEIO]/.test(needs) ? "an" : "a";
|
|
47
|
+
return { ok: false, reason: `Needs ${article} ${needs} GPU \u2014 you have ${VENDOR_DISPLAY[p.gpuVendor]}` };
|
|
48
|
+
}
|
|
49
|
+
if (r.minVramMb !== void 0 && p.vramMb > 0 && p.vramMb < r.minVramMb) {
|
|
50
|
+
const gb = Math.round(r.minVramMb / 1024);
|
|
51
|
+
return { ok: false, reason: `Needs ~${gb} GB VRAM` };
|
|
52
|
+
}
|
|
53
|
+
return { ok: true };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/agents/distiller.ts
|
|
57
|
+
var DISTILL_SYSTEM = `You write a single reusable SKILL from the material provided. A skill captures a repeatable approach so it can be applied to similar future tasks.
|
|
58
|
+
|
|
59
|
+
Output a JSON object: {"name": <short kebab-case id>, "description": <one sentence: when to use this skill>, "procedure": <concise step-by-step procedure, markdown>}
|
|
60
|
+
|
|
61
|
+
Rules:
|
|
62
|
+
- The skill must be GENERAL and reusable, not a one-off answer to this specific input.
|
|
63
|
+
- "name" is a short kebab-case identifier (e.g. "csv-summary", "extract-config-values").
|
|
64
|
+
- "description" is one sentence describing WHEN to apply it.
|
|
65
|
+
- "procedure" is a concise, numbered set of steps \u2014 the how.
|
|
66
|
+
- If the material does not contain a clear reusable approach, output {"name": null, "description": null, "procedure": null}.
|
|
67
|
+
Respond with ONLY the JSON object, nothing else.`;
|
|
68
|
+
async function distill(d, material) {
|
|
69
|
+
const ms = d.manager.status();
|
|
70
|
+
const target = d.manager.target();
|
|
71
|
+
if (ms.state !== "running" || !ms.model || !target) return { name: null, description: null, procedure: null };
|
|
72
|
+
const model = engineModelAlias(d.registry.active()?.kind ?? "") ?? ms.model.key;
|
|
73
|
+
try {
|
|
74
|
+
const res = await fetch(`${target}/v1/chat/completions`, {
|
|
75
|
+
method: "POST",
|
|
76
|
+
headers: { "Content-Type": "application/json" },
|
|
77
|
+
body: JSON.stringify({
|
|
78
|
+
model,
|
|
79
|
+
messages: [
|
|
80
|
+
{ role: "system", content: DISTILL_SYSTEM },
|
|
81
|
+
{ role: "user", content: `Material:
|
|
82
|
+
|
|
83
|
+
${material.slice(0, 24e3)}
|
|
84
|
+
|
|
85
|
+
Write ONE reusable skill as raw JSON \u2014 no markdown fences.` }
|
|
86
|
+
],
|
|
87
|
+
temperature: 0.3,
|
|
88
|
+
max_tokens: 800,
|
|
89
|
+
reasoning_budget: 0,
|
|
90
|
+
chat_template_kwargs: { enable_thinking: false },
|
|
91
|
+
response_format: { type: "json_object" },
|
|
92
|
+
stream: false
|
|
93
|
+
}),
|
|
94
|
+
signal: AbortSignal.timeout(9e4)
|
|
95
|
+
});
|
|
96
|
+
if (!res.ok) return { name: null, description: null, procedure: null };
|
|
97
|
+
const data = await res.json();
|
|
98
|
+
let txt = data.choices?.[0]?.message?.content ?? "";
|
|
99
|
+
txt = txt.replace(/<think>[\s\S]*?<\/think>/gi, "").replace(/```json|```/gi, "").trim();
|
|
100
|
+
const m = txt.match(/\{[\s\S]*\}/);
|
|
101
|
+
if (!m) return { name: null, description: null, procedure: null };
|
|
102
|
+
const j = JSON.parse(m[0]);
|
|
103
|
+
const valid = (s) => typeof s === "string" && s.trim() && s.toLowerCase() !== "null" ? s.trim() : null;
|
|
104
|
+
const name = valid(j.name);
|
|
105
|
+
const procedure = valid(j.procedure);
|
|
106
|
+
if (!name || !procedure) return { name: null, description: null, procedure: null };
|
|
107
|
+
return { name: name.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64), description: valid(j.description) ?? "", procedure };
|
|
108
|
+
} catch {
|
|
109
|
+
return { name: null, description: null, procedure: null };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function distillFromConversation(d, transcript) {
|
|
113
|
+
const text = transcript.map((m) => `${m.role.toUpperCase()}: ${m.content}`).join("\n");
|
|
114
|
+
return distill(d, `A successful completed task:
|
|
115
|
+
|
|
116
|
+
${text}`);
|
|
117
|
+
}
|
|
118
|
+
var FOLDER_TEXT = /\.(md|txt|json|ya?ml|csv|js|ts|py|sh|html?|css)$/i;
|
|
119
|
+
function collectFolderFiles(folder, max) {
|
|
120
|
+
const files = [];
|
|
121
|
+
const walk = (dir, depth) => {
|
|
122
|
+
if (depth > 4 || files.length >= max) return;
|
|
123
|
+
let entries;
|
|
124
|
+
try {
|
|
125
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
126
|
+
} catch {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
for (const e of entries) {
|
|
130
|
+
if (files.length >= max) return;
|
|
131
|
+
const p = join(dir, e.name);
|
|
132
|
+
if (e.isDirectory()) {
|
|
133
|
+
walk(p, depth + 1);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (!FOLDER_TEXT.test(e.name)) continue;
|
|
137
|
+
try {
|
|
138
|
+
if (statSync(p).size > 2e5) continue;
|
|
139
|
+
const content = readFileSync(p, "utf8").slice(0, 6e3).trim();
|
|
140
|
+
if (content) files.push({ name: e.name, content });
|
|
141
|
+
} catch {
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
walk(folder, 0);
|
|
146
|
+
return files;
|
|
147
|
+
}
|
|
148
|
+
async function distillSkillsFromFolder(d, folder, opts = {}) {
|
|
149
|
+
if (!existsSync(folder) || !statSync(folder).isDirectory()) return [];
|
|
150
|
+
const max = opts.max ?? 12;
|
|
151
|
+
const files = collectFolderFiles(folder, max);
|
|
152
|
+
if (!files.length) return [];
|
|
153
|
+
const out = [];
|
|
154
|
+
const seen = /* @__PURE__ */ new Set();
|
|
155
|
+
for (let i = 0; i < files.length; i++) {
|
|
156
|
+
const f = files[i];
|
|
157
|
+
opts.onProgress?.(i, files.length, f.name);
|
|
158
|
+
const s = await distill(d, `A reusable approach captured in "${f.name}":
|
|
159
|
+
|
|
160
|
+
${f.content}`);
|
|
161
|
+
if (s.name && s.procedure && !seen.has(s.name)) {
|
|
162
|
+
seen.add(s.name);
|
|
163
|
+
out.push(s);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return out;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export {
|
|
170
|
+
engineAcceptsFormat,
|
|
171
|
+
engineModelAlias,
|
|
172
|
+
evaluateVariant,
|
|
173
|
+
distillFromConversation,
|
|
174
|
+
distillSkillsFromFolder
|
|
175
|
+
};
|