x_aeon_agents 1.0.28

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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/AGENTS.md +136 -0
  3. data/CHANGELOG.md +398 -0
  4. data/README.md +579 -0
  5. data/TODO.md +48 -0
  6. data/bin/xaa +5 -0
  7. data/lib/x_aeon_agents/agent_defaults.rb +60 -0
  8. data/lib/x_aeon_agents/agent_options.rb +58 -0
  9. data/lib/x_aeon_agents/agents/coder_agent.rb +82 -0
  10. data/lib/x_aeon_agents/agents/committer_agent.rb +71 -0
  11. data/lib/x_aeon_agents/agents/developer_agent.rb +235 -0
  12. data/lib/x_aeon_agents/agents/diff_interpreter_agent.rb +80 -0
  13. data/lib/x_aeon_agents/agents/documenter_agent.rb +44 -0
  14. data/lib/x_aeon_agents/agents/executor_agent.rb +9 -0
  15. data/lib/x_aeon_agents/agents/feedback_analyst_agent.rb +62 -0
  16. data/lib/x_aeon_agents/agents/gh_comments.gql +64 -0
  17. data/lib/x_aeon_agents/agents/git_diff_interpreter_agent.rb +57 -0
  18. data/lib/x_aeon_agents/agents/issue_implementer_agent.rb +88 -0
  19. data/lib/x_aeon_agents/agents/one_line_code_diff_summarizer_agent.rb +57 -0
  20. data/lib/x_aeon_agents/agents/plan_generator_agent.rb +51 -0
  21. data/lib/x_aeon_agents/agents/planner_agent.rb +89 -0
  22. data/lib/x_aeon_agents/agents/pull_request_creator_agent.rb +144 -0
  23. data/lib/x_aeon_agents/agents/readme/about_analyzer_agent.rb +55 -0
  24. data/lib/x_aeon_agents/agents/readme/contributing_agent.rb +47 -0
  25. data/lib/x_aeon_agents/agents/readme/development_agent.rb +54 -0
  26. data/lib/x_aeon_agents/agents/readme/documentation_agent.rb +43 -0
  27. data/lib/x_aeon_agents/agents/readme/features_agent.rb +45 -0
  28. data/lib/x_aeon_agents/agents/readme/how_it_works_agent.rb +47 -0
  29. data/lib/x_aeon_agents/agents/readme/license_agent.rb +43 -0
  30. data/lib/x_aeon_agents/agents/readme/public_api_agent.rb +44 -0
  31. data/lib/x_aeon_agents/agents/readme/quick_start_agent.rb +50 -0
  32. data/lib/x_aeon_agents/agents/readme/requirements_agent.rb +43 -0
  33. data/lib/x_aeon_agents/agents/readme_generator_agent.rb +438 -0
  34. data/lib/x_aeon_agents/agents/review_resolver_agent.rb +236 -0
  35. data/lib/x_aeon_agents/agents/review_responder_agent.rb +64 -0
  36. data/lib/x_aeon_agents/agents/skill_generator_agent.rb +95 -0
  37. data/lib/x_aeon_agents/agents/skill_installer_agent.rb +103 -0
  38. data/lib/x_aeon_agents/agents/task_starter_agent.rb +66 -0
  39. data/lib/x_aeon_agents/agents/tester_agent.rb +44 -0
  40. data/lib/x_aeon_agents/cli.rb +384 -0
  41. data/lib/x_aeon_agents/config.rb +110 -0
  42. data/lib/x_aeon_agents/gen_helpers.rb +270 -0
  43. data/lib/x_aeon_agents/helpers.rb +211 -0
  44. data/lib/x_aeon_agents/logger.rb +21 -0
  45. data/lib/x_aeon_agents/providers/cline.rb +78 -0
  46. data/lib/x_aeon_agents/version.rb +6 -0
  47. data/lib/x_aeon_agents.rb +38 -0
  48. metadata +296 -0
@@ -0,0 +1,60 @@
1
+ module XAeonAgents
2
+ # Mixin setting up default settings for agents.
3
+ # This mixin is meant to be the last prepended mixin in all Agent classes.
4
+ module AgentDefaults
5
+ class << self
6
+ # Get the singleton session ID.
7
+ # If it is the first time it is invoked, use a default session ID.
8
+ def singleton_session_id
9
+ @singleton_session_id ||= Time.now.utc.strftime('%Y-%m-%d-%H-%M-%S-%N')
10
+ end
11
+ end
12
+
13
+ # Instantiate a new agent.
14
+ # Transfer the same session to the new agent.
15
+ #
16
+ # @param agent_class [Class] The agent class to be instantiated
17
+ # @param args [Array] Constructor parameters
18
+ # @param kwargs [Hash] Constructor kwargs
19
+ # @return [ComposableAgents::Agent] The new agent
20
+ def new_agent(agent_class, *args, **kwargs)
21
+ agent_class.new(*args, session_id: @session_id, **kwargs)
22
+ end
23
+
24
+ # Hook called when this mixin is prepended in a class
25
+ #
26
+ # @param base [Class] The base class prepending this mixin
27
+ def self.prepended(base)
28
+ base.prepend ComposableAgents::Mixins::ArtifactContract unless base.ancestors.include?(ComposableAgents::Mixins::ArtifactContract)
29
+ base.prepend ComposableAgents::Mixins::Resumable unless base.ancestors.include?(ComposableAgents::Mixins::Resumable)
30
+ # Make sure we always prepend at the top our initializer that sets all defaults
31
+ base.prepend(
32
+ Module.new do
33
+ # Constructor
34
+ #
35
+ # @param args [Array] Agent's constructor arguments
36
+ # @param session_id [String, nil] Specific X-Aeon session id to be used, or nil if none
37
+ # @param kwargs [Array] Agent's constructor kwargs
38
+ def initialize(*args, session_id: nil, **kwargs)
39
+ # If we inherit from some frameworks initialize them now.
40
+ Config.setup_composable_agents
41
+ case self
42
+ when ComposableAgents::AiAgents::Agent
43
+ Config.setup_ai_agents
44
+ when ComposableAgents::Cline::Agent
45
+ Config.setup_cline
46
+ end
47
+ @session_id = session_id || AgentDefaults.singleton_session_id
48
+ @session_dir = "#{Config.data_dir}/sessions/#{@session_id}"
49
+ super(
50
+ *args,
51
+ composable_agents_dir: "#{@session_dir}/composable_agents",
52
+ run_id: "#{@session_id}-#{kwargs[:name] || self.class.name.split('::').last}",
53
+ **kwargs
54
+ )
55
+ end
56
+ end
57
+ )
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,58 @@
1
+ module XAeonAgents
2
+ # Provide agent options for different agent categories
3
+ class AgentOptions
4
+ # @!group Public API
5
+
6
+ # Get an agent's option for a given agent category.
7
+ # Those options can be given directly to the agent's constructor to tune it for the desired category.
8
+ #
9
+ # @param agent_category [String] The agent category for which we want the agent's options
10
+ # @return [Hash{Symbol => Object}, nil] The corresponding agent's options, or nil if none
11
+ def [](agent_category)
12
+ # Lazy-evaluate it if needed
13
+ options[agent_category] = options[agent_category].call if options[agent_category].is_a?(Proc)
14
+ options[agent_category]
15
+ end
16
+
17
+ # Set an agent's option for a given agent category.
18
+ #
19
+ # @param agent_category [String] The agent category for which we want the agent's options
20
+ # @param agent_options [Hash{Symbol => Object}, #call -> Hash] The corresponding agent's options (can be lazily evaluated)
21
+ def []=(agent_category, agent_options)
22
+ options[agent_category] = agent_options
23
+ end
24
+
25
+ private
26
+
27
+ # @return [Hash{String => Hash{Symbol => Object}, #call -> Hash}] The memoized options (can be lazily evaluated), per agent category.
28
+ def options
29
+ @options ||= {
30
+ 'free_simple' => {
31
+ model: 'openrouter/free',
32
+ strategy: ComposableAgents::PromptRenderingStrategy::Markdown
33
+ },
34
+ 'free_complex' => proc do
35
+ {
36
+ model: 'tencent/hy3:free',
37
+ api_key: Config.cline_api_key,
38
+ cli_options: Config.default_cline_cli_args
39
+ }
40
+ end,
41
+ 'free_complex_planning' => proc do
42
+ {
43
+ model: 'tencent/hy3:free',
44
+ api_key: Config.cline_api_key,
45
+ cli_options: Config.default_cline_cli_args.merge(
46
+ {
47
+ plan: true
48
+ }
49
+ ),
50
+ configure_global: proc do |global_settings|
51
+ global_settings.disabled_tools = %w[editor run_commands]
52
+ end
53
+ }
54
+ end
55
+ }
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,82 @@
1
+ module XAeonAgents
2
+ # Collection of agents that can be used
3
+ module Agents
4
+ # Agent responsible for implementing tasks following an implementation plan
5
+ class CoderAgent < ComposableAgents::Cline::Agent
6
+ prepend AgentDefaults
7
+
8
+ # Define input artifacts contracts
9
+ #
10
+ # @return [Hash{Symbol => Object}] Set of input artifacts description, per artifact name
11
+ def input_artifacts_contracts
12
+ super.merge(plan: 'The implementation plan that you must follow')
13
+ end
14
+
15
+ # Constructor
16
+ #
17
+ # @param agent_params [Hash{Symbol => Object}] Extra agent parameters
18
+ def initialize(**agent_params)
19
+ super(
20
+ name: 'Coder',
21
+ role: 'You are a Coder agent',
22
+ objective: <<~EO_OBJECTIVE,
23
+ Your primary goal is to assist users with various coding tasks by leveraging your knowledge and the tools at your disposal.
24
+ Given the user's prompt, you should use the tools available to you to answer user's question.
25
+ EO_OBJECTIVE
26
+ system_instructions: <<~EO_INSTRUCTIONS,
27
+ Always gather all the necessary context before starting to work on a task.
28
+ For example, if you are generating a unit test or new code, make sure you understand the requirement, the naming conventions, frameworks and libraries used and aligned in the current codebase, and the environment and commands used to run and test the code etc.
29
+ Always validate the new unit test at the end including running the code if possible for live feedback.
30
+
31
+ Begin by analyzing the user's input and gathering any necessary additional context.
32
+ Then, present your plan at the start of your response along with tool calls before proceeding with the task.
33
+ It's OK for this section to be quite long.
34
+
35
+ Review each question carefully and answer it with detailed, accurate information.
36
+
37
+ If you need more information, use one of the available tools or ask for clarification instead of making assumptions or lies.
38
+
39
+ When you have completed the task, please provide a summary of what you did and any relevant information that the user should know.
40
+ This will help ensure that the user understands the changes made and can easily follow up if they have any questions or need further assistance.
41
+ EO_INSTRUCTIONS
42
+ constraints: <<~EO_CONSTRAINTS,
43
+ Remember:
44
+ - Always adhere to existing code conventions and patterns.
45
+ - Use only libraries and frameworks that are confirmed to be in use in the current codebase.
46
+ - Provide complete and functional code without omissions or placeholders.
47
+ - Be explicit about any assumptions or limitations in your solution.
48
+ - Always show your planning process before executing any task.
49
+ This will help ensure that you have a clear understanding of the requirements and that your approach aligns with the user's needs.
50
+ - Always use absolute paths when referring to files.
51
+ - You can call multiple tools in a single response.
52
+ Before using tools, identify every independent read, search, command, or edit needed for the next step and emit all of those tool calls now, either as multiple tool calls or as one batched input for tools that accept arrays.
53
+ Do not wait for one independent result before requesting another.
54
+ Do not split independent reads, searches, checks, or edits across separate turns.
55
+ - Good parallelism examples: read all known relevant files in one read_files call;
56
+ run independent inspection commands in one run_commands call;
57
+ emit independent read_files, search_codebase, and run_commands calls together in one response;
58
+ emit multiple editor calls together when editing different files or non-overlapping regions.
59
+ - Always verify the files you have edited or created at the end of the task to ensure they are completed and working as expected.
60
+
61
+ REMEMBER, be helpful and proactive!
62
+ Don't ask for permission to do something when you can do it!
63
+ Do not indicates you will be using a tool unless you are actually going to use it.
64
+
65
+ IMPORTANT: Always includes tool calls in your response until the task is completed.
66
+ Response without tool calls will be considered as completed with the final answer.
67
+
68
+ Do not indicate that you will perform an action without actually doing it.
69
+ Always provide the final result in your response.
70
+ Always validate your answer with checking the code and running it if possible.
71
+ EO_CONSTRAINTS
72
+ skills: %w[
73
+ applying-ruby-conventions
74
+ applying-test-conventions
75
+ enforcing-project-rules
76
+ ],
77
+ **agent_params
78
+ )
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,71 @@
1
+ module XAeonAgents
2
+ module Agents
3
+ # Agent responsible for git committing locally staged or modified files
4
+ class CommitterAgent < ComposableAgents::Agent
5
+ prepend AgentDefaults
6
+
7
+ # Constructor
8
+ #
9
+ # @param user_review [Boolean] Should the agent ask for user's git comment review?
10
+ # @param stage [Symbol] Apply different staging strategies:
11
+ # - `all`: Always stage all files
12
+ # - `if_empty`: Stage all files only if the staging aread is empty
13
+ # - `none`: Don't stage anything
14
+ # @param authors [Array<Agent>] List of agents that should be credited as authors of this commit
15
+ # @param agent_params [Hash{Symbol => Object}] Extra agent parameters
16
+ def initialize(user_review: true, stage: :if_empty, authors: [], **agent_params)
17
+ super(name: 'Committer', **agent_params)
18
+ @user_review = user_review
19
+ @stage = stage
20
+ @authors = authors
21
+ end
22
+
23
+ # Execute the agent to generate some output artifacts based on some input artifacts.
24
+ #
25
+ # @return [Hash{Symbol => Object}] Output artifacts content
26
+ def run
27
+ case @stage
28
+ when :all
29
+ Helpers.git.add(all: true)
30
+ when :if_empty
31
+ Helpers.git.add(all: true) if Helpers.git_diff_cached.empty?
32
+ when :none
33
+ # Do nothing
34
+ else
35
+ raise "Unknown staging strategy: #{@stage}"
36
+ end
37
+ if Helpers.git_diff_cached.empty?
38
+ log_debug 'Nothing to commit'
39
+ else
40
+ git_diff_interpreter_agent = GitDiffInterpreterAgent.new
41
+ git_diff_interpreter_agent_output = git_diff_interpreter_agent.run(git_ref_base: 'cached')
42
+ content = <<~EO_COMMIT
43
+ #{git_diff_interpreter_agent_output[:one_line_summary].strip}
44
+
45
+ #{git_diff_interpreter_agent_output[:change_intent].strip}
46
+
47
+ Co-authored by X-Aeon AI Agents:
48
+ #{
49
+ (@authors + [git_diff_interpreter_agent.diff_interpreter_agent]).map do |agent|
50
+ "* #{agent.full_name}"
51
+ end.join("\n")
52
+ }
53
+ EO_COMMIT
54
+ if @user_review
55
+ content, _user_prompt = Helpers.review_content(
56
+ name: 'commit.md',
57
+ description: 'Git commit comment',
58
+ editable: true,
59
+ content:
60
+ )
61
+ end
62
+ Helpers.git.commit(content)
63
+
64
+ puts
65
+ puts 'Commit created successfully.'
66
+ end
67
+ {}
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,235 @@
1
+ require 'diffy'
2
+
3
+ module XAeonAgents
4
+ module Agents
5
+ # Agent responsible for developing some requirements
6
+ class DeveloperAgent < ComposableAgents::Agent
7
+ prepend AgentDefaults
8
+
9
+ # Define input artifacts contracts
10
+ #
11
+ # @return [Hash{Symbol => Object}] Set of input artifacts description, per artifact name
12
+ def input_artifacts_contracts
13
+ { requirements: 'The initial requirements that need to be implemented' }
14
+ end
15
+
16
+ # Constructor
17
+ #
18
+ # @param commit [Boolean] Should we commit files at every step?
19
+ # @param pull_request [Boolean] Should we create a Github Pull Request with this implementation?
20
+ # @param agent_params [Hash{Symbol => Object}] Extra agent parameters
21
+ def initialize(commit: false, pull_request: false, **agent_params)
22
+ super(name: 'Developer', **agent_params)
23
+ @commit = commit
24
+ @pull_request = pull_request
25
+ end
26
+
27
+ # Execute the agent to generate some output artifacts based on some input artifacts.
28
+ #
29
+ # @param requirements [String] Requirements to be implemented
30
+ # @return [Hash{Symbol => Object}] Output artifacts content
31
+ def run(requirements:)
32
+ # Initial artifacts
33
+ step(:setup_requirements) do
34
+ @artifacts.merge!(
35
+ requirements:,
36
+ base_sha: Helpers.git.gcommit('HEAD').sha
37
+ )
38
+ end
39
+
40
+ planner_agent = new_agent(PlannerAgent)
41
+ step_agent(planner_agent)
42
+
43
+ coder_agent = new_agent(CoderAgent, **Config.agent_options['free_complex'])
44
+
45
+ step_agent(
46
+ coder_agent,
47
+ user_instructions: "Follow all the steps of the implementation plan described in the artifact named `#{coder_agent.artifact_ref(:plan)}`."
48
+ )
49
+ puts "===== Coder changes: #{Helpers.git.status.changed.keys.join(', ')}"
50
+
51
+ step_agent(new_agent(CommitterAgent, user_review: false, stage: :all, authors: [coder_agent])) if @commit
52
+
53
+ tester_agent = new_agent(TesterAgent, **Config.agent_options['free_complex'])
54
+
55
+ step(:test) do
56
+ tests_cmd = 'bundle exec rspec --format documentation'
57
+ @artifacts[:tests_cmd] = tests_cmd
58
+ idx_test = 0
59
+ loop do
60
+ puts
61
+ puts "===== Run tests ##{idx_test}..."
62
+ test_result = Helpers.run_cmd(tests_cmd, expected_exit_status: nil)
63
+ puts "Tests ##{idx_test} exit status: #{test_result[:exit_status]}"
64
+ @artifacts[:tests_output] = <<~EO_ARTIFACT
65
+ ```
66
+ #{test_result[:stdout]}
67
+ ```
68
+ EO_ARTIFACT
69
+ break if test_result[:exit_status].zero?
70
+
71
+ @artifacts[:files_diffs] = Helpers.artifact_files_diffs(@artifacts[:base_sha])
72
+ step_agent(
73
+ tester_agent,
74
+ user_instructions: {
75
+ ordered_list: [
76
+ <<~EO_STEP,
77
+ Understand the initial requirements from the artifact named `#{tester_agent.artifact_ref(:requirements)}`
78
+
79
+ - Understand those requirements and their intent.
80
+ EO_STEP
81
+ <<~EO_STEP,
82
+ Understand the implementation plan from the artifact named `#{tester_agent.artifact_ref(:plan)}`
83
+
84
+ - Understand all the steps of the implementation plan.
85
+ EO_STEP
86
+ <<~EO_STEP,
87
+ Understand the file changes from the artifact named `#{tester_agent.artifact_ref(:files_diffs)}`
88
+
89
+ - Understand what was the intent of the developer implementing the requirements.
90
+ EO_STEP
91
+ <<~EO_STEP,
92
+ Analyze the full output of unit tests run from the artifact named `#{tester_agent.artifact_ref(:tests_output)}`
93
+
94
+ - Check every error reported in the output.
95
+ EO_STEP
96
+ 'Fix any issue that unit tests are surfacing, while keeping the original intent of the requirements',
97
+ 'Remember any inconsistency and modification you need to make to the implementation plan ' \
98
+ 'so that your fixes are in-line with a better implementation plan',
99
+ <<~EO_STEP
100
+ Make sure all tests are running without issue after your fixes
101
+
102
+ - You can run tests again using the provided tests command from the artifact named `#{tester_agent.artifact_ref(:tests_cmd)}` to test your own fixes.
103
+ EO_STEP
104
+ ]
105
+ }
106
+ )
107
+ puts "===== Tester changes: #{Helpers.git.status.changed.keys.join(', ')}"
108
+ # Integrate potential implementation plan modifications
109
+ unless @artifacts[:plan_modifications].strip.empty?
110
+ plan_modifications = @artifacts.delete(:plan_modifications)
111
+ @artifacts[:plan] = <<~EO_PLAN
112
+ #{@artifacts[:plan].strip}
113
+
114
+ # Revision ##{idx_test} to the implementation plan
115
+
116
+ #{ComposableAgents::Utils::Markdown.align_markdown_headers(plan_modifications, level: 2)}
117
+
118
+ EO_PLAN
119
+ end
120
+ step_agent(new_agent(CommitterAgent, user_review: false, stage: :all, authors: [tester_agent])) if @commit
121
+ idx_test += 1
122
+ end
123
+ end
124
+
125
+ step_agent(new_agent(CommitterAgent, user_review: false, stage: :all, authors: [tester_agent])) if @commit
126
+
127
+ documenter_agent = new_agent(DocumenterAgent, **Config.agent_options['free_complex'])
128
+ @artifacts[:files_diffs] = Helpers.artifact_files_diffs(@artifacts[:base_sha])
129
+
130
+ step_agent(
131
+ documenter_agent,
132
+ user_instructions: {
133
+ ordered_list: [
134
+ <<~EO_STEP,
135
+ Analyze the initial requirements from the artifact named `#{documenter_agent.artifact_ref(:requirements)}`
136
+
137
+ - Those give you information about the requirements you should be documenting.
138
+ EO_STEP
139
+ <<~EO_STEP,
140
+ Analyze all the steps of the implementation plan from the artifact named `#{documenter_agent.artifact_ref(:plan)}`
141
+
142
+ - Those give you every step that should have been followed for this new development.
143
+ EO_STEP
144
+ <<~EO_STEP,
145
+ Analyze the concrete changes from the artifact named `#{documenter_agent.artifact_ref(:files_diffs)}`
146
+
147
+ - Understand what was the intent of the developer implementing those requirements.
148
+ EO_STEP
149
+ <<~EO_STEP,
150
+ Decide if documentation is needed
151
+
152
+ Before making any change, classify the development:
153
+
154
+ - If the change affects:
155
+ - Features
156
+ - Usage
157
+ - APIs
158
+ - Behavior visible to users
159
+ → Documentation update MAY be required
160
+
161
+ - If the change is:
162
+ - Internal refactor
163
+ - Cleanup (removal of useless content)
164
+ - Formatting
165
+ - Documentation-only removal of irrelevant info
166
+ → NO documentation update is required
167
+
168
+ If no documentation is required:
169
+ → STOP and do nothing
170
+ EO_STEP
171
+ <<~EO_STEP,
172
+ Explore the filesystem to locate documentation files
173
+
174
+ Guidelines:
175
+ - Start with README.md and docs/**/*.md if they exist.
176
+ - Look for files mentioning related features or APIs.
177
+ - Find documentation files that are referenced recursively from other documentation files.
178
+ - Understand the documentation structure and content.
179
+ - If no relevant documentation is found, proceed by assuming documentation needs to be created or extended.
180
+ - If you are unsure which documentation file to update: default to updating README.md.
181
+
182
+ This step is best-effort and should not block progress.
183
+ EO_STEP
184
+ <<~EO_STEP
185
+ Update the relevant documentation files
186
+
187
+ - Only perform this step if you think documentation is required.
188
+ - Use artifacts as the source of truth for understanding the changes to be documented.
189
+ - Use the filesystem to locate where documentation should be updated.
190
+ - After exploring the filesystem, if relevant documentation files are found: update them.
191
+
192
+ When updating documentation:
193
+ - Modify existing sections if they already describe related functionality.
194
+ - Add new sections if the feature is not documented.
195
+ - Keep consistency with existing documentation style.
196
+ - Prefer minimal, precise updates over large rewrites.
197
+ EO_STEP
198
+ ]
199
+ }
200
+ )
201
+ puts "===== Documenter changes: #{Helpers.git.status.changed.keys.join(', ')}"
202
+
203
+ if @commit || @pull_request
204
+ step_agent(
205
+ new_agent(
206
+ CommitterAgent,
207
+ user_review: false,
208
+ stage: :all,
209
+ authors: (@commit ? [] : [coder_agent, tester_agent]) + [documenter_agent]
210
+ )
211
+ )
212
+ end
213
+
214
+ if @pull_request
215
+ step_agent(
216
+ new_agent(
217
+ PullRequestCreatorAgent,
218
+ authors: [
219
+ planner_agent.plan_generator_agent,
220
+ coder_agent,
221
+ tester_agent,
222
+ documenter_agent
223
+ ]
224
+ )
225
+ )
226
+ end
227
+
228
+ puts
229
+ puts 'Requirements implemented successfully'
230
+
231
+ @artifacts
232
+ end
233
+ end
234
+ end
235
+ end
@@ -0,0 +1,80 @@
1
+ module XAeonAgents
2
+ module Agents
3
+ # Agent responsible for analyzing files differences in a repository
4
+ class DiffInterpreterAgent < ComposableAgents::AiAgents::Agent
5
+ prepend AgentDefaults
6
+
7
+ # Define input artifacts contracts
8
+ #
9
+ # @return [Hash{Symbol => Object}] Set of input artifacts description, per artifact name
10
+ def input_artifacts_contracts
11
+ super.merge(files_diff: 'The full list of files changes and differences that have been done')
12
+ end
13
+
14
+ # Define output artifacts contracts
15
+ #
16
+ # @return [Hash{Symbol => Object}] Set of output artifacts description, per artifact name
17
+ def output_artifacts_contracts
18
+ super.merge(
19
+ change_intent: {
20
+ description: 'The full explanation of the changes, as in a git commit description',
21
+ type: :text
22
+ }
23
+ )
24
+ end
25
+
26
+ # Constructor
27
+ #
28
+ # @param agent_params [Hash{Symbol => Object}] Extra agent parameters
29
+ def initialize(**agent_params)
30
+ super(
31
+ name: 'Diff interpreter',
32
+ role: 'You are a files diff interpreter agent',
33
+ objective: <<~EO_OBJECTIVE,
34
+ Interpret files modifications and explain the changes properly with its meaning and intent.
35
+
36
+ The goals are:
37
+ - Get a general explanation of those changes.
38
+ - Identify the kind of changes involved (new features, feature change, bug fix, documentation...).
39
+ - Identify the components that are impacted by those changes (a specific plugin, CLI, UI...).
40
+ EO_OBJECTIVE
41
+ **agent_params
42
+ )
43
+ self.system_instructions = {
44
+ ordered_list: [
45
+ <<~EO_INSTRUCTIONS,
46
+ Read and analyze ALL file changes from the artifact named `#{artifact_ref(:files_diff)}`
47
+
48
+ - Those changes are the ones you must explain.
49
+ EO_INSTRUCTIONS
50
+ <<~EO_INSTRUCTIONS,
51
+ Analyze the project files
52
+
53
+ - Those files give you context to understand the changes.
54
+ - Changes made on those files should NOT be explained unless they are part of the artifact named `#{artifact_ref(:files_diff)}`.
55
+ EO_INSTRUCTIONS
56
+ <<~EO_INSTRUCTIONS
57
+ Create an artifact named `#{artifact_ref(:change_intent)}` to explain properly the changes reported by the artifact named `#{artifact_ref(:files_diff)}`
58
+
59
+ - You MUST create an artifact named `change_intent` that contains:
60
+ 1. A general explanation of the changes, their meaning and intent in the context of this project.
61
+ 2. The types of changes (feature, bug fix, documentation, etc.).
62
+ 3. The impacted architectural components (backend, login screen, CLI, etc.).
63
+ - Describe those changes in a way similar to a git commit comment or a pull request description.
64
+ - ONLY cover changes from the artifact named `#{artifact_ref(:files_diff)}`.
65
+ - Do NOT explain changes for other files.
66
+ EO_INSTRUCTIONS
67
+ ]
68
+ }
69
+ self.constraints = <<~EO_CONSTRAINTS
70
+ - You are in read-only mode.
71
+ - Do NOT modify or write any file.
72
+ - You must ONLY explain the changes of the artifact named `#{artifact_ref(:files_diff)}`, NOT other changes.
73
+ - You already have ALL the information required.
74
+ - The user's intent is fully specified.
75
+ - The conversation log is provided for context only. You MUST NOT ask follow-up questions.
76
+ EO_CONSTRAINTS
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,44 @@
1
+ module XAeonAgents
2
+ module Agents
3
+ # Agent responsible for updating documentation after a new development
4
+ class DocumenterAgent < ComposableAgents::Cline::Agent
5
+ prepend AgentDefaults
6
+
7
+ # Define input artifacts contracts
8
+ #
9
+ # @return [Hash{Symbol => Object}] Set of input artifacts description, per artifact name
10
+ def input_artifacts_contracts
11
+ super.merge(
12
+ requirements: 'The initial requirements',
13
+ plan: 'Implementation plan that introduced features and fixes to be documented',
14
+ files_diffs: 'Full list of files changes and differences that have been done to implement the initial requirements following the implementation plan'
15
+ )
16
+ end
17
+
18
+ # Constructor
19
+ #
20
+ # @param agent_params [Hash{Symbol => Object}] Extra agent parameters
21
+ def initialize(**agent_params)
22
+ super(
23
+ name: 'Documenter',
24
+ objective: 'Ensure documentation reflects the current product behavior and usage after a new development.',
25
+ constraints: <<~EO_CONSTRAINTS,
26
+ - Only update documentation files.
27
+ - Do NOT change any code or test.
28
+ - NEVER document the fact that a change happened.
29
+ - NEVER explain that something was removed, renamed, or fixed.
30
+ - Documentation describes the CURRENT STATE only.
31
+ - Documentation is NOT a changelog.
32
+ EO_CONSTRAINTS
33
+ skills: %w[
34
+ applying-ruby-conventions
35
+ applying-test-conventions
36
+ updating-doc
37
+ enforcing-project-rules
38
+ ],
39
+ **agent_params
40
+ )
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,9 @@
1
+ module XAeonAgents
2
+ module Agents
3
+ # Simple AI agent executing some prompt and interacting with the user
4
+ class ExecutorAgent < ComposableAgents::AiAgents::Agent
5
+ prepend ComposableAgents::Mixins::UserInteraction
6
+ prepend AgentDefaults
7
+ end
8
+ end
9
+ end