sublayer 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3ad3ab932b7da063821a5f9047d6a58e895fb5db1b34ca71ef8a7742ccddd7dc
4
- data.tar.gz: ef15f73fd28e091667f1316f60b5b0c882240d1897f57b806e001dc3c885e3cf
3
+ metadata.gz: 05adf0abb1924f82c0e60a66265331c2b9cfead17a39114fc0dd9c395e5e00ff
4
+ data.tar.gz: 20a1dfdfbdec1bb59356736150dfc48e623838fc8807e13e743a08205a8d6105
5
5
  SHA512:
6
- metadata.gz: b606328f717c6312fde90b91b6bed4d58cacc0ae266199a6287b72f4da8aa0fcc3c01ffb28aff19043b81c2e7a3891e628db9c8f373cb14e359385e617e4bd76
7
- data.tar.gz: b4fec2575647858bae068d41117e5842438e5ec8d1e8303a12a613cec913b11d6b8ff261fd84d276b874c19c4f1aea0fef3d94748bbebc443134ba0cb84c91e8
6
+ metadata.gz: 9bc8be69c42f61099bd35163d7b15661cee6244fd5d26a7b1ca0d2cb6b4932c08ed57721a88def4ba2168a27d04080242c19d3c5282d0d9724826de4c1fc9a77
7
+ data.tar.gz: 7b3e0f0948534ac8313568d8318db2fac51a60467fb8d879d648bccd900ca67ff1dcb7757330f9c5348e69ce463e4376684959d154007365095abd290eea9cda
data/README.md CHANGED
@@ -1,16 +1,22 @@
1
1
  # Sublayer
2
2
 
3
- A model-agnostic Ruby Generative AI DSL and framework. Provides base classes for
3
+ A model-agnostic Ruby AI Agent framework. Provides base classes for
4
4
  building Generators, Actions, Tasks, and Agents that can be used to build AI
5
5
  powered applications in Ruby.
6
6
 
7
+ For more detailed documentation visit our documentation site: [https://docs.sublayer.com](https://docs.sublayer.com).
8
+
7
9
  ## Installation
8
10
 
9
11
  Install the gem by running the following commands:
10
12
 
11
- $ bundle
12
- $ gem build sublayer.gemspec
13
- $ gem install sublayer-0.0.1.gem
13
+ $ gem install sublayer
14
+
15
+ Or add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'sublayer'
19
+ ```
14
20
 
15
21
  ## Choose your AI Model
16
22
 
@@ -0,0 +1,6 @@
1
+ module Sublayer
2
+ module Actions
3
+ class Base
4
+ end
5
+ end
6
+ end
@@ -44,10 +44,9 @@ module Sublayer
44
44
  raise "Error generating with Claude, error: #{response.body}" unless response.code == 200
45
45
 
46
46
  text_containing_xml = JSON.parse(response.body).dig("content", 0, "text")
47
- xml = text_containing_xml.match(/\<response\>(.*?)\<\/response\>/m).to_s
48
- response_xml = ::Nokogiri::XML(xml)
49
- function_output = response_xml.at_xpath("//response/function_calls/invoke/parameters/#{output_adapter.name}").children.to_s
47
+ function_output = Nokogiri::HTML.parse(text_containing_xml.match(/\<#{output_adapter.name}\>(.*?)\<\/#{output_adapter.name}\>/m)[1]).text
50
48
 
49
+ raise "Claude did not format response, error: #{response.body}" unless function_output
51
50
  return function_output
52
51
  end
53
52
  end
@@ -5,21 +5,49 @@ module Sublayer
5
5
  module Providers
6
6
  class Gemini
7
7
  def self.call(prompt:, output_adapter:)
8
+ system_prompt = <<-PROMPT
9
+ You have access to a set of tools to answer the prompt.
10
+
11
+ You may call tools like this:
12
+ <tool_calls>
13
+ <tool_call>
14
+ <tool_name>$TOOL_NAME</tool_name>
15
+ <parameters>
16
+ <$PARAMETER_NAME>$VALUE</$PARAMETER_NAME>
17
+ ...
18
+ </parameters>
19
+ </tool_call>
20
+ </tool_calls>
21
+
22
+ Here are the tools available:
23
+ <tools>
24
+ <tool>
25
+ #{output_adapter.to_xml}
26
+ </tool>
27
+ </tools>
28
+
29
+ Respond only with valid xml.
30
+ The entire response should be wrapped in a <response> tag.
31
+ Your response should call a tool inside a <tool_calls> tag.
32
+ PROMPT
33
+
8
34
  response = HTTParty.post(
9
35
  "https://generativelanguage.googleapis.com/v1beta/models/#{Sublayer.configuration.ai_model}:generateContent?key=#{ENV['GEMINI_API_KEY']}",
10
36
  body: {
11
- tools: { function_declarations: [output_adapter.to_hash] },
12
- contents: { role: "user", parts: { text: prompt } }
37
+ contents: { role: "user", parts: { text: "#{system_prompt}\n#{prompt}" } }
13
38
  }.to_json,
14
39
  headers: {
15
40
  "Content-Type" => "application/json"
16
- })
41
+ }
42
+ )
43
+
44
+ raise "Error generating with Gemini, error: #{response.body}" unless response.success?
17
45
 
18
- part = response.dig('candidates', 0, 'content', 'parts', 0)
19
- raise "No function called" unless part['functionCall']
46
+ text_containing_xml = response.dig('candidates', 0, 'content', 'parts', 0, 'text')
47
+ tool_output = Nokogiri::HTML.parse(text_containing_xml.match(/\<#{output_adapter.name}\>(.*?)\<\/#{output_adapter.name}\>/m)[1]).text
20
48
 
21
- args = part['functionCall']['args']
22
- args[output_adapter.name]
49
+ raise "Gemini did not format response, error: #{response.body}" unless tool_output
50
+ return tool_output
23
51
  end
24
52
  end
25
53
  end
@@ -6,27 +6,27 @@ module Sublayer
6
6
  class Groq
7
7
  def self.call(prompt:, output_adapter:)
8
8
  system_prompt = <<-PROMPT
9
- In this environment you have access to a set of tools you can use to answer the user's question.
9
+ You have access to a set of tools to answer the prompt.
10
10
 
11
- You may call them like this:
12
- <function_calls>
13
- <invoke>
14
- <tool_name>$TOOL_NAME</tool_name>
15
- <parameters>
16
- <#{output_adapter.name}>value</#{output_adapter.name}>
17
- ...
18
- </parameters>
19
- </invoke>
20
- </function_calls>
11
+ You may call tools like this:
12
+ <tool_calls>
13
+ <tool_call>
14
+ <tool_name>$TOOL_NAME</tool_name>
15
+ <parameters>
16
+ <#{output_adapter.name}>$VALUE</#{output_adapter.name}>
17
+ ...
18
+ </parameters>
19
+ </tool_call>
20
+ </tool_calls>
21
21
 
22
22
  Here are the tools available:
23
23
  <tools>
24
- #{output_adapter.to_xml}
24
+ #{output_adapter.to_xml}
25
25
  </tools>
26
26
 
27
27
  Respond only with valid xml.
28
28
  The entire response should be wrapped in a <response> tag.
29
- Any additional information not inside a tool call should go in a <scratch> tag.
29
+ Your response should call a tool inside a <tool_calls> tag.
30
30
  PROMPT
31
31
 
32
32
  response = HTTParty.post(
@@ -41,12 +41,11 @@ module Sublayer
41
41
  }.to_json
42
42
  )
43
43
 
44
- text_containing_xml = JSON.parse(response.body).dig("choices", 0, "message", "content")
45
- xml = text_containing_xml.match(/\<response\>(.*?)\<\/response\>/m).to_s
46
- response_xml = ::Nokogiri::XML(xml)
47
- function_output = response_xml.at_xpath("//response/function_calls/invoke/parameters/command").children.to_s
44
+ text_containing_xml = response.dig("choices", 0, "message", "content")
45
+ tool_output = Nokogiri::HTML.parse(text_containing_xml.match(/\<#{output_adapter.name}\>(.*?)\<\/#{output_adapter.name}\>/m)[1]).text
46
+ raise "Groq did not format response correctly, error: #{response.body}" unless tool_output
48
47
 
49
- return function_output
48
+ return tool_output
50
49
  end
51
50
  end
52
51
  end
@@ -6,23 +6,23 @@ module Sublayer
6
6
  class Local
7
7
  def self.call(prompt:, output_adapter:)
8
8
  system_prompt = <<-PROMPT
9
- You are a function calling AI agent
10
- You can call only one function at a time
11
- You are provided with function signatures within <tools></tools> XML tags.
9
+ You have access to a set of tools to respond to the prompt.
12
10
 
13
- Please call a function and wait for results to be provided to you in the next iteration.
14
- Don't make assumptions about what values to plug into function arguments.
11
+ You may call a tool with xml like this:
12
+ <parameters>
13
+ <#{output_adapter.name}>$VALUE</#{output_adapter.name}>
14
+ ...
15
+ </parameters>
15
16
 
16
- Here are the available tools:
17
+ Here are descriptions of the available tools:
17
18
  <tools>
18
- #{output_adapter.to_hash.to_json}
19
+ <tool>
20
+ #{output_adapter.to_xml}
21
+ </tool>
19
22
  </tools>
20
23
 
21
- For the function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags as follows:
22
-
23
- <tool_call>
24
- {"arguments": <args-dict>, "name": <function-name>}
25
- </tool_call>
24
+ Respond only with valid xml.
25
+ Your response should call a tool with xml inside a <parameters> tag.
26
26
  PROMPT
27
27
 
28
28
  response = HTTParty.post(
@@ -34,17 +34,16 @@ module Sublayer
34
34
  body: {
35
35
  "model": Sublayer.configuration.ai_model,
36
36
  "messages": [
37
- { "role": "system", "content": system_prompt },
38
- { "role": "user", "content": prompt }
37
+ { "role": "user", "content": "#{system_prompt}\n#{prompt}}" }
39
38
  ]
40
39
  }.to_json
41
40
  )
42
41
 
43
- text_containing_xml = JSON.parse(response.body).dig("choices", 0, "message", "content")
44
- results = JSON.parse(::Nokogiri::XML(text_containing_xml).at_xpath("//tool_call").children.to_s.strip)
45
- function_output = results["arguments"][output_adapter.name]
42
+ text_containing_xml = response.dig("choices", 0, "message", "content")
43
+ tool_output = Nokogiri::HTML.parse(text_containing_xml.match(/\<#{output_adapter.name}\>(.*?)\<\/#{output_adapter.name}\>/m)[1]).text
44
+ raise "The response was not formatted correctly: #{response.body}" unless tool_output
46
45
 
47
- return function_output
46
+ return tool_output
48
47
  end
49
48
  end
50
49
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sublayer
4
- VERSION = "0.0.3"
4
+ VERSION = "0.0.5"
5
5
  end
data/sublayer.gemspec CHANGED
@@ -11,10 +11,12 @@ Gem::Specification.new do |spec|
11
11
 
12
12
  spec.summary = "A model-agnostic Ruby GenerativeAI DSL and Framework"
13
13
  spec.description = "A DSL and framework for building AI powered applications through the use of Generators, Actions, Tasks, and Agents"
14
- spec.homepage = "https://www.sublayer.com"
14
+ spec.homepage = "https://docs.sublayer.com"
15
15
  spec.required_ruby_version = ">= 2.6.0"
16
16
 
17
- spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["homepage_uri"] = "https://docs.sublayer.com"
18
+ spec.metadata["documentation_uri"] = "https://docs.sublayer.com"
19
+ spec.metadata["bug_tracker_uri"] = "https://github.com/sublayerapp/sublayer/issues"
18
20
 
19
21
  # Specify which files should be added to the gem when it is released.
20
22
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -36,4 +38,5 @@ Gem::Specification.new do |spec|
36
38
 
37
39
  spec.add_development_dependency "rspec", "~> 3.12"
38
40
  spec.add_development_dependency "pry", " ~> 0.14"
41
+ spec.add_development_dependency "clag"
39
42
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sublayer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Werner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-20 00:00:00.000000000 Z
11
+ date: 2024-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-openai
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0.14'
125
+ - !ruby/object:Gem::Dependency
126
+ name: clag
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  description: A DSL and framework for building AI powered applications through the
126
140
  use of Generators, Actions, Tasks, and Agents
127
141
  email:
@@ -138,6 +152,7 @@ files:
138
152
  - examples/description_from_code_generator.rb
139
153
  - examples/invalid_to_valid_json_generator.rb
140
154
  - lib/sublayer.rb
155
+ - lib/sublayer/actions/base.rb
141
156
  - lib/sublayer/components/output_adapters.rb
142
157
  - lib/sublayer/components/output_adapters/single_string.rb
143
158
  - lib/sublayer/generators/base.rb
@@ -148,11 +163,13 @@ files:
148
163
  - lib/sublayer/providers/open_ai.rb
149
164
  - lib/sublayer/version.rb
150
165
  - sublayer.gemspec
151
- homepage: https://www.sublayer.com
166
+ homepage: https://docs.sublayer.com
152
167
  licenses:
153
168
  - MIT
154
169
  metadata:
155
- homepage_uri: https://www.sublayer.com
170
+ homepage_uri: https://docs.sublayer.com
171
+ documentation_uri: https://docs.sublayer.com
172
+ bug_tracker_uri: https://github.com/sublayerapp/sublayer/issues
156
173
  post_install_message:
157
174
  rdoc_options: []
158
175
  require_paths: