feat: API timeout config, Retry-After header support, and configurable retry

- Add TimeoutConfig to HTTP client builder with connect_timeout (30s)
  and request_timeout (5min) defaults, configurable via
  CLAW_API_CONNECT_TIMEOUT and CLAW_API_REQUEST_TIMEOUT env vars
- Add with_timeout() builder to both AnthropicClient and
  OpenAiCompatClient for per-client timeout configuration
- Parse Retry-After header on 429 responses and use it to override
  exponential backoff delay when present
- Add ApiTimeoutConfig to runtime config with apiTimeout settings
  in ~/.claw/settings.json (connectTimeout, requestTimeout, maxRetries)
- Add retry_after field to ApiError::Api for propagating rate limit
  backoff hints through the retry pipeline
This commit is contained in:
TheArchitectit
2026-04-27 11:38:31 -05:00
committed by Independent Security Research
parent c345ce6d02
commit ade8539846
8 changed files with 260 additions and 79 deletions

View File

@@ -10547,7 +10547,8 @@ mod tests {
body: String::new(),
retryable: true,
suggested_action: None,
};
retry_after: None,
};
let rendered = format_user_visible_api_error("session-issue-22", &error);
assert!(rendered.contains("provider_internal"));
@@ -10570,7 +10571,8 @@ mod tests {
body: String::new(),
retryable: true,
suggested_action: None,
}),
retry_after: None,
}),
};
let rendered = format_user_visible_api_error("session-issue-22", &error);
@@ -10634,7 +10636,8 @@ mod tests {
body: String::new(),
retryable: false,
suggested_action: None,
};
retry_after: None,
};
let rendered = format_user_visible_api_error("session-issue-32", &error);
assert!(rendered.contains("context_window_blocked"), "{rendered}");
@@ -10701,7 +10704,8 @@ mod tests {
body: String::new(),
retryable: false,
suggested_action: None,
}),
retry_after: None,
}),
};
let rendered = format_user_visible_api_error("session-issue-32", &error);