nexo-brain 0.8.4 → 0.8.5
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/nexo-brain.js +37 -17
- package/package.json +1 -1
- package/src/db.py +1 -1
- package/src/plugins/agents.py +1 -1
- package/src/server.py +1 -1
- package/src/tools_credentials.py +2 -2
- package/src/tools_task_history.py +5 -5
package/bin/nexo-brain.js
CHANGED
|
@@ -53,6 +53,9 @@ function log(msg) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
async function main() {
|
|
56
|
+
// Non-interactive mode: --defaults or --yes skips all prompts
|
|
57
|
+
const useDefaults = process.argv.includes("--defaults") || process.argv.includes("--yes") || process.argv.includes("-y");
|
|
58
|
+
|
|
56
59
|
console.log("");
|
|
57
60
|
console.log(
|
|
58
61
|
" ╔══════════════════════════════════════════════════════════╗"
|
|
@@ -67,6 +70,10 @@ async function main() {
|
|
|
67
70
|
" ╚══════════════════════════════════════════════════════════╝"
|
|
68
71
|
);
|
|
69
72
|
console.log("");
|
|
73
|
+
if (useDefaults) {
|
|
74
|
+
log("Running with defaults (non-interactive mode).");
|
|
75
|
+
console.log("");
|
|
76
|
+
}
|
|
70
77
|
|
|
71
78
|
// Check prerequisites
|
|
72
79
|
const platform = process.platform;
|
|
@@ -275,12 +282,15 @@ async function main() {
|
|
|
275
282
|
console.log("");
|
|
276
283
|
|
|
277
284
|
// Step 1: Name
|
|
278
|
-
const name = await ask(" How should I call myself? (default: NEXO) > ");
|
|
285
|
+
const name = useDefaults ? "" : await ask(" How should I call myself? (default: NEXO) > ");
|
|
279
286
|
const operatorName = name.trim() || "NEXO";
|
|
280
287
|
log(`Got it. I'm ${operatorName}.`);
|
|
281
288
|
console.log("");
|
|
282
289
|
|
|
283
290
|
// Step 2: Personality Calibration
|
|
291
|
+
let autonomyLevel = "full", communicationStyle = "concise", honestyLevel = "firm-pushback", proactivityLevel = "proactive", errorHandling = "brief-fix";
|
|
292
|
+
|
|
293
|
+
if (!useDefaults) {
|
|
284
294
|
log("Let's calibrate my personality to work best with you.");
|
|
285
295
|
log("(These can be changed anytime via nexo_preference_set)");
|
|
286
296
|
console.log("");
|
|
@@ -292,7 +302,7 @@ async function main() {
|
|
|
292
302
|
" 3. Act first, inform after — only ask when truly uncertain (full autonomy)\n" +
|
|
293
303
|
" > "
|
|
294
304
|
);
|
|
295
|
-
|
|
305
|
+
autonomyLevel = ["conservative", "balanced", "full"][parseInt(autonomyAnswer.trim()) - 1] || "balanced";
|
|
296
306
|
|
|
297
307
|
const communicationAnswer = await ask(
|
|
298
308
|
"\n How should I communicate?\n" +
|
|
@@ -301,7 +311,7 @@ async function main() {
|
|
|
301
311
|
" 3. Detailed — explain reasoning and trade-offs\n" +
|
|
302
312
|
" > "
|
|
303
313
|
);
|
|
304
|
-
|
|
314
|
+
communicationStyle = ["concise", "balanced", "detailed"][parseInt(communicationAnswer.trim()) - 1] || "balanced";
|
|
305
315
|
|
|
306
316
|
const honestyAnswer = await ask(
|
|
307
317
|
"\n When I disagree with your approach, should I:\n" +
|
|
@@ -310,7 +320,7 @@ async function main() {
|
|
|
310
320
|
" 3. Just do what you ask\n" +
|
|
311
321
|
" > "
|
|
312
322
|
);
|
|
313
|
-
|
|
323
|
+
honestyLevel = ["firm-pushback", "mention-and-follow", "just-execute"][parseInt(honestyAnswer.trim()) - 1] || "firm-pushback";
|
|
314
324
|
|
|
315
325
|
const proactivityAnswer = await ask(
|
|
316
326
|
"\n How proactive should I be?\n" +
|
|
@@ -319,7 +329,7 @@ async function main() {
|
|
|
319
329
|
" 3. Fix things I notice without asking, and propose optimizations\n" +
|
|
320
330
|
" > "
|
|
321
331
|
);
|
|
322
|
-
|
|
332
|
+
proactivityLevel = ["reactive", "suggestive", "proactive"][parseInt(proactivityAnswer.trim()) - 1] || "proactive";
|
|
323
333
|
|
|
324
334
|
const errorAnswer = await ask(
|
|
325
335
|
"\n When I make a mistake, how should I handle it?\n" +
|
|
@@ -327,7 +337,8 @@ async function main() {
|
|
|
327
337
|
" 2. Explain what went wrong and what I learned\n" +
|
|
328
338
|
" > "
|
|
329
339
|
);
|
|
330
|
-
|
|
340
|
+
errorHandling = ["brief-fix", "explain-and-learn"][parseInt(errorAnswer.trim()) - 1] || "brief-fix";
|
|
341
|
+
} // end if (!useDefaults)
|
|
331
342
|
|
|
332
343
|
console.log("");
|
|
333
344
|
log(`Calibrated: autonomy=${autonomyLevel}, communication=${communicationStyle}, honesty=${honestyLevel}, proactivity=${proactivityLevel}, errors=${errorHandling}`);
|
|
@@ -348,18 +359,27 @@ async function main() {
|
|
|
348
359
|
);
|
|
349
360
|
|
|
350
361
|
// Step 3: Permission to scan
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
)
|
|
354
|
-
|
|
355
|
-
|
|
362
|
+
let doScan = false;
|
|
363
|
+
let doCaffeinate = false;
|
|
364
|
+
if (!useDefaults) {
|
|
365
|
+
const scanAnswer = await ask(
|
|
366
|
+
" Can I explore your workspace to learn about your projects? (y/n) > "
|
|
367
|
+
);
|
|
368
|
+
doScan = scanAnswer.trim().toLowerCase().startsWith("y");
|
|
369
|
+
console.log("");
|
|
356
370
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
)
|
|
361
|
-
|
|
362
|
-
|
|
371
|
+
// Keep Mac awake for nocturnal processes?
|
|
372
|
+
if (platform === "darwin") {
|
|
373
|
+
const caffeinateAnswer = await ask(
|
|
374
|
+
" Keep Mac awake so my cognitive processes run on schedule? (y/n) > "
|
|
375
|
+
);
|
|
376
|
+
doCaffeinate = caffeinateAnswer.trim().toLowerCase().startsWith("y");
|
|
377
|
+
console.log("");
|
|
378
|
+
}
|
|
379
|
+
} else {
|
|
380
|
+
log("Skipping workspace scan (non-interactive).");
|
|
381
|
+
console.log("");
|
|
382
|
+
}
|
|
363
383
|
|
|
364
384
|
// Step 3: Install Python dependencies
|
|
365
385
|
log("Installing cognitive engine dependencies...");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.5",
|
|
4
4
|
"mcpName": "io.github.wazionapps/nexo",
|
|
5
5
|
"description": "NEXO — Cognitive co-operator for Claude Code. Atkinson-Shiffrin memory, semantic RAG, trust scoring, and metacognitive error prevention.",
|
|
6
6
|
"bin": {
|
package/src/db.py
CHANGED
|
@@ -437,7 +437,7 @@ _SYNONYMS = {
|
|
|
437
437
|
"plantilla": ["template"],
|
|
438
438
|
"template": ["plantilla"],
|
|
439
439
|
"webhook": ["gancho"],
|
|
440
|
-
"cron": ["
|
|
440
|
+
"cron": ["scheduled task", "scheduled"],
|
|
441
441
|
"extension": ["extensión", "plugin", "addon"],
|
|
442
442
|
"plugin": ["extension", "extensión"],
|
|
443
443
|
}
|
package/src/plugins/agents.py
CHANGED
|
@@ -24,7 +24,7 @@ def handle_agent_update(id: str, name: str = "", specialization: str = "", model
|
|
|
24
24
|
for k, v in [("name", name), ("specialization", specialization), ("model", model),
|
|
25
25
|
("tools", tools), ("context_files", context_files), ("rules", rules)]:
|
|
26
26
|
if v: kwargs[k] = v
|
|
27
|
-
if not kwargs: return "
|
|
27
|
+
if not kwargs: return "Nothing to update."
|
|
28
28
|
update_agent(id, **kwargs)
|
|
29
29
|
return f"Agent '{id}' updated."
|
|
30
30
|
|
package/src/server.py
CHANGED
|
@@ -214,7 +214,7 @@ def nexo_reminder_create(id: str, description: str, date: str = "", category: st
|
|
|
214
214
|
id: Unique ID starting with 'R' (e.g., R90).
|
|
215
215
|
description: What needs to be done.
|
|
216
216
|
date: Target date YYYY-MM-DD (optional).
|
|
217
|
-
category: One of:
|
|
217
|
+
category: One of: decisions, tasks, waiting, ideas, general.
|
|
218
218
|
"""
|
|
219
219
|
return handle_reminder_create(id, description, date, category)
|
|
220
220
|
|
package/src/tools_credentials.py
CHANGED
|
@@ -8,7 +8,7 @@ def handle_credential_get(service: str, key: str = '') -> str:
|
|
|
8
8
|
results = get_credential(service, key if key else None)
|
|
9
9
|
if not results:
|
|
10
10
|
target = f"{service}/{key}" if key else service
|
|
11
|
-
return f"ERROR: No
|
|
11
|
+
return f"ERROR: No credentials found for '{target}'."
|
|
12
12
|
lines = []
|
|
13
13
|
for r in results:
|
|
14
14
|
lines.append(f"CREDENCIAL {r['service']}/{r['key']}:")
|
|
@@ -44,7 +44,7 @@ def handle_credential_delete(service: str, key: str = '') -> str:
|
|
|
44
44
|
deleted = delete_credential(service, key if key else None)
|
|
45
45
|
if not deleted:
|
|
46
46
|
target = f"{service}/{key}" if key else service
|
|
47
|
-
return f"ERROR: No
|
|
47
|
+
return f"ERROR: No credentials found for '{target}'."
|
|
48
48
|
if key:
|
|
49
49
|
return f"Credential {service}/{key} deleted."
|
|
50
50
|
return f"All credentials for {service} deleted."
|
|
@@ -28,13 +28,13 @@ def handle_task_list(task_num: str = '', days: int = 30) -> str:
|
|
|
28
28
|
"""Show execution history for all tasks or a specific task number."""
|
|
29
29
|
results = list_task_history(task_num if task_num else None, days)
|
|
30
30
|
if not results:
|
|
31
|
-
scope = f"
|
|
32
|
-
return f"
|
|
31
|
+
scope = f"task {task_num}" if task_num else "no task"
|
|
32
|
+
return f"HISTORY: No executions of {scope} in the last {days} days."
|
|
33
33
|
lines = [f"HISTORIAL ({len(results)} ejecuciones, {days}d):"]
|
|
34
34
|
for r in results:
|
|
35
35
|
date_str = _epoch_to_date(r["executed_at"])
|
|
36
36
|
notes_str = f": {r['notes']}" if r.get("notes") else ""
|
|
37
|
-
lines.append(f" {date_str} —
|
|
37
|
+
lines.append(f" {date_str} — Task {r['task_num']} ({r['task_name']}){notes_str}")
|
|
38
38
|
return "\n".join(lines)
|
|
39
39
|
|
|
40
40
|
|
|
@@ -42,7 +42,7 @@ def handle_task_frequency() -> str:
|
|
|
42
42
|
"""Report tasks that are overdue based on their configured frequency."""
|
|
43
43
|
overdue = get_overdue_tasks()
|
|
44
44
|
if not overdue:
|
|
45
|
-
return "
|
|
45
|
+
return "All tasks up to date."
|
|
46
46
|
lines = ["TAREAS VENCIDAS:"]
|
|
47
47
|
for t in overdue:
|
|
48
48
|
days_since = t.get("days_since_last")
|
|
@@ -51,7 +51,7 @@ def handle_task_frequency() -> str:
|
|
|
51
51
|
else:
|
|
52
52
|
since_str = "nunca ejecutada"
|
|
53
53
|
lines.append(
|
|
54
|
-
f"
|
|
54
|
+
f" Task {t['task_num']} ({t['task_name']}): "
|
|
55
55
|
f"{since_str}, frecuencia cada {t['frequency_days']} días"
|
|
56
56
|
)
|
|
57
57
|
return "\n".join(lines)
|