@adhdev/daemon-core 0.9.82-rc.110 → 0.9.82-rc.111

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": "@adhdev/daemon-core",
3
- "version": "0.9.82-rc.110",
3
+ "version": "0.9.82-rc.111",
4
4
  "description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -200,6 +200,8 @@ export class ProviderCliAdapter implements CliAdapter {
200
200
  private pendingOutboundQueue: PendingOutboundMessage[] = [];
201
201
  private pendingOutboundFlushTimer: NodeJS.Timeout | null = null;
202
202
  private pendingOutboundFlushInFlight = false;
203
+ private providerErrorRetryTimer: NodeJS.Timeout | null = null;
204
+ private providerErrorRetryKey = '';
203
205
 
204
206
  // Resize redraw suppression
205
207
  private resizeSuppressUntil: number = 0;
@@ -959,6 +961,8 @@ export class ProviderCliAdapter implements CliAdapter {
959
961
  if (this.pendingScriptStatusTimer) { clearTimeout(this.pendingScriptStatusTimer); this.pendingScriptStatusTimer = null; }
960
962
  if (this.pendingOutputParseTimer) { clearTimeout(this.pendingOutputParseTimer); this.pendingOutputParseTimer = null; }
961
963
  if (this.ptyOutputFlushTimer) { clearTimeout(this.ptyOutputFlushTimer); this.ptyOutputFlushTimer = null; }
964
+ if (this.providerErrorRetryTimer) { clearTimeout(this.providerErrorRetryTimer); this.providerErrorRetryTimer = null; }
965
+ this.providerErrorRetryKey = '';
962
966
  }
963
967
 
964
968
  private clearStaleIdleResponseGuard(reason: string): boolean {
@@ -1154,7 +1158,11 @@ export class ProviderCliAdapter implements CliAdapter {
1154
1158
  && !(parsedStatus === 'idle' && !!lastParsedAssistant);
1155
1159
 
1156
1160
  if (shouldHoldGenerating) { this.applyHoldGenerating(ctx, recentInteractiveActivity); return; }
1157
- if (status === 'error') { this.applyError(ctx, session); return; }
1161
+ if (status === 'error') {
1162
+ if (this.maybeScheduleProviderErrorRetry(ctx, session)) return;
1163
+ this.applyError(ctx, session);
1164
+ return;
1165
+ }
1158
1166
  if (status === 'waiting_approval') { this.applyWaitingApproval(ctx); return; }
1159
1167
  if (status === 'generating') { this.applyGenerating(ctx); return; }
1160
1168
  if (status === 'idle') { this.applyIdle(ctx, now); }
@@ -1333,6 +1341,72 @@ export class ProviderCliAdapter implements CliAdapter {
1333
1341
  this.onStatusChange?.();
1334
1342
  }
1335
1343
 
1344
+ private maybeScheduleProviderErrorRetry(ctx: SettledEvalContext, session: ParsedSession): boolean {
1345
+ const retryPrompt = typeof (session as any).retryPrompt === 'string'
1346
+ ? String((session as any).retryPrompt).trim()
1347
+ : '';
1348
+ const retryDelayMs = typeof (session as any).retryDelayMs === 'number'
1349
+ ? Number((session as any).retryDelayMs)
1350
+ : NaN;
1351
+ if (!retryPrompt || !Number.isFinite(retryDelayMs) || retryDelayMs < 0) return false;
1352
+ if (!this.ptyProcess) return false;
1353
+
1354
+ const retryAttempt = typeof (session as any).retryAttempt === 'number'
1355
+ ? Number((session as any).retryAttempt)
1356
+ : 0;
1357
+ const retryMaxAttempts = typeof (session as any).retryMaxAttempts === 'number'
1358
+ ? Number((session as any).retryMaxAttempts)
1359
+ : 0;
1360
+ const errorReason = typeof session.errorReason === 'string' && session.errorReason.trim()
1361
+ ? session.errorReason.trim()
1362
+ : 'provider_error';
1363
+ const retryKey = `${errorReason}:${retryAttempt}:${retryPrompt}`;
1364
+ if (this.providerErrorRetryTimer && this.providerErrorRetryKey === retryKey) return true;
1365
+
1366
+ if (this.providerErrorRetryTimer) clearTimeout(this.providerErrorRetryTimer);
1367
+ this.providerErrorRetryKey = retryKey;
1368
+ this.clearIdleFinishCandidate('provider_error_retry');
1369
+ if (this.idleTimeout) { clearTimeout(this.idleTimeout); this.idleTimeout = null; }
1370
+ if (this.approvalExitTimeout) { clearTimeout(this.approvalExitTimeout); this.approvalExitTimeout = null; }
1371
+ this.providerErrorMessage = typeof session.errorMessage === 'string' && session.errorMessage.trim()
1372
+ ? session.errorMessage.trim()
1373
+ : 'Provider reported an error';
1374
+ this.providerErrorReason = errorReason;
1375
+ this.activeModal = null;
1376
+ this.responseSettleIgnoreUntil = Date.now() + retryDelayMs + this.timeouts.outputSettle + 400;
1377
+ this.setStatus('generating', 'provider_error_retry_scheduled');
1378
+ this.recordTrace('provider_error_retry_scheduled', {
1379
+ retryPrompt,
1380
+ retryDelayMs,
1381
+ retryAttempt,
1382
+ retryMaxAttempts,
1383
+ errorReason,
1384
+ parsedStatus: ctx.parsedStatus || ctx.status,
1385
+ });
1386
+ this.onStatusChange?.();
1387
+ this.providerErrorRetryTimer = setTimeout(() => {
1388
+ this.providerErrorRetryTimer = null;
1389
+ this.providerErrorRetryKey = '';
1390
+ if (!this.ptyProcess) return;
1391
+ this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
1392
+ this.submitRetryUsed = false;
1393
+ this.recordTrace('provider_error_retry_write', {
1394
+ retryPrompt,
1395
+ retryAttempt,
1396
+ retryMaxAttempts,
1397
+ errorReason,
1398
+ });
1399
+ this.ptyProcess.write(`${retryPrompt}\r`);
1400
+ if (this.settleTimer) clearTimeout(this.settleTimer);
1401
+ this.settleTimer = setTimeout(() => {
1402
+ this.settleTimer = null;
1403
+ this.settledBuffer = this.recentOutputBuffer;
1404
+ this.evaluateSettled();
1405
+ }, this.timeouts.outputSettle + 150);
1406
+ }, retryDelayMs);
1407
+ return true;
1408
+ }
1409
+
1336
1410
  private applyIdle(ctx: SettledEvalContext, now: number): void {
1337
1411
  const { modal, lastParsedAssistant, prevStatus } = ctx;
1338
1412
  if (prevStatus === 'waiting_approval') {