Browse Source

chore: finalize PR #653 integration

Alvin Unreal 1 month ago
parent
commit
c8aa72c1b8

+ 4 - 0
src/hooks/foreground-fallback/index.test.ts

@@ -89,6 +89,10 @@ describe('isRateLimitError', () => {
     expect(isRateLimitError({ message: 'Insufficient balance.' })).toBe(true);
     expect(isRateLimitError({ message: 'Insufficient balance.' })).toBe(true);
   });
   });
 
 
+  test('returns true for "Service Unavailable"', () => {
+    expect(isRateLimitError({ message: 'Service Unavailable' })).toBe(true);
+  });
+
   test('returns true for "Monthly usage limit reached"', () => {
   test('returns true for "Monthly usage limit reached"', () => {
     expect(
     expect(
       isRateLimitError({
       isRateLimitError({

+ 3 - 0
src/hooks/foreground-fallback/index.ts

@@ -43,6 +43,9 @@ const RATE_LIMIT_PATTERNS = [
   /insufficient.?(quota|balance)/i,
   /insufficient.?(quota|balance)/i,
   /high concurrency/i,
   /high concurrency/i,
   /reduce concurrency/i,
   /reduce concurrency/i,
+  // ponytail: transient server errors mixed in; rename to isRetryableError
+  // and split from rate-limit detection when this list grows further
+  /service unavailable/i,
   /monthly usage limit/i,
   /monthly usage limit/i,
   /5-hour usage limit/i,
   /5-hour usage limit/i,
   /weekly usage limit/i,
   /weekly usage limit/i,

+ 3 - 3
src/tools/cancel-task.ts

@@ -126,12 +126,12 @@ Use only for obsolete, wrong, conflicting, or user-requested cancellation. Accep
       try {
       try {
         await abortAndVerifySession(options, job.taskID);
         await abortAndVerifySession(options, job.taskID);
       } catch (error) {
       } catch (error) {
-        const stillRunning =
-          error instanceof SessionStillRunningError ||
-          options.backgroundJobBoard.isRunning(job.taskID); // ponytail: intent-revealing query
+        const stillRunning = error instanceof SessionStillRunningError;
+        const boardRunning = options.backgroundJobBoard.isRunning(job.taskID);
         log('[cancel-task] abort failed', {
         log('[cancel-task] abort failed', {
           taskID: job.taskID,
           taskID: job.taskID,
           stillRunning,
           stillRunning,
+          boardRunning,
           error: error instanceof Error ? error.message : String(error),
           error: error instanceof Error ? error.message : String(error),
         });
         });
         options.backgroundJobBoard.updateStatus({
         options.backgroundJobBoard.updateStatus({

+ 6 - 0
src/utils/background-job-board.test.ts

@@ -742,6 +742,12 @@ describe('BackgroundJobBoard', () => {
         agent: 'fixer',
         agent: 'fixer',
         now: 100,
         now: 100,
       });
       });
+      board.registerLaunch({
+        taskID: 'terminal-1',
+        parentSessionID: 'parent-1',
+        agent: 'fixer',
+        now: 100,
+      });
       board.updateStatus({
       board.updateStatus({
         taskID: 'terminal-1',
         taskID: 'terminal-1',
         state: 'completed',
         state: 'completed',

+ 5 - 2
src/utils/background-job-board.ts

@@ -399,8 +399,11 @@ export class BackgroundJobBoard {
     for (const file of files) {
     for (const file of files) {
       const previous = existing.get(file.path);
       const previous = existing.get(file.path);
       if (previous) {
       if (previous) {
-        previous.lineCount = Math.max(previous.lineCount, file.lineCount);
-        previous.lastReadAt = Math.max(previous.lastReadAt, file.lastReadAt);
+        existing.set(file.path, {
+          ...previous,
+          lineCount: Math.max(previous.lineCount, file.lineCount),
+          lastReadAt: Math.max(previous.lastReadAt, file.lastReadAt),
+        });
       } else {
       } else {
         existing.set(file.path, { ...file });
         existing.set(file.path, { ...file });
       }
       }