sublayer 0.1.0.pre.alpha.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sublayer/agents/base.rb +23 -19
- data/lib/sublayer/triggers/base.rb +13 -0
- data/lib/sublayer/triggers/file_change.rb +20 -0
- data/lib/sublayer/version.rb +1 -1
- metadata +6 -10
- data/lib/sublayer/generators/examples/code_from_blueprint_generator.rb +0 -30
- data/lib/sublayer/generators/examples/code_from_description_generator.rb +0 -26
- data/lib/sublayer/generators/examples/description_from_code_generator.rb +0 -23
- data/lib/sublayer/generators/examples/invalid_to_valid_json_generator.rb +0 -23
- data/lib/sublayer/generators/examples/route_selection_from_user_intent_generator.rb +0 -29
- data/lib/sublayer/generators/examples/sentiment_from_text_generator.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8254634ae1c2de3daa2f3a1fddf102df81ee82e79e345c1ef4a9256ea35553e2
|
4
|
+
data.tar.gz: 7a2eb512a983ae642858af5c395d3651b69449359204975be9468b30736c6c40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea8183fce2be4f378a581d079a124df8c82b03165186575b6152576e76ca26fd93a925df6a108d1e348bdd393a71206d3e79ce832b000c9607224c9ea5fc46df
|
7
|
+
data.tar.gz: a52f4942386fabe647fe97ee060747fa02e6f93c1261a33336bb14012383907419ad92e385c7fe4973df313dad8cc818f772063c8637ca81e318ba0b273430bb
|
data/lib/sublayer/agents/base.rb
CHANGED
@@ -2,48 +2,52 @@ module Sublayer
|
|
2
2
|
module Agents
|
3
3
|
class Base
|
4
4
|
class << self
|
5
|
-
|
5
|
+
attr_reader :triggers, :goal_condition_block, :check_status_block, :step_block, :listeners
|
6
6
|
|
7
|
-
def
|
8
|
-
|
7
|
+
def trigger(trigger_instance = nil)
|
8
|
+
@triggers ||= []
|
9
|
+
|
10
|
+
if trigger_instance
|
11
|
+
@triggers << trigger_instance
|
12
|
+
else
|
13
|
+
raise ArgumentError, "Either a trigger instance or a block must be provided"
|
14
|
+
end
|
9
15
|
end
|
10
16
|
|
11
17
|
def trigger_on_files_changed(&block)
|
12
|
-
|
18
|
+
trigger(Triggers::FileChange.new(&block))
|
13
19
|
end
|
14
20
|
|
15
21
|
def goal_condition(&block)
|
16
|
-
|
22
|
+
@goal_condition_block = block
|
17
23
|
end
|
18
24
|
|
19
25
|
def check_status(&block)
|
20
|
-
|
26
|
+
@check_status_block = block
|
21
27
|
end
|
22
28
|
|
23
29
|
def step(&block)
|
24
|
-
|
30
|
+
@step_block = block
|
25
31
|
end
|
26
32
|
end
|
27
33
|
|
28
34
|
def run
|
29
|
-
|
30
|
-
folders = files_to_listen_to.map { |file| File.dirname(file) }.uniq
|
31
|
-
|
32
|
-
listener = Listen.to(*folders) do |modified, added, removed|
|
33
|
-
if files_to_listen_to.any? { |file| modified.include?(file) }
|
34
|
-
take_step
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
listener.start
|
39
|
-
|
35
|
+
setup_triggers
|
40
36
|
take_step
|
41
|
-
|
42
37
|
sleep
|
43
38
|
end
|
44
39
|
|
45
40
|
private
|
46
41
|
|
42
|
+
def setup_triggers
|
43
|
+
@listeners = []
|
44
|
+
|
45
|
+
self.class.triggers.each do |trigger|
|
46
|
+
listener = trigger.setup(self)
|
47
|
+
@listeners << listener if listener
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
47
51
|
def take_step
|
48
52
|
instance_eval(&self.class.check_status_block)
|
49
53
|
instance_eval(&self.class.step_block) unless instance_eval(&self.class.goal_condition_block)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Sublayer
|
2
|
+
module Triggers
|
3
|
+
class FileChange < Base
|
4
|
+
def initialize(&block)
|
5
|
+
@block = block
|
6
|
+
end
|
7
|
+
|
8
|
+
def setup(agent)
|
9
|
+
files_to_watch = agent.instance_eval(&@block)
|
10
|
+
folders = files_to_watch.map { |file| File.dirname(File.expand_path(file)) }.uniq
|
11
|
+
|
12
|
+
Listen.to(*folders) do |modified, added, removed|
|
13
|
+
if files_to_watch.any? { |file| modified.include?(File.expand_path(file)) }
|
14
|
+
activate(agent)
|
15
|
+
end
|
16
|
+
end.start
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/sublayer/version.rb
CHANGED
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.1.0
|
4
|
+
version: 0.1.0
|
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-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-openai
|
@@ -196,16 +196,12 @@ files:
|
|
196
196
|
- lib/sublayer/components/output_adapters/single_string.rb
|
197
197
|
- lib/sublayer/components/output_adapters/string_selection_from_list.rb
|
198
198
|
- lib/sublayer/generators/base.rb
|
199
|
-
- lib/sublayer/generators/examples/code_from_blueprint_generator.rb
|
200
|
-
- lib/sublayer/generators/examples/code_from_description_generator.rb
|
201
|
-
- lib/sublayer/generators/examples/description_from_code_generator.rb
|
202
|
-
- lib/sublayer/generators/examples/invalid_to_valid_json_generator.rb
|
203
|
-
- lib/sublayer/generators/examples/route_selection_from_user_intent_generator.rb
|
204
|
-
- lib/sublayer/generators/examples/sentiment_from_text_generator.rb
|
205
199
|
- lib/sublayer/providers/claude.rb
|
206
200
|
- lib/sublayer/providers/gemini.rb
|
207
201
|
- lib/sublayer/providers/open_ai.rb
|
208
202
|
- lib/sublayer/tasks/base.rb
|
203
|
+
- lib/sublayer/triggers/base.rb
|
204
|
+
- lib/sublayer/triggers/file_change.rb
|
209
205
|
- lib/sublayer/version.rb
|
210
206
|
- sublayer.gemspec
|
211
207
|
homepage: https://docs.sublayer.com
|
@@ -227,9 +223,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
227
223
|
version: 2.6.0
|
228
224
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
229
225
|
requirements:
|
230
|
-
- - "
|
226
|
+
- - ">="
|
231
227
|
- !ruby/object:Gem::Version
|
232
|
-
version:
|
228
|
+
version: '0'
|
233
229
|
requirements: []
|
234
230
|
rubygems_version: 3.3.26
|
235
231
|
signing_key:
|
@@ -1,30 +0,0 @@
|
|
1
|
-
class CodeFromBlueprintGenerator < Sublayer::Generators::Base
|
2
|
-
llm_output_adapter type: :single_string,
|
3
|
-
name: "generated_code",
|
4
|
-
description: "The generated code for the description"
|
5
|
-
|
6
|
-
def initialize(blueprint_description:, blueprint_code:, description:)
|
7
|
-
@blueprint_description = blueprint_description
|
8
|
-
@blueprint_code = blueprint_code
|
9
|
-
@description = description
|
10
|
-
end
|
11
|
-
|
12
|
-
def generate
|
13
|
-
super
|
14
|
-
end
|
15
|
-
|
16
|
-
def prompt
|
17
|
-
<<-PROMPT
|
18
|
-
You are an expert programmer and are great at looking at and understanding existing patterns and applying them to new situations.
|
19
|
-
|
20
|
-
The blueprint we're working with is: #{@blueprint_description}.
|
21
|
-
The code for that blueprint is:
|
22
|
-
#{@blueprint_code}
|
23
|
-
|
24
|
-
You need to use the blueprint above and modify it so that it satisfied the following description:
|
25
|
-
#{@description}
|
26
|
-
|
27
|
-
Take a deep breath and think step by step before you start coding.
|
28
|
-
PROMPT
|
29
|
-
end
|
30
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
class CodeFromDescriptionGenerator < Sublayer::Generators::Base
|
2
|
-
llm_output_adapter type: :single_string,
|
3
|
-
name: "generated_code",
|
4
|
-
description: "The generated code in the requested language"
|
5
|
-
|
6
|
-
def initialize(description:, technologies:)
|
7
|
-
@description = description
|
8
|
-
@technologies = technologies
|
9
|
-
end
|
10
|
-
|
11
|
-
def generate
|
12
|
-
super
|
13
|
-
end
|
14
|
-
|
15
|
-
def prompt
|
16
|
-
<<-PROMPT
|
17
|
-
You are an expert programmer in #{@technologies.join(", ")}.
|
18
|
-
|
19
|
-
You are tasked with writing code using the following technologies: #{@technologies.join(", ")}.
|
20
|
-
|
21
|
-
The description of the task is #{@description}
|
22
|
-
|
23
|
-
Take a deep breath and think step by step before you start coding.
|
24
|
-
PROMPT
|
25
|
-
end
|
26
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
class DescriptionFromCodeGenerator < Sublayer::Generators::Base
|
2
|
-
llm_output_adapter type: :single_string,
|
3
|
-
name: "code_description",
|
4
|
-
description: "A description of what the code in the file does"
|
5
|
-
|
6
|
-
def initialize(code:)
|
7
|
-
@code = code
|
8
|
-
end
|
9
|
-
|
10
|
-
def generate
|
11
|
-
super
|
12
|
-
end
|
13
|
-
|
14
|
-
def prompt
|
15
|
-
<<-PROMPT
|
16
|
-
You are an experienced software engineer. Below is a chunk of code:
|
17
|
-
|
18
|
-
#{@code}
|
19
|
-
|
20
|
-
Please read the code carefully and provide a high-level description of what this code does, including its purpose, functionalities, and any noteworthy details.
|
21
|
-
PROMPT
|
22
|
-
end
|
23
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
class InvalidToValidJsonGenerator < Sublayer::Generators::Base
|
2
|
-
llm_output_adapter type: :single_string,
|
3
|
-
name: "valid_json",
|
4
|
-
description: "The valid JSON string"
|
5
|
-
|
6
|
-
def initialize(invalid_json:)
|
7
|
-
@invalid_json = invalid_json
|
8
|
-
end
|
9
|
-
|
10
|
-
def generate
|
11
|
-
super
|
12
|
-
end
|
13
|
-
|
14
|
-
def prompt
|
15
|
-
<<-PROMPT
|
16
|
-
You are an expert in JSON parsing.
|
17
|
-
|
18
|
-
The given string is not a valid JSON: #{@invalid_json}
|
19
|
-
|
20
|
-
Please fix this and produce a valid JSON.
|
21
|
-
PROMPT
|
22
|
-
end
|
23
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
class RouteSelectionFromUserIntentGenerator < Sublayer::Generators::Base
|
2
|
-
llm_output_adapter type: :string_selection_from_list,
|
3
|
-
name: "route",
|
4
|
-
description: "A route selected from the list",
|
5
|
-
options: :available_routes
|
6
|
-
|
7
|
-
def initialize(user_intent:)
|
8
|
-
@user_intent = user_intent
|
9
|
-
end
|
10
|
-
|
11
|
-
def generate
|
12
|
-
super
|
13
|
-
end
|
14
|
-
|
15
|
-
def available_routes
|
16
|
-
["GET /", "GET /users", "GET /users/:id", "POST /users", "PUT /users/:id", "DELETE /users/:id"]
|
17
|
-
end
|
18
|
-
|
19
|
-
def prompt
|
20
|
-
<<-PROMPT
|
21
|
-
You are skilled at selecting routes based on user intent.
|
22
|
-
|
23
|
-
Your task is to choose a route based on the following intent:
|
24
|
-
|
25
|
-
The user's intent is:
|
26
|
-
#{@user_intent}
|
27
|
-
PROMPT
|
28
|
-
end
|
29
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
class SentimentFromTextGenerator < Sublayer::Generators::Base
|
2
|
-
llm_output_adapter type: :string_selection_from_list,
|
3
|
-
name: "sentiment_value",
|
4
|
-
description: "A sentiment value from the list",
|
5
|
-
options: -> { @sentiment_options }
|
6
|
-
|
7
|
-
def initialize(text:, sentiment_options:)
|
8
|
-
@text = text
|
9
|
-
@sentiment_options = sentiment_options
|
10
|
-
end
|
11
|
-
|
12
|
-
def generate
|
13
|
-
super
|
14
|
-
end
|
15
|
-
|
16
|
-
def prompt
|
17
|
-
<<-PROMPT
|
18
|
-
You are an expert at determining sentiment from text.
|
19
|
-
|
20
|
-
You are tasked with analyzing the following text and determining its sentiment value.
|
21
|
-
|
22
|
-
The text is:
|
23
|
-
#{@text}
|
24
|
-
PROMPT
|
25
|
-
end
|
26
|
-
end
|