chatMessageFromParts function

ChatMessage chatMessageFromParts({
  1. String? text,
  2. List<FunctionCallResponse> calls = const [],
  3. String? thinking,
  4. Map<String, Object?> metadata = const {},
})

Coalesce a whole model turn into one ChatMessage.

Parts follow generation order: ThinkingPart → TextPart → ToolPart.call…. A preamble ("Let me check…") that accompanies a tool call is kept, not dropped — matching what chatMessageFromChunk emits on the streaming path.

callId mirrors toolName: flutter_gemma's tool protocol is name-keyed (FunctionCallResponse carries no independent id), so parallel calls to the same tool share a callId and callId is ignored when a result is fed back in.

Implementation

ChatMessage chatMessageFromParts({
  String? text,
  List<FunctionCallResponse> calls = const [],
  String? thinking,
  Map<String, Object?> metadata = const {},
}) {
  final parts = <StandardPart>[];
  if (thinking != null && thinking.isNotEmpty) {
    parts.add(ThinkingPart(thinking));
  }
  if (text != null && text.isNotEmpty) {
    parts.add(TextPart(text));
  }
  for (final c in calls) {
    parts.add(
      ToolPart.call(callId: c.name, toolName: c.name, arguments: c.args),
    );
  }
  return ChatMessage(
    role: ChatMessageRole.model,
    parts: parts,
    metadata: metadata,
  );
}