sublayer 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0e73536f0855136d66096a10b35fe12acc7860e92b7c61a6408450716a7610d
4
- data.tar.gz: 7de63a9367edf5e27424e15200132024e6fbde702d76f36156a0a95cb1928194
3
+ metadata.gz: 05adf0abb1924f82c0e60a66265331c2b9cfead17a39114fc0dd9c395e5e00ff
4
+ data.tar.gz: 20a1dfdfbdec1bb59356736150dfc48e623838fc8807e13e743a08205a8d6105
5
5
  SHA512:
6
- metadata.gz: bf794d00c4704c474586a5c3943a704109516af3dec85d431c8b610fc38d90f574a95f7c72e8d3e15daaa6214ec236d362e2350c435073807ec92c25d6cf1215
7
- data.tar.gz: e5ec8d95d8966006830213a8d4058fbbf8679ae33353b41c25e5e3b620167226e760380961ae17f4adf4779d0920b7b5f60c7880c87800c1c908a3b99f763779
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
 
@@ -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.4"
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.
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.4
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-04-04 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
@@ -163,11 +163,13 @@ files:
163
163
  - lib/sublayer/providers/open_ai.rb
164
164
  - lib/sublayer/version.rb
165
165
  - sublayer.gemspec
166
- homepage: https://www.sublayer.com
166
+ homepage: https://docs.sublayer.com
167
167
  licenses:
168
168
  - MIT
169
169
  metadata:
170
- 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
171
173
  post_install_message:
172
174
  rdoc_options: []
173
175
  require_paths: