All files / src/executor Executor.ts

85.71% Statements 12/14
87.5% Branches 7/8
66.66% Functions 2/3
91.66% Lines 11/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35          127x 127x           116x 119x 119x   5x     5x   5x 2x     3x           3x      
import { Provider, ChatRequest, ChatResponse } from "../providers/Provider.js";
import { RateLimitError, ServerError } from "../errors/index.js";
 
export class Executor {
  constructor(
    private readonly provider: Provider,
    private readonly retry: { attempts: number; delayMs: number }
  ) {}
 
  async executeChat(request: ChatRequest): Promise<ChatResponse> {
    let lastError: unknown;
 
    for (let attempt = 1; attempt <= this.retry.attempts; attempt++) {
      try {
        return await this.provider.chat(request);
      } catch (error) {
        lastError = error;
 
        // If it's a fatal error (BadRequest, Authentication), don't retry
        const isRetryable = error instanceof RateLimitError || error instanceof ServerError;
 
        if (!isRetryable || attempt >= this.retry.attempts) {
          throw error;
        }
 
        Iif (this.retry.delayMs > 0) {
          await new Promise((r) => setTimeout(r, this.retry.delayMs));
        }
      }
    }
 
    throw lastError;
  }
}