This is a Rack-based chatbot with an implmentation-agnostic chat backend. Add it to your Gemfile, and with a little bit of code you'll be on your way to integrating chat into your Ruby app.
There are two main components for chatting: a component designed to act as a responsive sidebar and a component you can use in fullscreen fashion.
Install the gem and add it to your application's Gemfile by executing:
$ bundle add phlex-chatbot
If bundler is not being used to manage dependencies, install the gem by executing:
$ gem install phlex-chatbot
You will need to mount the chatbot app into your Rack application, which will differ depending on your host app's configuration.
In Rails, update your config/routes.rb
file by adding:
mount Phlex::Chatbot::Web, at: "/phlex-chatbot"
Create an initializer config/initializers/phlex_chatbot.rb
to set your logger:
Phlex::Chatbot.logger = Rails.logger
Phlex::Chatbot.conversator = ... <a subclass of Phlex::Chatbot::Conversator, see below>
Phlex::Chatbot.disallow_error_messages! # if you don't want Ruby error messages shown in the bot UI (default)
Phlex::Chatbot.allow_error_messages! # if you want Ruby error messages shown in the bot UI
In other Rack applications, you might do something like the following or consult your framework's specific instructions for mounting Rack apps:
map 'phlex-chatbot' do
use Phlex::Chatbot::Web
end
The path at which you host the chatbot is up to you, here we've named it phlex-chatbot
. Somewhere in
your application you will need to render the chatbot:
render Phlex::Chatbot::Chat::SidebarComponent.new(
conversation_token: token,
endpoint: "/phlex-chatbot",
)
render Phlex::Chatbot::Chat::FullScreenComponent.new(
conversation_token: token,
endpoint: "/phlex-chatbot",
)
The chat components receive the same set of arguments:
conversation_token
- the token received when creating your chatbot conversation (see below)endpoint
- the route at which you are hosting the chatbot (e.g./phlex-chatbot
)messages
- any messages you want to seed the chatbot with (i.e. an initial message for any session, or a history of messages if your application maintains such a thing)
To allow your users to have a conversation with the chatbot, your app will need to get a token:
token = Phlex::Chatbot::Switchboard.create(user.email_address)
Here we are passing the email address of a User
in the system as the application's identifier for this
conversation. The chatbot will encrypt and store that identifier and return the unique token to you. Later,
your application can use that token to interact with the chatbot: send it messages or status information,
and eventually terminate the conversation.
Your application is responsible for determining how to respond to that new message. Here is an example that
sends the chatbot a status message, processes the incoming message using langchainrb
and ruby-openai
, and
finally sends a final response.
Your application is responsible for setting the Phlex::Chatbot.conversator
which is a subclass of
Phlex::Chatbot::Conversator
. At a minimum, you should implement #call(bot, incoming_message, bot_id)
.
You can also implement the #contextualize
message that is responsible for adding more context to the mesasge
that gets sent to the bot's UI. Specifically, it should add the user_name
and avatar
keys to the message
hash (as symbols) based on whether the message is from the bot or the person with whom the bot is conversing.
The base implementation adds some basic defaults.
Phlex::Chatbot.conversator = Class.new(Phlex::Chatbot::Conversator) do
def call(bot, incoming_message, bot_id)
bot.send_status!(message: "I got your message, just a sec...")
llm = Langchain::LLM::OpenAI.new(api_key: ENV["OPENAI_API_KEY"])
chat = llm.chat(messages: [{ role: user.type, content: incoming_message }])
bot.send_response!(message: chat.chat_completion)
end
end
Phlex::Chatbot::Switchboard.create(user.email)
This example uses a custom class and the excellent Sequel library to do a full text search for the top 10 results matching the incoming message.
class FullTextSearch < Phlex::Chatbot::Conversator
SYSTEM_NAME = 'My Bot'
def call(bot, incoming_message, bot_id)
bot.send_status!(message: "Compiling results...")
terms = parse_terms(incoming_message)
if terms.empty?
bot.send_failure!(message: "you need to give me some terms")
else
results = DB[:fluberties].full_text_search(:borts, terms, rank: true).limit(10).select_map(:blobbities)
bot.send_response!(message: results.join(". "))
end
end
def contextualize(hash)
hash.merge!(user_name: SYSTEM_NAME) unless hash[:from_user]
hash
end
def self.parse_terms(incoming_message)
CSV.parse_line(incoming_message).compact.map(&:strip)
rescue
[]
end
end
Phlex::Chatbot::Switchboard.create(user.email)
You can converse with your chatbot in three ways:
#send_status!
- sends a status message that is displayed at the top of the bot's temporary response#send_response!
- sends a final message that replace's the bot's temporary response#send_failure!
- similar to#send_response!
this will replace the bot's temporary response but allows the UI to style the response differently, indicating to the user that something unexpected has occured
This message receives a String
which is broadcast to all chat subscribers. The chatbot will change the title
of the bot response placeholder with this message. It is expected that the "backend" will either broadcast
a final response or a failure at some point after this.
This message receives message: String
and sources: Array<String>
.
message: String
- the message you want to broadcast to all chat subscribers. Sources can be link with the pattern[1]
,[2]
,[3]
, etc. These text patterns will be replaced with the corresponding source from thesources
argument, if supplied. The links are one-based, not zero-based.sources: Array<String>
- links to source data in themessage
This message receives an Exception object. Its message
is broadcast to all chat subscribers. This will cause
the chatbot placeholder to be finalized with this message. No other response is needed after this point.
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update
the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for
the version, push git commits and the created tag, and push the .gem
file to rubygems.org.
While you are actively developing you'll likely want to watch for asset changes:
$ npm run watch-all
- edit
lib/phlex/chatbot/version.rb
- run
bundle install
(which will update the version in Gemfile.lock) - commit
- tag with new version
- push
- create a release in GitHub
Bug reports and pull requests are welcome on GitHub at https://github.com/hedgeyedev/phlex-chatbot.
The gem is available as open source under the terms of the MIT License.