0agent 1.0.35 → 1.0.37
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 +114 -13
- package/dist/daemon.mjs +62 -11
- package/package.json +1 -1
package/bin/chat.js
CHANGED
|
@@ -39,6 +39,18 @@ class Spinner {
|
|
|
39
39
|
if (clearIt) process.stdout.write('\r\x1b[2K');
|
|
40
40
|
}
|
|
41
41
|
get active() { return this._active; }
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Pause spinner, run fn() (which may print lines), then resume.
|
|
45
|
+
* Prevents spinner from overwriting printed content.
|
|
46
|
+
*/
|
|
47
|
+
pauseFor(fn) {
|
|
48
|
+
const wasActive = this._active;
|
|
49
|
+
const savedMsg = this._msg;
|
|
50
|
+
if (wasActive) this.stop(true);
|
|
51
|
+
fn();
|
|
52
|
+
if (wasActive) this.start(savedMsg);
|
|
53
|
+
}
|
|
42
54
|
}
|
|
43
55
|
|
|
44
56
|
// ─── ANSI helpers ─────────────────────────────────────────────────────────────
|
|
@@ -124,6 +136,8 @@ function getCurrentProvider(cfg) {
|
|
|
124
136
|
// ─── State ────────────────────────────────────────────────────────────────────
|
|
125
137
|
let cfg = loadConfig();
|
|
126
138
|
let sessionId = null;
|
|
139
|
+
const messageQueue = []; // queued tasks while session is running
|
|
140
|
+
let lastFailedTask = null; // for retry-on-abort
|
|
127
141
|
let streaming = false;
|
|
128
142
|
let ws = null;
|
|
129
143
|
let wsReady = false;
|
|
@@ -280,13 +294,34 @@ function handleWsEvent(event) {
|
|
|
280
294
|
confirmServer(r, lineBuffer);
|
|
281
295
|
lineBuffer = '';
|
|
282
296
|
if (pendingResolve) { pendingResolve(); pendingResolve = null; }
|
|
283
|
-
|
|
297
|
+
sessionId = null;
|
|
298
|
+
// auto-drain queued messages
|
|
299
|
+
drainQueue();
|
|
284
300
|
break;
|
|
285
301
|
}
|
|
286
302
|
case 'session.failed': {
|
|
287
303
|
spinner.stop();
|
|
288
304
|
if (streaming) { process.stdout.write('\n'); streaming = false; }
|
|
305
|
+
const isAbort = /aborted|timeout|AbortError/i.test(event.error ?? '');
|
|
289
306
|
console.log(`\n ${fmt(C.red, '✗')} ${event.error}\n`);
|
|
307
|
+
// Offer retry if it was a timeout/abort
|
|
308
|
+
if (isAbort && event.task) {
|
|
309
|
+
lastFailedTask = event.task;
|
|
310
|
+
process.stdout.write(` ${fmt(C.yellow, '↺')} Retry this task? ${fmt(C.bold, '[y/N]')} `);
|
|
311
|
+
process.stdin.once('data', async (buf) => {
|
|
312
|
+
const ans = buf.toString().trim().toLowerCase();
|
|
313
|
+
process.stdout.write(ans + '\n');
|
|
314
|
+
if (ans === 'y' && lastFailedTask) {
|
|
315
|
+
messageQueue.unshift(lastFailedTask); // put at front of queue
|
|
316
|
+
lastFailedTask = null;
|
|
317
|
+
}
|
|
318
|
+
const resolve_ = pendingResolve;
|
|
319
|
+
pendingResolve = null; sessionId = null;
|
|
320
|
+
resolve_?.();
|
|
321
|
+
await drainQueue();
|
|
322
|
+
});
|
|
323
|
+
return; // don't fall through to pendingResolve below
|
|
324
|
+
}
|
|
290
325
|
lineBuffer = '';
|
|
291
326
|
if (pendingResolve) { pendingResolve(); pendingResolve = null; }
|
|
292
327
|
rl.prompt();
|
|
@@ -348,7 +383,9 @@ async function runTask(input) {
|
|
|
348
383
|
});
|
|
349
384
|
const s = await res.json();
|
|
350
385
|
sessionId = s.session_id ?? s.id;
|
|
351
|
-
|
|
386
|
+
// Show affordance so user knows they can queue messages while agent works
|
|
387
|
+
process.stdout.write(`\n \x1b[2m(type and press Enter to queue next message)\x1b[0m\n`);
|
|
388
|
+
spinner.start('Thinking');
|
|
352
389
|
|
|
353
390
|
// Polling fallback — runs concurrently with WS events.
|
|
354
391
|
// Catches completion when WS is disconnected (e.g. daemon just restarted).
|
|
@@ -402,8 +439,8 @@ async function runTask(input) {
|
|
|
402
439
|
const resolve_ = pendingResolve;
|
|
403
440
|
pendingResolve = null;
|
|
404
441
|
sessionId = null;
|
|
405
|
-
resolve_();
|
|
406
|
-
|
|
442
|
+
resolve_?.();
|
|
443
|
+
drainQueue(); // auto-process queued messages
|
|
407
444
|
}
|
|
408
445
|
} catch {}
|
|
409
446
|
}, 800);
|
|
@@ -505,6 +542,37 @@ async function handleCommand(input) {
|
|
|
505
542
|
}
|
|
506
543
|
|
|
507
544
|
// /status
|
|
545
|
+
// /update — check for updates and install immediately
|
|
546
|
+
case '/update': {
|
|
547
|
+
process.stdout.write(` ${fmt(C.dim, 'Checking for updates...')}\n`);
|
|
548
|
+
try {
|
|
549
|
+
const pkgPath = resolve(new URL(import.meta.url).pathname, '..', '..', 'package.json');
|
|
550
|
+
const currentVersion = existsSync(pkgPath)
|
|
551
|
+
? JSON.parse(readFileSync(pkgPath, 'utf8')).version
|
|
552
|
+
: '?';
|
|
553
|
+
const reg = await fetch('https://registry.npmjs.org/0agent/latest', {
|
|
554
|
+
signal: AbortSignal.timeout(5000),
|
|
555
|
+
}).then(r => r.json()).catch(() => null);
|
|
556
|
+
const latest = reg?.version;
|
|
557
|
+
if (!latest) { console.log(` ${fmt(C.yellow, '⚠')} Could not reach npm registry\n`); break; }
|
|
558
|
+
if (!isNewerVersion(latest, currentVersion)) {
|
|
559
|
+
console.log(` ${fmt(C.green, '✓')} Already on latest (${currentVersion})\n`);
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
console.log(` ${fmt(C.cyan, '↑')} Updating ${currentVersion} → ${latest}...`);
|
|
563
|
+
const { execSync: exs } = await import('node:child_process');
|
|
564
|
+
exs('npm install -g 0agent@latest --silent', { stdio: 'ignore', timeout: 120_000 });
|
|
565
|
+
process.stdout.write(` ${fmt(C.green, '✓')} Updated to ${latest} — restarting...\n\n`);
|
|
566
|
+
const { spawn: sp } = await import('node:child_process');
|
|
567
|
+
const child = sp(process.argv[0], process.argv.slice(1), { stdio: 'inherit' });
|
|
568
|
+
child.on('close', (code) => process.exit(code ?? 0));
|
|
569
|
+
process.stdin.pause();
|
|
570
|
+
} catch (e) {
|
|
571
|
+
console.log(` ${fmt(C.red, '✗')} Update failed: ${e.message}\n`);
|
|
572
|
+
}
|
|
573
|
+
break;
|
|
574
|
+
}
|
|
575
|
+
|
|
508
576
|
case '/status': {
|
|
509
577
|
try {
|
|
510
578
|
const h = await fetch(`${BASE_URL}/api/health`).then(r => r.json());
|
|
@@ -843,20 +911,53 @@ function isNewerVersion(a, b) {
|
|
|
843
911
|
}
|
|
844
912
|
|
|
845
913
|
|
|
846
|
-
|
|
847
|
-
const line = input.trim();
|
|
848
|
-
if (!line) { rl.prompt(); return; }
|
|
914
|
+
// ─── Message queue + serial executor ─────────────────────────────────────────
|
|
849
915
|
|
|
850
|
-
|
|
916
|
+
const COMMAND_PREFIXES = ['/model','/key','/status','/skills','/graph','/clear','/help','/schedule','/update'];
|
|
917
|
+
|
|
918
|
+
async function executeInput(line) {
|
|
919
|
+
const isCmd = line.startsWith('/') || COMMAND_PREFIXES.some(c => line.startsWith(c));
|
|
920
|
+
if (isCmd) {
|
|
851
921
|
await handleCommand(line);
|
|
852
|
-
rl.prompt();
|
|
853
922
|
} else {
|
|
923
|
+
lastFailedTask = null;
|
|
854
924
|
await runTask(line);
|
|
855
|
-
// runTask resolves when session completes (via WS or polling fallback)
|
|
856
|
-
// rl.prompt() may already have been called by the handler that resolved it,
|
|
857
|
-
// but calling it again is a safe no-op if readline is already prompting
|
|
858
|
-
if (!streaming) rl.prompt();
|
|
859
925
|
}
|
|
926
|
+
// After this input completes, drain the queue
|
|
927
|
+
await drainQueue();
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
async function drainQueue() {
|
|
931
|
+
if (messageQueue.length === 0) { if (!streaming) rl.prompt(); return; }
|
|
932
|
+
const next = messageQueue.shift();
|
|
933
|
+
if (messageQueue.length > 0) {
|
|
934
|
+
console.log(` ${fmt(C.dim, `[${messageQueue.length} more in queue]`)}`);
|
|
935
|
+
}
|
|
936
|
+
await executeInput(next);
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
rl.on('line', async (input) => {
|
|
940
|
+
const line = input.trim();
|
|
941
|
+
if (!line) { rl.prompt(); return; }
|
|
942
|
+
|
|
943
|
+
// If a session is already running, queue the message.
|
|
944
|
+
// pauseFor() stops the spinner briefly so the user can see the confirmation,
|
|
945
|
+
// then resumes — prevents spinner from overwriting their typed text.
|
|
946
|
+
if (pendingResolve) {
|
|
947
|
+
messageQueue.push(line);
|
|
948
|
+
const qLen = messageQueue.length;
|
|
949
|
+
spinner.pauseFor(() => {
|
|
950
|
+
process.stdout.write(
|
|
951
|
+
` ${fmt(C.magenta, '↳')} ${fmt(C.bold, `[queued #${qLen}]`)} ${fmt(C.dim, line.slice(0, 70))}\n`
|
|
952
|
+
);
|
|
953
|
+
if (qLen > 1) {
|
|
954
|
+
process.stdout.write(` ${fmt(C.dim, `${qLen} tasks waiting`)}\n`);
|
|
955
|
+
}
|
|
956
|
+
});
|
|
957
|
+
return;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
await executeInput(line);
|
|
860
961
|
});
|
|
861
962
|
|
|
862
963
|
rl.on('close', () => {
|
package/dist/daemon.mjs
CHANGED
|
@@ -2617,11 +2617,12 @@ var init_capabilities = __esm({
|
|
|
2617
2617
|
import { spawn as spawn2 } from "node:child_process";
|
|
2618
2618
|
import { writeFileSync as writeFileSync2, readFileSync as readFileSync3, readdirSync as readdirSync2, mkdirSync as mkdirSync2, existsSync as existsSync3 } from "node:fs";
|
|
2619
2619
|
import { resolve as resolve3, dirname as dirname2, relative } from "node:path";
|
|
2620
|
-
var AgentExecutor;
|
|
2620
|
+
var SELF_MOD_PATTERN, AgentExecutor;
|
|
2621
2621
|
var init_AgentExecutor = __esm({
|
|
2622
2622
|
"packages/daemon/src/AgentExecutor.ts"() {
|
|
2623
2623
|
"use strict";
|
|
2624
2624
|
init_capabilities();
|
|
2625
|
+
SELF_MOD_PATTERN = /\b(yourself|the agent|this agent|this cli|0agent|your code|your source|agent cli|improve.*agent|update.*agent|add.*to.*agent|fix.*agent|self.?improv)\b/i;
|
|
2625
2626
|
AgentExecutor = class {
|
|
2626
2627
|
constructor(llm, config, onStep, onToken) {
|
|
2627
2628
|
this.llm = llm;
|
|
@@ -2631,21 +2632,28 @@ var init_AgentExecutor = __esm({
|
|
|
2631
2632
|
this.cwd = config.cwd;
|
|
2632
2633
|
this.maxIterations = config.max_iterations ?? 20;
|
|
2633
2634
|
this.maxCommandMs = config.max_command_ms ?? 3e4;
|
|
2635
|
+
this.agentRoot = config.agent_root;
|
|
2634
2636
|
this.registry = new CapabilityRegistry();
|
|
2635
2637
|
}
|
|
2636
2638
|
cwd;
|
|
2637
2639
|
maxIterations;
|
|
2638
2640
|
maxCommandMs;
|
|
2639
2641
|
registry;
|
|
2642
|
+
agentRoot;
|
|
2640
2643
|
async execute(task, systemContext) {
|
|
2641
2644
|
const filesWritten = [];
|
|
2642
2645
|
const commandsRun = [];
|
|
2643
2646
|
let totalTokens = 0;
|
|
2644
2647
|
let modelName = "";
|
|
2645
|
-
const
|
|
2648
|
+
const isSelfMod = this.isSelfModTask(task);
|
|
2649
|
+
const systemPrompt = this.buildSystemPrompt(systemContext, task);
|
|
2646
2650
|
const messages = [
|
|
2647
2651
|
{ role: "user", content: task }
|
|
2648
2652
|
];
|
|
2653
|
+
if (isSelfMod) {
|
|
2654
|
+
this.maxIterations = Math.max(this.maxIterations, 30);
|
|
2655
|
+
this.onStep("Self-modification mode \u2014 reading source files\u2026");
|
|
2656
|
+
}
|
|
2649
2657
|
let finalOutput = "";
|
|
2650
2658
|
for (let i = 0; i < this.maxIterations; i++) {
|
|
2651
2659
|
this.onStep(i === 0 ? "Thinking\u2026" : "Continuing\u2026");
|
|
@@ -2879,7 +2887,8 @@ content = element.text if element else page.get_all_text()` : `content = page.ge
|
|
|
2879
2887
|
const resolved = resolve3(this.cwd, p);
|
|
2880
2888
|
return resolved.startsWith(this.cwd) ? resolved : null;
|
|
2881
2889
|
}
|
|
2882
|
-
buildSystemPrompt(extra) {
|
|
2890
|
+
buildSystemPrompt(extra, task) {
|
|
2891
|
+
const isSelfMod = !!(task && SELF_MOD_PATTERN.test(task));
|
|
2883
2892
|
const lines = [
|
|
2884
2893
|
`You are 0agent, an AI software engineer. You can execute shell commands and manage files.`,
|
|
2885
2894
|
`Working directory: ${this.cwd}`,
|
|
@@ -2889,7 +2898,6 @@ content = element.text if element else page.get_all_text()` : `content = page.ge
|
|
|
2889
2898
|
`- For web servers/background processes: ALWAYS redirect output to avoid hanging:`,
|
|
2890
2899
|
` cmd > /tmp/0agent-server.log 2>&1 &`,
|
|
2891
2900
|
` Example: python3 -m http.server 3000 > /tmp/0agent-server.log 2>&1 &`,
|
|
2892
|
-
` Example: node server.js > /tmp/0agent-server.log 2>&1 &`,
|
|
2893
2901
|
` NEVER run background commands without redirecting output.`,
|
|
2894
2902
|
`- For npm/node projects: check package.json first with read_file or list_dir`,
|
|
2895
2903
|
`- After write_file, verify with read_file if needed`,
|
|
@@ -2898,9 +2906,39 @@ content = element.text if element else page.get_all_text()` : `content = page.ge
|
|
|
2898
2906
|
`- Use relative paths from the working directory`,
|
|
2899
2907
|
`- Be concise in your final response: state what was done and where to find it`
|
|
2900
2908
|
];
|
|
2909
|
+
if (isSelfMod && this.agentRoot) {
|
|
2910
|
+
lines.push(
|
|
2911
|
+
``,
|
|
2912
|
+
`\u2550\u2550\u2550 SELF-MODIFICATION MODE \u2550\u2550\u2550`,
|
|
2913
|
+
`You are being asked to improve YOUR OWN SOURCE CODE.`,
|
|
2914
|
+
``,
|
|
2915
|
+
`Your source is at: ${this.agentRoot}`,
|
|
2916
|
+
`Key files (edit THESE, not dist/):`,
|
|
2917
|
+
` ${this.agentRoot}/bin/chat.js \u2190 the chat TUI you are running in`,
|
|
2918
|
+
` ${this.agentRoot}/bin/0agent.js \u2190 CLI entry point`,
|
|
2919
|
+
` ${this.agentRoot}/packages/daemon/src/ \u2190 daemon source`,
|
|
2920
|
+
` ${this.agentRoot}/packages/daemon/src/capabilities/ \u2190 tools (shell, browser, etc.)`,
|
|
2921
|
+
``,
|
|
2922
|
+
`\u26A0 CRITICAL TOKEN LIMIT RULES:`,
|
|
2923
|
+
` - Use shell_exec("head -100 FILE") or ("sed -n '50,100p' FILE") to read SECTIONS of files`,
|
|
2924
|
+
` - NEVER cat an entire source file \u2014 they are thousands of lines`,
|
|
2925
|
+
` - Read only the function/section you need to modify`,
|
|
2926
|
+
` - When writing changes, write ONLY the modified function/section, not the entire file`,
|
|
2927
|
+
` - Use shell_exec("grep -n 'functionName' FILE") to find the right line numbers first`,
|
|
2928
|
+
``,
|
|
2929
|
+
`After making changes:`,
|
|
2930
|
+
` 1. cd ${this.agentRoot} && node scripts/bundle.mjs`,
|
|
2931
|
+
` 2. pkill -f "daemon.mjs"`,
|
|
2932
|
+
`\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550`
|
|
2933
|
+
);
|
|
2934
|
+
}
|
|
2901
2935
|
if (extra) lines.push(``, `Context:`, extra);
|
|
2902
2936
|
return lines.join("\n");
|
|
2903
2937
|
}
|
|
2938
|
+
/** Returns true if task is a self-modification request. Self-mod tasks get longer LLM timeouts. */
|
|
2939
|
+
isSelfModTask(task) {
|
|
2940
|
+
return SELF_MOD_PATTERN.test(task);
|
|
2941
|
+
}
|
|
2904
2942
|
summariseInput(toolName, input) {
|
|
2905
2943
|
if (toolName === "shell_exec") return `"${String(input.command ?? "").slice(0, 60)}"`;
|
|
2906
2944
|
if (toolName === "write_file") return `"${input.path}"`;
|
|
@@ -3489,7 +3527,7 @@ var init_ProactiveSurface = __esm({
|
|
|
3489
3527
|
|
|
3490
3528
|
// packages/daemon/src/ZeroAgentDaemon.ts
|
|
3491
3529
|
init_src();
|
|
3492
|
-
import { writeFileSync as writeFileSync8, unlinkSync as unlinkSync2, existsSync as existsSync14, mkdirSync as mkdirSync6 } from "node:fs";
|
|
3530
|
+
import { writeFileSync as writeFileSync8, unlinkSync as unlinkSync2, existsSync as existsSync14, mkdirSync as mkdirSync6, readFileSync as readFileSync14 } from "node:fs";
|
|
3493
3531
|
import { resolve as resolve13 } from "node:path";
|
|
3494
3532
|
import { homedir as homedir8 } from "node:os";
|
|
3495
3533
|
|
|
@@ -3793,7 +3831,7 @@ var LLMExecutor = class {
|
|
|
3793
3831
|
"anthropic-version": "2023-06-01"
|
|
3794
3832
|
},
|
|
3795
3833
|
body: JSON.stringify(body),
|
|
3796
|
-
signal: AbortSignal.timeout(
|
|
3834
|
+
signal: AbortSignal.timeout(12e4)
|
|
3797
3835
|
// 60s timeout
|
|
3798
3836
|
});
|
|
3799
3837
|
if (!res.ok) {
|
|
@@ -3918,7 +3956,7 @@ var LLMExecutor = class {
|
|
|
3918
3956
|
"Authorization": `Bearer ${this.config.api_key}`
|
|
3919
3957
|
},
|
|
3920
3958
|
body: JSON.stringify(body),
|
|
3921
|
-
signal: AbortSignal.timeout(
|
|
3959
|
+
signal: AbortSignal.timeout(12e4)
|
|
3922
3960
|
});
|
|
3923
3961
|
if (!res.ok) {
|
|
3924
3962
|
const err = await res.text();
|
|
@@ -4347,6 +4385,7 @@ var SessionManager = class {
|
|
|
4347
4385
|
conversationStore;
|
|
4348
4386
|
weightUpdater;
|
|
4349
4387
|
anthropicFetcher = new AnthropicSkillFetcher();
|
|
4388
|
+
agentRoot;
|
|
4350
4389
|
constructor(deps = {}) {
|
|
4351
4390
|
this.inferenceEngine = deps.inferenceEngine;
|
|
4352
4391
|
this.eventBus = deps.eventBus;
|
|
@@ -4355,6 +4394,7 @@ var SessionManager = class {
|
|
|
4355
4394
|
this.cwd = deps.cwd ?? process.cwd();
|
|
4356
4395
|
this.identity = deps.identity;
|
|
4357
4396
|
this.projectContext = deps.projectContext;
|
|
4397
|
+
this.agentRoot = deps.agentRoot;
|
|
4358
4398
|
if (deps.adapter) {
|
|
4359
4399
|
this.conversationStore = new ConversationStore(deps.adapter);
|
|
4360
4400
|
this.conversationStore.init();
|
|
@@ -4557,7 +4597,7 @@ var SessionManager = class {
|
|
|
4557
4597
|
if (activeLLM?.isConfigured) {
|
|
4558
4598
|
const executor = new AgentExecutor(
|
|
4559
4599
|
activeLLM,
|
|
4560
|
-
{ cwd: this.cwd },
|
|
4600
|
+
{ cwd: this.cwd, agent_root: this.agentRoot },
|
|
4561
4601
|
// step callback → emit session.step events
|
|
4562
4602
|
(step) => this.addStep(sessionId, step),
|
|
4563
4603
|
// token callback → emit session.token events
|
|
@@ -4589,7 +4629,7 @@ Current task:`;
|
|
|
4589
4629
|
const { SelfHealLoop: SelfHealLoop2 } = await Promise.resolve().then(() => (init_SelfHealLoop(), SelfHealLoop_exports));
|
|
4590
4630
|
const healLoop = new SelfHealLoop2(
|
|
4591
4631
|
activeLLM,
|
|
4592
|
-
{ cwd: this.cwd },
|
|
4632
|
+
{ cwd: this.cwd, agent_root: this.agentRoot },
|
|
4593
4633
|
(step) => this.addStep(sessionId, step),
|
|
4594
4634
|
(token) => this.emit({ type: "session.token", session_id: sessionId, token })
|
|
4595
4635
|
);
|
|
@@ -6760,6 +6800,8 @@ var CodespaceManager = class {
|
|
|
6760
6800
|
|
|
6761
6801
|
// packages/daemon/src/ZeroAgentDaemon.ts
|
|
6762
6802
|
init_RuntimeSelfHeal();
|
|
6803
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
6804
|
+
import { dirname as dirname6 } from "node:path";
|
|
6763
6805
|
var ZeroAgentDaemon = class {
|
|
6764
6806
|
config = null;
|
|
6765
6807
|
adapter = null;
|
|
@@ -6845,6 +6887,14 @@ var ZeroAgentDaemon = class {
|
|
|
6845
6887
|
if (teams.length > 0) {
|
|
6846
6888
|
console.log(`[0agent] Teams: ${teams.map((t) => t.team_name).join(", ")}`);
|
|
6847
6889
|
}
|
|
6890
|
+
const _daemonFile = fileURLToPath3(import.meta.url);
|
|
6891
|
+
const _agentRoot = resolve13(dirname6(_daemonFile), "..");
|
|
6892
|
+
let agentRoot;
|
|
6893
|
+
try {
|
|
6894
|
+
const _pkg = JSON.parse(readFileSync14(resolve13(_agentRoot, "package.json"), "utf8"));
|
|
6895
|
+
if (_pkg.name === "0agent") agentRoot = _agentRoot;
|
|
6896
|
+
} catch {
|
|
6897
|
+
}
|
|
6848
6898
|
this.eventBus = new WebSocketEventBus();
|
|
6849
6899
|
this.sessionManager = new SessionManager({
|
|
6850
6900
|
inferenceEngine: this.inferenceEngine,
|
|
@@ -6854,8 +6904,9 @@ var ZeroAgentDaemon = class {
|
|
|
6854
6904
|
cwd,
|
|
6855
6905
|
identity: identity ?? void 0,
|
|
6856
6906
|
projectContext: projectContext ?? void 0,
|
|
6857
|
-
adapter: this.adapter
|
|
6858
|
-
|
|
6907
|
+
adapter: this.adapter,
|
|
6908
|
+
agentRoot
|
|
6909
|
+
// agent source path — self-improvement tasks read the right files
|
|
6859
6910
|
});
|
|
6860
6911
|
const teamSync = identity && teams.length > 0 ? new TeamSync(teamManager, this.adapter, identity.entity_node_id) : null;
|
|
6861
6912
|
if (this.githubMemorySync) {
|