Skip to content

Commit

Permalink
Merge pull request #45 from merefield/optional_inner_thoughts_in_pms
Browse files Browse the repository at this point in the history
FEATURE: Add optional inner thought output in PMs (EXPERIMENTAL)
  • Loading branch information
merefield authored Sep 19, 2023
2 parents 5e830fc + 0571155 commit 86a2ed8
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 26 deletions.
5 changes: 3 additions & 2 deletions app/jobs/regular/chatbot_reply_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def execute(opts)
elsif type == ::DiscourseChatbot::POST && post
message_body = nil
is_private_msg = post.topic.private_message?
opts.merge!(is_private_msg: is_private_msg)

permitted_categories = SiteSetting.chatbot_permitted_categories.split('|')

Expand Down Expand Up @@ -79,13 +80,13 @@ def execute(opts)
else
bot = ::DiscourseChatbot::OpenAIBot.new
end
message_body = bot.ask(opts)
reply_and_thoughts = bot.ask(opts)
rescue => e
Rails.logger.error ("OpenAIBot: There was a problem, but will retry til limit: #{e}")
fail e
end
end
opts.merge!(message_body: message_body)
opts.merge!(reply_and_thoughts)
if type == ::DiscourseChatbot::POST
reply_creator = ::DiscourseChatbot::PostReplyCreator.new(opts)
else
Expand Down
1 change: 1 addition & 0 deletions config/locales/server.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ en:
chatbot_max_look_behind: "Maximum number of Posts or Chat Messages bot will consider as prompt for completion, the more the more impressive may be its response, but the more costly the interaction will be."
chatbot_strip_quotes: "Determine if quotes are stripped and not sent within prompts (doesn't affect OP)"
chatbot_permitted_in_private_messages: "Allow Chatbot to interact in Private Messages"
chatbot_include_inner_thoughts_in_private_messages: "EXPERIMENTAL: Get Chatbot to post its background thinking on Private Messages (Agent only)"
chatbot_permitted_in_chat: "Allow Chatbot to interact in Chat"
chatbot_can_trigger_from_whisper: "Allow Chatbot to be triggered from a whisper (get creative!)"
chatbot_permitted_all_categories: "Allow Chatbot to interact in any Category"
Expand Down
3 changes: 3 additions & 0 deletions config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ plugins:
chatbot_permitted_in_private_messages:
default: true
client: true
chatbot_include_inner_thoughts_in_private_messages:
default: false
client: false
chatbot_permitted_in_chat:
default: true
client: true
Expand Down
18 changes: 10 additions & 8 deletions lib/discourse_chatbot/bots/open_ai_agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ def generate_response
# Iteration: #{iteration}
-------------------------------
EOS
res = create_chat_completion(@chat_history + @internal_thoughts)
res = create_chat_completion(@chat_history + @inner_thoughts)
finish_reason = res["choices"][0]["finish_reason"]

if finish_reason == 'stop' || @internal_thoughts.length > 5
if finish_reason == 'stop' || @inner_thoughts.length > 5
final_thought = final_thought_answer
final_res = create_chat_completion(
@chat_history + [final_thought],
Expand All @@ -102,12 +102,12 @@ def generate_response

def handle_function_call(res)
first_message = res["choices"][0]["message"]
@internal_thoughts << first_message.to_hash
@inner_thoughts << first_message.to_hash
func_name = first_message["function_call"]["name"]
args_str = first_message["function_call"]["arguments"]
result = call_function(func_name, args_str)
res_msg = { 'role' => 'function', 'name' => func_name, 'content' => I18n.t("chatbot.prompt.agent.handle_function_call.answer", result: result) }
@internal_thoughts << res_msg
@inner_thoughts << res_msg
end

def call_function(func_name, args_str)
Expand All @@ -128,7 +128,7 @@ def call_function(func_name, args_str)

def final_thought_answer
thoughts = I18n.t("chatbot.prompt.agent.final_thought_answer.opener")
@internal_thoughts.each do |thought|
@inner_thoughts.each do |thought|
if thought.key?('function_call')
thoughts += I18n.t("chatbot.prompt.agent.final_thought_answer.thought_declaration", function_name: thought['function_call']['name'], arguments: thought['function_call']['arguments'])
else
Expand All @@ -148,14 +148,16 @@ def get_response(prompt)
system_message = { "role": "system", "content": I18n.t("chatbot.prompt.system.agent", current_date_time: DateTime.current) }
prompt.unshift(system_message)

@internal_thoughts = []
@inner_thoughts = []

@chat_history += prompt

res = generate_response

@chat_history << res["choices"][0]["message"].to_hash
res["choices"][0]["message"]["content"]
{
reply: res["choices"][0]["message"]["content"],
inner_thoughts: @inner_thoughts.to_s
}
end

def ask(opts)
Expand Down
30 changes: 18 additions & 12 deletions lib/discourse_chatbot/post/post_reply_creator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,36 @@ def initialize(options = {})
def create
::DiscourseChatbot.progress_debug_message("5. Creating a new Post...")

begin
default_opts = {
raw: @message_body,
topic_id: @topic_or_channel_id,
post_alert_options: { skip_send_email: true },
skip_validations: true
}

default_opts.merge!(reply_to_post_number: @reply_to_post_number) unless SiteSetting.chatbot_can_trigger_from_whisper
if SiteSetting.chatbot_bot_type == "agent" && SiteSetting.chatbot_include_inner_thoughts_in_private_messages && @is_private_msg
default_opts.merge!(raw: '[details="Inner Thoughts"]<br/>' + @inner_thoughts + '<br/>[/details]')

begin
new_post = PostCreator.create!(@author, default_opts)
end

is_private_msg = new_post.topic.private_message?
default_opts.merge!(reply_to_post_number: @reply_to_post_number) unless SiteSetting.chatbot_can_trigger_from_whisper
default_opts.merge!(raw: @message_body)

if is_private_msg
presence = PresenceChannel.new("/discourse-presence/reply/#{@topic_or_channel_id}")
presence.leave(user_id: @author.id, client_id: "12345")
end
new_post = PostCreator.create!(@author, default_opts)

::DiscourseChatbot.progress_debug_message("6. The Post has been created successfully")
rescue => e
::DiscourseChatbot.progress_debug_message("Problem with the bot Post: #{e}")
Rails.logger.error ("AI Bot: There was a problem: #{e}")
is_private_msg = new_post.topic.private_message?

if is_private_msg
presence = PresenceChannel.new("/discourse-presence/reply/#{@topic_or_channel_id}")
presence.leave(user_id: @author.id, client_id: "12345")
end

::DiscourseChatbot.progress_debug_message("6. The Post has been created successfully")
rescue => e
::DiscourseChatbot.progress_debug_message("Problem with the bot Post: #{e}")
Rails.logger.error ("AI Bot: There was a problem: #{e}")
end
end
end
end
4 changes: 3 additions & 1 deletion lib/discourse_chatbot/reply_creator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ def initialize(options = {})
@reply_to = options[:reply_to_message_or_post_id]
@reply_to_post_number = options[:original_post_number]
@topic_or_channel_id = options[:topic_or_channel_id]
@message_body = options[:message_body]
@message_body = options[:reply]
@is_private_msg = options[:is_private_msg]
@inner_thoughts = options[:inner_thoughts]
if @message_body.blank?
@message_body = '...'
end
Expand Down
4 changes: 2 additions & 2 deletions plugin.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true
# name: discourse-chatbot
# about: a plugin that allows you to have a conversation with a configurable chatbot in Discourse Chat, Topics and Private Messages
# version: 0.44
# version: 0.45
# authors: merefield
# url: https://github.com/merefield/discourse-chatbot

Expand All @@ -24,7 +24,7 @@ module ::DiscourseChatbot
POST_TYPES_REGULAR_ONLY = [1]
POST_TYPES_INC_WHISPERS = [1, 4]
EMBEDDING_MODEL = "text-embedding-ada-002".freeze
EMBEDDING_CHAR_LIMIT = 13250
EMBEDDING_CHAR_LIMIT = 12500

def progress_debug_message(message)
if SiteSetting.chatbot_enable_verbose_console_response_progress_logging
Expand Down
2 changes: 1 addition & 1 deletion spec/lib/bot/open_ai_agent_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
::DiscourseChatbot::OpenAIAgent.any_instance.expects(:create_chat_completion).with(second_query).returns(llm_interim_response)
::DiscourseChatbot::OpenAIAgent.any_instance.expects(:create_chat_completion).with(final_query, false).returns(llm_final_response)

expect(agent.get_response(query)).to eq(llm_final_response["choices"][0]["message"]["content"])
expect(agent.get_response(query)[:reply]).to eq(llm_final_response["choices"][0]["message"]["content"])
end
end

0 comments on commit 86a2ed8

Please sign in to comment.