completeWithTools method

  1. @override
Future<ChatResponse> completeWithTools(
  1. List<ChatMessage> messages, {
  2. String? system,
  3. int? maxTokens,
  4. List<Tool> tools = const [],
})
override

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,
  );
}