@melaya/runner 1.0.52 → 1.0.54
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/dist/connection.js +61 -1
- package/dist/pythonEnv.js +13 -0
- package/package.json +1 -1
package/dist/connection.js
CHANGED
|
@@ -14,7 +14,7 @@ import { io } from "socket.io-client";
|
|
|
14
14
|
import chalk from "chalk";
|
|
15
15
|
import ora from "ora";
|
|
16
16
|
import { spawn } from "child_process";
|
|
17
|
-
import { writeFileSync, mkdirSync } from "fs";
|
|
17
|
+
import { writeFileSync, mkdirSync, existsSync } from "fs";
|
|
18
18
|
import { dirname, join } from "path";
|
|
19
19
|
import { fileURLToPath } from "url";
|
|
20
20
|
import { tmpdir, homedir } from "os";
|
|
@@ -170,6 +170,66 @@ export async function connect(opts) {
|
|
|
170
170
|
mkdirSync(runDir, { recursive: true });
|
|
171
171
|
writeFileSync(join(runDir, "main.py"), payload.mainPyContent, "utf-8");
|
|
172
172
|
writeFileSync(join(runDir, "config.json"), payload.configJson, "utf-8");
|
|
173
|
+
// Write rag/ static-context files alongside main.py so
|
|
174
|
+
// _load_rag_context() inside the spawned pipeline sees them.
|
|
175
|
+
// Two paths:
|
|
176
|
+
// Cloud-upload mode: server ships payload.ragFiles (b64 bytes).
|
|
177
|
+
// Local-folder Mode B: server sets staticContextLocalFolderPath
|
|
178
|
+
// and omits ragFiles. We walk that folder here so the bytes
|
|
179
|
+
// NEVER round-trip through prod.
|
|
180
|
+
const _SC_EXTS = new Set([".txt", ".md", ".csv", ".json", ".pdf", ".doc", ".docx", ".pptx", ".xlsx"]);
|
|
181
|
+
const _SC_MAX_BYTES = 4 * 1024 * 1024;
|
|
182
|
+
const ragDir = join(runDir, "rag");
|
|
183
|
+
let scFilesWritten = 0;
|
|
184
|
+
const scLocalPath = (payload.staticContextLocalFolderPath || "").trim();
|
|
185
|
+
if (scLocalPath) {
|
|
186
|
+
try {
|
|
187
|
+
if (!existsSync(scLocalPath)) {
|
|
188
|
+
console.log(chalk.yellow(` ! static-context local folder not found: ${scLocalPath}`));
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
const { readdirSync, statSync, readFileSync } = await import("node:fs");
|
|
192
|
+
const { extname, basename } = await import("node:path");
|
|
193
|
+
mkdirSync(ragDir, { recursive: true });
|
|
194
|
+
for (const name of readdirSync(scLocalPath)) {
|
|
195
|
+
if (name.startsWith("."))
|
|
196
|
+
continue;
|
|
197
|
+
const full = join(scLocalPath, name);
|
|
198
|
+
try {
|
|
199
|
+
const st = statSync(full);
|
|
200
|
+
if (!st.isFile())
|
|
201
|
+
continue;
|
|
202
|
+
if (st.size > _SC_MAX_BYTES)
|
|
203
|
+
continue;
|
|
204
|
+
if (!_SC_EXTS.has(extname(name).toLowerCase()))
|
|
205
|
+
continue;
|
|
206
|
+
writeFileSync(join(ragDir, basename(name)), readFileSync(full));
|
|
207
|
+
scFilesWritten++;
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
console.log(chalk.yellow(` ! skip ${name}: ${err.message}`));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
console.log(chalk.gray(` [rag] local-folder mode: copied ${scFilesWritten} file(s) from ${scLocalPath} to ${ragDir} (bytes never round-tripped through prod)`));
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
console.log(chalk.yellow(` ! static-context local-folder scan failed: ${err.message}`));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else if (payload.ragFiles && Object.keys(payload.ragFiles).length > 0) {
|
|
221
|
+
mkdirSync(ragDir, { recursive: true });
|
|
222
|
+
for (const [name, b64] of Object.entries(payload.ragFiles)) {
|
|
223
|
+
try {
|
|
224
|
+
writeFileSync(join(ragDir, name), Buffer.from(b64, "base64"));
|
|
225
|
+
scFilesWritten++;
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
console.log(chalk.yellow(` ! could not write rag/${name}: ${err.message}`));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
console.log(chalk.gray(` [rag] cloud-upload mode: wrote ${scFilesWritten} static-context file(s) to ${ragDir}`));
|
|
232
|
+
}
|
|
173
233
|
// Local-model preflight: ensure LM Studio / Ollama have the
|
|
174
234
|
// pipeline's model loaded BEFORE we spawn the Python subprocess.
|
|
175
235
|
// Without this, the subprocess hangs on its first chat completion
|
package/dist/pythonEnv.js
CHANGED
|
@@ -92,6 +92,19 @@ const PIP_DEPS = [
|
|
|
92
92
|
// `scrapling install` to download Chromium — best-effort run below
|
|
93
93
|
// (failure non-fatal: AsyncFetcher fast-path still works without it).
|
|
94
94
|
"scrapling[fetchers]",
|
|
95
|
+
// beautifulsoup4 + lxml — HTML parser used by _search_ddg_html in
|
|
96
|
+
// shared.tools.core to scrape DDG's HTML search results page (the
|
|
97
|
+
// primary, non-rate-limited path). Without these, every web_search
|
|
98
|
+
// call raises ModuleNotFoundError, falls through to DDGS, and if
|
|
99
|
+
// DDGS is also down or rate-limited, the tool surfaces an error
|
|
100
|
+
// STRING that small local models (qwen3-vl-8b et al) read as
|
|
101
|
+
// data and hallucinate URLs around. Scrapling's [fetchers] extra
|
|
102
|
+
// does NOT pull bs4 (it brings curl_cffi+playwright), so pin
|
|
103
|
+
// explicitly. Tokano's run d38e09f747134084 hit this — Copywriter
|
|
104
|
+
// invented theinformation.com + nature.com URLs because every
|
|
105
|
+
// search returned 'Search error: ModuleNotFoundError bs4'.
|
|
106
|
+
"beautifulsoup4",
|
|
107
|
+
"lxml",
|
|
95
108
|
// Telethon — Telegram MTProto user-mode client. Used by
|
|
96
109
|
// shared.tools.telegram_user_tools. The bot-API path in
|
|
97
110
|
// shared.tools.messaging.py uses plain HTTP and needs no extra dep.
|