0agent 1.0.34 → 1.0.36
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 +137 -60
- package/dist/daemon.mjs +62 -11
- package/package.json +1 -1
package/bin/chat.js
CHANGED
|
@@ -124,6 +124,8 @@ function getCurrentProvider(cfg) {
|
|
|
124
124
|
// ─── State ────────────────────────────────────────────────────────────────────
|
|
125
125
|
let cfg = loadConfig();
|
|
126
126
|
let sessionId = null;
|
|
127
|
+
const messageQueue = []; // queued tasks while session is running
|
|
128
|
+
let lastFailedTask = null; // for retry-on-abort
|
|
127
129
|
let streaming = false;
|
|
128
130
|
let ws = null;
|
|
129
131
|
let wsReady = false;
|
|
@@ -280,13 +282,34 @@ function handleWsEvent(event) {
|
|
|
280
282
|
confirmServer(r, lineBuffer);
|
|
281
283
|
lineBuffer = '';
|
|
282
284
|
if (pendingResolve) { pendingResolve(); pendingResolve = null; }
|
|
283
|
-
|
|
285
|
+
sessionId = null;
|
|
286
|
+
// auto-drain queued messages
|
|
287
|
+
drainQueue();
|
|
284
288
|
break;
|
|
285
289
|
}
|
|
286
290
|
case 'session.failed': {
|
|
287
291
|
spinner.stop();
|
|
288
292
|
if (streaming) { process.stdout.write('\n'); streaming = false; }
|
|
293
|
+
const isAbort = /aborted|timeout|AbortError/i.test(event.error ?? '');
|
|
289
294
|
console.log(`\n ${fmt(C.red, '✗')} ${event.error}\n`);
|
|
295
|
+
// Offer retry if it was a timeout/abort
|
|
296
|
+
if (isAbort && event.task) {
|
|
297
|
+
lastFailedTask = event.task;
|
|
298
|
+
process.stdout.write(` ${fmt(C.yellow, '↺')} Retry this task? ${fmt(C.bold, '[y/N]')} `);
|
|
299
|
+
process.stdin.once('data', async (buf) => {
|
|
300
|
+
const ans = buf.toString().trim().toLowerCase();
|
|
301
|
+
process.stdout.write(ans + '\n');
|
|
302
|
+
if (ans === 'y' && lastFailedTask) {
|
|
303
|
+
messageQueue.unshift(lastFailedTask); // put at front of queue
|
|
304
|
+
lastFailedTask = null;
|
|
305
|
+
}
|
|
306
|
+
const resolve_ = pendingResolve;
|
|
307
|
+
pendingResolve = null; sessionId = null;
|
|
308
|
+
resolve_?.();
|
|
309
|
+
await drainQueue();
|
|
310
|
+
});
|
|
311
|
+
return; // don't fall through to pendingResolve below
|
|
312
|
+
}
|
|
290
313
|
lineBuffer = '';
|
|
291
314
|
if (pendingResolve) { pendingResolve(); pendingResolve = null; }
|
|
292
315
|
rl.prompt();
|
|
@@ -402,8 +425,8 @@ async function runTask(input) {
|
|
|
402
425
|
const resolve_ = pendingResolve;
|
|
403
426
|
pendingResolve = null;
|
|
404
427
|
sessionId = null;
|
|
405
|
-
resolve_();
|
|
406
|
-
|
|
428
|
+
resolve_?.();
|
|
429
|
+
drainQueue(); // auto-process queued messages
|
|
407
430
|
}
|
|
408
431
|
} catch {}
|
|
409
432
|
}, 800);
|
|
@@ -505,6 +528,37 @@ async function handleCommand(input) {
|
|
|
505
528
|
}
|
|
506
529
|
|
|
507
530
|
// /status
|
|
531
|
+
// /update — check for updates and install immediately
|
|
532
|
+
case '/update': {
|
|
533
|
+
process.stdout.write(` ${fmt(C.dim, 'Checking for updates...')}\n`);
|
|
534
|
+
try {
|
|
535
|
+
const pkgPath = resolve(new URL(import.meta.url).pathname, '..', '..', 'package.json');
|
|
536
|
+
const currentVersion = existsSync(pkgPath)
|
|
537
|
+
? JSON.parse(readFileSync(pkgPath, 'utf8')).version
|
|
538
|
+
: '?';
|
|
539
|
+
const reg = await fetch('https://registry.npmjs.org/0agent/latest', {
|
|
540
|
+
signal: AbortSignal.timeout(5000),
|
|
541
|
+
}).then(r => r.json()).catch(() => null);
|
|
542
|
+
const latest = reg?.version;
|
|
543
|
+
if (!latest) { console.log(` ${fmt(C.yellow, '⚠')} Could not reach npm registry\n`); break; }
|
|
544
|
+
if (!isNewerVersion(latest, currentVersion)) {
|
|
545
|
+
console.log(` ${fmt(C.green, '✓')} Already on latest (${currentVersion})\n`);
|
|
546
|
+
break;
|
|
547
|
+
}
|
|
548
|
+
console.log(` ${fmt(C.cyan, '↑')} Updating ${currentVersion} → ${latest}...`);
|
|
549
|
+
const { execSync: exs } = await import('node:child_process');
|
|
550
|
+
exs('npm install -g 0agent@latest --silent', { stdio: 'ignore', timeout: 120_000 });
|
|
551
|
+
process.stdout.write(` ${fmt(C.green, '✓')} Updated to ${latest} — restarting...\n\n`);
|
|
552
|
+
const { spawn: sp } = await import('node:child_process');
|
|
553
|
+
const child = sp(process.argv[0], process.argv.slice(1), { stdio: 'inherit' });
|
|
554
|
+
child.on('close', (code) => process.exit(code ?? 0));
|
|
555
|
+
process.stdin.pause();
|
|
556
|
+
} catch (e) {
|
|
557
|
+
console.log(` ${fmt(C.red, '✗')} Update failed: ${e.message}\n`);
|
|
558
|
+
}
|
|
559
|
+
break;
|
|
560
|
+
}
|
|
561
|
+
|
|
508
562
|
case '/status': {
|
|
509
563
|
try {
|
|
510
564
|
const h = await fetch(`${BASE_URL}/api/health`).then(r => r.json());
|
|
@@ -773,62 +827,61 @@ async function _safeJsonFetch(url, opts) {
|
|
|
773
827
|
console.log(` ${fmt(C.yellow, '⚠')} LLM check failed: ${e.message}\n`);
|
|
774
828
|
}
|
|
775
829
|
|
|
776
|
-
// ──
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
830
|
+
// ── Auto-update: check npm, update silently, restart ─────────────────────
|
|
831
|
+
// Runs in background after prompt — never blocks startup.
|
|
832
|
+
// If update found: counts down 3s (press any key to skip), then auto-installs.
|
|
833
|
+
(async () => {
|
|
834
|
+
try {
|
|
835
|
+
const pkgPath = resolve(new URL(import.meta.url).pathname, '..', '..', 'package.json');
|
|
836
|
+
const currentVersion = existsSync(pkgPath)
|
|
837
|
+
? JSON.parse(readFileSync(pkgPath, 'utf8')).version
|
|
838
|
+
: null;
|
|
839
|
+
if (!currentVersion) return;
|
|
782
840
|
|
|
783
|
-
if (currentVersion) {
|
|
784
841
|
const reg = await fetch('https://registry.npmjs.org/0agent/latest', {
|
|
785
|
-
signal: AbortSignal.timeout(
|
|
842
|
+
signal: AbortSignal.timeout(5000),
|
|
786
843
|
}).then(r => r.json()).catch(() => null);
|
|
787
844
|
|
|
788
845
|
const latest = reg?.version;
|
|
789
|
-
if (latest
|
|
790
|
-
console.log(`\n ${fmt(C.yellow, '↑')} Update available: ${fmt(C.dim, currentVersion)} → ${fmt(C.bold + C.green, latest)}`);
|
|
791
|
-
process.stdout.write(` Update now? ${fmt(C.bold, '[y/N]')} `);
|
|
792
|
-
|
|
793
|
-
await new Promise((res) => {
|
|
794
|
-
const handler = async (buf) => {
|
|
795
|
-
const answer = buf.toString().trim().toLowerCase();
|
|
796
|
-
process.stdout.write(answer + '\n');
|
|
797
|
-
if (answer === 'y') {
|
|
798
|
-
process.stdout.write(`\n ${fmt(C.dim, 'Installing 0agent@latest...')}\n`);
|
|
799
|
-
try {
|
|
800
|
-
const { execSync: exs } = await import('node:child_process');
|
|
801
|
-
exs('npm install -g 0agent@latest', { stdio: 'inherit', timeout: 120_000 });
|
|
802
|
-
process.stdout.write(`\n ${fmt(C.green, '✓')} Updated to ${latest} — restarting...\n\n`);
|
|
803
|
-
// Restart: spawn new instance, exit current
|
|
804
|
-
const { spawn: sp } = await import('node:child_process');
|
|
805
|
-
const child = sp(process.argv[0], process.argv.slice(1), { stdio: 'inherit' });
|
|
806
|
-
child.on('close', (code) => process.exit(code ?? 0));
|
|
807
|
-
process.stdin.pause();
|
|
808
|
-
} catch (e) {
|
|
809
|
-
process.stdout.write(`\n ${fmt(C.red, '✗')} Update failed: ${e.message}\n Try manually: npm install -g 0agent@latest\n\n`);
|
|
810
|
-
rl.prompt();
|
|
811
|
-
}
|
|
812
|
-
} else {
|
|
813
|
-
process.stdout.write(` ${fmt(C.dim, `Skipping — run: npm install -g 0agent@${latest} to update later`)}\n\n`);
|
|
814
|
-
rl.prompt();
|
|
815
|
-
}
|
|
816
|
-
res();
|
|
817
|
-
};
|
|
846
|
+
if (!latest || !isNewerVersion(latest, currentVersion)) return;
|
|
818
847
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
848
|
+
// Show banner immediately above current prompt line
|
|
849
|
+
process.stdout.write(`\n ${fmt(C.yellow, '↑')} New version ${fmt(C.bold, latest)} available (you have ${currentVersion})\n`);
|
|
850
|
+
|
|
851
|
+
// 3-second countdown — press any key to skip, otherwise auto-updates
|
|
852
|
+
let skipped = false;
|
|
853
|
+
const skipHandler = () => { skipped = true; };
|
|
854
|
+
process.stdin.once('data', skipHandler);
|
|
855
|
+
|
|
856
|
+
for (let i = 3; i > 0; i--) {
|
|
857
|
+
if (skipped) break;
|
|
858
|
+
process.stdout.write(`\r ${fmt(C.dim, `Auto-updating in ${i}s — press any key to skip... `)}`);
|
|
859
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
860
|
+
}
|
|
861
|
+
process.stdin.removeListener('data', skipHandler);
|
|
862
|
+
process.stdout.write('\r\x1b[2K'); // clear countdown line
|
|
863
|
+
|
|
864
|
+
if (skipped) {
|
|
865
|
+
console.log(` ${fmt(C.dim, `Skipped. Run: npm install -g 0agent@${latest}`)}`);
|
|
866
|
+
rl.prompt(true);
|
|
867
|
+
return;
|
|
827
868
|
}
|
|
869
|
+
|
|
870
|
+
// Auto-install
|
|
871
|
+
console.log(` ${fmt(C.cyan, '↑')} Updating to ${latest}...`);
|
|
872
|
+
const { execSync: exs } = await import('node:child_process');
|
|
873
|
+
exs('npm install -g 0agent@latest --silent', { stdio: 'ignore', timeout: 120_000 });
|
|
874
|
+
process.stdout.write(` ${fmt(C.green, '✓')} Updated to ${latest} — restarting...\n\n`);
|
|
875
|
+
|
|
876
|
+
// Restart cleanly
|
|
877
|
+
const { spawn: sp } = await import('node:child_process');
|
|
878
|
+
const child = sp(process.argv[0], process.argv.slice(1), { stdio: 'inherit' });
|
|
879
|
+
child.on('close', (code) => process.exit(code ?? 0));
|
|
880
|
+
process.stdin.pause();
|
|
881
|
+
} catch {
|
|
882
|
+
// Non-fatal — update failure never crashes the agent
|
|
828
883
|
}
|
|
829
|
-
}
|
|
830
|
-
// Version check is non-fatal — never block startup
|
|
831
|
-
}
|
|
884
|
+
})();
|
|
832
885
|
|
|
833
886
|
rl.prompt();
|
|
834
887
|
})();
|
|
@@ -844,20 +897,44 @@ function isNewerVersion(a, b) {
|
|
|
844
897
|
}
|
|
845
898
|
|
|
846
899
|
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
900
|
+
// ─── Message queue + serial executor ─────────────────────────────────────────
|
|
901
|
+
|
|
902
|
+
const COMMAND_PREFIXES = ['/model','/key','/status','/skills','/graph','/clear','/help','/schedule','/update'];
|
|
850
903
|
|
|
851
|
-
|
|
904
|
+
async function executeInput(line) {
|
|
905
|
+
const isCmd = line.startsWith('/') || COMMAND_PREFIXES.some(c => line.startsWith(c));
|
|
906
|
+
if (isCmd) {
|
|
852
907
|
await handleCommand(line);
|
|
853
|
-
rl.prompt();
|
|
854
908
|
} else {
|
|
909
|
+
lastFailedTask = null;
|
|
855
910
|
await runTask(line);
|
|
856
|
-
// runTask resolves when session completes (via WS or polling fallback)
|
|
857
|
-
// rl.prompt() may already have been called by the handler that resolved it,
|
|
858
|
-
// but calling it again is a safe no-op if readline is already prompting
|
|
859
|
-
if (!streaming) rl.prompt();
|
|
860
911
|
}
|
|
912
|
+
// After this input completes, drain the queue
|
|
913
|
+
await drainQueue();
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
async function drainQueue() {
|
|
917
|
+
if (messageQueue.length === 0) { if (!streaming) rl.prompt(); return; }
|
|
918
|
+
const next = messageQueue.shift();
|
|
919
|
+
if (messageQueue.length > 0) {
|
|
920
|
+
console.log(` ${fmt(C.dim, `[${messageQueue.length} more in queue]`)}`);
|
|
921
|
+
}
|
|
922
|
+
await executeInput(next);
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
rl.on('line', async (input) => {
|
|
926
|
+
const line = input.trim();
|
|
927
|
+
if (!line) { rl.prompt(); return; }
|
|
928
|
+
|
|
929
|
+
// If a session is already running, queue the message
|
|
930
|
+
if (pendingResolve) {
|
|
931
|
+
messageQueue.push(line);
|
|
932
|
+
const qLen = messageQueue.length;
|
|
933
|
+
process.stdout.write(`\n ${fmt(C.dim, `↳ queued [${qLen}]`)} ${fmt(C.dim, line.slice(0, 60))}\n`);
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
await executeInput(line);
|
|
861
938
|
});
|
|
862
939
|
|
|
863
940
|
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) {
|