patterns-ai-core / langchainrb

Build LLM-powered applications in Ruby
https://rubydoc.info/gems/langchainrb
MIT License
1.41k stars 195 forks source link

Using Langchain::Assistant with MistralAI throws an error when tool output is returned #839

Closed andreibondarev closed 3 weeks ago

andreibondarev commented 1 month ago

Describe the bug I believe when the role is equal to "tool" the Langchain::Assistant::Messages::MistralAIMessage#to_hash() is generating incorrect hash.

To Reproduce

llm = Langchain::LLM::MistralAI.new(api_key: ENV["MISTRAL_AI_API_KEY"])

assistant = Langchain::Assistant.new(
  llm: llm,
  instructions: "You're a helpful AI assistant",
  tools: [Langchain::Tool::NewsRetriever.new(api_key: ENV["NEWS_API_KEY"])]
)

# Add a user message and run the assistant
assistant.add_message_and_run!(content: "What's the latest news about AI?")

Actual behavior Error is thrown:

/Users/andrei/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/faraday-2.12.0/lib/faraday/response/raise_error.rb:30:in `on_complete': the server responded with status 422 (Faraday::UnprocessableEntityError)
    from /Users/andrei/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/faraday-2.12.0/lib/faraday/middleware.rb:57:in `block in call'
    from /Users/andrei/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/faraday-2.12.0/lib/faraday/response.rb:42:in `on_complete'
    from /Users/andrei/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/faraday-2.12.0/lib/faraday/middleware.rb:56:in `call'
    from /Users/andrei/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/faraday-2.12.0/lib/faraday/rack_builder.rb:152:in `build_response'
    from /Users/andrei/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/faraday-2.12.0/lib/faraday/connection.rb:452:in `run_request'
    from /Users/andrei/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/faraday-2.12.0/lib/faraday/connection.rb:280:in `post'
    from /Users/andrei/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/mistral-ai-1.2.0/controllers/client.rb:75:in `request'
    from /Users/andrei/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/mistral-ai-1.2.0/controllers/client.rb:48:in `chat_completions'
    from /Users/andrei/Code/langchain/lib/langchain/llm/mistral_ai.rb:40:in `chat'
    from /Users/andrei/Code/langchain/lib/langchain/assistant.rb:347:in `chat_with_llm'
    from /Users/andrei/Code/langchain/lib/langchain/assistant.rb:302:in `handle_user_or_tool_message'
    from /Users/andrei/Code/langchain/lib/langchain/assistant.rb:269:in `process_latest_message'
    from /Users/andrei/Code/langchain/lib/langchain/assistant.rb:251:in `handle_state'
    from /Users/andrei/Code/langchain/lib/langchain/assistant.rb:142:in `run'
    from /Users/andrei/Code/langchain/lib/langchain/assistant.rb:161:in `add_message_and_run'
    from /Users/andrei/Code/langchain/lib/langchain/assistant.rb:169:in `add_message_and_run!'
    ... 3 levels...

Expected behavior An error is not thrown.

Note From the Mistral AI docs: image

I believe we're sending content: [...] but it expects a string back.

andreibondarev commented 1 month ago

I think it would be great to also split to_hash methods into:

def to_user_hash
end

def to_system_hash
end

def to_assistant_hash
end

def to_tool_hash
end