@lzhzzzzwill/cofos 1.1.1 → 1.1.6
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 -12
- package/package.json +1 -1
- package/runtime/config/config.yaml +3 -3
- package/runtime/config/prompt_templates.yaml +4 -5
- package/scripts/chat.py +7 -5
package/bin/cofos.js
CHANGED
|
@@ -186,7 +186,7 @@ function main() {
|
|
|
186
186
|
proc.stdout.setEncoding("utf-8");
|
|
187
187
|
proc.stderr.setEncoding("utf-8");
|
|
188
188
|
|
|
189
|
-
let buf = "", ready = false, generating = false, closed = false;
|
|
189
|
+
let buf = "", ready = false, generating = false, responseOpen = false, closed = false;
|
|
190
190
|
const inputQ = [];
|
|
191
191
|
const rl = createInterface({ input: process.stdin, terminal: true });
|
|
192
192
|
rl.on("line", (l) => { inputQ.push(l); });
|
|
@@ -210,27 +210,35 @@ function main() {
|
|
|
210
210
|
// dropping it keeps it from being prepended to the next one.
|
|
211
211
|
if (!generating) { buf = ""; return; }
|
|
212
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
|
+
|
|
213
226
|
// Scan for DONE marker — stream everything before it.
|
|
214
227
|
const di = buf.indexOf(DONE);
|
|
215
228
|
if (di !== -1) {
|
|
216
|
-
|
|
217
|
-
let pre = buf.slice(0, di);
|
|
218
|
-
const ri = pre.indexOf(RESPONSE);
|
|
219
|
-
if (ri !== -1) pre = pre.slice(ri + RESPONSE.length);
|
|
229
|
+
const pre = buf.slice(0, di);
|
|
220
230
|
if (pre) process.stdout.write(pre);
|
|
221
231
|
buf = buf.slice(di + DONE.length);
|
|
222
232
|
if (buf[0] === "\n") buf = buf.slice(1);
|
|
223
233
|
generating = false;
|
|
234
|
+
responseOpen = false;
|
|
224
235
|
console.log("");
|
|
225
236
|
drain();
|
|
226
237
|
} else {
|
|
227
|
-
// Stream buffered content, keeping
|
|
228
|
-
|
|
229
|
-
const keep = DONE.length;
|
|
238
|
+
// Stream buffered content, keeping enough tail to catch a partial DONE marker.
|
|
239
|
+
const keep = DONE.length - 1;
|
|
230
240
|
if (buf.length > keep) {
|
|
231
|
-
|
|
232
|
-
const ri = out.indexOf(RESPONSE);
|
|
233
|
-
if (ri !== -1) out = out.slice(ri + RESPONSE.length);
|
|
241
|
+
const out = buf.slice(0, -keep);
|
|
234
242
|
if (out) process.stdout.write(out);
|
|
235
243
|
buf = buf.slice(-keep);
|
|
236
244
|
}
|
|
@@ -299,6 +307,7 @@ function main() {
|
|
|
299
307
|
}
|
|
300
308
|
if (/^\/(clear)$/.test(input)) {
|
|
301
309
|
mlBuf = [];
|
|
310
|
+
responseOpen = false;
|
|
302
311
|
proc.stdin.write(input + "\n");
|
|
303
312
|
generating = true;
|
|
304
313
|
return;
|
|
@@ -314,7 +323,9 @@ function main() {
|
|
|
314
323
|
ask(); return;
|
|
315
324
|
}
|
|
316
325
|
|
|
317
|
-
// Forward to backend.
|
|
326
|
+
// Forward to backend. Echo a stable user turn so pasted/submitted questions remain visible in the transcript.
|
|
327
|
+
console.log(G + " you " + R + input);
|
|
328
|
+
responseOpen = false;
|
|
318
329
|
generating = true;
|
|
319
330
|
proc.stdin.write(input + "\n");
|
|
320
331
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# COFOS standalone runtime config.
|
|
2
2
|
# This file is generated by scripts/sync_fwdemo_runtime.py for the npm CLI.
|
|
3
3
|
# It intentionally omits full-project training, extraction, and Ollama teacher settings.
|
|
4
|
-
project_name:
|
|
4
|
+
project_name: COFOS
|
|
5
5
|
version: 1.0.0
|
|
6
6
|
paths:
|
|
7
7
|
raw_pdfs: data/raw_pdfs
|
|
@@ -48,8 +48,8 @@ generation:
|
|
|
48
48
|
no_repeat_ngram_size: 0
|
|
49
49
|
min_new_tokens: 0
|
|
50
50
|
history_max_turns: 4
|
|
51
|
-
refine_answers:
|
|
52
|
-
stream_refinement:
|
|
51
|
+
refine_answers: false
|
|
52
|
+
stream_refinement: false
|
|
53
53
|
refinement_max_new_tokens: 512
|
|
54
54
|
data_processing:
|
|
55
55
|
chunk_size: 768
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# COFOS standalone student prompt templates.
|
|
2
2
|
# This file is generated by scripts/sync_fwdemo_runtime.py for the npm CLI.
|
|
3
|
-
student_qa_system_prompt: 'You are
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
student_qa_system_prompt: 'You are COFOS, a scientific question-answering assistant
|
|
4
|
+
specializing in covalent organic frameworks, photocatalysis, reactive oxygen species,
|
|
5
|
+
and oxygen-reduction products.
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
Answer the user''s actual question in the same language as the question unless the
|
|
@@ -69,8 +69,7 @@ student_rag_user_prompt: 'User question:
|
|
|
69
69
|
template.
|
|
70
70
|
|
|
71
71
|
'
|
|
72
|
-
student_answer_refinement_system_prompt: 'You are
|
|
73
|
-
renderer.
|
|
72
|
+
student_answer_refinement_system_prompt: 'You are COFOS''s final-answer renderer.
|
|
74
73
|
|
|
75
74
|
|
|
76
75
|
Output contract:
|
package/scripts/chat.py
CHANGED
|
@@ -470,10 +470,12 @@ def main() -> None:
|
|
|
470
470
|
config_path = default_config_path(runtime_root) if args.config == DEFAULT_CONFIG else resolve_project_path(runtime_root, args.config)
|
|
471
471
|
model_path = resolve_project_path(runtime_root, args.model_path)
|
|
472
472
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
473
|
+
debug = os.environ.get("COFOS_DEBUG", "").lower() in {"1", "true", "yes", "on"}
|
|
474
|
+
if debug:
|
|
475
|
+
print(f"[chat] Runtime root: {runtime_root}", file=sys.stderr, flush=True)
|
|
476
|
+
print(f"[chat] Cache root: {runtime_cache_root()}", file=sys.stderr, flush=True)
|
|
477
|
+
print(f"[chat] Config: {config_path}", file=sys.stderr, flush=True)
|
|
478
|
+
print(f"[chat] Model: {model_path}", file=sys.stderr, flush=True)
|
|
477
479
|
print(f"[chat] RAG: {'disabled' if args.no_rag else 'enabled'}", file=sys.stderr, flush=True)
|
|
478
480
|
|
|
479
481
|
t0 = time.time()
|
|
@@ -486,7 +488,7 @@ def main() -> None:
|
|
|
486
488
|
pdf_changed = parse_pdfs_if_needed(runtime_root, config, force=args.rebuild_pdf_index)
|
|
487
489
|
build_augmented_bm25_if_needed(runtime_root, config, force=args.rebuild_pdf_index or pdf_changed)
|
|
488
490
|
|
|
489
|
-
print("[chat] Loading model
|
|
491
|
+
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)
|
|
490
492
|
|
|
491
493
|
runner = StudentAdapterInference(
|
|
492
494
|
config=config,
|