sublayer 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/sublayer +5 -0
- data/lib/sublayer/cli.rb +191 -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/templates/cli/.gitignore +14 -0
- data/lib/sublayer/templates/cli/Gemfile +7 -0
- data/lib/sublayer/templates/cli/PROJECT_NAME.gemspec +35 -0
- data/lib/sublayer/templates/cli/README.md +22 -0
- data/lib/sublayer/templates/cli/bin/PROJECT_NAME +5 -0
- data/lib/sublayer/templates/cli/lib/PROJECT_NAME/actions/example_action.rb +15 -0
- data/lib/sublayer/templates/cli/lib/PROJECT_NAME/agents/example_agent.rb +21 -0
- data/lib/sublayer/templates/cli/lib/PROJECT_NAME/cli.rb +13 -0
- data/lib/sublayer/templates/cli/lib/PROJECT_NAME/commands/base_command.rb +21 -0
- data/lib/sublayer/templates/cli/lib/PROJECT_NAME/commands/example_command.rb +13 -0
- data/lib/sublayer/templates/cli/lib/PROJECT_NAME/config/.keep +0 -0
- data/lib/sublayer/templates/cli/lib/PROJECT_NAME/config.rb +19 -0
- data/lib/sublayer/templates/cli/lib/PROJECT_NAME/generators/example_generator.rb +25 -0
- data/lib/sublayer/templates/cli/lib/PROJECT_NAME/version.rb +5 -0
- data/lib/sublayer/templates/cli/lib/project_name.rb +21 -0
- data/lib/sublayer/templates/cli/spec/.keep +0 -0
- data/lib/sublayer/templates/quick_script/README.md +16 -0
- data/lib/sublayer/templates/quick_script/actions/example_action.rb +11 -0
- data/lib/sublayer/templates/quick_script/agents/example_agent.rb +17 -0
- data/lib/sublayer/templates/quick_script/generators/example_generator.rb +21 -0
- data/lib/sublayer/templates/quick_script/project_name.rb +7 -0
- data/lib/sublayer/version.rb +1 -1
- data/lib/sublayer.rb +1 -0
- data/sublayer.gemspec +7 -0
- metadata +98 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2238a9858f994058b23edf70f97255d6c3b20d648c7e73991c05eb7232a9ec6b
|
4
|
+
data.tar.gz: 935f154d71e8dab6ee3906f700d1f42092f33b9e15ce07c3b305817bcca8177e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae8d296c701a18a7e4dde9366f05e4ecf8a5afc964cdc336a563201049660d92345f92219bd1537517bc961e6baf74bab4b9f4652d79666cdf2041e510be2451
|
7
|
+
data.tar.gz: af8c3a33325de5e2354cc82edd73212f91e5f24bf8c70ae2fac31b58d480ea1c08c76e938e60be714a5f67871940d497b21611daf1e576d6333bb52772e1e4cd
|
data/bin/sublayer
ADDED
data/lib/sublayer/cli.rb
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
require "tty-prompt"
|
2
|
+
require "tty-progressbar"
|
3
|
+
require "tty-command"
|
4
|
+
require "tty-file"
|
5
|
+
require "fileutils"
|
6
|
+
require "yaml"
|
7
|
+
require "sublayer/version"
|
8
|
+
|
9
|
+
module Sublayer
|
10
|
+
class CLI
|
11
|
+
PLACEHOLDERS = {
|
12
|
+
"PROJECT_NAME" => { gsub: true, camelcase: false },
|
13
|
+
"ProjectName" => { gsub: true, camelcase: true },
|
14
|
+
"project_name" => { gsub: true, camelcase: false, underscore: true }
|
15
|
+
}
|
16
|
+
|
17
|
+
def self.start(args)
|
18
|
+
new.run(args)
|
19
|
+
end
|
20
|
+
|
21
|
+
def run(args)
|
22
|
+
command = args.shift
|
23
|
+
|
24
|
+
case command
|
25
|
+
when "new"
|
26
|
+
create_new_project(args.first)
|
27
|
+
when "help", nil
|
28
|
+
display_help
|
29
|
+
else
|
30
|
+
puts "Unknown command: #{command}"
|
31
|
+
display_help
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def create_new_project(project_name)
|
38
|
+
prompt = TTY::Prompt.new
|
39
|
+
|
40
|
+
project_name ||= prompt.ask("What is the name of your project?")
|
41
|
+
|
42
|
+
project_type = prompt.select("Select a project template: ", ["CLI", "Quick Script"])
|
43
|
+
ai_provider = prompt.select("Select an AI provider:", ["OpenAI", "Claude", "Gemini"])
|
44
|
+
|
45
|
+
ai_model = if ai_provider == "OpenAI"
|
46
|
+
prompt.select("Which OpenAI model would you like to use?", ["gpt-4o", "gpt-4o-mini", "gpt-4-turbo", "gpt-4", "gpt-3.5-turbo"])
|
47
|
+
elsif ai_provider == "Claude"
|
48
|
+
prompt.select("Which Anthropic model would you like to use?", ["claude-3-5-sonnet-20240620", "claude-3-opus-20240229", "claude-3-haiku-20240307"])
|
49
|
+
elsif ai_provider == "Gemini"
|
50
|
+
prompt.select("Which Gemini model would you like to use?", ["gemini-1.5-pro-latest", "gemini-1.5-flash-latest"])
|
51
|
+
end
|
52
|
+
|
53
|
+
create_project(project_name, project_type, ai_provider, ai_model)
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_project(project_name, project_type, ai_provider, ai_model)
|
57
|
+
project_path = File.join(Dir.pwd, project_name)
|
58
|
+
|
59
|
+
progress_bar = TTY::ProgressBar.new("Creating project [:bar] :percent", total: 8)
|
60
|
+
|
61
|
+
progress_bar.advance(1, log: "Creating project directory")
|
62
|
+
FileUtils.mkdir_p(project_path)
|
63
|
+
|
64
|
+
progress_bar.advance(1, log: "Copying template files")
|
65
|
+
copy_template_files(project_path, project_type)
|
66
|
+
|
67
|
+
progress_bar.advance(1, log: "Replacing placeholders")
|
68
|
+
replace_placeholders(project_path, project_name)
|
69
|
+
|
70
|
+
progress_bar.advance(1, log: "Generating configuration")
|
71
|
+
generate_config_file(project_path, project_name, project_type, ai_provider, ai_model)
|
72
|
+
|
73
|
+
progress_bar.advance(1, log: "Finalizing project")
|
74
|
+
finalize_project(project_path, project_type)
|
75
|
+
|
76
|
+
puts "\nSublayer project '#{project_name}' created successfully!"
|
77
|
+
end
|
78
|
+
|
79
|
+
def copy_template_files(project_path, project_type)
|
80
|
+
template_dir = project_type == "CLI" ? "cli" : "quick_script"
|
81
|
+
source_path = File.join(File.dirname(__FILE__), "templates", template_dir)
|
82
|
+
FileUtils.cp_r("#{source_path}/.", project_path)
|
83
|
+
|
84
|
+
FileUtils.mkdir_p(File.join(project_path, "log")) if should_add_log_folder(project_type)
|
85
|
+
end
|
86
|
+
|
87
|
+
def should_add_log_folder(project_type)
|
88
|
+
project_type == "CLI"
|
89
|
+
end
|
90
|
+
|
91
|
+
def generate_config_file(project_path, project_name, project_type, ai_provider, ai_model)
|
92
|
+
config = {
|
93
|
+
project_name: project_name,
|
94
|
+
project_type: project_type,
|
95
|
+
ai_provider: ai_provider,
|
96
|
+
ai_model: ai_model
|
97
|
+
}
|
98
|
+
|
99
|
+
TTY::File.create_file(File.join(project_path, "lib", project_name, "config", "sublayer.yml"), YAML.dump(config)) if project_type == "CLI"
|
100
|
+
|
101
|
+
if project_type == "Quick Script"
|
102
|
+
config_lines = <<~CONFIG
|
103
|
+
Sublayer.configuration.ai_provider = Sublayer::Providers::#{config[:ai_provider]}
|
104
|
+
Sublayer.configuration.ai_model = "#{config[:ai_model]}"
|
105
|
+
CONFIG
|
106
|
+
project_file = File.join(project_path, "#{project_name}.rb")
|
107
|
+
File.write(project_file, File.read(project_file) + config_lines)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def project_type_instructions(project_type)
|
112
|
+
if project_type == "CLI"
|
113
|
+
"Run your CLI application:\n ```\n ruby bin/#{File.basename(project_path)}\n ```"
|
114
|
+
else
|
115
|
+
"Start your web server:\n ```\n ruby app.rb\n ```\n Then visit http://localhost:4567 in your browser."
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def replace_placeholders(project_path, project_name)
|
120
|
+
# First rename the lib/PROJECT_NAME directory to lib/project_name
|
121
|
+
FileUtils.mv(File.join(project_path, "lib", "PROJECT_NAME"), File.join(project_path, "lib", project_name.gsub("-", "_").downcase)) if File.directory?(File.join(project_path, "lib", "PROJECT_NAME"))
|
122
|
+
|
123
|
+
# Then walk through each file in the project and replace the placeholder content and filenames
|
124
|
+
Dir.glob("#{project_path}/**/*", File::FNM_DOTMATCH).each do |file_path|
|
125
|
+
next if File.directory?(file_path)
|
126
|
+
next if file_path.include?(".git/")
|
127
|
+
|
128
|
+
content = File.read(file_path)
|
129
|
+
PLACEHOLDERS.each do |placeholder, options|
|
130
|
+
replacement = if options[:camelcase]
|
131
|
+
project_name.split(/[_-]/).map(&:capitalize).join
|
132
|
+
elsif options[:underscore]
|
133
|
+
project_name.gsub("-", "_").downcase
|
134
|
+
else
|
135
|
+
project_name
|
136
|
+
end
|
137
|
+
content.gsub!(placeholder, replacement) if options[:gsub]
|
138
|
+
end
|
139
|
+
|
140
|
+
File.write(file_path, content)
|
141
|
+
|
142
|
+
|
143
|
+
if file_path.include?('PROJECT_NAME')
|
144
|
+
new_path = file_path.gsub("PROJECT_NAME", project_name.gsub("-", "_").downcase)
|
145
|
+
|
146
|
+
FileUtils.mkdir_p(File.dirname(new_path))
|
147
|
+
FileUtils.mv(file_path, new_path)
|
148
|
+
end
|
149
|
+
|
150
|
+
if file_path.include?('project_name')
|
151
|
+
new_path = file_path.gsub("project_name", project_name.gsub("-", "_").downcase)
|
152
|
+
|
153
|
+
FileUtils.mkdir_p(File.dirname(new_path))
|
154
|
+
FileUtils.mv(file_path, new_path)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# replace the sublayer version in the gemspec file with Sublayer::VERSION
|
159
|
+
if File.exist?(File.join(project_path, "#{project_name}.gemspec"))
|
160
|
+
gemspec_path = File.join(project_path, "#{project_name}.gemspec")
|
161
|
+
gemspec_content = File.read(gemspec_path)
|
162
|
+
gemspec_content.gsub!("SUBLAYER_VERSION", Sublayer::VERSION)
|
163
|
+
File.write(gemspec_path, gemspec_content)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def finalize_project(project_path, project_type)
|
168
|
+
cmd = TTY::Command.new(printer: :null)
|
169
|
+
|
170
|
+
if TTY::Prompt.new.yes?("Initialize a git repository?")
|
171
|
+
cmd.run("git init", chdir: project_path)
|
172
|
+
end
|
173
|
+
|
174
|
+
if TTY::Prompt.new.yes?("Install dependencies now?")
|
175
|
+
cmd.run("bundle install", chdir: project_path)
|
176
|
+
end
|
177
|
+
|
178
|
+
puts "To get started, run:"
|
179
|
+
puts " cd #{File.basename(project_path)}"
|
180
|
+
puts " ./bin/#{File.basename(project_path)}" if project_type == "CLI"
|
181
|
+
puts " ruby #{File.basename(project_path)}.rb" if project_type == "Quick Script"
|
182
|
+
end
|
183
|
+
|
184
|
+
def display_help
|
185
|
+
puts "Usage: sublayer [command] [arguments]"
|
186
|
+
puts "Commands:"
|
187
|
+
puts " new PROJECT_NAME Create a new Sublayer project"
|
188
|
+
puts " help Display this help message"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
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,35 @@
|
|
1
|
+
require_relative "lib/PROJECT_NAME/version"
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "PROJECT_NAME"
|
5
|
+
spec.version = ProjectName::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
|
+
# ProjectName
|
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 ProjectName
|
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 ProjectName
|
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 ProjectName
|
4
|
+
class CLI < Thor
|
5
|
+
ProjectName::Commands.constants.reject{ |command_class| command_class == :BaseCommand }.each do |command_class|
|
6
|
+
command = ProjectName::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 ProjectName
|
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 ProjectName
|
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 ProjectName::Generators::ExampleGenerator.new(input: args.join(" ")).generate
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
File without changes
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ProjectName
|
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 ProjectName
|
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/version"
|
5
|
+
require_relative "PROJECT_NAME/config"
|
6
|
+
|
7
|
+
Dir[File.join(__dir__, "PROJECT_NAME", "commands", "*.rb")].each { |file| require file }
|
8
|
+
Dir[File.join(__dir__, "PROJECT_NAME", "generators", "*.rb")].each { |file| require file }
|
9
|
+
Dir[File.join(__dir__, "PROJECT_NAME", "actions", "*.rb")].each { |file| require file }
|
10
|
+
Dir[File.join(__dir__, "PROJECT_NAME", "agents", "*.rb")].each { |file| require file }
|
11
|
+
|
12
|
+
require_relative "PROJECT_NAME/cli"
|
13
|
+
|
14
|
+
module ProjectName
|
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,16 @@
|
|
1
|
+
# ProjectName
|
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/version.rb
CHANGED
data/lib/sublayer.rb
CHANGED
data/sublayer.gemspec
CHANGED
@@ -29,6 +29,8 @@ 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
36
|
spec.add_dependency "colorize"
|
@@ -37,6 +39,11 @@ Gem::Specification.new do |spec|
|
|
37
39
|
spec.add_dependency "nokogiri", "~> 1.16.5"
|
38
40
|
spec.add_dependency "httparty"
|
39
41
|
spec.add_dependency "listen"
|
42
|
+
spec.add_dependency "tty-prompt", "~> 0.23"
|
43
|
+
spec.add_dependency "tty-progressbar", "~> 0.18"
|
44
|
+
spec.add_dependency "tty-command", "~> 0.10"
|
45
|
+
spec.add_dependency "tty-file", "~> 0.10"
|
46
|
+
spec.add_dependency "thor"
|
40
47
|
|
41
48
|
spec.add_development_dependency "rspec", "~> 3.12"
|
42
49
|
spec.add_development_dependency "pry", "~> 0.14"
|
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.2.
|
4
|
+
version: 0.2.4
|
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-08-
|
11
|
+
date: 2024-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-openai
|
@@ -108,6 +108,76 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: tty-prompt
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.23'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.23'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: tty-progressbar
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.18'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.18'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: tty-command
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.10'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.10'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: tty-file
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.10'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.10'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: thor
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
111
181
|
- !ruby/object:Gem::Dependency
|
112
182
|
name: rspec
|
113
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -182,18 +252,22 @@ description: A DSL and framework for building AI powered applications through th
|
|
182
252
|
use of Generators, Actions, Tasks, and Agents
|
183
253
|
email:
|
184
254
|
- scott@sublayer.com
|
185
|
-
executables:
|
255
|
+
executables:
|
256
|
+
- sublayer
|
186
257
|
extensions: []
|
187
258
|
extra_rdoc_files: []
|
188
259
|
files:
|
189
260
|
- LICENSE
|
190
261
|
- README.md
|
191
262
|
- Rakefile
|
263
|
+
- bin/sublayer
|
192
264
|
- lib/sublayer.rb
|
193
265
|
- lib/sublayer/actions/base.rb
|
194
266
|
- lib/sublayer/agents/base.rb
|
267
|
+
- lib/sublayer/cli.rb
|
195
268
|
- lib/sublayer/components/output_adapters.rb
|
196
269
|
- lib/sublayer/components/output_adapters/formattable.rb
|
270
|
+
- lib/sublayer/components/output_adapters/list_of_named_strings.rb
|
197
271
|
- lib/sublayer/components/output_adapters/list_of_strings.rb
|
198
272
|
- lib/sublayer/components/output_adapters/named_strings.rb
|
199
273
|
- lib/sublayer/components/output_adapters/single_string.rb
|
@@ -207,6 +281,27 @@ files:
|
|
207
281
|
- lib/sublayer/providers/gemini.rb
|
208
282
|
- lib/sublayer/providers/open_ai.rb
|
209
283
|
- lib/sublayer/tasks/base.rb
|
284
|
+
- lib/sublayer/templates/cli/.gitignore
|
285
|
+
- lib/sublayer/templates/cli/Gemfile
|
286
|
+
- lib/sublayer/templates/cli/PROJECT_NAME.gemspec
|
287
|
+
- lib/sublayer/templates/cli/README.md
|
288
|
+
- lib/sublayer/templates/cli/bin/PROJECT_NAME
|
289
|
+
- lib/sublayer/templates/cli/lib/PROJECT_NAME/actions/example_action.rb
|
290
|
+
- lib/sublayer/templates/cli/lib/PROJECT_NAME/agents/example_agent.rb
|
291
|
+
- lib/sublayer/templates/cli/lib/PROJECT_NAME/cli.rb
|
292
|
+
- lib/sublayer/templates/cli/lib/PROJECT_NAME/commands/base_command.rb
|
293
|
+
- lib/sublayer/templates/cli/lib/PROJECT_NAME/commands/example_command.rb
|
294
|
+
- lib/sublayer/templates/cli/lib/PROJECT_NAME/config.rb
|
295
|
+
- lib/sublayer/templates/cli/lib/PROJECT_NAME/config/.keep
|
296
|
+
- lib/sublayer/templates/cli/lib/PROJECT_NAME/generators/example_generator.rb
|
297
|
+
- lib/sublayer/templates/cli/lib/PROJECT_NAME/version.rb
|
298
|
+
- lib/sublayer/templates/cli/lib/project_name.rb
|
299
|
+
- lib/sublayer/templates/cli/spec/.keep
|
300
|
+
- lib/sublayer/templates/quick_script/README.md
|
301
|
+
- lib/sublayer/templates/quick_script/actions/example_action.rb
|
302
|
+
- lib/sublayer/templates/quick_script/agents/example_agent.rb
|
303
|
+
- lib/sublayer/templates/quick_script/generators/example_generator.rb
|
304
|
+
- lib/sublayer/templates/quick_script/project_name.rb
|
210
305
|
- lib/sublayer/triggers/base.rb
|
211
306
|
- lib/sublayer/triggers/file_change.rb
|
212
307
|
- lib/sublayer/version.rb
|