summaryrefslogtreecommitdiff
path: root/logic
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 /logic
parentab22d1bbe37093912cb7418b3c945153a15f4255 (diff)
adding support for tools
Diffstat (limited to 'logic')
-rw-r--r--logic/cartridge/adapters.rb2
-rw-r--r--logic/cartridge/affixes.rb2
-rw-r--r--logic/cartridge/default.rb4
-rw-r--r--logic/cartridge/fetch.rb24
-rw-r--r--logic/cartridge/interaction.rb14
-rw-r--r--logic/cartridge/tools.rb53
-rw-r--r--logic/providers/openai.rb57
-rw-r--r--logic/providers/openai/tools.rb70
8 files changed, 215 insertions, 11 deletions
diff --git a/logic/cartridge/adapters.rb b/logic/cartridge/adapters.rb
index bc8ddaf..4a3fadf 100644
--- a/logic/cartridge/adapters.rb
+++ b/logic/cartridge/adapters.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require_relative '../helpers/hash'
-require_relative './default'
+require_relative 'default'
module NanoBot
module Logic
diff --git a/logic/cartridge/affixes.rb b/logic/cartridge/affixes.rb
index 0b40fa2..bf94d92 100644
--- a/logic/cartridge/affixes.rb
+++ b/logic/cartridge/affixes.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require_relative '../helpers/hash'
-require_relative './default'
+require_relative 'default'
module NanoBot
module Logic
diff --git a/logic/cartridge/default.rb b/logic/cartridge/default.rb
index 43d45d4..24a8e7c 100644
--- a/logic/cartridge/default.rb
+++ b/logic/cartridge/default.rb
@@ -15,7 +15,7 @@ module NanoBot
return @values if @values
path = File.expand_path('../../static/cartridges/default.yml', __dir__)
- cartridge = YAML.safe_load(File.read(path), permitted_classes: [Symbol])
+ cartridge = YAML.safe_load_file(path, permitted_classes: [Symbol])
@values = Logic::Helpers::Hash.symbolize_keys(cartridge)
@values
end
@@ -24,7 +24,7 @@ module NanoBot
return @baseline if @baseline
path = File.expand_path('../../static/cartridges/baseline.yml', __dir__)
- cartridge = YAML.safe_load(File.read(path), permitted_classes: [Symbol])
+ cartridge = YAML.safe_load_file(path, permitted_classes: [Symbol])
@baseline = Logic::Helpers::Hash.symbolize_keys(cartridge)
@baseline
end
diff --git a/logic/cartridge/fetch.rb b/logic/cartridge/fetch.rb
new file mode 100644
index 0000000..2335358
--- /dev/null
+++ b/logic/cartridge/fetch.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require_relative 'default'
+require_relative '../helpers/hash'
+
+module NanoBot
+ module Logic
+ module Cartridge
+ module Fetch
+ def self.cascate(cartridge, paths)
+ results = paths.map { |path| Helpers::Hash.fetch(cartridge, path) }
+ result = results.find { |candidate| !candidate.nil? }
+ return result unless result.nil?
+
+ results = paths.map { |path| Helpers::Hash.fetch(Default.instance.values, path) }
+ result = results.find { |candidate| !candidate.nil? }
+ return result unless result.nil?
+
+ nil
+ end
+ end
+ end
+ end
+end
diff --git a/logic/cartridge/interaction.rb b/logic/cartridge/interaction.rb
index 160d818..5e8264e 100644
--- a/logic/cartridge/interaction.rb
+++ b/logic/cartridge/interaction.rb
@@ -1,9 +1,7 @@
# frozen_string_literal: true
-require 'sweet-moon'
-
-require_relative './affixes'
-require_relative './adapters'
+require_relative 'affixes'
+require_relative 'adapters'
module NanoBot
module Logic
@@ -12,23 +10,25 @@ module NanoBot
def self.input(cartridge, interface, content)
lua = Adapter.expression(cartridge, interface, :input, :lua)
fennel = Adapter.expression(cartridge, interface, :input, :fennel)
+ clojure = Adapter.expression(cartridge, interface, :input, :clojure)
prefix = Affixes.get(cartridge, interface, :input, :prefix)
suffix = Affixes.get(cartridge, interface, :input, :suffix)
- { content:, prefix:, suffix:, lua:, fennel: }
+ { content:, prefix:, suffix:, lua:, fennel:, clojure: }
end
def self.output(cartridge, interface, result, streaming, _finished)
if streaming
- result[:message] = { content: result[:message], lua: nil, fennel: nil }
+ result[:message] = { content: result[:message], lua: nil, fennel: nil, clojure: nil }
return result
end
lua = Adapter.expression(cartridge, interface, :output, :lua)
fennel = Adapter.expression(cartridge, interface, :output, :fennel)
+ clojure = Adapter.expression(cartridge, interface, :output, :clojure)
- result[:message] = { content: result[:message], lua:, fennel: }
+ result[:message] = { content: result[:message], lua:, fennel:, clojure: }
result
end
diff --git a/logic/cartridge/tools.rb b/logic/cartridge/tools.rb
new file mode 100644
index 0000000..6a45bf0
--- /dev/null
+++ b/logic/cartridge/tools.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require_relative 'fetch'
+require_relative 'affixes'
+require_relative 'adapters'
+
+module NanoBot
+ module Logic
+ module Cartridge
+ module Tools
+ def self.fetch_from_interface(cartridge, interface, action, path)
+ Fetch.cascate(cartridge, [
+ [:interfaces, interface, :tools, action].concat(path),
+ [:interfaces, :tools, action].concat(path),
+ %i[interfaces tools].concat(path)
+ ])
+ end
+
+ def self.feedback?(cartridge, interface, action)
+ Fetch.cascate(cartridge, [
+ [:interfaces, interface, :tools, action, :feedback],
+ [:interfaces, :tools, action, :feedback],
+ %i[interfaces tools feedback]
+ ])
+ end
+
+ def self.input(cartridge, interface, content)
+ lua = Adapter.expression(cartridge, interface, :input, :lua)
+ fennel = Adapter.expression(cartridge, interface, :input, :fennel)
+
+ prefix = Affixes.get(cartridge, interface, :input, :prefix)
+ suffix = Affixes.get(cartridge, interface, :input, :suffix)
+
+ { content:, prefix:, suffix:, lua:, fennel: }
+ end
+
+ def self.output(cartridge, interface, result, streaming, _finished)
+ if streaming
+ result[:message] = { content: result[:message], lua: nil, fennel: nil }
+ return result
+ end
+
+ lua = Adapter.expression(cartridge, interface, :output, :lua)
+ fennel = Adapter.expression(cartridge, interface, :output, :fennel)
+
+ result[:message] = { content: result[:message], lua:, fennel: }
+
+ result
+ end
+ end
+ end
+ end
+end
diff --git a/logic/providers/openai.rb b/logic/providers/openai.rb
new file mode 100644
index 0000000..00e7a43
--- /dev/null
+++ b/logic/providers/openai.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'json'
+
+module NanoBot
+ module Logic
+ module OpenAI
+ def self.prepare_tools(cartridge, tools)
+ applies = []
+ tools.each do |tool|
+ cartridge.each do |candidate|
+ next unless candidate[:type] == 'function' &&
+ tool[:type] == candidate[:type] &&
+ tool[:function][:name] == candidate[:name]
+
+ source = {}
+
+ source[:fennel] = candidate[:fennel] if candidate[:fennel]
+ source[:lua] = candidate[:lua] if candidate[:lua]
+
+ applies << {
+ name: tool[:function][:name],
+ type: candidate[:type],
+ parameters: JSON.parse(tool[:function][:arguments]),
+ source:
+ }
+ end
+ end
+
+ applies
+ end
+
+ def self.adapt_tool(cartridge)
+ raise 'unsupported tool' if cartridge[:type] != 'function'
+
+ adapted = {
+ type: 'function',
+ function: {
+ name: cartridge[:name], description: cartridge[:description],
+ parameters: { type: 'object', properties: {} }
+ }
+ }
+
+ properties = adapted[:function][:parameters][:properties]
+
+ cartridge[:parameters].each do |parameter|
+ key = parameter[:name].to_sym
+ properties[key] = {}
+ properties[key][:type] = parameter[:type] || 'string'
+ properties[key][:description] = parameter[:description] if parameter[:description]
+ end
+
+ adapted
+ end
+ end
+ end
+end
diff --git a/logic/providers/openai/tools.rb b/logic/providers/openai/tools.rb
new file mode 100644
index 0000000..080d81e
--- /dev/null
+++ b/logic/providers/openai/tools.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'json'
+
+require_relative '../../helpers/hash'
+
+module NanoBot
+ module Logic
+ module OpenAI
+ module Tools
+ def self.prepare(cartridge, tools)
+ applies = []
+ tools.each do |tool|
+ # TODO: Does this mutate the hash?
+ tool = Helpers::Hash.symbolize_keys(tool)
+
+ cartridge.each do |candidate|
+ next unless (
+ candidate[:type].nil? ||
+ (candidate[:type] == 'function' && tool[:type] == candidate[:type])
+ ) && tool[:function][:name] == candidate[:name]
+
+ source = {}
+
+ source[:clojure] = candidate[:clojure] if candidate[:clojure]
+ source[:fennel] = candidate[:fennel] if candidate[:fennel]
+ source[:lua] = candidate[:lua] if candidate[:lua]
+
+ applies << {
+ id: tool[:id],
+ name: tool[:function][:name],
+ type: candidate[:type] || 'function',
+ parameters: JSON.parse(tool[:function][:arguments]),
+ source:
+ }
+ end
+ end
+
+ applies
+ end
+
+ def self.adapt(cartridge)
+ raise 'unsupported tool' if cartridge[:type] != 'function' && !cartridge[:type].nil?
+
+ adapted = {
+ type: cartridge[:type] || 'function',
+ function: {
+ name: cartridge[:name], description: cartridge[:description],
+ parameters: { type: 'object', properties: {} }
+ }
+ }
+
+ properties = adapted[:function][:parameters][:properties]
+
+ adapted[:function][:parameters][:required] = cartridge[:required] if cartridge[:required]
+
+ cartridge[:parameters]&.each do |parameter|
+ key = parameter[:name].to_sym
+ properties[key] = {}
+ properties[key][:type] = parameter[:type] || 'string'
+ properties[key][:description] = parameter[:description] if parameter[:description]
+ properties[key][:items] = parameter[:items].slice(:type) if parameter[:items]
+ end
+
+ adapted
+ end
+ end
+ end
+ end
+end