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.
Files changed (3) hide show
  1. package/bin/chat.js +137 -60
  2. package/dist/daemon.mjs +62 -11
  3. 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
- rl.prompt();
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
- rl.prompt();
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
- // ── 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;
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(4000),
842
+ signal: AbortSignal.timeout(5000),
786
843
  }).then(r => r.json()).catch(() => null);
787
844
 
788
845
  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
- };
846
+ if (!latest || !isNewerVersion(latest, currentVersion)) return;
818
847
 
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
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
- } catch {
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
- rl.on('line', async (input) => {
848
- const line = input.trim();
849
- if (!line) { rl.prompt(); return; }
900
+ // ─── Message queue + serial executor ─────────────────────────────────────────
901
+
902
+ const COMMAND_PREFIXES = ['/model','/key','/status','/skills','/graph','/clear','/help','/schedule','/update'];
850
903
 
851
- if (line.startsWith('/') || ['/model','/key','/status','/skills','/graph','/clear','/help','/schedule'].some(c => line.startsWith(c))) {
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 systemPrompt = this.buildSystemPrompt(systemContext);
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(6e4)
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(6e4)
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
- // enables ConversationStore + weight feedback
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "0agent",
3
- "version": "1.0.34",
3
+ "version": "1.0.36",
4
4
  "description": "A persistent, learning AI agent that runs on your machine. An agent that learns.",
5
5
  "private": false,
6
6
  "license": "Apache-2.0",