diff options
author | icebaker <icebaker@proton.me> | 2023-11-18 19:07:10 -0300 |
---|---|---|
committer | icebaker <icebaker@proton.me> | 2023-11-18 19:07:10 -0300 |
commit | 8ae78b954350755a47a13133668dba93bac15f37 (patch) | |
tree | 9cdc3bb770d778bd8d00675fdbc1f27a6e27e37c /controllers/session.rb | |
parent | ab22d1bbe37093912cb7418b3c945153a15f4255 (diff) |
adding support for tools
Diffstat (limited to 'controllers/session.rb')
-rw-r--r-- | controllers/session.rb | 89 |
1 files changed, 65 insertions, 24 deletions
diff --git a/controllers/session.rb b/controllers/session.rb index 4694911..d20deb2 100644 --- a/controllers/session.rb +++ b/controllers/session.rb @@ -3,10 +3,13 @@ require 'babosa' require 'fileutils' +require 'rainbow' require_relative '../logic/helpers/hash' require_relative '../logic/cartridge/streaming' require_relative '../logic/cartridge/interaction' +require_relative '../logic/cartridge/fetch' +require_relative 'interfaces/tools' require_relative '../components/storage' require_relative '../components/adapter' require_relative '../components/crypto' @@ -41,9 +44,9 @@ module NanoBot end def load_state - @state = Logic::Helpers::Hash.symbolize_keys(JSON.parse( - Components::Crypto.decrypt(File.read(@state_path)) - )) + @state = Logic::Helpers::Hash.symbolize_keys( + JSON.parse(Components::Crypto.decrypt(File.read(@state_path))) + ) end def store_state! @@ -78,42 +81,78 @@ module NanoBot end def process(input, mode:) + interface = Logic::Helpers::Hash.fetch(@cartridge, [:interfaces, mode.to_sym]) || {} + + input[:interface] = interface + input[:tools] = @cartridge[:tools] + + needs_another_round = true + + # TODO: Improve infinite loop prevention. + needs_another_round = process_interaction(input, mode:) while needs_another_round + end + + def process_interaction(input, mode:) prefix = Logic::Cartridge::Affixes.get(@cartridge, mode.to_sym, :output, :prefix) suffix = Logic::Cartridge::Affixes.get(@cartridge, mode.to_sym, :output, :suffix) - interface = Logic::Helpers::Hash.fetch(@cartridge, [:interfaces, mode.to_sym]) || {} + color = Logic::Cartridge::Fetch.cascate(@cartridge, [ + [:interfaces, mode.to_sym, :output, :color], + %i[interfaces output color] + ]) - streaming = Logic::Cartridge::Streaming.enabled?(@cartridge, mode.to_sym) + color = color.to_sym if color - input[:interface] = interface + streaming = Logic::Cartridge::Streaming.enabled?(@cartridge, mode.to_sym) updated_at = Time.now ready = false - @provider.evaluate(input) do |output, finished| - updated_at = Time.now - - if finished - event = Marshal.load(Marshal.dump(output)) - output = Logic::Cartridge::Interaction.output( - @cartridge, mode.to_sym, output, streaming, finished - ) + needs_another_round = false - output[:message] = Components::Adapter.apply(:output, output[:message]) - - event[:mode] = mode.to_s - event[:output] = "#{prefix}#{output[:message]}#{suffix}" + @provider.evaluate(input) do |feedback| + updated_at = Time.now - @state[:history] << event + needs_another_round = true if feedback[:needs_another_round] - self.print(output[:message]) unless streaming + if feedback[:interaction] && feedback.dig(:interaction, :meta, :tool, :action) + Interfaces::Tool.dispatch_feedback(self, @cartridge, mode, feedback[:interaction][:meta][:tool]) + end - ready = true - flush - elsif streaming - self.print(output[:message]) + if feedback[:interaction] + event = Marshal.load(Marshal.dump(feedback[:interaction])) + event[:mode] = mode.to_s + event[:output] = nil + + if feedback[:interaction][:who] == 'AI' && feedback[:interaction][:message] + event[:output] = feedback[:interaction][:message] + unless streaming + output = Logic::Cartridge::Interaction.output( + @cartridge, mode.to_sym, feedback[:interaction], streaming, feedback[:finished] + ) + output[:message] = Components::Adapter.apply(:output, output[:message]) + event[:output] = (output[:message]).to_s + end + end + + @state[:history] << event if feedback[:should_be_stored] + if event[:output] && ((!feedback[:finished] && streaming) || (!streaming && feedback[:finished])) + # TODO: Color? + if color + self.print(Rainbow(event[:output]).send(color)) + else + self.print(event[:output]) + end + + flush if feedback[:finished] + end + + # `.print` already adds a prefix and suffix, so we add them after printing to avoid duplications. + event[:output] = "#{prefix}#{event[:output]}#{suffix}" end + + ready = true if feedback[:finished] end until ready @@ -122,6 +161,8 @@ module NanoBot end store_state! unless @stateless + + needs_another_round end def flush |