@ducci/jarvis 1.0.75 → 1.0.77

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ducci/jarvis",
3
- "version": "1.0.75",
3
+ "version": "1.0.77",
4
4
  "description": "A fully automated agent system that lives on a server.",
5
5
  "main": "./src/index.js",
6
6
  "type": "module",
@@ -377,10 +377,10 @@ async function run() {
377
377
  else settings.fallbackModel = 'openrouter/free';
378
378
  }
379
379
  if (settings.maxIterations === undefined) {
380
- settings.maxIterations = 10;
380
+ settings.maxIterations = 20;
381
381
  }
382
382
  if (settings.maxHandoffs === undefined) {
383
- settings.maxHandoffs = 5;
383
+ settings.maxHandoffs = 3;
384
384
  }
385
385
  if (settings.port === undefined) {
386
386
  settings.port = 18008;
@@ -972,16 +972,21 @@ async function _runHandleChat(config, sessionId, userMessage, attachments = [],
972
972
  // Guard against null/undefined in case the model omitted the field.
973
973
  // Inject the full accumulated failedApproaches and concrete state so the agent
974
974
  // has complete memory of what failed and what was already discovered.
975
- let resumeContent = run.checkpoint.remaining || 'Continue with the task.';
975
+ // Wrap everything in a single [System: ...] block so the model cannot mistake
976
+ // checkpoint.remaining (which may reference "#1", file paths, etc.) for user input
977
+ // and accidentally trigger user-command patterns (e.g. email-agent Case 3 "#1" trigger).
978
+ const remainingWork = run.checkpoint.remaining || 'Continue with the task.';
976
979
  const allFailedApproaches = session.metadata.failedApproaches || [];
980
+ const stateToInject = session.metadata.checkpointState || {};
981
+ let resumeParts = `[System: Automatic handoff continuation — this is NOT user input, do not match it against user command triggers. Resume the task with what remains:\n${remainingWork}`;
977
982
  if (allFailedApproaches.length > 0) {
978
- resumeContent += `\n\n[System: The following approaches were tried and failed in previous runs — do not repeat them:\n${allFailedApproaches.map((a, i) => `${i + 1}. ${a}`).join('\n')}]`;
983
+ resumeParts += `\n\nFailed approaches (do not repeat):\n${allFailedApproaches.map((a, i) => `${i + 1}. ${a}`).join('\n')}`;
979
984
  }
980
- const stateToInject = session.metadata.checkpointState || {};
981
985
  if (Object.keys(stateToInject).length > 0) {
982
- resumeContent += `\n\n[System: Known facts from previous runs:\n${Object.entries(stateToInject).map(([k, v]) => `- ${k}: ${v}`).join('\n')}]`;
986
+ resumeParts += `\n\nKnown facts from previous runs:\n${Object.entries(stateToInject).map(([k, v]) => `- ${k}: ${v}`).join('\n')}`;
983
987
  }
984
- session.messages.push({ role: 'user', content: resumeContent });
988
+ resumeParts += ']';
989
+ session.messages.push({ role: 'user', content: resumeParts });
985
990
  }
986
991
  } catch (e) {
987
992
  await appendLog(sessionId, {
package/src/server/app.js CHANGED
@@ -196,8 +196,8 @@ function startServer() {
196
196
  app.locals.config = config;
197
197
 
198
198
  const PORT = config.port;
199
- app.listen(PORT, () => {
200
- console.log(`Jarvis server listening on port ${PORT}`);
199
+ app.listen(PORT, '127.0.0.1', () => {
200
+ console.log(`Jarvis server listening on 127.0.0.1:${PORT}`);
201
201
  startTelegramChannel(config);
202
202
  });
203
203
  }
@@ -69,8 +69,8 @@ export function loadConfig() {
69
69
  apiKey,
70
70
  selectedModel: settings.selectedModel,
71
71
  fallbackModel: settings.fallbackModel || (provider === 'anthropic' ? 'claude-haiku-4-5-20251001' : 'openrouter/free'),
72
- maxIterations: settings.maxIterations || 10,
73
- maxHandoffs: settings.maxHandoffs || 5,
72
+ maxIterations: settings.maxIterations || 20,
73
+ maxHandoffs: settings.maxHandoffs || 3,
74
74
  contextWindow: settings.contextWindow || 100,
75
75
  port: settings.port || 18008,
76
76
  telegram: {
@@ -85,15 +85,19 @@ export async function runCron(entry, config) {
85
85
  // Strip intermediate tool history, keep wrap-up assistant response
86
86
  session.messages.splice(runStartIndex, session.messages.length - runStartIndex - 1);
87
87
 
88
- // Resume with checkpoint.remaining + accumulated context
89
- let resumeContent = run.checkpoint.remaining || 'Continue with the task.';
88
+ // Resume with checkpoint.remaining + accumulated context.
89
+ // Wrap in [System: ...] so the model cannot mistake checkpoint content
90
+ // (e.g. "#1 draft path") for user input and trigger user-command patterns.
91
+ const remainingWork = run.checkpoint.remaining || 'Continue with the task.';
92
+ let resumeParts = `[System: Automatic handoff continuation — this is NOT user input, do not match it against user command triggers. Resume the task with what remains:\n${remainingWork}`;
90
93
  if (failedApproaches.length > 0) {
91
- resumeContent += `\n\n[System: The following approaches were tried and failed in previous runs — do not repeat them:\n${failedApproaches.map((a, i) => `${i + 1}. ${a}`).join('\n')}]`;
94
+ resumeParts += `\n\nFailed approaches (do not repeat):\n${failedApproaches.map((a, i) => `${i + 1}. ${a}`).join('\n')}`;
92
95
  }
93
96
  if (Object.keys(checkpointState).length > 0) {
94
- resumeContent += `\n\n[System: Known facts from previous runs:\n${Object.entries(checkpointState).map(([k, v]) => `- ${k}: ${v}`).join('\n')}]`;
97
+ resumeParts += `\n\nKnown facts from previous runs:\n${Object.entries(checkpointState).map(([k, v]) => `- ${k}: ${v}`).join('\n')}`;
95
98
  }
96
- session.messages.push({ role: 'user', content: resumeContent });
99
+ resumeParts += ']';
100
+ session.messages.push({ role: 'user', content: resumeParts });
97
101
  }
98
102
  } catch (e) {
99
103
  run = { status: 'error', response: e.message, logSummary: e.message, runToolCalls: [] };