0agent 1.0.47 → 1.0.49
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/chat.js +75 -24
- package/dist/daemon.mjs +54 -8
- package/package.json +1 -1
package/bin/chat.js
CHANGED
|
@@ -31,6 +31,7 @@ const SLASH_COMMANDS = [
|
|
|
31
31
|
{ cmd: '/security-audit',desc: 'Security audit — find vulnerabilities' },
|
|
32
32
|
{ cmd: '/design-review', desc: 'Design review — architecture and patterns' },
|
|
33
33
|
// Built-ins
|
|
34
|
+
{ cmd: '/memory', desc: 'Show graph nodes and force-push to GitHub' },
|
|
34
35
|
{ cmd: '/telegram', desc: 'Connect Telegram bot — forward messages to 0agent'},
|
|
35
36
|
{ cmd: '/model', desc: 'Show or switch the LLM model' },
|
|
36
37
|
{ cmd: '/key', desc: 'Update a stored API key' },
|
|
@@ -902,6 +903,50 @@ async function handleCommand(input) {
|
|
|
902
903
|
break;
|
|
903
904
|
}
|
|
904
905
|
|
|
906
|
+
// /memory — inspect graph nodes + force GitHub sync
|
|
907
|
+
case '/memory': {
|
|
908
|
+
try {
|
|
909
|
+
const sub = parts[1]?.toLowerCase();
|
|
910
|
+
|
|
911
|
+
if (sub === 'sync' || sub === 'push') {
|
|
912
|
+
process.stdout.write(` ${fmt(C.dim, 'Pushing to GitHub...')}\n`);
|
|
913
|
+
const res = await fetch(`${BASE_URL}/api/memory/push`, { method: 'POST' }).catch(() => null);
|
|
914
|
+
const data = res?.ok ? await res.json().catch(() => null) : null;
|
|
915
|
+
if (data?.pushed) {
|
|
916
|
+
console.log(` ${fmt(C.green, '✓')} Pushed ${data.nodes_synced} nodes, ${data.edges_synced} edges to GitHub\n`);
|
|
917
|
+
} else {
|
|
918
|
+
console.log(` ${fmt(C.yellow, '⚠')} ${data?.error ?? 'Sync not configured or failed'}\n`);
|
|
919
|
+
}
|
|
920
|
+
break;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
// Show memory nodes from graph
|
|
924
|
+
const res = await fetch(`${BASE_URL}/api/graph/nodes?limit=200`).then(r => r.json()).catch(() => []);
|
|
925
|
+
const nodes = Array.isArray(res) ? res : [];
|
|
926
|
+
const memNodes = nodes.filter(n => n.id?.startsWith('memory:') || n.type === 'context');
|
|
927
|
+
const total = nodes.length;
|
|
928
|
+
|
|
929
|
+
console.log(`\n ${fmt(C.bold, 'Knowledge graph')} — ${total} nodes total, ${memNodes.length} memory nodes\n`);
|
|
930
|
+
|
|
931
|
+
if (memNodes.length === 0) {
|
|
932
|
+
console.log(` ${fmt(C.dim, 'No memory nodes yet. Run a task — the agent will write facts here.')}\n`);
|
|
933
|
+
} else {
|
|
934
|
+
for (const n of memNodes.slice(0, 20)) {
|
|
935
|
+
const content = n.metadata?.content ?? n.label;
|
|
936
|
+
const type = n.metadata?.type ?? n.type;
|
|
937
|
+
console.log(` ${fmt(C.cyan, n.label.padEnd(28))} ${fmt(C.dim, String(content).slice(0, 50))}`);
|
|
938
|
+
console.log(` ${fmt(C.dim, ` ${n.id} [${type}]`)}`);
|
|
939
|
+
}
|
|
940
|
+
if (memNodes.length > 20) console.log(fmt(C.dim, `\n …and ${memNodes.length - 20} more`));
|
|
941
|
+
}
|
|
942
|
+
console.log();
|
|
943
|
+
console.log(` ${fmt(C.dim, 'Force sync: /memory sync · Dashboard: http://localhost:4200')}\n`);
|
|
944
|
+
} catch {
|
|
945
|
+
console.log(` ${fmt(C.red, '✗')} Daemon not running\n`);
|
|
946
|
+
}
|
|
947
|
+
break;
|
|
948
|
+
}
|
|
949
|
+
|
|
905
950
|
// /telegram — configure Telegram bot token
|
|
906
951
|
case '/telegram': {
|
|
907
952
|
if (!cfg) { console.log(fmt(C.red, ' No config found. Run: 0agent init')); break; }
|
|
@@ -1002,51 +1047,55 @@ async function openPalette(initialFilter = '') {
|
|
|
1002
1047
|
|
|
1003
1048
|
let filter = initialFilter.toLowerCase();
|
|
1004
1049
|
let idx = 0;
|
|
1005
|
-
let
|
|
1050
|
+
let scroll = 0; // top of the visible window
|
|
1051
|
+
let drawn = 0;
|
|
1052
|
+
const PAGE = 10; // visible rows at once
|
|
1006
1053
|
|
|
1007
1054
|
const getItems = () => SLASH_COMMANDS.filter(c =>
|
|
1008
1055
|
!filter || c.cmd.slice(1).startsWith(filter)
|
|
1009
1056
|
);
|
|
1010
1057
|
|
|
1011
1058
|
const paint = () => {
|
|
1012
|
-
// Erase previous draw: move up `drawn` lines, clear everything below
|
|
1013
1059
|
if (drawn > 0) process.stdout.write(`\x1b[${drawn}A\x1b[0J`);
|
|
1014
1060
|
|
|
1015
|
-
const items
|
|
1016
|
-
|
|
1017
|
-
|
|
1061
|
+
const items = getItems();
|
|
1062
|
+
if (items.length === 0) { idx = 0; scroll = 0; }
|
|
1063
|
+
else {
|
|
1064
|
+
idx = Math.max(0, Math.min(idx, items.length - 1));
|
|
1065
|
+
// Keep selected item inside the visible window
|
|
1066
|
+
if (idx < scroll) scroll = idx;
|
|
1067
|
+
if (idx >= scroll + PAGE) scroll = idx - PAGE + 1;
|
|
1068
|
+
}
|
|
1018
1069
|
|
|
1070
|
+
const show = items.slice(scroll, scroll + PAGE);
|
|
1019
1071
|
const lines = [];
|
|
1020
1072
|
|
|
1021
|
-
// Top border
|
|
1022
1073
|
lines.push(` \x1b[2m${'─'.repeat(58)}\x1b[0m`);
|
|
1023
1074
|
|
|
1024
|
-
if (
|
|
1075
|
+
if (items.length === 0) {
|
|
1025
1076
|
lines.push(` \x1b[2m no commands match "/${filter}"\x1b[0m`);
|
|
1026
1077
|
} else {
|
|
1027
1078
|
for (let i = 0; i < show.length; i++) {
|
|
1028
1079
|
const m = show[i];
|
|
1029
|
-
const sel = i === idx;
|
|
1080
|
+
const sel = (scroll + i) === idx;
|
|
1030
1081
|
if (sel) {
|
|
1031
|
-
lines.push(
|
|
1032
|
-
` \x1b[36;1m›\x1b[0m \x1b[36;1m${m.cmd.padEnd(22)}\x1b[0m \x1b[0m${m.desc}\x1b[0m`
|
|
1033
|
-
);
|
|
1082
|
+
lines.push(` \x1b[36;1m›\x1b[0m \x1b[36;1m${m.cmd.padEnd(22)}\x1b[0m ${m.desc}`);
|
|
1034
1083
|
} else {
|
|
1035
|
-
lines.push(
|
|
1036
|
-
` \x1b[36m${m.cmd.padEnd(22)}\x1b[0m \x1b[2m${m.desc}\x1b[0m`
|
|
1037
|
-
);
|
|
1084
|
+
lines.push(` \x1b[36m${m.cmd.padEnd(22)}\x1b[0m \x1b[2m${m.desc}\x1b[0m`);
|
|
1038
1085
|
}
|
|
1039
1086
|
}
|
|
1040
1087
|
}
|
|
1041
1088
|
|
|
1042
|
-
|
|
1089
|
+
// Scroll indicator
|
|
1090
|
+
if (items.length > PAGE) {
|
|
1091
|
+
const pct = Math.round(((scroll + PAGE / 2) / items.length) * 100);
|
|
1092
|
+
lines.push(` \x1b[2m ${idx + 1} / ${items.length} (${pct}%)\x1b[0m`);
|
|
1093
|
+
}
|
|
1043
1094
|
|
|
1044
|
-
// Bottom: search input line
|
|
1045
1095
|
lines.push(` \x1b[2m${'─'.repeat(58)}\x1b[0m`);
|
|
1046
|
-
lines.push(` ${fmt(C.cyan, '/')}${filter}\x1b[K \x1b[2m↑↓
|
|
1096
|
+
lines.push(` ${fmt(C.cyan, '/')}${filter}\x1b[K \x1b[2m↑↓ scroll · Enter select · Esc cancel\x1b[0m`);
|
|
1047
1097
|
|
|
1048
|
-
|
|
1049
|
-
process.stdout.write(out);
|
|
1098
|
+
process.stdout.write(lines.join('\n') + '\n');
|
|
1050
1099
|
drawn = lines.length;
|
|
1051
1100
|
};
|
|
1052
1101
|
|
|
@@ -1069,11 +1118,11 @@ async function openPalette(initialFilter = '') {
|
|
|
1069
1118
|
paint();
|
|
1070
1119
|
} else if (s === '\x7f' || s === '\x08') { // Backspace
|
|
1071
1120
|
filter = filter.slice(0, -1);
|
|
1072
|
-
idx = 0;
|
|
1121
|
+
idx = 0; scroll = 0;
|
|
1073
1122
|
paint();
|
|
1074
1123
|
} else if (/^[a-z0-9\-_]$/i.test(s)) { // Printable letter/digit/hyphen
|
|
1075
1124
|
filter += s.toLowerCase();
|
|
1076
|
-
idx = 0;
|
|
1125
|
+
idx = 0; scroll = 0;
|
|
1077
1126
|
paint();
|
|
1078
1127
|
}
|
|
1079
1128
|
};
|
|
@@ -1410,17 +1459,19 @@ function isNewerVersion(a, b) {
|
|
|
1410
1459
|
|
|
1411
1460
|
// ─── Message queue + serial executor ─────────────────────────────────────────
|
|
1412
1461
|
|
|
1413
|
-
|
|
1462
|
+
// Only these exact prefixes are built-in commands handled by handleCommand().
|
|
1463
|
+
// Everything else starting with '/' is a skill → routed to runTask().
|
|
1464
|
+
const COMMAND_PREFIXES = ['/model','/key','/status','/skills','/graph','/clear',
|
|
1465
|
+
'/help','/schedule','/update','/telegram'];
|
|
1414
1466
|
|
|
1415
1467
|
async function executeInput(line) {
|
|
1416
|
-
const isCmd =
|
|
1468
|
+
const isCmd = COMMAND_PREFIXES.some(c => line === c || line.startsWith(c + ' '));
|
|
1417
1469
|
if (isCmd) {
|
|
1418
1470
|
await handleCommand(line);
|
|
1419
1471
|
} else {
|
|
1420
1472
|
lastFailedTask = null;
|
|
1421
1473
|
await runTask(line);
|
|
1422
1474
|
}
|
|
1423
|
-
// After this input completes, drain the queue
|
|
1424
1475
|
await drainQueue();
|
|
1425
1476
|
}
|
|
1426
1477
|
|
package/dist/daemon.mjs
CHANGED
|
@@ -4765,12 +4765,18 @@ Current task:`;
|
|
|
4765
4765
|
anthropicContext,
|
|
4766
4766
|
enrichedReq.context?.system_context ? String(enrichedReq.context.system_context) : void 0
|
|
4767
4767
|
].filter(Boolean).join("\n\n") || void 0;
|
|
4768
|
+
const fullConfig = {
|
|
4769
|
+
cwd: this.cwd,
|
|
4770
|
+
agent_root: this.agentRoot,
|
|
4771
|
+
graph: this.graph,
|
|
4772
|
+
onMemoryWrite: this.onMemoryWritten
|
|
4773
|
+
};
|
|
4768
4774
|
let agentResult;
|
|
4769
4775
|
try {
|
|
4770
4776
|
const { SelfHealLoop: SelfHealLoop2 } = await Promise.resolve().then(() => (init_SelfHealLoop(), SelfHealLoop_exports));
|
|
4771
4777
|
const healLoop = new SelfHealLoop2(
|
|
4772
4778
|
activeLLM,
|
|
4773
|
-
|
|
4779
|
+
fullConfig,
|
|
4774
4780
|
(step) => this.addStep(sessionId, step),
|
|
4775
4781
|
(token) => this.emit({ type: "session.token", session_id: sessionId, token })
|
|
4776
4782
|
);
|
|
@@ -4827,7 +4833,37 @@ Current task:`;
|
|
|
4827
4833
|
this.addStep(sessionId, `Commands run: ${agentResult.commands_run.length}`);
|
|
4828
4834
|
}
|
|
4829
4835
|
this.addStep(sessionId, `Done (${agentResult.tokens_used} tokens, ${agentResult.iterations} LLM turns)`);
|
|
4830
|
-
this.
|
|
4836
|
+
if (this.graph) {
|
|
4837
|
+
try {
|
|
4838
|
+
const nodeId = `memory:session_${sessionId.slice(0, 8)}`;
|
|
4839
|
+
const label = enrichedReq.task.slice(0, 80);
|
|
4840
|
+
const existing = this.graph.getNode(nodeId);
|
|
4841
|
+
const meta = {
|
|
4842
|
+
task: enrichedReq.task.slice(0, 300),
|
|
4843
|
+
output: agentResult.output.slice(0, 300),
|
|
4844
|
+
type: "session_summary",
|
|
4845
|
+
tokens: agentResult.tokens_used,
|
|
4846
|
+
saved_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
4847
|
+
};
|
|
4848
|
+
if (existing) {
|
|
4849
|
+
this.graph.updateNode(nodeId, { label, metadata: meta });
|
|
4850
|
+
} else {
|
|
4851
|
+
this.graph.addNode(createNode({
|
|
4852
|
+
id: nodeId,
|
|
4853
|
+
graph_id: "root",
|
|
4854
|
+
label,
|
|
4855
|
+
type: "context" /* CONTEXT */,
|
|
4856
|
+
metadata: meta
|
|
4857
|
+
}));
|
|
4858
|
+
}
|
|
4859
|
+
console.log(`[0agent] Graph: wrote session summary node (${nodeId})`);
|
|
4860
|
+
this.onMemoryWritten?.();
|
|
4861
|
+
} catch (err) {
|
|
4862
|
+
console.warn("[0agent] Graph: baseline write failed:", err instanceof Error ? err.message : err);
|
|
4863
|
+
}
|
|
4864
|
+
}
|
|
4865
|
+
this._extractAndPersistFacts(enrichedReq.task, agentResult.output, activeLLM).catch((err) => {
|
|
4866
|
+
console.warn("[0agent] Memory extraction outer error:", err instanceof Error ? err.message : err);
|
|
4831
4867
|
});
|
|
4832
4868
|
this.completeSession(sessionId, {
|
|
4833
4869
|
output: agentResult.output,
|
|
@@ -7323,13 +7359,18 @@ var ZeroAgentDaemon = class {
|
|
|
7323
7359
|
adapter: this.adapter,
|
|
7324
7360
|
agentRoot,
|
|
7325
7361
|
// agent source path — self-improvement tasks read the right files
|
|
7326
|
-
// Push to GitHub immediately when facts are
|
|
7362
|
+
// Push to GitHub immediately when facts are written to the graph
|
|
7327
7363
|
onMemoryWritten: () => {
|
|
7328
7364
|
this.githubMemorySync?.markDirty();
|
|
7329
7365
|
if (this.githubMemorySync) {
|
|
7330
7366
|
this.githubMemorySync.push("sync: new facts learned").then((r) => {
|
|
7331
|
-
if (r.pushed)
|
|
7332
|
-
|
|
7367
|
+
if (r.pushed) {
|
|
7368
|
+
console.log(`[0agent] Memory pushed: ${r.nodes_synced} nodes, ${r.edges_synced} edges \u2192 github`);
|
|
7369
|
+
} else if (r.error) {
|
|
7370
|
+
console.warn(`[0agent] Memory push failed: ${r.error}`);
|
|
7371
|
+
}
|
|
7372
|
+
}).catch((err) => {
|
|
7373
|
+
console.warn("[0agent] Memory push exception:", err instanceof Error ? err.message : err);
|
|
7333
7374
|
});
|
|
7334
7375
|
}
|
|
7335
7376
|
}
|
|
@@ -7338,9 +7379,14 @@ var ZeroAgentDaemon = class {
|
|
|
7338
7379
|
if (this.githubMemorySync) {
|
|
7339
7380
|
const memSync = this.githubMemorySync;
|
|
7340
7381
|
this.memorySyncTimer = setInterval(async () => {
|
|
7341
|
-
const result = await memSync.push().catch(() =>
|
|
7342
|
-
|
|
7343
|
-
|
|
7382
|
+
const result = await memSync.push().catch((err) => {
|
|
7383
|
+
console.warn("[0agent] Memory timer push failed:", err instanceof Error ? err.message : err);
|
|
7384
|
+
return null;
|
|
7385
|
+
});
|
|
7386
|
+
if (result?.pushed) {
|
|
7387
|
+
console.log(`[0agent] Memory sync: ${result.nodes_synced} nodes \u2192 github`);
|
|
7388
|
+
} else if (result?.error) {
|
|
7389
|
+
console.warn(`[0agent] Memory sync error: ${result.error}`);
|
|
7344
7390
|
}
|
|
7345
7391
|
}, 2 * 60 * 1e3);
|
|
7346
7392
|
if (typeof this.memorySyncTimer === "object") this.memorySyncTimer.unref?.();
|