@agent-native/core 0.85.4 → 0.85.5

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.
@@ -1,5 +1,11 @@
1
1
  # @agent-native/core
2
2
 
3
+ ## 0.85.5
4
+
5
+ ### Patch Changes
6
+
7
+ - bd7c040: Auto-continue active chat reconnects when action preparation stalls, and count first action-prep events as durable progress.
8
+
3
9
  ## 0.85.4
4
10
 
5
11
  ### Patch Changes
@@ -235,7 +235,7 @@ Privacy defaults are intentionally conservative but still useful for playback:
235
235
  - URLs are scrubbed with the same `scrubUrl()` helper used by browser analytics.
236
236
  - Replay capture is web-only and opt-in; it does not record native desktop screens.
237
237
 
238
- While recording, session replay also captures browser console output (`log`, `info`, `warn`, `error`, `debug`, plus window `error` / `unhandledrejection`) and network request metadata (`fetch` and XHR) as tagged rrweb custom events, so agents and the replay viewer can debug user-reported issues. Capture is on by default when replay is enabled; tune or disable it with the `sessionReplay.console` and `sessionReplay.network` options, each accepting a boolean or an options object. Request/response bodies and headers are never captured, URLs are scrubbed, messages are truncated, the recorder's own ingest/tracking traffic is excluded, and per-session budgets (1000 console / 2000 network events) add a truncation notice when exceeded.
238
+ While recording, session replay also captures browser console output (`log`, `info`, `warn`, `error`, `debug`, plus window `error` / `unhandledrejection`) and network request metadata (`fetch` and XHR) as tagged rrweb custom events, so agents and the replay viewer can debug user-reported issues. Capture is on by default when replay is enabled; tune or disable it with the `sessionReplay.console` and `sessionReplay.network` options, each accepting a boolean or an options object (`{ maxEvents?: number }`). Request/response bodies and headers are never captured, URLs are scrubbed, messages are truncated, the recorder's own ingest/tracking traffic is excluded, and per-session budgets (1000 console / 2000 network events) add a truncation notice when exceeded.
239
239
 
240
240
  The Analytics template stores replay metadata in SQL (`session_recordings`) and stores chunks through private blob refs (`session_replay_chunks`). Browsers and agents never receive provider URLs. Playback goes through scoped server routes and the default agent tools return summaries or bounded replay events, not raw chunk table access.
241
241
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.85.4",
3
+ "version": "0.85.5",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -553,6 +553,16 @@ export function startRun(
553
553
  preparingActivityBytes.get(activityKey) ?? 0,
554
554
  restartHighWater,
555
555
  );
556
+ if (
557
+ !preparingActivityBytes.has(activityKey) &&
558
+ progressBytes === 0 &&
559
+ !preparingActivityRestartHighWater.has(toolKey)
560
+ ) {
561
+ preparingActivityTools.set(activityKey, toolKey);
562
+ preparingActivityBytes.set(activityKey, 0);
563
+ preparingActivityRestartHighWater.set(toolKey, 0);
564
+ return true;
565
+ }
556
566
  if (progressBytes <= previousBytes) {
557
567
  preparingActivityTools.set(activityKey, toolKey);
558
568
  preparingActivityBytes.set(
@@ -242,6 +242,9 @@ const ACTIVE_RUN_STUCK_THRESHOLD_MS = 90_000;
242
242
  const BACKGROUND_ACTIVE_RUN_STUCK_THRESHOLD_MS = 13 * 60_000;
243
243
  const ACTIVE_RUN_POLL_INTERVAL_MS = 150;
244
244
  const AUTO_RESUME_STATUS_TIMEOUT_MS = 30_000;
245
+ const MAX_RECONNECT_AUTO_RECOVERIES = 3;
246
+ const RECONNECT_NO_PROGRESS_CONTINUE_MESSAGE =
247
+ "Continue from where you stopped. Use the partial work above, verify what succeeded, and finish the original request. Do not rerun the exact same failed tool input unless the failure was transient or the user explicitly asked for an exact rerun. Prefer dedicated app actions over raw database edits when they exist.";
245
248
  // How long a single activity (model call, tool prep, long tool) must stay
246
249
  // in-flight before its label is surfaced in the running indicator. Below this
247
250
  // the indicator stays a steady "Thinking" so normal fast turns don't flicker
@@ -262,6 +265,11 @@ type ActiveRunLookup = {
262
265
  serverNow?: number;
263
266
  };
264
267
 
268
+ type PendingReconnectRecovery = {
269
+ id: number;
270
+ message: string;
271
+ };
272
+
265
273
  function isReplayableTerminalRun(runInfo: ActiveRunLookup): boolean {
266
274
  const dispatchMode =
267
275
  typeof runInfo.dispatchMode === "string" ? runInfo.dispatchMode : "";
@@ -1568,6 +1576,9 @@ const AssistantChatInner = forwardRef<
1568
1576
  const reconnectTailOnlyRef = useRef(false);
1569
1577
  const reconnectCanMaterializeRef = useRef(false);
1570
1578
  const reconnectAbortRef = useRef<AbortController | null>(null);
1579
+ const reconnectAutoRecoveryCountRef = useRef(0);
1580
+ const [pendingReconnectRecovery, setPendingReconnectRecovery] =
1581
+ useState<PendingReconnectRecovery | null>(null);
1571
1582
  // Nuclear stop: user clicked stop. Clears the stop button/indicator AND
1572
1583
  // lets new submissions go through immediately — prevents the "stuck
1573
1584
  // queueing forever" state where isReconnecting or isRuntimeRunning gets
@@ -2134,6 +2145,38 @@ const AssistantChatInner = forwardRef<
2134
2145
  setReconnectFrozen(latestContent.length > 0);
2135
2146
  reconnectCanMaterializeRef.current = latestContent.length > 0;
2136
2147
  }
2148
+ const canAutoRecoverReconnect =
2149
+ reconnectTerminalReason !== "run_timeout" &&
2150
+ reconnectAutoRecoveryCountRef.current <
2151
+ MAX_RECONNECT_AUTO_RECOVERIES;
2152
+ if (canAutoRecoverReconnect) {
2153
+ reconnectAutoRecoveryCountRef.current += 1;
2154
+ setRunErrorInfo(null);
2155
+ setDismissedRunErrorKey(null);
2156
+ clearActiveRunIfMatches(threadId, runId);
2157
+ reconnectAbortRef.current = null;
2158
+ setIsReconnecting(false);
2159
+ reconnectRunIdRef.current = null;
2160
+ reconnectTailOnlyRef.current = false;
2161
+ if (afterSeq > 0) {
2162
+ reconnectCanMaterializeRef.current = false;
2163
+ }
2164
+ window.dispatchEvent(
2165
+ new CustomEvent("agent-chat:auto-continue", {
2166
+ detail: { tabId: tabId || threadId },
2167
+ }),
2168
+ );
2169
+ setPendingReconnectRecovery({
2170
+ id: Date.now(),
2171
+ message: RECONNECT_NO_PROGRESS_CONTINUE_MESSAGE,
2172
+ });
2173
+ window.dispatchEvent(
2174
+ new CustomEvent("agentNative.chatRunning", {
2175
+ detail: { isRunning: false, tabId: tabId || threadId },
2176
+ }),
2177
+ );
2178
+ return;
2179
+ }
2137
2180
  setRunErrorInfo({
2138
2181
  message:
2139
2182
  reconnectTerminalReason === "run_timeout"
@@ -2188,6 +2231,9 @@ const AssistantChatInner = forwardRef<
2188
2231
  if (loaded || afterSeq > 0 || latestContent.length === 0) {
2189
2232
  reconnectCanMaterializeRef.current = false;
2190
2233
  }
2234
+ if (loaded) {
2235
+ reconnectAutoRecoveryCountRef.current = 0;
2236
+ }
2191
2237
  window.dispatchEvent(
2192
2238
  new CustomEvent("agentNative.chatRunning", {
2193
2239
  detail: { isRunning: false, tabId: tabId || threadId },
@@ -3070,10 +3116,14 @@ const AssistantChatInner = forwardRef<
3070
3116
  recoveryAction?: AgentRecoveryAction,
3071
3117
  includeComposerContext = false,
3072
3118
  trackInRunsTray = false,
3119
+ preserveReconnectAutoRecoveryBudget = false,
3073
3120
  ) => {
3074
3121
  if (!(await ensureAgentEngineReadyForSubmit())) {
3075
3122
  return;
3076
3123
  }
3124
+ if (!preserveReconnectAutoRecoveryBudget) {
3125
+ reconnectAutoRecoveryCountRef.current = 0;
3126
+ }
3077
3127
  materializeFrozenReconnectContent();
3078
3128
  setShowContinue(false);
3079
3129
  setLoopLimitInfo(null);
@@ -3296,6 +3346,29 @@ const AssistantChatInner = forwardRef<
3296
3346
  ],
3297
3347
  );
3298
3348
 
3349
+ useEffect(() => {
3350
+ if (!pendingReconnectRecovery) return;
3351
+ const recovery = pendingReconnectRecovery;
3352
+ const timer = window.setTimeout(() => {
3353
+ setPendingReconnectRecovery((current) =>
3354
+ current?.id === recovery.id ? null : current,
3355
+ );
3356
+ addToQueue(
3357
+ recovery.message,
3358
+ undefined,
3359
+ undefined,
3360
+ undefined,
3361
+ undefined,
3362
+ "queued",
3363
+ "continue",
3364
+ false,
3365
+ false,
3366
+ true,
3367
+ );
3368
+ }, 0);
3369
+ return () => window.clearTimeout(timer);
3370
+ }, [addToQueue, pendingReconnectRecovery]);
3371
+
3299
3372
  // Expose imperative handle
3300
3373
  useImperativeHandle(
3301
3374
  ref,
@@ -3871,7 +3944,7 @@ const AssistantChatInner = forwardRef<
3871
3944
  onContinue={() => {
3872
3945
  setRunErrorInfo(null);
3873
3946
  addToQueue(
3874
- "Continue from where you stopped. Use the partial work above, verify what succeeded, and finish the original request. Do not rerun the exact same failed tool input unless the failure was transient or the user explicitly asked for an exact rerun. Prefer dedicated app actions over raw database edits when they exist.",
3947
+ RECONNECT_NO_PROGRESS_CONTINUE_MESSAGE,
3875
3948
  undefined,
3876
3949
  undefined,
3877
3950
  undefined,
@@ -46,7 +46,7 @@ agent answers about browser recordings in the Analytics template.
46
46
  custom events tagged `agent-native.console` and `agent-native.network`.
47
47
  - Capture is on by default whenever session replay is enabled. Tune or disable
48
48
  it with the `console` / `network` options on the session replay config; each
49
- accepts a boolean or an options object.
49
+ accepts a boolean or an options object (`{ maxEvents?: number }`).
50
50
  - Privacy bounds: request/response bodies and headers are never captured, URLs
51
51
  are scrubbed, messages are truncated, and recorder self-traffic (the replay
52
52
  ingest and tracking endpoints) is excluded.
@@ -1 +1 @@
1
- {"version":3,"file":"run-manager.d.ts","sourceRoot":"","sources":["../../src/agent/run-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-manager.d.ts","sourceRoot":"","sources":["../../src/agent/run-manager.ts"],"names":[],"mappings":"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"}
@@ -406,6 +406,14 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
406
406
  return progressBytes > 0;
407
407
  }
408
408
  const previousBytes = Math.max(preparingActivityBytes.get(activityKey) ?? 0, restartHighWater);
409
+ if (!preparingActivityBytes.has(activityKey) &&
410
+ progressBytes === 0 &&
411
+ !preparingActivityRestartHighWater.has(toolKey)) {
412
+ preparingActivityTools.set(activityKey, toolKey);
413
+ preparingActivityBytes.set(activityKey, 0);
414
+ preparingActivityRestartHighWater.set(toolKey, 0);
415
+ return true;
416
+ }
409
417
  if (progressBytes <= previousBytes) {
410
418
  preparingActivityTools.set(activityKey, toolKey);
411
419
  preparingActivityBytes.set(activityKey, Math.max(previousBytes, progressBytes));