@noobdemon/noob-cli 1.10.0 → 1.10.2
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/package.json +1 -1
- package/src/agent.js +33 -0
- package/src/repl.js +2 -1
package/package.json
CHANGED
package/src/agent.js
CHANGED
|
@@ -242,6 +242,24 @@ export function compact(history, budget) {
|
|
|
242
242
|
return [...head, elided, ...out.slice(tailStart)];
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
+
// Trích xuất todo items chưa hoàn thành từ history assistant messages.
|
|
246
|
+
// Format: `- [ ] task` (unchecked) / `- [x] task` (checked).
|
|
247
|
+
// Trả về mảng text của các item chưa check, giữ nguyên thứ tự.
|
|
248
|
+
function extractUncheckedTodos(history) {
|
|
249
|
+
const todos = [];
|
|
250
|
+
for (const m of history) {
|
|
251
|
+
if (m.role !== "assistant" || typeof m.content !== "string") continue;
|
|
252
|
+
for (const line of m.content.split("\n")) {
|
|
253
|
+
const unchecked = line.match(/^[\s]*-\s*\[\s?\]\s+(.+)/);
|
|
254
|
+
if (unchecked) todos.push(unchecked[1].trim());
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// Dedupe: giữ item cuối cùng (model có thể repeat todo).
|
|
258
|
+
const seen = new Map();
|
|
259
|
+
for (const t of todos) seen.set(t, t);
|
|
260
|
+
return [...seen.values()];
|
|
261
|
+
}
|
|
262
|
+
|
|
245
263
|
// Bộ nhớ dài hạn cho phiên: khi history phình to, gọi model phụ TÓM TẮT các
|
|
246
264
|
// lượt cũ thành một message system gọn (giữ quyết định, file đã sửa, lý do,
|
|
247
265
|
// việc dở) rồi thay phần đầu history bằng tóm tắt đó. Mutates `history` in place.
|
|
@@ -565,6 +583,21 @@ export async function runAgent({ history, model, signal, onTool, onStatus, onDel
|
|
|
565
583
|
content: allow ? result : t.toolDenied,
|
|
566
584
|
});
|
|
567
585
|
|
|
586
|
+
// ── Todo continuation nudge ──────────────────────────────────────────
|
|
587
|
+
// Sau mỗi tool result, kiểm tra xem còn todo item nào chưa check không.
|
|
588
|
+
// Nếu có → inject nudge nhắc model TIẾP TỤC, KHÔNG dừng.
|
|
589
|
+
{
|
|
590
|
+
const unchecked = extractUncheckedTodos(history);
|
|
591
|
+
if (unchecked.length > 0) {
|
|
592
|
+
const next = unchecked[0];
|
|
593
|
+
history.push({
|
|
594
|
+
role: "tool",
|
|
595
|
+
name: "todo_nudge",
|
|
596
|
+
content: `[TODO] Còn ${unchecked.length} việc chưa xong. Việc tiếp theo: "${next}". HÃY LÀM NGAY — gọi tool (write_file/edit_file/run_command) để hoàn thành việc này. KHÔNG dừng, KHÔNG tóm tắt, KHÔNG hỏi lại.`,
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
568
601
|
// ── Loop detection ──────────────────────────────────────────────────
|
|
569
602
|
// Theo dõi N tool call gần nhất. Nếu cùng tên + input giống nhau liên tiếp
|
|
570
603
|
// quá ngưỡng → model bị kẹt. Inject thông báo nhắc model chuyển bước,
|
package/src/repl.js
CHANGED
|
@@ -151,13 +151,13 @@ export async function startRepl(opts = {}) {
|
|
|
151
151
|
const tokenMeter = new TokenMeter();
|
|
152
152
|
|
|
153
153
|
// Set terminal title bar — hiện trên CMD/PowerShell.
|
|
154
|
+
// session chưa được khai báo ở đây → updateTitle() gọi SAU khi session = null (dòng ~295).
|
|
154
155
|
const updateTitle = () => {
|
|
155
156
|
const name = session?.title
|
|
156
157
|
? session.title.slice(0, 40) + (session.title.length > 40 ? "…" : "")
|
|
157
158
|
: state.model.name;
|
|
158
159
|
process.title = `noob — ${name}`;
|
|
159
160
|
};
|
|
160
|
-
updateTitle();
|
|
161
161
|
|
|
162
162
|
// Prompt = dòng trạng thái sống. Luôn phản ánh yolo + version theo thời gian
|
|
163
163
|
// thực (vẽ lại mỗi lượt và ngay khi Shift+Tab), nên không cần gõ /status.
|
|
@@ -291,6 +291,7 @@ export async function startRepl(opts = {}) {
|
|
|
291
291
|
|
|
292
292
|
// ── phiên (session): lưu lịch sử + resume giống Claude Code ───────────────
|
|
293
293
|
let session = null;
|
|
294
|
+
updateTitle(); // gọi lần đầu — state.model đã có, session chưa
|
|
294
295
|
const persist = () => {
|
|
295
296
|
if (!session || !state.history.length) return; // đừng lưu phiên rỗng
|
|
296
297
|
session.history = state.history; // giữ đồng bộ tuyệt đối với history sống
|