completeWithTools method
Like ChatModel.complete, but the model may answer with ChatResponse.toolCalls instead of (or as well as) text.
Implementation
@override
Future<ChatResponse> completeWithTools(
List<ChatMessage> messages, {
String? system,
int? maxTokens,
List<Tool> tools = const [],
}) async {
final json = await _http.postJson(
_endpoint,
_headers,
_body(
messages,
system,
maxTokens ?? this.maxTokens,
stream: false,
tools: tools,
),
);
final stop = json['stop_reason'] as String?;
// Check the stop reason before reading content: a refusal can come with
// empty or partial content.
if (stop == 'refusal') throw _refusal(json['stop_details']);
final text = StringBuffer();
final calls = <ToolCall>[];
for (final block in (json['content'] as List? ?? const [])) {
if (block is! Map) continue;
switch (block['type']) {
// Only text: thinking and fallback-marker blocks are not the answer.
case 'text':
text.write(block['text']);
case 'tool_use':
calls.add(
ToolCall(
id: '${block['id']}',
name: '${block['name']}',
input: decodeToolInput(block['input']),
),
);
}
}
return ChatResponse(
text.toString(),
stopReason: stop,
model: json['model'] as String?,
usage: _usage(json['usage']),
toolCalls: calls,
);
}