neoagent 2.2.1-beta.5 → 2.2.1-beta.6

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": "neoagent",
3
- "version": "2.2.1-beta.5",
3
+ "version": "2.2.1-beta.6",
4
4
  "description": "Proactive personal AI agent with no limits",
5
5
  "license": "MIT",
6
6
  "main": "server/index.js",
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"59aa584fdf100e6c78c785d8a5b565d1de4b48
37
37
 
38
38
  _flutter.loader.load({
39
39
  serviceWorkerSettings: {
40
- serviceWorkerVersion: "3025620122" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
40
+ serviceWorkerVersion: "3879536533" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
41
41
  }
42
42
  });
@@ -39,6 +39,7 @@ const {
39
39
  } = require('./interim');
40
40
 
41
41
  const MAX_CONSECUTIVE_TOOL_FAILURES = 3;
42
+ const WIDGET_REFRESH_MAX_ITERATIONS = 6;
42
43
 
43
44
  function generateTitle(task) {
44
45
  if (!task || typeof task !== 'string') return 'Untitled';
@@ -1324,8 +1325,9 @@ class AgentEngine {
1324
1325
  runMeta.toolPids.delete(pid);
1325
1326
  }
1326
1327
 
1327
- getIterationLimit(triggerType, aiSettings) {
1328
+ getIterationLimit(triggerType, aiSettings, options = {}) {
1328
1329
  if (triggerType === 'subagent') return aiSettings.subagent_max_iterations;
1330
+ if (options.widgetId) return Math.min(this.maxIterations, WIDGET_REFRESH_MAX_ITERATIONS);
1329
1331
  return this.maxIterations;
1330
1332
  }
1331
1333
 
@@ -1467,7 +1469,7 @@ class AgentEngine {
1467
1469
  Number(options.historyWindow || aiSettings.chat_history_window) || aiSettings.chat_history_window,
1468
1470
  );
1469
1471
  const toolReplayBudget = aiSettings.tool_replay_budget_chars;
1470
- const maxIterations = this.getIterationLimit(triggerType, aiSettings);
1472
+ const maxIterations = this.getIterationLimit(triggerType, aiSettings, options);
1471
1473
  const providerStatusConfig = {
1472
1474
  agentId,
1473
1475
  onStatus: (status) => {
@@ -1507,6 +1509,7 @@ class AgentEngine {
1507
1509
  explicitMessageSent: carriedExplicitMessageSent,
1508
1510
  lastSentMessage: carriedExplicitMessageSent ? carriedVisibleMessage : '',
1509
1511
  sentMessages: [],
1512
+ widgetSnapshotSaved: false,
1510
1513
  triggerType,
1511
1514
  triggerSource,
1512
1515
  startedAt: Date.now(),
@@ -2092,6 +2095,14 @@ class AgentEngine {
2092
2095
  if (runMeta) {
2093
2096
  runMeta.lastToolName = toolName;
2094
2097
  runMeta.lastToolTarget = toolName === 'send_message' ? toolArgs.to : null;
2098
+ if (toolName === 'save_widget_snapshot' && !toolErrorMessage) {
2099
+ runMeta.widgetSnapshotSaved = true;
2100
+ }
2101
+ }
2102
+
2103
+ if (toolName === 'save_widget_snapshot' && !toolErrorMessage) {
2104
+ lastContent = 'Widget snapshot updated.';
2105
+ break;
2095
2106
  }
2096
2107
 
2097
2108
  if (runMeta?.terminalInterim) {
@@ -2101,6 +2112,7 @@ class AgentEngine {
2101
2112
 
2102
2113
  if (this.isRunStopped(runId)) break;
2103
2114
  if (this.getRunMeta(runId)?.terminalInterim) break;
2115
+ if (this.getRunMeta(runId)?.widgetSnapshotSaved) break;
2104
2116
  if (!this.activeRuns.has(runId)) break;
2105
2117
  }
2106
2118
 
@@ -2119,6 +2131,9 @@ class AgentEngine {
2119
2131
  if (runMeta?.terminalInterim) {
2120
2132
  lastContent = '';
2121
2133
  }
2134
+ if (runMeta?.widgetSnapshotSaved && !lastContent) {
2135
+ lastContent = 'Widget snapshot updated.';
2136
+ }
2122
2137
  const messagingSent = runMeta?.messagingSent || false;
2123
2138
  const lastToolWasMessaging = runMeta?.lastToolName === 'send_message' || runMeta?.lastToolName === 'make_call';
2124
2139
 
@@ -2147,7 +2162,11 @@ class AgentEngine {
2147
2162
  }
2148
2163
  }
2149
2164
 
2150
- if (!normalizeOutgoingMessage(lastContent, options?.source || null) && !messagingSent) {
2165
+ if (
2166
+ !normalizeOutgoingMessage(lastContent, options?.source || null)
2167
+ && !messagingSent
2168
+ && runMeta?.widgetSnapshotSaved !== true
2169
+ ) {
2151
2170
  if (iteration >= maxIterations) {
2152
2171
  throw new Error(`Iteration limit reached before explicit completion after ${maxIterations} iterations.`);
2153
2172
  }
@@ -527,6 +527,7 @@ class WidgetService {
527
527
  '{"title":"","kicker":"","subtitle":"","body":"","metric":"","metricLabel":"","secondaryMetric":"","secondaryLabel":"","tertiaryMetric":"","tertiaryLabel":"","trend":{"label":"","direction":"flat"},"progress":{"value":0,"max":100,"label":""},"rows":[{"label":"","value":""}],"chips":[""],"iconToken":"","accentToken":"","backgroundToken":"","surfaceColor":"","updatedAt":"","deepLink":""}',
528
528
  'Rules:',
529
529
  '- Do not change the template or layout variant.',
530
+ '- Once you have enough accurate data, call save_widget_snapshot exactly once and stop. Do not keep exploring after saving.',
530
531
  '- Keep rows to at most 3 and chips to at most 3.',
531
532
  '- Prefer concrete data over generic prose. Use metric + supporting fields whenever live data exists.',
532
533
  '- Make the widget immediately useful at a glance. Avoid filler copy, duplicated labels, or repeating the widget name unless it helps identify the subject.',