sublayer 0.2.3 → 0.2.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/bin/sublayer +5 -0
- data/lib/sublayer/cli/commands/action.rb +65 -0
- data/lib/sublayer/cli/commands/agent.rb +79 -0
- data/lib/sublayer/cli/commands/generator.rb +68 -0
- data/lib/sublayer/cli/commands/generators/example_action_api_call.rb +23 -0
- data/lib/sublayer/cli/commands/generators/example_action_file_manipulation.rb +12 -0
- data/lib/sublayer/cli/commands/generators/example_agent.rb +33 -0
- data/lib/sublayer/cli/commands/generators/example_generator.rb +26 -0
- data/lib/sublayer/cli/commands/generators/sublayer_action_generator.rb +55 -0
- data/lib/sublayer/cli/commands/generators/sublayer_agent_generator.rb +61 -0
- data/lib/sublayer/cli/commands/generators/sublayer_generator_generator.rb +96 -0
- data/lib/sublayer/cli/commands/new_project.rb +116 -0
- data/lib/sublayer/cli/commands/subcommand_base.rb +13 -0
- data/lib/sublayer/cli/templates/cli/%project_name%.gemspec.tt +35 -0
- data/lib/sublayer/cli/templates/cli/.gitignore +14 -0
- data/lib/sublayer/cli/templates/cli/Gemfile +7 -0
- data/lib/sublayer/cli/templates/cli/README.md.tt +22 -0
- data/lib/sublayer/cli/templates/cli/bin/%project_name%.tt +5 -0
- data/lib/sublayer/cli/templates/cli/lib/%project_name%/actions/example_action.rb.tt +15 -0
- data/lib/sublayer/cli/templates/cli/lib/%project_name%/agents/example_agent.rb.tt +21 -0
- data/lib/sublayer/cli/templates/cli/lib/%project_name%/cli.rb.tt +13 -0
- data/lib/sublayer/cli/templates/cli/lib/%project_name%/commands/base_command.rb.tt +21 -0
- data/lib/sublayer/cli/templates/cli/lib/%project_name%/commands/example_command.rb.tt +13 -0
- data/lib/sublayer/cli/templates/cli/lib/%project_name%/config/.keep +0 -0
- data/lib/sublayer/cli/templates/cli/lib/%project_name%/config.rb.tt +19 -0
- data/lib/sublayer/cli/templates/cli/lib/%project_name%/generators/example_generator.rb.tt +25 -0
- data/lib/sublayer/cli/templates/cli/lib/%project_name%/version.rb.tt +5 -0
- data/lib/sublayer/cli/templates/cli/lib/%project_name%.rb.tt +21 -0
- data/lib/sublayer/cli/templates/cli/spec/.keep +0 -0
- data/lib/sublayer/cli/templates/quick_script/%project_name%.rb +7 -0
- data/lib/sublayer/cli/templates/quick_script/README.md.tt +16 -0
- data/lib/sublayer/cli/templates/quick_script/actions/example_action.rb +11 -0
- data/lib/sublayer/cli/templates/quick_script/agents/example_agent.rb +17 -0
- data/lib/sublayer/cli/templates/quick_script/generators/example_generator.rb +21 -0
- data/lib/sublayer/cli.rb +59 -0
- data/lib/sublayer/components/output_adapters/formattable.rb +1 -0
- data/lib/sublayer/components/output_adapters/list_of_named_strings.rb +48 -0
- data/lib/sublayer/components/output_adapters/named_strings.rb +3 -1
- data/lib/sublayer/components/output_adapters/single_integer.rb +25 -0
- data/lib/sublayer/providers/gemini.rb +10 -22
- data/lib/sublayer/version.rb +1 -1
- data/lib/sublayer.rb +1 -1
- data/sublayer.gemspec +3 -3
- metadata +46 -36
@@ -0,0 +1,13 @@
|
|
1
|
+
module Sublayer
|
2
|
+
module Commands
|
3
|
+
class SubCommandBase < Thor
|
4
|
+
def self.banner(command, namespace = nil, subcommand = false)
|
5
|
+
"#{basename} #{subcommand_prefix} #{command.usage}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.subcommand_prefix
|
9
|
+
self.name.gsub(%r{.*::}, '').gsub(%r{^[A-Z]}) { |match| match[0].downcase }.gsub(%r{[A-Z]}) { |match| "-#{match[0].downcase}" }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative "lib/<%= project_name.gsub("-", "_") %>/version"
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "<%= project_name %>"
|
5
|
+
spec.version = <%= project_name.camelize %>::VERSION
|
6
|
+
spec.authors = ["Your Name"]
|
7
|
+
spec.email = ["your.email@example.com"]
|
8
|
+
|
9
|
+
spec.summary = "Summary of your project"
|
10
|
+
spec.description = "Longer description of your project"
|
11
|
+
spec.homepage = "https://github.com/yourusername/<%= project_name %>"
|
12
|
+
spec.license = "MIT"
|
13
|
+
spec.required_ruby_version = ">= 2.6.0"
|
14
|
+
|
15
|
+
spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
|
16
|
+
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
+
spec.metadata["source_code_uri"] = "https://github.com/yourusername/<%= project_name %>"
|
19
|
+
spec.metadata["changelog_uri"] = "https://github.com/yourusername/<%= project_name %>/blob/master/CHANGELOG.md"
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
25
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
26
|
+
end
|
27
|
+
end
|
28
|
+
spec.bindir = "bin"
|
29
|
+
spec.executables = spec.files.grep(%r{\Abin/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
# Add dependencies here
|
33
|
+
spec.add_dependency "sublayer", "~> <%= sublayer_version %>"
|
34
|
+
spec.add_dependency "thor", "~> 1.2"
|
35
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# <%= project_name %>
|
2
|
+
|
3
|
+
Welcome to your new Sublayer CLI project!
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Execute:
|
8
|
+
|
9
|
+
$ bundle install
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
To run your CLI application:
|
14
|
+
|
15
|
+
```
|
16
|
+
$ bin/<%= project_name %>
|
17
|
+
```
|
18
|
+
|
19
|
+
Available commands:
|
20
|
+
- `example`: Run the example generator
|
21
|
+
- `help`: Display the help message
|
22
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module <%= project_name.camelize %>
|
4
|
+
module Actions
|
5
|
+
class ExampleAction < Sublayer::Actions::Base
|
6
|
+
def initialize(input:)
|
7
|
+
@input = input
|
8
|
+
end
|
9
|
+
|
10
|
+
def call
|
11
|
+
puts "Performing action with input: #{@input}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module <%= project_name.camelize %>
|
4
|
+
module Agents
|
5
|
+
class ExampleAgent < Sublayer::Agents::Base
|
6
|
+
trigger_on_files_changed { ["example_file.txt"] }
|
7
|
+
|
8
|
+
goal_condition { @goal_reached }
|
9
|
+
|
10
|
+
check_status do
|
11
|
+
@status_checked = true
|
12
|
+
end
|
13
|
+
|
14
|
+
step do
|
15
|
+
@step_taken = true
|
16
|
+
@goal_reached = true
|
17
|
+
puts "Example agent step executed"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module <%= project_name.camelize %>
|
4
|
+
class CLI < Thor
|
5
|
+
<%= project_name.camelize %>::Commands.constants.reject{ |command_class| command_class == :BaseCommand }.each do |command_class|
|
6
|
+
command = <%= project_name.camelize %>::Commands.const_get(command_class)
|
7
|
+
desc command.command_name, command.description
|
8
|
+
define_method(command.command_name) do |*args|
|
9
|
+
command.new(options).execute(*args)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module <%= project_name.camelize %>
|
2
|
+
module Commands
|
3
|
+
class BaseCommand
|
4
|
+
def self.command_name
|
5
|
+
name.split("::").last.gsub(/Command$/, '').downcase
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.description
|
9
|
+
"Description for #{command_name}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(options)
|
13
|
+
@options = options
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute(*args)
|
17
|
+
raise NotImplementedError, "#{self.class} must implement #execute"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module <%= project_name.camelize %>
|
2
|
+
module Commands
|
3
|
+
class ExampleCommand < BaseCommand
|
4
|
+
def self.description
|
5
|
+
"An example command that generates a story based on the command line arguments."
|
6
|
+
end
|
7
|
+
|
8
|
+
def execute(*args)
|
9
|
+
puts <%= project_name.camelize %>::Generators::ExampleGenerator.new(input: args.join(" ")).generate
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
File without changes
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module <%= project_name.camelize %>
|
2
|
+
module Config
|
3
|
+
def self.load
|
4
|
+
config_path = File.join(File.dirname(__FILE__), "config", "sublayer.yml")
|
5
|
+
|
6
|
+
if File.exist?(config_path)
|
7
|
+
config = YAML.load_file(config_path)
|
8
|
+
|
9
|
+
Sublayer.configure do |c|
|
10
|
+
c.ai_provider = Object.const_get("Sublayer::Providers::#{config[:ai_provider]}")
|
11
|
+
c.ai_model = config[:ai_model]
|
12
|
+
c.logger = Sublayer::Logging::JsonLogger.new(File.join(Dir.pwd, 'log', 'sublayer.log'))
|
13
|
+
end
|
14
|
+
else
|
15
|
+
puts "Warning: config/sublayer.yml not found. Using default configuration."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module <%= project_name.camelize %>
|
4
|
+
module Generators
|
5
|
+
class ExampleGenerator < Sublayer::Generators::Base
|
6
|
+
llm_output_adapter type: :single_string,
|
7
|
+
name: "generated_text",
|
8
|
+
description: "A simple generated text"
|
9
|
+
|
10
|
+
def initialize(input:)
|
11
|
+
@input = input
|
12
|
+
end
|
13
|
+
|
14
|
+
def generate
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def prompt
|
19
|
+
<<-PROMPT
|
20
|
+
Generate a simple story based on this input: #{@input}
|
21
|
+
PROMPT
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "thor"
|
3
|
+
require "sublayer"
|
4
|
+
require_relative "<%= project_name.gsub("-", "_") %>/version"
|
5
|
+
require_relative "<%= project_name.gsub("-", "_") %>/config"
|
6
|
+
|
7
|
+
Dir[File.join(__dir__, "<%= project_name.gsub("-", "_") %>", "commands", "*.rb")].each { |file| require file }
|
8
|
+
Dir[File.join(__dir__, "<%= project_name.gsub("-", "_") %>", "generators", "*.rb")].each { |file| require file }
|
9
|
+
Dir[File.join(__dir__, "<%= project_name.gsub("-", "_") %>", "actions", "*.rb")].each { |file| require file }
|
10
|
+
Dir[File.join(__dir__, "<%= project_name.gsub("-", "_") %>", "agents", "*.rb")].each { |file| require file }
|
11
|
+
|
12
|
+
require_relative "<%= project_name.gsub("-", "_") %>/cli"
|
13
|
+
|
14
|
+
module <%= project_name.camelize %>
|
15
|
+
class Error < StandardError; end
|
16
|
+
Config.load
|
17
|
+
|
18
|
+
def self.root
|
19
|
+
File.dirname __dir__
|
20
|
+
end
|
21
|
+
end
|
File without changes
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "sublayer"
|
3
|
+
|
4
|
+
# Load any Actions, Generators, and Agents
|
5
|
+
Dir[File.join(__dir__, "actions", "*.rb")].each { |file| require file }
|
6
|
+
Dir[File.join(__dir__, "generators", "*.rb")].each { |file| require file }
|
7
|
+
Dir[File.join(__dir__, "agents", "*.rb")].each { |file| require file }
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# <%= project_name.camelize %>
|
2
|
+
|
3
|
+
Welcome to your new Sublayer quick script project!
|
4
|
+
|
5
|
+
There are example Agents, Generators, and Actions in the respective folders.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
Create your own custom agents, generators, and actions and use them in
|
10
|
+
`<%= project_name %>.rb`
|
11
|
+
|
12
|
+
Run your script:
|
13
|
+
|
14
|
+
```
|
15
|
+
$ ruby <%= project_name %>.rb
|
16
|
+
```
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ExampleAgent < Sublayer::Agents::Base
|
4
|
+
trigger_on_files_changed { ["example_file.txt"] }
|
5
|
+
|
6
|
+
goal_condition { @goal_reached }
|
7
|
+
|
8
|
+
check_status do
|
9
|
+
@status_checked = true
|
10
|
+
end
|
11
|
+
|
12
|
+
step do
|
13
|
+
@step_taken = true
|
14
|
+
@goal_reached = true
|
15
|
+
puts "Example agent step executed"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ExampleGenerator < Sublayer::Generators::Base
|
4
|
+
llm_output_adapter type: :single_string,
|
5
|
+
name: "generated_text",
|
6
|
+
description: "A simple generated text"
|
7
|
+
|
8
|
+
def initialize(input:)
|
9
|
+
@input = input
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def prompt
|
17
|
+
<<-PROMPT
|
18
|
+
Generate a simple story based on this input: #{@input}
|
19
|
+
PROMPT
|
20
|
+
end
|
21
|
+
end
|
data/lib/sublayer/cli.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require "thor"
|
2
|
+
|
3
|
+
require "sublayer"
|
4
|
+
require "sublayer/version"
|
5
|
+
require "yaml"
|
6
|
+
require "fileutils"
|
7
|
+
require "active_support/inflector"
|
8
|
+
|
9
|
+
require_relative "cli/commands/subcommand_base"
|
10
|
+
require_relative "cli/commands/new_project"
|
11
|
+
require_relative "cli/commands/generator"
|
12
|
+
require_relative "cli/commands/agent"
|
13
|
+
require_relative "cli/commands/action"
|
14
|
+
|
15
|
+
module Sublayer
|
16
|
+
class CLI < Thor
|
17
|
+
|
18
|
+
register(Sublayer::Commands::NewProject, "new", "new PROJECT_NAME", "Creates a new Sublayer project")
|
19
|
+
|
20
|
+
register(Sublayer::Commands::Generator, "generate:generator", "generate:generator", "Generates a new Sublayer::Generator subclass for your project")
|
21
|
+
register(Sublayer::Commands::Agent, "generate:agent", "generate:agent", "Generates a new Sublayer::Agent subclass for your project")
|
22
|
+
register(Sublayer::Commands::Action, "generate:action", "generate:action", "Generates a new Sublayer::Action subclass for your project")
|
23
|
+
|
24
|
+
desc "version", "Prints the Sublayer version"
|
25
|
+
def version
|
26
|
+
puts Sublayer::VERSION
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "help [COMMAND]", "Describe available commands or one specific command"
|
30
|
+
def help(command = nil, subcommand = false)
|
31
|
+
if command.nil?
|
32
|
+
puts "Sublayer CLI"
|
33
|
+
puts
|
34
|
+
puts "Usage:"
|
35
|
+
puts " sublayer COMMAND [OPTIONS]"
|
36
|
+
puts
|
37
|
+
puts "Commands:"
|
38
|
+
print_commands(self.class.commands.reject { |name, _| name == "help" || name == "version" })
|
39
|
+
puts
|
40
|
+
print_commands(self.class.commands.select { |name, _| name == "help" })
|
41
|
+
print_commands(self.class.commands.select { |name, _| name == "version" })
|
42
|
+
puts
|
43
|
+
puts "Run 'sublayer COMMAND --help' for more information on a command."
|
44
|
+
else
|
45
|
+
super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
default_command :help
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def print_commands(commands)
|
54
|
+
commands.each do |name, command|
|
55
|
+
puts " #{name.ljust(15)} # #{command.description}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -33,6 +33,7 @@ module Sublayer
|
|
33
33
|
result[:items] = property.items.is_a?(OpenStruct) ? format_property(property.items) : property.items
|
34
34
|
when 'object'
|
35
35
|
result[:properties] = build_json_schema(property.properties) if property.properties
|
36
|
+
result[:required] = property.properties.select(&:required).map(&:name) if property.properties
|
36
37
|
end
|
37
38
|
|
38
39
|
result
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Sublayer
|
2
|
+
module Components
|
3
|
+
module OutputAdapters
|
4
|
+
class ListOfNamedStrings
|
5
|
+
attr_reader :name, :description, :attributes, :item_name
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@name = options[:name]
|
9
|
+
@item_name = options[:item_name]
|
10
|
+
@description = options[:description]
|
11
|
+
@attributes = options[:attributes]
|
12
|
+
end
|
13
|
+
|
14
|
+
def properties
|
15
|
+
[
|
16
|
+
OpenStruct.new(
|
17
|
+
name: @name,
|
18
|
+
type: "array",
|
19
|
+
description: @description,
|
20
|
+
required: true,
|
21
|
+
items: OpenStruct.new(
|
22
|
+
type: "object",
|
23
|
+
description: "a single #{@item_name}",
|
24
|
+
name: @item_name,
|
25
|
+
properties: @attributes.map do |attribute|
|
26
|
+
OpenStruct.new(
|
27
|
+
type: "string",
|
28
|
+
name: attribute[:name],
|
29
|
+
description: attribute[:description],
|
30
|
+
required: true
|
31
|
+
)
|
32
|
+
end
|
33
|
+
)
|
34
|
+
)
|
35
|
+
]
|
36
|
+
end
|
37
|
+
|
38
|
+
def materialize_result(raw_results)
|
39
|
+
raw_results.map do |raw_result|
|
40
|
+
OpenStruct.new(
|
41
|
+
@attributes.map { |attribute| [attribute[:name], raw_result[attribute[:name]]] }.to_h
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -17,7 +17,9 @@ module Sublayer
|
|
17
17
|
type: "object",
|
18
18
|
description: @description,
|
19
19
|
required: true,
|
20
|
-
properties: @attributes.map { |attribute|
|
20
|
+
properties: @attributes.map { |attribute|
|
21
|
+
OpenStruct.new(type: "string", description: attribute[:description], required: true, name: attribute[:name])
|
22
|
+
}
|
21
23
|
)
|
22
24
|
]
|
23
25
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Sublayer
|
2
|
+
module Components
|
3
|
+
module OutputAdapters
|
4
|
+
class SingleInteger
|
5
|
+
attr_reader :name, :description
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@name = options[:name]
|
9
|
+
@description = options[:description]
|
10
|
+
end
|
11
|
+
|
12
|
+
def properties
|
13
|
+
[
|
14
|
+
OpenStruct.new(
|
15
|
+
name: @name,
|
16
|
+
type: 'integer',
|
17
|
+
description: @description,
|
18
|
+
required: true
|
19
|
+
)
|
20
|
+
]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,8 +1,5 @@
|
|
1
|
-
# *UNSTABLE* Gemini function calling API is in beta.
|
2
|
-
# Provider is not recommended until API update.
|
3
|
-
|
4
1
|
# Sublayer.configuration.ai_provider = Sublayer::Providers::Gemini
|
5
|
-
# Sublayer.configuration.ai_model = "gemini-1.5-
|
2
|
+
# Sublayer.configuration.ai_model = "gemini-1.5-flash-latest"
|
6
3
|
|
7
4
|
module Sublayer
|
8
5
|
module Providers
|
@@ -26,23 +23,12 @@ module Sublayer
|
|
26
23
|
text: "#{prompt}"
|
27
24
|
},
|
28
25
|
},
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
type: "OBJECT",
|
36
|
-
properties: output_adapter.format_properties,
|
37
|
-
required: output_adapter.format_required
|
38
|
-
}
|
39
|
-
}
|
40
|
-
]
|
41
|
-
}],
|
42
|
-
tool_config: {
|
43
|
-
function_calling_config: {
|
44
|
-
mode: "ANY",
|
45
|
-
allowed_function_names: [output_adapter.name]
|
26
|
+
generationConfig: {
|
27
|
+
responseMimeType: "application/json",
|
28
|
+
responseSchema: {
|
29
|
+
type: "OBJECT",
|
30
|
+
properties: output_adapter.format_properties,
|
31
|
+
required: output_adapter.format_required
|
46
32
|
}
|
47
33
|
}
|
48
34
|
}.to_json,
|
@@ -66,7 +52,9 @@ module Sublayer
|
|
66
52
|
|
67
53
|
raise "Error generating with Gemini, error: #{response.body}" unless response.success?
|
68
54
|
|
69
|
-
|
55
|
+
output = response.dig("candidates", 0, "content", "parts", 0, "text")
|
56
|
+
|
57
|
+
parsed_output = JSON.parse(output)[output_adapter.name]
|
70
58
|
end
|
71
59
|
end
|
72
60
|
end
|
data/lib/sublayer/version.rb
CHANGED
data/lib/sublayer.rb
CHANGED
@@ -7,7 +7,6 @@ require 'active_support/inflector'
|
|
7
7
|
require 'ostruct'
|
8
8
|
require "httparty"
|
9
9
|
require "openai"
|
10
|
-
require "nokogiri"
|
11
10
|
require "listen"
|
12
11
|
require "securerandom"
|
13
12
|
require "time"
|
@@ -16,6 +15,7 @@ require_relative "sublayer/version"
|
|
16
15
|
|
17
16
|
loader = Zeitwerk::Loader.for_gem
|
18
17
|
loader.inflector.inflect('open_ai' => 'OpenAI')
|
18
|
+
loader.inflector.inflect("cli" => "CLI")
|
19
19
|
loader.setup
|
20
20
|
|
21
21
|
module Sublayer
|
data/sublayer.gemspec
CHANGED
@@ -29,18 +29,18 @@ Gem::Specification.new do |spec|
|
|
29
29
|
end
|
30
30
|
|
31
31
|
spec.require_paths = ["lib"]
|
32
|
+
spec.bindir = "bin"
|
33
|
+
spec.executables = ["sublayer"]
|
32
34
|
|
33
35
|
spec.add_dependency "ruby-openai"
|
34
|
-
spec.add_dependency "colorize"
|
35
36
|
spec.add_dependency "activesupport"
|
36
37
|
spec.add_dependency "zeitwerk"
|
37
|
-
spec.add_dependency "nokogiri", "~> 1.16.5"
|
38
38
|
spec.add_dependency "httparty"
|
39
39
|
spec.add_dependency "listen"
|
40
|
+
spec.add_dependency "thor"
|
40
41
|
|
41
42
|
spec.add_development_dependency "rspec", "~> 3.12"
|
42
43
|
spec.add_development_dependency "pry", "~> 0.14"
|
43
44
|
spec.add_development_dependency "vcr", "~> 6.0"
|
44
45
|
spec.add_development_dependency "webmock", "~> 3"
|
45
|
-
spec.add_development_dependency "clag"
|
46
46
|
end
|