sendChatRequest method
Future<Map<String, dynamic> >
sendChatRequest(
- List<
Map< messages,String, dynamic> > - List<
Map< ? tools, {String, dynamic> > - double? temperature,
- int? maxCompletionTokens,
- double? topP,
- bool? stream,
- String? reasoningEffort,
- dynamic stop,
- CancellationToken? cancellationToken,
override
Sends a single, complete chat request to the LLM.
Implementation
@override
Future<Map<String, dynamic>> sendChatRequest(
List<Map<String, dynamic>> messages,
List<Map<String, dynamic>>? tools, {
double? temperature,
int? maxCompletionTokens,
double? topP,
bool? stream,
String? reasoningEffort,
dynamic stop,
CancellationToken? cancellationToken,
}) async {
sdkLogger.info(
'Sending chat request to Anthropic (model: $model)',
tag: 'API',
extra: {
'model': model,
'message_count': messages.length,
'has_tools': tools != null && tools.isNotEmpty,
},
);
final anthropicData = _convertToAnthropicFormat(messages, tools);
final body = jsonEncode({
'model': model,
'max_tokens': maxCompletionTokens ?? maxTokens,
if (anthropicData['system'] != null) 'system': anthropicData['system'],
'messages': anthropicData['messages'],
if (anthropicData['tools'] != null) 'tools': anthropicData['tools'],
if ((temperature ?? this.temperature) != null)
'temperature': temperature ?? this.temperature,
});
const int maxRetries = 3;
const Duration baseDelay = Duration(seconds: 1);
for (int attempt = 1; attempt <= maxRetries; attempt++) {
if (cancellationToken?.isCancelled == true) {
throw VanturaCancellationException();
}
try {
final stopwatch = Stopwatch()..start();
final response = await _httpClient.post(
Uri.parse(baseUrl),
headers: _headers,
body: body,
);
stopwatch.stop();
sdkLogger.logPerformance(
'Anthropic API request ($model)',
stopwatch.elapsed,
context: {'status_code': response.statusCode},
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body) as Map<String, dynamic>;
return _convertFromAnthropicResponse(data);
} else if (response.statusCode == 429 || response.statusCode >= 500) {
if (attempt == maxRetries) {
throw VanturaApiException(
'Anthropic API error after $maxRetries attempts',
statusCode: response.statusCode,
responseBody: response.body,
);
}
final retrySeconds = attempt * 2;
sdkLogger.warning(
'Anthropic API hit ${response.statusCode}. Retrying in ${retrySeconds}s... (Attempt $attempt/$maxRetries)',
tag: 'API',
);
if (onRetry != null) {
onRetry!(
attempt,
Duration(seconds: retrySeconds),
'HTTP ${response.statusCode}',
);
}
await Future.delayed(Duration(seconds: retrySeconds));
continue;
} else {
throw VanturaApiException(
'Anthropic API error',
statusCode: response.statusCode,
responseBody: response.body,
);
}
} on http.ClientException catch (_) {
if (attempt == maxRetries) rethrow;
await Future.delayed(baseDelay * attempt);
}
}
throw Exception('Unexpected error in Anthropic request');
}