# `LangChain.Message.ToolResult`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/message/tool_result.ex#L1)

Represents a the result of running a requested tool. The LLM's requests a tool
use through a `ToolCall`. A `ToolResult` returns the answer or result from the
application back to the AI.

## Content
The `content` can be a string or a list of ContentParts for multi-modal
responses (text, images, etc.) that gets returned to the LLM as the result.

## Processed Content
The `processed_content` field is optional. When you want to keep the results
of the Elixir function call as a native Elixir data structure,
`processed_content` can hold it.

Advanced use: You can use the `options` field for LLM-specific features like
cache control.

## Errors and rescued exceptions

`is_error` marks any failed result: a tool that returned `{:error, reason}`, a
tool call naming a tool that doesn't exist, a rejected human review, or a tool
that raised.

`is_exception` narrows that to results where LangChain rescued an exception, and
`exception` holds the `{exception, stacktrace}` pair it rescued. The exception is
never sent to the LLM — only the formatted message in `content` is — and it is
never persisted: `exception` is a virtual field, so a result restored from
storage carries `is_exception: true` with `exception: nil`. Code that needs the
exception itself should read it during the run, most conveniently through the
`:on_tool_execution_exception` callback.

Because `content` carries LangChain's formatted exception message and source
location, tools should not put secrets in exception messages.

## Message expansion

`message_expansion` holds a `LangChain.MessageExpansion`: a request to insert
messages into the conversation before the next LLM call, and to trim what this
result keeps once they are in. It is applied by
`LangChain.Chains.LLMChain.Mode.Steps.expand_tool_results/2`, so it does
nothing under a mode that does not compose that step. Like `interrupt_data` it
is virtual: it is never sent to the LLM and does not survive storage, which is
what keeps a restored conversation from inserting the same material twice.

To do this, the Elixir function's result should be a `{:ok, "String response
for LLM", native_elixir_data}`. See `LangChain.Function` for details and
examples.

# `t`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/message/tool_result.ex#L88)

```elixir
@type t() :: %LangChain.Message.ToolResult{
  content: term(),
  display_text: term(),
  exception: term(),
  interrupt_data: term(),
  is_error: term(),
  is_exception: term(),
  is_interrupt: term(),
  message_expansion: term(),
  name: term(),
  options: term(),
  processed_content: term(),
  tool_call_id: term(),
  type: term()
}
```

# `new`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/message/tool_result.ex#L112)

```elixir
@spec new(attrs :: map()) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
```

Build a new ToolResult and return an `:ok`/`:error` tuple with the result.

# `new!`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/message/tool_result.ex#L124)

```elixir
@spec new!(attrs :: map()) :: t() | no_return()
```

Build a new ToolResult and return it or raise an error if invalid.

---

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