0agent 1.0.32 → 1.0.34
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 +83 -1
- package/dist/daemon.mjs +5 -1
- package/package.json +1 -1
package/bin/chat.js
CHANGED
|
@@ -354,8 +354,23 @@ async function runTask(input) {
|
|
|
354
354
|
// Catches completion when WS is disconnected (e.g. daemon just restarted).
|
|
355
355
|
let lastPolledStep = 0;
|
|
356
356
|
const sid = sessionId;
|
|
357
|
+
const sessionStart = Date.now();
|
|
357
358
|
const pollTimer = setInterval(async () => {
|
|
358
359
|
if (!pendingResolve || sessionId !== sid) { clearInterval(pollTimer); return; }
|
|
360
|
+
|
|
361
|
+
// Hard cap: if session runs for > 2 minutes, force-unblock the chat.
|
|
362
|
+
// The daemon session may still run in background, but the user gets their prompt back.
|
|
363
|
+
if (Date.now() - sessionStart > 120_000) {
|
|
364
|
+
clearInterval(pollTimer);
|
|
365
|
+
spinner.stop();
|
|
366
|
+
console.log(`\n \x1b[33m⚠\x1b[0m Session still running in background (> 2min). Chat unblocked.\n`);
|
|
367
|
+
const res = pendingResolve;
|
|
368
|
+
pendingResolve = null;
|
|
369
|
+
sessionId = null;
|
|
370
|
+
res();
|
|
371
|
+
rl.prompt();
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
359
374
|
try {
|
|
360
375
|
const r = await fetch(`${BASE_URL}/api/sessions/${sid}`, { signal: AbortSignal.timeout(2000) });
|
|
361
376
|
const session = await r.json();
|
|
@@ -391,7 +406,7 @@ async function runTask(input) {
|
|
|
391
406
|
rl.prompt();
|
|
392
407
|
}
|
|
393
408
|
} catch {}
|
|
394
|
-
},
|
|
409
|
+
}, 800);
|
|
395
410
|
|
|
396
411
|
return new Promise(resolve => { pendingResolve = resolve; });
|
|
397
412
|
} catch (e) {
|
|
@@ -758,9 +773,76 @@ async function _safeJsonFetch(url, opts) {
|
|
|
758
773
|
console.log(` ${fmt(C.yellow, '⚠')} LLM check failed: ${e.message}\n`);
|
|
759
774
|
}
|
|
760
775
|
|
|
776
|
+
// ── Version check — ask to update if newer version is on npm ──────────────
|
|
777
|
+
try {
|
|
778
|
+
const pkgPath = resolve(new URL(import.meta.url).pathname, '..', '..', 'package.json');
|
|
779
|
+
const currentVersion = existsSync(pkgPath)
|
|
780
|
+
? JSON.parse(readFileSync(pkgPath, 'utf8')).version
|
|
781
|
+
: null;
|
|
782
|
+
|
|
783
|
+
if (currentVersion) {
|
|
784
|
+
const reg = await fetch('https://registry.npmjs.org/0agent/latest', {
|
|
785
|
+
signal: AbortSignal.timeout(4000),
|
|
786
|
+
}).then(r => r.json()).catch(() => null);
|
|
787
|
+
|
|
788
|
+
const latest = reg?.version;
|
|
789
|
+
if (latest && latest !== currentVersion && isNewerVersion(latest, currentVersion)) {
|
|
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
|
+
};
|
|
818
|
+
|
|
819
|
+
// Single keypress if TTY, line otherwise
|
|
820
|
+
if (process.stdin.isTTY) {
|
|
821
|
+
process.stdin.once('data', handler);
|
|
822
|
+
} else {
|
|
823
|
+
rl.once('line', (line) => handler(Buffer.from(line)));
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
return; // rl.prompt() already called in handler
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
} catch {
|
|
830
|
+
// Version check is non-fatal — never block startup
|
|
831
|
+
}
|
|
832
|
+
|
|
761
833
|
rl.prompt();
|
|
762
834
|
})();
|
|
763
835
|
|
|
836
|
+
function isNewerVersion(a, b) {
|
|
837
|
+
const pa = a.split('.').map(Number);
|
|
838
|
+
const pb = b.split('.').map(Number);
|
|
839
|
+
for (let i = 0; i < 3; i++) {
|
|
840
|
+
if ((pa[i] ?? 0) > (pb[i] ?? 0)) return true;
|
|
841
|
+
if ((pa[i] ?? 0) < (pb[i] ?? 0)) return false;
|
|
842
|
+
}
|
|
843
|
+
return false;
|
|
844
|
+
}
|
|
845
|
+
|
|
764
846
|
|
|
765
847
|
rl.on('line', async (input) => {
|
|
766
848
|
const line = input.trim();
|
package/dist/daemon.mjs
CHANGED
|
@@ -2339,9 +2339,13 @@ var init_ShellCapability = __esm({
|
|
|
2339
2339
|
}
|
|
2340
2340
|
};
|
|
2341
2341
|
async execute(input, cwd) {
|
|
2342
|
-
|
|
2342
|
+
let command = String(input.command ?? "");
|
|
2343
2343
|
const timeout = Number(input.timeout_ms ?? 3e4);
|
|
2344
2344
|
const start = Date.now();
|
|
2345
|
+
if (/&\s*$/.test(command) && !/[>|].*&\s*$/.test(command)) {
|
|
2346
|
+
const logFile = `/tmp/0agent-bg-${Date.now()}.log`;
|
|
2347
|
+
command = command.replace(/\s*&\s*$/, ` > ${logFile} 2>&1 &`);
|
|
2348
|
+
}
|
|
2345
2349
|
return new Promise((resolve_) => {
|
|
2346
2350
|
const chunks = [];
|
|
2347
2351
|
let settled = false;
|