summaryrefslogtreecommitdiff
path: root/components/embedding.rb
diff options
context:
space:
mode:
authoricebaker <icebaker@proton.me>2023-11-18 19:07:10 -0300
committericebaker <icebaker@proton.me>2023-11-18 19:07:10 -0300
commit8ae78b954350755a47a13133668dba93bac15f37 (patch)
tree9cdc3bb770d778bd8d00675fdbc1f27a6e27e37c /components/embedding.rb
parentab22d1bbe37093912cb7418b3c945153a15f4255 (diff)
adding support for tools
Diffstat (limited to 'components/embedding.rb')
-rw-r--r--components/embedding.rb75
1 files changed, 75 insertions, 0 deletions
diff --git a/components/embedding.rb b/components/embedding.rb
new file mode 100644
index 0000000..c464244
--- /dev/null
+++ b/components/embedding.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+require 'sweet-moon'
+
+require 'open3'
+require 'json'
+require 'tempfile'
+
+module NanoBot
+ module Components
+ class Embedding
+ def self.lua(source:, parameters:, values:, safety:)
+ state = SweetMoon::State.new
+ # code = "_, embedded = pcall(load([[\nreturn function(#{parameters.join(', ')})\nreturn #{source}\nend\n]], nil, 't', {math=math,string=string,table=table}))"
+ code = "_, embedded = pcall(load([[\nreturn function(#{parameters.join(', ')})\n#{source}\nend\n]], nil, 't'))"
+
+ state.eval(code)
+ embedded = state.get(:embedded)
+ embedded.call(values)
+ end
+
+ def self.fennel(source:, parameters:, values:, safety:)
+ path = "#{File.expand_path('../static/fennel', __dir__)}/?.lua"
+ state = SweetMoon::State.new(package_path: path).fennel
+
+ # TODO: global is deprecated...
+ state.fennel.eval(
+ "(global embedded (fn [#{parameters.join(' ')}] #{source}))", 1,
+ safety ? { allowedGlobals: %w[math string table] } : nil
+ )
+ embedded = state.get(:embedded)
+ embedded.call(values)
+ end
+
+ def self.clojure(source:, parameters:, values:, safety:)
+ raise 'invalid Clojure parameter name' if parameters.include?('injected-parameters')
+
+ key_value = {}
+
+ parameters.each_with_index { |key, index| key_value[key] = values[index] }
+
+ parameters_json = key_value.to_json
+
+ json_file = Tempfile.new(['nano-bot', '.json'])
+ clojure_file = Tempfile.new(['nano-bot', '.clj'])
+
+ begin
+ json_file.write(parameters_json)
+ json_file.close
+
+ clojure_source = <<~CLOJURE
+ (require '[cheshire.core :as json])
+ (def injected-parameters (json/parse-string (slurp (java.io.FileReader. "#{json_file.path}"))))
+
+ #{parameters.map { |p| "(def #{p} (get injected-parameters \"#{p}\"))" }.join("\n")}
+
+ #{source}
+ CLOJURE
+
+ clojure_file.write(clojure_source)
+ clojure_file.close
+
+ bb_command = "bb --prn #{clojure_file.path} | bb -e \"(->> *in* slurp read-string print)\""
+
+ stdout, stderr, status = Open3.capture3(bb_command)
+
+ status.success? ? stdout : stderr
+ ensure
+ json_file&.unlink
+ clojure_file&.unlink
+ end
+ end
+ end
+ end
+end