class RubyLLM::Chat

def add_message(message_or_attributes)

def add_message(message_or_attributes)
  message = message_or_attributes.is_a?(Message) ? message_or_attributes : Message.new(message_or_attributes)
  messages << message
  message
end

def add_tool_result(tool_use_id, result)

def add_tool_result(tool_use_id, result)
  add_message(
    role: :tool,
    content: result.is_a?(Hash) && result[:error] ? result[:error] : result.to_s,
    tool_call_id: tool_use_id
  )
end

def ask(message, &block)

def ask(message, &block)
  add_message role: :user, content: message
  complete(&block)
end

def complete(&block)

def complete(&block)
  response = @provider.complete messages, tools: @tools, temperature: @temperature, model: @model.id, &block
  add_message response
  if response.tool_call?
    handle_tool_calls response, &block
  else
    response
  end
end

def each(&block)

def each(&block)
  messages.each(&block)
end

def ensure_valid_tools

def ensure_valid_tools
  tools.each_key do |name|
    unless name.is_a?(Symbol) && tools[name].is_a?(RubyLLM::Tool)
      raise Error, 'Tools should be of the format {<name.to_sym>: <RubyLLM::Tool>}'
    end
  end
end

def execute_tool(tool_call)

def execute_tool(tool_call)
  tool = tools[tool_call.name.to_sym]
  args = tool_call.arguments
  tool.call(args)
end

def handle_tool_calls(response, &block)

def handle_tool_calls(response, &block)
  response.tool_calls.each_value do |tool_call|
    result = execute_tool tool_call
    add_tool_result tool_call.id, result if result
  end
  complete(&block)
end

def initialize(model: nil)

def initialize(model: nil)
  model_id = model || RubyLLM.config.default_model
  @model = Models.find model_id
  @provider = Models.provider_for model_id
  @temperature = 0.7
  @messages = []
  @tools = {}
  ensure_valid_tools
end

def with_model(model_id)

def with_model(model_id)
  @model = Models.find model_id
  @provider = Models.provider_for model_id
  self
end

def with_temperature(temperature)

def with_temperature(temperature)
  @temperature = temperature
  self
end

def with_tool(tool)

def with_tool(tool)
  raise Error, "Model #{@model.id} doesn't support function calling" unless @model.supports_functions
  tool_instance = tool.is_a?(Class) ? tool.new : tool
  @tools[tool_instance.name.to_sym] = tool_instance
  self
end

def with_tools(*tools)

def with_tools(*tools)
  tools.each { |tool| with_tool tool }
  self
end