@lzhzzzzwill/cofos 1.1.0 → 1.1.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/bin/cofos.js +23 -11
- package/package.json +1 -1
- package/scripts/chat.py +25 -5
package/bin/cofos.js
CHANGED
|
@@ -172,6 +172,8 @@ function main() {
|
|
|
172
172
|
HF_HUB_ENABLE_HF_TRANSFER: process.env.HF_HUB_ENABLE_HF_TRANSFER || "0",
|
|
173
173
|
HF_HUB_DOWNLOAD_TIMEOUT: process.env.HF_HUB_DOWNLOAD_TIMEOUT || "120",
|
|
174
174
|
HF_HUB_ETAG_TIMEOUT: process.env.HF_HUB_ETAG_TIMEOUT || "30",
|
|
175
|
+
HF_HUB_VERBOSITY: process.env.HF_HUB_VERBOSITY || "warning",
|
|
176
|
+
TRANSFORMERS_VERBOSITY: process.env.TRANSFORMERS_VERBOSITY || "warning",
|
|
175
177
|
};
|
|
176
178
|
const proc = spawn(py, backendArgs, {
|
|
177
179
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -184,7 +186,7 @@ function main() {
|
|
|
184
186
|
proc.stdout.setEncoding("utf-8");
|
|
185
187
|
proc.stderr.setEncoding("utf-8");
|
|
186
188
|
|
|
187
|
-
let buf = "", ready = false, generating = false, closed = false;
|
|
189
|
+
let buf = "", ready = false, generating = false, responseOpen = false, closed = false;
|
|
188
190
|
const inputQ = [];
|
|
189
191
|
const rl = createInterface({ input: process.stdin, terminal: true });
|
|
190
192
|
rl.on("line", (l) => { inputQ.push(l); });
|
|
@@ -208,27 +210,35 @@ function main() {
|
|
|
208
210
|
// dropping it keeps it from being prepended to the next one.
|
|
209
211
|
if (!generating) { buf = ""; return; }
|
|
210
212
|
|
|
213
|
+
if (!responseOpen) {
|
|
214
|
+
const ri = buf.indexOf(RESPONSE);
|
|
215
|
+
if (ri === -1) {
|
|
216
|
+
// Keep enough tail to catch a RESPONSE marker split across chunks.
|
|
217
|
+
const keep = RESPONSE.length - 1;
|
|
218
|
+
if (buf.length > keep) buf = buf.slice(-keep);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
buf = buf.slice(ri + RESPONSE.length);
|
|
222
|
+
if (buf[0] === "\n") buf = buf.slice(1);
|
|
223
|
+
responseOpen = true;
|
|
224
|
+
}
|
|
225
|
+
|
|
211
226
|
// Scan for DONE marker — stream everything before it.
|
|
212
227
|
const di = buf.indexOf(DONE);
|
|
213
228
|
if (di !== -1) {
|
|
214
|
-
|
|
215
|
-
let pre = buf.slice(0, di);
|
|
216
|
-
const ri = pre.indexOf(RESPONSE);
|
|
217
|
-
if (ri !== -1) pre = pre.slice(ri + RESPONSE.length);
|
|
229
|
+
const pre = buf.slice(0, di);
|
|
218
230
|
if (pre) process.stdout.write(pre);
|
|
219
231
|
buf = buf.slice(di + DONE.length);
|
|
220
232
|
if (buf[0] === "\n") buf = buf.slice(1);
|
|
221
233
|
generating = false;
|
|
234
|
+
responseOpen = false;
|
|
222
235
|
console.log("");
|
|
223
236
|
drain();
|
|
224
237
|
} else {
|
|
225
|
-
// Stream buffered content, keeping
|
|
226
|
-
|
|
227
|
-
const keep = DONE.length;
|
|
238
|
+
// Stream buffered content, keeping enough tail to catch a partial DONE marker.
|
|
239
|
+
const keep = DONE.length - 1;
|
|
228
240
|
if (buf.length > keep) {
|
|
229
|
-
|
|
230
|
-
const ri = out.indexOf(RESPONSE);
|
|
231
|
-
if (ri !== -1) out = out.slice(ri + RESPONSE.length);
|
|
241
|
+
const out = buf.slice(0, -keep);
|
|
232
242
|
if (out) process.stdout.write(out);
|
|
233
243
|
buf = buf.slice(-keep);
|
|
234
244
|
}
|
|
@@ -297,6 +307,7 @@ function main() {
|
|
|
297
307
|
}
|
|
298
308
|
if (/^\/(clear)$/.test(input)) {
|
|
299
309
|
mlBuf = [];
|
|
310
|
+
responseOpen = false;
|
|
300
311
|
proc.stdin.write(input + "\n");
|
|
301
312
|
generating = true;
|
|
302
313
|
return;
|
|
@@ -313,6 +324,7 @@ function main() {
|
|
|
313
324
|
}
|
|
314
325
|
|
|
315
326
|
// Forward to backend.
|
|
327
|
+
responseOpen = false;
|
|
316
328
|
generating = true;
|
|
317
329
|
proc.stdin.write(input + "\n");
|
|
318
330
|
}
|
package/package.json
CHANGED
package/scripts/chat.py
CHANGED
|
@@ -24,6 +24,8 @@ os.environ.setdefault("HF_HUB_DISABLE_XET", "1")
|
|
|
24
24
|
os.environ.setdefault("HF_HUB_ENABLE_HF_TRANSFER", "0")
|
|
25
25
|
os.environ.setdefault("HF_HUB_DOWNLOAD_TIMEOUT", "120")
|
|
26
26
|
os.environ.setdefault("HF_HUB_ETAG_TIMEOUT", "30")
|
|
27
|
+
os.environ.setdefault("HF_HUB_VERBOSITY", "warning")
|
|
28
|
+
os.environ.setdefault("TRANSFORMERS_VERBOSITY", "warning")
|
|
27
29
|
|
|
28
30
|
HISTORY_FILE = os.path.join(os.path.expanduser("~"), ".cofos_history.jsonl")
|
|
29
31
|
HISTORY_MAX_TURNS = 20
|
|
@@ -338,19 +340,35 @@ def ensure_runtime_data(project_root: Path, config: dict) -> None:
|
|
|
338
340
|
"runtime/bm25/bm25_info.json": bm25_dir,
|
|
339
341
|
}
|
|
340
342
|
|
|
343
|
+
missing_items = []
|
|
341
344
|
for remote_path, target_dir in file_map.items():
|
|
342
|
-
target_dir.mkdir(parents=True, exist_ok=True)
|
|
343
345
|
local_name = remote_path.rsplit("/", 1)[-1]
|
|
344
346
|
local_path = target_dir / local_name
|
|
345
|
-
if local_path.exists():
|
|
346
|
-
|
|
347
|
+
if not local_path.exists():
|
|
348
|
+
missing_items.append((remote_path, target_dir, local_path))
|
|
349
|
+
|
|
350
|
+
total = len(missing_items)
|
|
351
|
+
if total == 0:
|
|
352
|
+
print("[chat] Runtime data ready.", file=sys.stderr, flush=True)
|
|
353
|
+
return
|
|
354
|
+
|
|
355
|
+
def progress_line(index: int, remote_path: str) -> str:
|
|
356
|
+
width = 18
|
|
357
|
+
filled = int(width * index / total)
|
|
358
|
+
bar = "#" * filled + "-" * (width - filled)
|
|
359
|
+
pct = int(100 * index / total)
|
|
360
|
+
return f"[chat] Runtime data [{index}/{total}] [{bar}] {pct:3d}% {remote_path}"
|
|
361
|
+
|
|
362
|
+
for index, (remote_path, target_dir, local_path) in enumerate(missing_items, 1):
|
|
363
|
+
target_dir.mkdir(parents=True, exist_ok=True)
|
|
364
|
+
print(progress_line(index, remote_path), file=sys.stderr, flush=True)
|
|
347
365
|
cached = hf_hub_download(
|
|
348
366
|
repo_id=repo,
|
|
349
367
|
repo_type="dataset",
|
|
350
368
|
filename=remote_path,
|
|
351
369
|
)
|
|
352
370
|
shutil.copy2(cached, local_path)
|
|
353
|
-
print(f"[chat]
|
|
371
|
+
print(f"[chat] -> {local_path}", file=sys.stderr, flush=True)
|
|
354
372
|
|
|
355
373
|
print("[chat] Runtime data ready.", file=sys.stderr, flush=True)
|
|
356
374
|
|
|
@@ -446,6 +464,8 @@ def main() -> None:
|
|
|
446
464
|
from inference.student_adapter_inference import StudentAdapterInference, StudentRAGContext
|
|
447
465
|
|
|
448
466
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
|
467
|
+
for noisy_logger in ("httpx", "httpcore", "huggingface_hub"):
|
|
468
|
+
logging.getLogger(noisy_logger).setLevel(logging.WARNING)
|
|
449
469
|
|
|
450
470
|
config_path = default_config_path(runtime_root) if args.config == DEFAULT_CONFIG else resolve_project_path(runtime_root, args.config)
|
|
451
471
|
model_path = resolve_project_path(runtime_root, args.model_path)
|
|
@@ -466,7 +486,7 @@ def main() -> None:
|
|
|
466
486
|
pdf_changed = parse_pdfs_if_needed(runtime_root, config, force=args.rebuild_pdf_index)
|
|
467
487
|
build_augmented_bm25_if_needed(runtime_root, config, force=args.rebuild_pdf_index or pdf_changed)
|
|
468
488
|
|
|
469
|
-
print("[chat] Loading model
|
|
489
|
+
print("[chat] Loading model weights. First run may download 12GB+ and take tens of minutes; cached runs are much faster ...", file=sys.stderr, flush=True)
|
|
470
490
|
|
|
471
491
|
runner = StudentAdapterInference(
|
|
472
492
|
config=config,
|