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.
Files changed (115) hide show
  1. package/README.md +13 -11
  2. package/dist/chunk-TPYU5ZAX.js +175 -0
  3. package/dist/cli.js +2124 -1948
  4. package/dist/distiller-UROKYEBN.js +9 -0
  5. package/dist/webdist/assets/AgentEditPage-DLuckXeR.js +1 -0
  6. package/dist/webdist/assets/ChatScreen-BOZjtqGu.js +65 -0
  7. package/dist/webdist/assets/CustomizeScreen-DoVGTM4C.js +4 -0
  8. package/dist/webdist/assets/DeveloperScreen-BJ7m4ZxK.js +1 -0
  9. package/dist/webdist/assets/EnginesScreen-D3b9VNx0.js +7 -0
  10. package/dist/webdist/assets/{MessageBubble-COuZ8jTd.js → MessageBubble-mJwFfOab.js} +15 -16
  11. package/dist/webdist/assets/ModelDetailDialog-M2tPWvP4.js +1 -0
  12. package/dist/webdist/assets/ModelDirs-CaIf1TUh.js +1 -0
  13. package/dist/webdist/assets/{ModelsScreen-DncNvsj6.js → ModelsScreen--sPDS_sx.js} +2 -2
  14. package/dist/webdist/assets/SettingsScreen-lBpo_MAD.js +1 -0
  15. package/dist/webdist/assets/SkillEditPage-B5S9Gtlh.js +1 -0
  16. package/dist/webdist/assets/WorkspaceScreen-Cpm-gLG1.js +1 -0
  17. package/dist/webdist/assets/agent-api-B3GXwr4Y.js +1 -0
  18. package/dist/webdist/assets/{arc-BrQAHE5c.js → arc-CRcL8nar.js} +1 -1
  19. package/dist/webdist/assets/{architectureDiagram-3BPJPVTR-DzOwDk0E.js → architectureDiagram-3BPJPVTR-BmOKGMd0.js} +1 -1
  20. package/dist/webdist/assets/{blockDiagram-GPEHLZMM-Cbs2lNCh.js → blockDiagram-GPEHLZMM-C4vusmQ-.js} +1 -1
  21. package/dist/webdist/assets/{c4Diagram-AAUBKEIU-BAull9Yv.js → c4Diagram-AAUBKEIU-DdY0YXKs.js} +1 -1
  22. package/dist/webdist/assets/channel-BB6NPD_B.js +1 -0
  23. package/dist/webdist/assets/chat-api-DrMO_g5m.js +3 -0
  24. package/dist/webdist/assets/check-BLFw3EpE.js +1 -0
  25. package/dist/webdist/assets/chevron-left-CfyO2AXW.js +1 -0
  26. package/dist/webdist/assets/chevron-right--1OIa5uV.js +1 -0
  27. package/dist/webdist/assets/{chunk-2J33WTMH-B38k4sJL.js → chunk-2J33WTMH-DzCJsNN1.js} +1 -1
  28. package/dist/webdist/assets/{chunk-4BX2VUAB-VxAkYvb7.js → chunk-4BX2VUAB-BNPfO47j.js} +1 -1
  29. package/dist/webdist/assets/{chunk-55IACEB6-CAz9ZWyR.js → chunk-55IACEB6-_vELiE2B.js} +1 -1
  30. package/dist/webdist/assets/{chunk-727SXJPM-CvLX5ghS.js → chunk-727SXJPM-CsQCgUxY.js} +1 -1
  31. package/dist/webdist/assets/{chunk-AQP2D5EJ-CZ0fsnc1.js → chunk-AQP2D5EJ-G0waQ7sq.js} +1 -1
  32. package/dist/webdist/assets/{chunk-FMBD7UC4-tjHz_yw8.js → chunk-FMBD7UC4-CkNtvlrw.js} +1 -1
  33. package/dist/webdist/assets/{chunk-ND2GUHAM-DVSh5E5_.js → chunk-ND2GUHAM-DGnw4n1I.js} +1 -1
  34. package/dist/webdist/assets/{chunk-QZHKN3VN-D1rUM2SU.js → chunk-QZHKN3VN-BpJ4HH0V.js} +1 -1
  35. package/dist/webdist/assets/circle-check-ByN99MCf.js +1 -0
  36. package/dist/webdist/assets/classDiagram-4FO5ZUOK-DwCs4wFr.js +1 -0
  37. package/dist/webdist/assets/classDiagram-v2-Q7XG4LA2-DwCs4wFr.js +1 -0
  38. package/dist/webdist/assets/collapsible-B_M28W08.js +1 -0
  39. package/dist/webdist/assets/{common-BD4Wa3KL.js → common-Cy1uxtS_.js} +1 -1
  40. package/dist/webdist/assets/{copy-button-DypRNkqI.js → copy-button-DgYGL35x.js} +1 -1
  41. package/dist/webdist/assets/{cose-bilkent-S5V4N54A-DIUqY7o2.js → cose-bilkent-S5V4N54A-fol9bGNP.js} +1 -1
  42. package/dist/webdist/assets/{dagre-BM42HDAG-BzTcsgZ1.js → dagre-BM42HDAG-kyg4YiiE.js} +1 -1
  43. package/dist/webdist/assets/{diagram-2AECGRRQ-DanHH-W_.js → diagram-2AECGRRQ-CK_mQs9l.js} +1 -1
  44. package/dist/webdist/assets/{diagram-5GNKFQAL-DQ5sWHUL.js → diagram-5GNKFQAL-MBl66jsh.js} +1 -1
  45. package/dist/webdist/assets/{diagram-KO2AKTUF-Jqr_pLwu.js → diagram-KO2AKTUF-IxjaUqTu.js} +1 -1
  46. package/dist/webdist/assets/{diagram-LMA3HP47-BZ89-cp0.js → diagram-LMA3HP47-Cc_fuuLo.js} +1 -1
  47. package/dist/webdist/assets/{diagram-OG6HWLK6-cidBc5qa.js → diagram-OG6HWLK6-DvprGLFT.js} +1 -1
  48. package/dist/webdist/assets/{dialog-3hyZ9j4e.js → dialog-d6eLRBbl.js} +1 -1
  49. package/dist/webdist/assets/{erDiagram-TEJ5UH35-DEAKZN7b.js → erDiagram-TEJ5UH35-BEebeQO0.js} +1 -1
  50. package/dist/webdist/assets/{flowDiagram-I6XJVG4X-Cyx8gMzN.js → flowDiagram-I6XJVG4X--NtrYHee.js} +1 -1
  51. package/dist/webdist/assets/folder-input-C5Td4Oz0.js +1 -0
  52. package/dist/webdist/assets/{ganttDiagram-6RSMTGT7-CqXYW44d.js → ganttDiagram-6RSMTGT7-DOx3A2YH.js} +1 -1
  53. package/dist/webdist/assets/{gitGraphDiagram-PVQCEYII-0dv_zKYA.js → gitGraphDiagram-PVQCEYII-BEY69HKU.js} +1 -1
  54. package/dist/webdist/assets/index-B8H9eSFq.css +1 -0
  55. package/dist/webdist/assets/{index-DHmOrvk5.js → index-Tpho8qZ0.js} +1 -1
  56. package/dist/webdist/assets/index-tVO2x-Rw.js +10 -0
  57. package/dist/webdist/assets/{infoDiagram-5YYISTIA-PxeM6E3u.js → infoDiagram-5YYISTIA-C4X5I5eI.js} +1 -1
  58. package/dist/webdist/assets/{ishikawaDiagram-YF4QCWOH-BnNdTjj1.js → ishikawaDiagram-YF4QCWOH-BhUZzSmP.js} +1 -1
  59. package/dist/webdist/assets/{journeyDiagram-JHISSGLW-D3AHUGxz.js → journeyDiagram-JHISSGLW-R-rmKLZ-.js} +1 -1
  60. package/dist/webdist/assets/{kanban-definition-UN3LZRKU-YARl6SUt.js → kanban-definition-UN3LZRKU-DUcDGDiT.js} +1 -1
  61. package/dist/webdist/assets/{linear-CMEhaWGh.js → linear-Cbr5iYFb.js} +1 -1
  62. package/dist/webdist/assets/{mermaid.core-Dfl2pPvv.js → mermaid.core-DJVxydy1.js} +4 -4
  63. package/dist/webdist/assets/{mindmap-definition-RKZ34NQL-BojWC6jk.js → mindmap-definition-RKZ34NQL-BSOgl-Cn.js} +1 -1
  64. package/dist/webdist/assets/pencil-Blh_Q7or.js +1 -0
  65. package/dist/webdist/assets/personas-Dm0JD8kn.js +305 -0
  66. package/dist/webdist/assets/{pieDiagram-4H26LBE5-cjsdMtJJ.js → pieDiagram-4H26LBE5-BwQ854zg.js} +1 -1
  67. package/dist/webdist/assets/plus-D4IwdkJ3.js +1 -0
  68. package/dist/webdist/assets/{quadrantDiagram-W4KKPZXB-DYVcgQuL.js → quadrantDiagram-W4KKPZXB-BOQGjhZD.js} +1 -1
  69. package/dist/webdist/assets/{radix-BY-fjzwm.js → radix-DVGeLgPN.js} +2 -2
  70. package/dist/webdist/assets/{refresh-cw-Cco9RapO.js → refresh-cw-BVSLL9xa.js} +1 -1
  71. package/dist/webdist/assets/{requirementDiagram-4Y6WPE33-Dkj58nhB.js → requirementDiagram-4Y6WPE33-b3dNYy6K.js} +1 -1
  72. package/dist/webdist/assets/rotate-ccw-B7QiZxpr.js +1 -0
  73. package/dist/webdist/assets/{sankeyDiagram-5OEKKPKP-l3GwUuNl.js → sankeyDiagram-5OEKKPKP-C26ntsbR.js} +1 -1
  74. package/dist/webdist/assets/{save-CSISNMk8.js → save-DI4M5kP-.js} +1 -1
  75. package/dist/webdist/assets/{sequenceDiagram-3UESZ5HK-CWj1Dplo.js → sequenceDiagram-3UESZ5HK-Bp8i1DIR.js} +1 -1
  76. package/dist/webdist/assets/{skeleton-CBRf-twG.js → skeleton-D6toQA7p.js} +1 -1
  77. package/dist/webdist/assets/star-BCxsXqcv.js +1 -0
  78. package/dist/webdist/assets/{stateDiagram-AJRCARHV-zbnPRcoE.js → stateDiagram-AJRCARHV-CmZpIELB.js} +1 -1
  79. package/dist/webdist/assets/stateDiagram-v2-BHNVJYJU-CswfYrBO.js +1 -0
  80. package/dist/webdist/assets/{timeline-definition-PNZ67QCA-C_zAo1WZ.js → timeline-definition-PNZ67QCA-slNuxmat.js} +1 -1
  81. package/dist/webdist/assets/{trash-2-DJmVqx0w.js → trash-2-DGVXsIsP.js} +1 -1
  82. package/dist/webdist/assets/{vendor-W5GIuFcv.js → vendor-BE0HADM8.js} +1 -1
  83. package/dist/webdist/assets/{vennDiagram-CIIHVFJN-DxfcocQu.js → vennDiagram-CIIHVFJN-Lf4xPS3i.js} +1 -1
  84. package/dist/webdist/assets/{vram-Dn53zt7R.js → vram-DVAmNgRC.js} +1 -1
  85. package/dist/webdist/assets/{wardley-L42UT6IY-BnZ8BinJ.js → wardley-L42UT6IY-DbEeYkcX.js} +1 -1
  86. package/dist/webdist/assets/{wardleyDiagram-YWT4CUSO-DMk9z7hr.js → wardleyDiagram-YWT4CUSO-WNGbDcCj.js} +1 -1
  87. package/dist/webdist/assets/wrench-DzoqtmhJ.js +1 -0
  88. package/dist/webdist/assets/{xychartDiagram-2RQKCTM6-BUtTPXPF.js → xychartDiagram-2RQKCTM6-D2kBZ8cG.js} +1 -1
  89. package/dist/webdist/index.html +4 -4
  90. package/package.json +1 -1
  91. package/dist/webdist/assets/AgentsScreen-sMeMB3IQ.js +0 -2
  92. package/dist/webdist/assets/ChatScreen-rXB7PrWJ.js +0 -65
  93. package/dist/webdist/assets/CustomizeScreen-BBwvtk28.js +0 -4
  94. package/dist/webdist/assets/DeveloperScreen-fXV-qXB5.js +0 -1
  95. package/dist/webdist/assets/EnginesScreen-CrmYzhio.js +0 -7
  96. package/dist/webdist/assets/ModelDetailDialog-Dlt5uF3h.js +0 -1
  97. package/dist/webdist/assets/ModelDirs-BYN-DmHL.js +0 -1
  98. package/dist/webdist/assets/SettingsScreen-DXX3r4Ep.js +0 -1
  99. package/dist/webdist/assets/arrow-left-Dp4XRnbs.js +0 -1
  100. package/dist/webdist/assets/channel-Bt5-ol5R.js +0 -1
  101. package/dist/webdist/assets/check-jMeH6YsH.js +0 -1
  102. package/dist/webdist/assets/chevron-down-C5ZMFCtb.js +0 -1
  103. package/dist/webdist/assets/chevron-right-DNVnXbZ1.js +0 -1
  104. package/dist/webdist/assets/circle-check-qnghY_qF.js +0 -1
  105. package/dist/webdist/assets/circle-x-FM28MwOL.js +0 -1
  106. package/dist/webdist/assets/classDiagram-4FO5ZUOK-jfnUpxOr.js +0 -1
  107. package/dist/webdist/assets/classDiagram-v2-Q7XG4LA2-jfnUpxOr.js +0 -1
  108. package/dist/webdist/assets/collapsible-CwqYFc9v.js +0 -1
  109. package/dist/webdist/assets/index-B_WtFoLC.css +0 -1
  110. package/dist/webdist/assets/index-CriwC5VH.js +0 -10
  111. package/dist/webdist/assets/pencil-CS33zp9q.js +0 -1
  112. package/dist/webdist/assets/personas-CzcXp8zg.js +0 -75
  113. package/dist/webdist/assets/plus-BO3vGy6f.js +0 -1
  114. package/dist/webdist/assets/stateDiagram-v2-BHNVJYJU-Ukx8AVKZ.js +0 -1
  115. 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
- - **Personas** — pick a style (Default · **Designer** · Concise · Detailed · Blunt · Formal · Tutor ·
200
- Creative · Research) per conversation, no prompt-wrangling required. The **Designer** persona
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>🤖 Background agentslong-running tasks that don't tie up your chat</strong></summary>
224
+ <summary><strong>🤖 Customize Agents edit any built-in, or build your own</strong></summary>
223
225
 
224
226
  <br/>
225
227
 
226
- - **Launch an agent and walk away.** The **Agents** screen runs tasks in the daemon, separate from
227
- the chat tab — describe the task, pick which tools it may use (web search / fetch URL / run code),
228
- and let it work.
229
- - **Live, reconnectable progress.** Watch the run stream in real time; navigate away or reload and
230
- the view **reconnects** to the in-progress output. Runs **queue** behind any active run and
231
- **persist** across restarts.
232
- - **Cancel anytime**, and review completed runs (messages + the tool calls they made) later.
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
+ };