Conjure.Conversation (Conjure v0.1.1-alpha)
View SourceManages the tool-use conversation loop.
The conversation module orchestrates the back-and-forth between Claude and tool execution. When Claude responds with tool_use blocks, this module executes the tools and formats the results to send back.
Conversation Flow
User Message
│
▼
Call Claude API ◄────────────────┐
│ │
▼ │
Parse Response │
│ │
▼ │
┌──────────┐ Yes ┌─────────────────┐
│Tool Uses?│───────────►│ Execute Tools │
└──────────┘ └────────┬────────┘
│ No │
▼ ▼
Return Final Format Results
Response Add to Messages ──┘Example
{:ok, skills} = Conjure.load("/path/to/skills")
messages = [%{role: "user", content: "Read the PDF skill"}]
{:ok, final_messages} = Conjure.Conversation.run_loop(
messages,
skills,
&call_claude/1,
max_iterations: 10
)Manual Processing
For more control, use process_response/3 directly:
response = call_claude(messages)
case Conjure.Conversation.process_response(response, skills) do
{:done, text} ->
IO.puts(text)
{:continue, tool_results} ->
# Send results back to Claude
next_response = call_claude(add_tool_results(messages, response, tool_results))
end
Summary
Functions
Check if the response indicates conversation is complete.
Execute multiple tool calls.
Extract text content from Claude's response.
Extract tool_use blocks from Claude's response.
Format tool results for sending back to Claude.
Process Claude's response, executing any tool calls.
Run a complete conversation loop until completion or max iterations.
Types
Functions
@spec conversation_complete?(api_response()) :: boolean()
Check if the response indicates conversation is complete.
Returns true if there are no tool_use blocks.
@spec execute_tool_calls( [Conjure.ToolCall.t()], [Conjure.Skill.t()], module(), Conjure.ExecutionContext.t(), keyword() ) :: [Conjure.ToolResult.t()]
Execute multiple tool calls.
Executes in parallel using Task.async_stream for efficiency.
@spec extract_text(api_response()) :: String.t()
Extract text content from Claude's response.
@spec extract_tool_uses(api_response()) :: [Conjure.ToolCall.t()]
Extract tool_use blocks from Claude's response.
@spec format_tool_results_message([Conjure.ToolResult.t()]) :: message()
Format tool results for sending back to Claude.
Returns a message with role "user" containing tool_result blocks.
@spec process_response(api_response(), [Conjure.Skill.t()], keyword()) :: {:done, String.t()} | {:continue, [Conjure.ToolResult.t()]} | {:error, term()}
Process Claude's response, executing any tool calls.
Returns:
{:done, text}- No tool calls, conversation complete{:continue, tool_results}- Tool calls executed, send results back{:error, reason}- Processing failed
@spec run_loop( messages :: [message()], skills :: [Conjure.Skill.t()], api_callback :: ([message()] -> {:ok, api_response()} | {:error, term()}), opts :: keyword() ) :: {:ok, [message()]} | {:error, Conjure.Error.t()}
Run a complete conversation loop until completion or max iterations.
Takes a callback function that makes Claude API calls. The callback
receives the current messages list and should return {:ok, response}
or {:error, reason}.
Options
:max_iterations- Maximum tool-use loops (default: 25):executor- Executor module to use (default: Conjure.Executor.Local):context- ExecutionContext to use (created if not provided):on_tool_call- Callback for each tool callfn tool_call -> :ok end:on_tool_result- Callback for each tool resultfn result -> :ok end