# `ReqLLM.Provider.Defaults.ResponseBuilder`
[🔗](https://github.com/agentjido/req_llm/blob/main/lib/req_llm/provider/defaults/response_builder.ex#L1)

Default ResponseBuilder implementation for OpenAI-compatible providers.

This module provides the standard Response assembly logic used by most
providers (OpenAI Chat API, xAI, Groq, Cerebras, OpenRouter, etc.).

Provider-specific builders can delegate to this implementation and then
apply their own post-processing, or override entirely.

## Responsibilities

1. Accumulate content from StreamChunks (text, thinking, tool_calls)
2. Merge fragmented tool call arguments
3. Normalize tool calls to `ToolCall` structs
4. Build `Message` with proper content parts
5. Construct final `Response` struct with metadata

## Usage

This is typically called via `ResponseBuilder.for_model/1`:

    builder = ResponseBuilder.for_model(model)
    {:ok, response} = builder.build_response(chunks, metadata, opts)

Or directly for OpenAI-compatible providers:

    {:ok, response} = Defaults.ResponseBuilder.build_response(chunks, metadata, opts)

# `build_content_parts`

```elixir
@spec build_content_parts(String.t(), String.t(), [ReqLLM.ToolCall.t()]) :: [
  ReqLLM.Message.ContentPart.t()
]
```

Build content parts from text, thinking, and tool calls.

Keep the original text and thinking content, including JSON text.
Structured values are extracted separately into `Response.object`.

# `normalize_tool_calls`

```elixir
@spec normalize_tool_calls([map() | ReqLLM.ToolCall.t()]) :: [ReqLLM.ToolCall.t()]
```

Normalize tool calls to `ToolCall` structs.

Accepts various input formats:
- `ToolCall` structs (passed through)
- Maps with atom keys `%{id:, name:, arguments:}`
- Maps with string keys `%{"id" =>, "name" =>, "arguments" =>}`

Arguments can be maps (encoded to JSON) or JSON strings (passed through).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
