sublayer 0.1.0.pre.alpha.3 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80d1bcf936b12b7638feb1ddc87d0369dd7438f535837e0c0353ffa4e717a9ac
4
- data.tar.gz: a2113a776870928e115e62a318e29e149ecc791633ad7b47f218a9f4d3df75ca
3
+ metadata.gz: 8254634ae1c2de3daa2f3a1fddf102df81ee82e79e345c1ef4a9256ea35553e2
4
+ data.tar.gz: 7a2eb512a983ae642858af5c395d3651b69449359204975be9468b30736c6c40
5
5
  SHA512:
6
- metadata.gz: ee8d2b20c430e814e400a224f351ac0dd8d4f4e0428f30fc490a3085d40f3fd1e3112044ab9365d4373e4ce1e4035a3a5acf58522fb9d63ec17abc75daa9efff
7
- data.tar.gz: 5c35b019b2e111f935f171fce4d22681195cc0c9d4f40f066283497cd5a99e090505dd8acfc05a3dabd7c241f8455c4c32a2b3916f4f71eb14c1c1f34b235abb
6
+ metadata.gz: ea8183fce2be4f378a581d079a124df8c82b03165186575b6152576e76ca26fd93a925df6a108d1e348bdd393a71206d3e79ce832b000c9607224c9ea5fc46df
7
+ data.tar.gz: a52f4942386fabe647fe97ee060747fa02e6f93c1261a33336bb14012383907419ad92e385c7fe4973df313dad8cc818f772063c8637ca81e318ba0b273430bb
@@ -2,48 +2,52 @@ module Sublayer
2
2
  module Agents
3
3
  class Base
4
4
  class << self
5
- attr_accessor :goal_condition_block, :trigger_condition_block, :trigger_on_files_changed_block, :check_status_block, :step_block
5
+ attr_reader :triggers, :goal_condition_block, :check_status_block, :step_block, :listeners
6
6
 
7
- def trigger_condition(&block)
8
- self.trigger_condition_block = block
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
- self.trigger_on_files_changed_block = block
18
+ trigger(Triggers::FileChange.new(&block))
13
19
  end
14
20
 
15
21
  def goal_condition(&block)
16
- self.goal_condition_block = block
22
+ @goal_condition_block = block
17
23
  end
18
24
 
19
25
  def check_status(&block)
20
- self.check_status_block = block
26
+ @check_status_block = block
21
27
  end
22
28
 
23
29
  def step(&block)
24
- self.step_block = block
30
+ @step_block = block
25
31
  end
26
32
  end
27
33
 
28
34
  def run
29
- files_to_listen_to = instance_eval(&self.class.trigger_on_files_changed_block).map { |file| File.expand_path(file) }
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,13 @@
1
+ module Sublayer
2
+ module Triggers
3
+ class Base
4
+ def setup(agent)
5
+ raise NotImplementedError, "Subclasses must implement setup method"
6
+ end
7
+
8
+ def activate(agent)
9
+ agent.send(:take_step)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sublayer
4
- VERSION = "0.1.0-alpha.3"
4
+ VERSION = "0.1.0"
5
5
  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.1.0.pre.alpha.3
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-05-17 00:00:00.000000000 Z
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: 1.3.1
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