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 +4 -4
- data/README.md +10 -4
- data/lib/sublayer/actions/base.rb +6 -0
- data/lib/sublayer/providers/claude.rb +2 -3
- data/lib/sublayer/providers/gemini.rb +35 -7
- data/lib/sublayer/providers/groq.rb +17 -18
- data/lib/sublayer/providers/local.rb +17 -18
- data/lib/sublayer/version.rb +1 -1
- data/sublayer.gemspec +5 -2
- metadata +21 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05adf0abb1924f82c0e60a66265331c2b9cfead17a39114fc0dd9c395e5e00ff
|
4
|
+
data.tar.gz: 20a1dfdfbdec1bb59356736150dfc48e623838fc8807e13e743a08205a8d6105
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
$
|
12
|
-
|
13
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
19
|
-
|
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
|
-
|
22
|
-
|
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
|
-
|
9
|
+
You have access to a set of tools to answer the prompt.
|
10
10
|
|
11
|
-
You may call
|
12
|
-
<
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
</
|
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
|
-
|
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
|
-
|
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 =
|
45
|
-
|
46
|
-
|
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
|
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
|
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
|
-
|
14
|
-
|
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
|
-
|
19
|
+
<tool>
|
20
|
+
#{output_adapter.to_xml}
|
21
|
+
</tool>
|
19
22
|
</tools>
|
20
23
|
|
21
|
-
|
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": "
|
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 =
|
44
|
-
|
45
|
-
|
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
|
46
|
+
return tool_output
|
48
47
|
end
|
49
48
|
end
|
50
49
|
end
|
data/lib/sublayer/version.rb
CHANGED
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://
|
14
|
+
spec.homepage = "https://docs.sublayer.com"
|
15
15
|
spec.required_ruby_version = ">= 2.6.0"
|
16
16
|
|
17
|
-
spec.metadata["homepage_uri"] =
|
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.
|
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-
|
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://
|
166
|
+
homepage: https://docs.sublayer.com
|
152
167
|
licenses:
|
153
168
|
- MIT
|
154
169
|
metadata:
|
155
|
-
homepage_uri: https://
|
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:
|