x_aeon_agents 1.0.28 → 1.0.31

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -0
  3. data/README.md +73 -20
  4. data/lib/x_aeon_agents/agent_defaults.rb +86 -13
  5. data/lib/x_aeon_agents/agents/coder_agent.rb +0 -5
  6. data/lib/x_aeon_agents/agents/committer_agent.rb +25 -16
  7. data/lib/x_aeon_agents/agents/developer_agent.rb +98 -89
  8. data/lib/x_aeon_agents/agents/documenter_agent.rb +0 -6
  9. data/lib/x_aeon_agents/agents/executor_agent.rb +7 -0
  10. data/lib/x_aeon_agents/agents/feedback_analyst_agent.rb +1 -6
  11. data/lib/x_aeon_agents/agents/git_diff_interpreter_agent.rb +9 -4
  12. data/lib/x_aeon_agents/agents/issue_implementer_agent.rb +21 -8
  13. data/lib/x_aeon_agents/agents/plan_generator_agent.rb +2 -7
  14. data/lib/x_aeon_agents/agents/planner_agent.rb +37 -22
  15. data/lib/x_aeon_agents/agents/pull_request_creator_agent.rb +21 -13
  16. data/lib/x_aeon_agents/agents/readme/about_analyzer_agent.rb +1 -1
  17. data/lib/x_aeon_agents/agents/readme/contributing_agent.rb +1 -1
  18. data/lib/x_aeon_agents/agents/readme/development_agent.rb +1 -1
  19. data/lib/x_aeon_agents/agents/readme/documentation_agent.rb +1 -1
  20. data/lib/x_aeon_agents/agents/readme/features_agent.rb +1 -1
  21. data/lib/x_aeon_agents/agents/readme/how_it_works_agent.rb +1 -1
  22. data/lib/x_aeon_agents/agents/readme/license_agent.rb +1 -1
  23. data/lib/x_aeon_agents/agents/readme/public_api_agent.rb +1 -1
  24. data/lib/x_aeon_agents/agents/readme/quick_start_agent.rb +1 -1
  25. data/lib/x_aeon_agents/agents/readme/requirements_agent.rb +1 -1
  26. data/lib/x_aeon_agents/agents/readme_generator_agent.rb +41 -23
  27. data/lib/x_aeon_agents/agents/review_resolver_agent.rb +67 -62
  28. data/lib/x_aeon_agents/agents/review_responder_agent.rb +1 -1
  29. data/lib/x_aeon_agents/agents/skill_generator_agent.rb +36 -32
  30. data/lib/x_aeon_agents/agents/skill_installer_agent.rb +30 -22
  31. data/lib/x_aeon_agents/agents/task_starter_agent.rb +61 -7
  32. data/lib/x_aeon_agents/cli.rb +19 -7
  33. data/lib/x_aeon_agents/config.rb +127 -18
  34. data/lib/x_aeon_agents/config_dsl.rb +90 -0
  35. data/lib/x_aeon_agents/helpers.rb +3 -26
  36. data/lib/x_aeon_agents/logger.rb +457 -13
  37. data/lib/x_aeon_agents/version.rb +1 -1
  38. metadata +90 -6
  39. data/lib/x_aeon_agents/agent_options.rb +0 -58
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 274bac6b54d8088177db949e35844922ef51bafc121cf9e9f6816c86c53aecb8
4
- data.tar.gz: 8841173b7bda8326b7db717401be6ce48e2245306c79237471a41f01ee3c84e4
3
+ metadata.gz: a3ff43b4352a549cc20bf1b286d89aa551f549c6109811c7456c3393e39f3184
4
+ data.tar.gz: 5671b1fe28a848307a12316ce54e962db5a67c3a6b0872c6f3034ca0c7c2478e
5
5
  SHA512:
6
- metadata.gz: 9b3653983e16b09d893bf1d165cd752f3998ecd0b983a738d207ee9c03b2eb7030a44fa4f0639b981393db59d8ab644de79a40645913b6652dd375b2ba417dcd
7
- data.tar.gz: f226b0a89b9c0348f975d23bf1d31a646e436cf737fab675f8a6ecb707b3540e7e83e0a8e3f000f621e04e3ca43018b73329adbe573a437baeb2dbc2d8d40768
6
+ metadata.gz: 184273cc4819f1aaa01dc74f51a6319b8a5d30e5e7dddf83a85fadb52d14246c9a3b136a46ab39eccc43e99ee38d1a9ed7bbb36a52a698e5a32cd73fe554239e
7
+ data.tar.gz: 0b5e05209e2e5a03d3de7c411e2686a9ee5672a343f27b81ba202ef5821ca97f40e0fd5a4003d19c81a3c7aaa7863d2ac3ee2f9d03fce4a6da0e17cd731a988d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,45 @@
1
+ # [v1.0.31](https://github.com/Muriel-Salvan/x_aeon_agents/compare/v1.0.30...v1.0.31) (2026-09-10 15:11:18)
2
+
3
+ ### Patches
4
+
5
+ * [chore: switch to cleanroom-next and RubyGems trusted publishing](https://github.com/Muriel-Salvan/x_aeon_agents/commit/26c07f2ba1b42500032d1f7d6055b3351ff5b95d)
6
+
7
+ # [v1.0.30](https://github.com/Muriel-Salvan/x_aeon_agents/compare/v1.0.29...v1.0.30) (2026-09-09 13:21:12)
8
+
9
+ ### Patches
10
+
11
+ * [Status logging](https://github.com/Muriel-Salvan/x_aeon_agents/commit/aac424c29176810f081cd5ba4435c4f19b7a27f7)
12
+ * [fix(config): pass through SecretString returned by config DSL](https://github.com/Muriel-Salvan/x_aeon_agents/commit/16baaf8161384f6d206e60f606af48cd6cb6118a)
13
+ * [test: stub AI model discovery in unit tests](https://github.com/Muriel-Salvan/x_aeon_agents/commit/10416fce4bbbd65c2539b7f386812bf5f5bc643b)
14
+ * [feat: make test command configurable and skip tests when unset](https://github.com/Muriel-Salvan/x_aeon_agents/commit/1e238bde0e24bf2443a3f4acad3cc2c43cbad144)
15
+ * [test: update git diff interpreter agent specs for artifact-based assertions](https://github.com/Muriel-Salvan/x_aeon_agents/commit/5637a822714c889f08d609e7202b8a124ed2b582)
16
+ * [ci: relax rubocop rules and clean up test helper](https://github.com/Muriel-Salvan/x_aeon_agents/commit/87147dfe7918147b92f2dc9353b65394fc9f24a9)
17
+ * [test: add CLI scenario specs for all commands](https://github.com/Muriel-Salvan/x_aeon_agents/commit/8faddbb3595a61187325753e7476c6be3bcca1d5)
18
+ * [test: replace inline strings with heredocs in scenario specs](https://github.com/Muriel-Salvan/x_aeon_agents/commit/c4b4a326b375279208ad756e7d5f3be96899cc5d)
19
+ * [test(agents): add integration specs for git workflow agents](https://github.com/Muriel-Salvan/x_aeon_agents/commit/182c66f3abadca3c8d4a396efb473b3c0cd7a786)
20
+ * [Prepare for logging work](https://github.com/Muriel-Salvan/x_aeon_agents/commit/fad1d84e8e18a3934cdaf6ad62d22c40e35ad303)
21
+ * [test: add common behavior specs for all XAeonAgents agents](https://github.com/Muriel-Salvan/x_aeon_agents/commit/4cb6944489d5e67c6d614f4b764cae4313decec2)
22
+ * [test: cover config DSL behaviors in agent defaults examples](https://github.com/Muriel-Salvan/x_aeon_agents/commit/687edc40286b8c4f7e069df2b4cbd5334ad87976)
23
+ * [test: extract AgentDefaults specs into shared examples](https://github.com/Muriel-Salvan/x_aeon_agents/commit/42c9f3bf9c0e64a3ce9d1f6d7223ec6751723dc4)
24
+ * [refactor: replace puts calls with Logger helpers in agents](https://github.com/Muriel-Salvan/x_aeon_agents/commit/cf2245c702dae65fa2dd86d2f800304aa4b5c3f6)
25
+ * [refactor: replace AgentOptions with default kwargs in AgentDefaults](https://github.com/Muriel-Salvan/x_aeon_agents/commit/9926870315499417fa6c8a43b2853b7a4fc2aa47)
26
+ * [feat: add configure_agent DSL for per-class agent defaults](https://github.com/Muriel-Salvan/x_aeon_agents/commit/5c900d9234a4ff96eeef148651dc24308c3675db)
27
+ * [feat(config): add on_open_worktree callback for worktree opening](https://github.com/Muriel-Salvan/x_aeon_agents/commit/c7ae1daa85859e1a789f2af9b80cf704fb9b664f)
28
+ * [feat: add setup_project config DSL for fresh worktree setup](https://github.com/Muriel-Salvan/x_aeon_agents/commit/23f7e3c8468724f1b153e0950aef1eaf552c7009)
29
+ * [feat(config): support X_AEON_AGENTS_CONFIG env var for config path](https://github.com/Muriel-Salvan/x_aeon_agents/commit/c6e33adf35dc35d717eb08469fa59a8bc7e8a542)
30
+ * [fix(planner): run Diffy in unbundled env for system calls](https://github.com/Muriel-Salvan/x_aeon_agents/commit/14dca12662241b1291e697f3fdd59584dafa18ff)
31
+ * [feat(config): support custom secret providers in config file](https://github.com/Muriel-Salvan/x_aeon_agents/commit/c48952f42f48f8f7fc52846ff13c1b954846c606)
32
+ * [feat(skills): add addressing-pull-request-comments skill config](https://github.com/Muriel-Salvan/x_aeon_agents/commit/d720fe13ea8dd07cda4ed6eb0c683ba43fa1442c)
33
+ * [Merge branch 'config-file'](https://github.com/Muriel-Salvan/x_aeon_agents/commit/116b67eb92193572b8373ebc3b4749e524b6044c)
34
+
35
+ # [v1.0.29](https://github.com/Muriel-Salvan/x_aeon_agents/compare/v1.0.28...v1.0.29) (2026-08-21 14:06:00)
36
+
37
+ ### Patches
38
+
39
+ * [chore: add TODOs and update API key descriptions](https://github.com/Muriel-Salvan/x_aeon_agents/commit/7eab6bf59ac760ed6b1b81580b9c9a65a5b9aaca)
40
+ * [fix: use raw git push command to set upstream tracking](https://github.com/Muriel-Salvan/x_aeon_agents/commit/b13498c5e69a30bdb3e7d90aa25d27c230f1fb21)
41
+ * [refactor: simplify git push mock assertions in specs](https://github.com/Muriel-Salvan/x_aeon_agents/commit/a70f024ba93ace278ae007baf61a2ad83530d735)
42
+
1
43
  # [v1.0.28](https://github.com/Muriel-Salvan/x_aeon_agents/compare/v1.0.27...v1.0.28) (2026-07-14 17:05:02)
2
44
 
3
45
  ### Patches
data/README.md CHANGED
@@ -33,6 +33,7 @@ Use it as a **⚡ CLI** in your terminal or as a **📦 library** inside your Ru
33
33
  - [Prerequisites](#prerequisites)
34
34
  - [Install](#install)
35
35
  - [Configure](#configure)
36
+ - [Optional configuration file](#optional-configuration-file)
36
37
  - [Use the CLI](#use-the-cli)
37
38
  - [Use as a library](#use-as-a-library)
38
39
  - [Requirements](#requirements)
@@ -109,6 +110,72 @@ export OPENROUTER_API_KEY="sk-or-..."
109
110
  export GITHUB_TOKEN="ghp_..."
110
111
  ```
111
112
 
113
+ ### Optional configuration file
114
+
115
+ You can fine-tune behaviour with an optional `.x_aeon_agents.rb` configuration file, read at the start of every `xaa` command:
116
+
117
+ - `~/.x_aeon_agents.rb` — in your **home directory**, for *global / user-level* settings;
118
+ - `.x_aeon_agents.rb` — in the **current project directory**, for *project-level* settings;
119
+ - any path stored in the **`X_AEON_AGENTS_CONFIG`** environment variable, for *explicitly designated* settings.
120
+
121
+ When several exist, they are evaluated in that order and the last one wins: the project file overrides the global one, and the `X_AEON_AGENTS_CONFIG` file overrides them both. Exposed directives:
122
+
123
+ - `debug true` / `debug false` — enable or disable debug logging. An explicit `--debug` / `--no-debug` command-line flag always overrides it, and when neither the file nor a flag sets a value, the `X_AEON_AGENTS_DEBUG` environment variable is still honoured.
124
+ - `cline_api_key`, `openrouter_api_key` and `github_token` — declare, using a block, custom Ruby code to retrieve the corresponding secret when it is needed, instead of relying on the `CLINE_API_KEY` / `OPENROUTER_API_KEY` / `GITHUB_TOKEN` environment variables:
125
+
126
+ ```ruby
127
+ cline_api_key do
128
+ # Any Ruby code that returns the key
129
+ File.read('/path/to/my/key').strip
130
+ end
131
+ ```
132
+
133
+ The block is evaluated lazily, only the first time the secret is actually needed, and its result is then cached for the whole session.
134
+ - `setup_project` — declare, using a block, the steps to execute in a freshly created git worktree to install the project's dependencies (used by the `start-task` command):
135
+
136
+ ```ruby
137
+ setup_project do
138
+ system 'bundle install'
139
+ end
140
+ ```
141
+
142
+ The block is evaluated right after the worktree has been created, with the current directory set to the worktree. If it is not defined, no setup step is executed.
143
+ - `test_project_cmd` — declare the command line used to run the project's tests suite, executed by the `implement` command after each code change and after each fix made by the Tester agent:
144
+
145
+ ```ruby
146
+ test_project_cmd 'bundle exec rspec'
147
+ ```
148
+
149
+ If it is not defined, the `implement` command does not run any tests.
150
+ - `on_open_worktree` — declare, using a block, a callback to execute every time the `start-task` command opens a worktree (freshly created or already existing), after the branch has been pushed to the remote. The block is given the worktree's directory as parameter:
151
+
152
+ ```ruby
153
+ on_open_worktree do |dir|
154
+ system "VSCodium.exe \"#{dir}\""
155
+ end
156
+ ```
157
+
158
+ If it is not defined, nothing is executed when a worktree is opened.
159
+
160
+ - `configure_agent` — declare, using a block, the default kwargs to be used when initializing agents of a given class. The block is evaluated every time an agent of this class is instantiated: it is given the currently merged configuration of the agent (a Hash of kwargs, that can be modified in place), and can return a Hash of additional kwargs to be merged into this configuration:
161
+
162
+ ```ruby
163
+ configure_agent(:PlanGeneratorAgent) do
164
+ {
165
+ model: 'deepseek/deepseek-v4-flash',
166
+ cli_options: { plan: true }
167
+ }
168
+ end
169
+
170
+ configure_agent(:PlanGeneratorAgent) do |agent_config|
171
+ agent_config[:skills].push('applying-ruby-conventions')
172
+ agent_config
173
+ end
174
+ ```
175
+
176
+ This method is re-entrant: it can be called several times for the same agent class, from the same config file or from different ones (global, project, env-var designated): each call sees the configuration accumulated by the previous ones, in the order the config files are evaluated. This lets a global config define base settings, and a project config read and adapt them.
177
+ For example, to always run in debug mode inside a given project, create a `.x_aeon_agents.rb` file in that project directory containing `debug true`.
178
+
112
179
  ### Use the CLI
113
180
 
114
181
  The `xaa` command is installed alongside the gem. Run it from inside any Git repository.
@@ -174,6 +241,8 @@ XAeonAgents::Agents::CommitterAgent.new.run
174
241
  - **`OPENROUTER_API_KEY`** environment variable — an OpenRouter API key that powers the AI agents through RubyLLM
175
242
  - **`CLINE_API_KEY`** environment variable (optional) — only required when driving the Cline agent integration
176
243
 
244
+ Each of these secrets can alternatively be retrieved by custom code declared in the [optional configuration file](#optional-configuration-file).
245
+
177
246
  ## Features
178
247
 
179
248
  **x_aeon_agents** provides a *`xaa`* command-line interface and a reusable Ruby library that package a suite of AI agents to automate everyday development workflows.
@@ -233,24 +302,7 @@ Public methods:
233
302
  - `data_dir` / `data_dir=` — X-Aeon Agents data directory. [doc](https://www.rubydoc.info/gems/x-aeon_agents/XAeonAgents/Config#data_dir-class_method)
234
303
  - `default_cline_cli_args` / `default_cline_cli_args=` — default Cline CLI arguments. [doc](https://www.rubydoc.info/gems/x-aeon_agents/XAeonAgents/Config#default_cline_cli_args-class_method)
235
304
  - `debug` / `debug=` — debug mode. [doc](https://www.rubydoc.info/gems/x-aeon_agents/XAeonAgents/Config#debug-class_method)
236
- - `agent_options` — the available `AgentOptions` instance. [doc](https://www.rubydoc.info/gems/x-aeon_agents/XAeonAgents/Config#agent_options-class_method)
237
-
238
- ### `XAeonAgents::AgentOptions`
239
-
240
- Provides agent options (model, strategy, etc.) keyed by agent category. These options can be passed to an agent's constructor.
241
-
242
- **Usecase** — read the options for a given category:
243
-
244
- ```ruby
245
- opts = XAeonAgents::Config.agent_options['free_simple']
246
- # => { model: 'openrouter/free', strategy: ComposableAgents::PromptRenderingStrategy::Markdown }
247
- ```
248
-
249
- More details: [RubyDoc — XAeonAgents::AgentOptions](https://www.rubydoc.info/gems/x-aeon_agents/XAeonAgents/AgentOptions)
250
-
251
- Public methods:
252
- - `[](agent_category)` — get the options for a category (lazily evaluated). [doc](https://www.rubydoc.info/gems/x-aeon_agents/XAeonAgents/AgentOptions#%5B%5D-instance_method)
253
- - `[]=(agent_category, agent_options)` — set the options for a category. [doc](https://www.rubydoc.info/gems/x-aeon_agents/XAeonAgents/AgentOptions)
305
+ - `config_paths` — locate the optional `.x_aeon_agents.rb` config file(s) (home dir, then project dir). [doc](https://www.rubydoc.info/gems/x-aeon_agents/XAeonAgents/Config)
254
306
 
255
307
  ### `XAeonAgents::GenHelpers`
256
308
 
@@ -314,7 +366,7 @@ The documented public methods (browseable on RubyDoc.info):
314
366
 
315
367
  ### Entry point 🚪
316
368
 
317
- The `xaa` executable ([`bin/xaa`](https://github.com/Muriel-Salvan/x_aeon_agents/blob/main/bin/xaa)) boots Zeitwerk auto-loading and calls `XAeonAgents::Cli.start(ARGV)`. The CLI ([`lib/x_aeon_agents/cli.rb`](https://github.com/Muriel-Salvan/x_aeon_agents/blob/main/lib/x_aeon_agents/cli.rb)) is a [Thor](https://github.com/rails/thor) application: each sub-command maps **1:1** to an agent and forwards global options (`--session-id`, `--debug`).
369
+ The `xaa` executable ([`bin/xaa`](https://github.com/Muriel-Salvan/x_aeon_agents/blob/main/bin/xaa)) boots Zeitwerk auto-loading and calls `XAeonAgents::Cli.start(ARGV)`. The CLI ([`lib/x_aeon_agents/cli.rb`](https://github.com/Muriel-Salvan/x_aeon_agents/blob/main/lib/x_aeon_agents/cli.rb)) is a [Thor](https://github.com/rails/thor) application: each sub-command maps **1:1** to an agent and forwards global options (`--session-id`, `--debug`). On startup, it also reads the optional `.x_aeon_agents.rb` configuration file (home directory, then project directory) so project-level settings can override global ones, and explicit command-line flags override both.
318
370
 
319
371
  ### Agents as composable workflows 🧩
320
372
 
@@ -327,6 +379,7 @@ Each agent is enriched by the `AgentDefaults` mixin ([`lib/x_aeon_agents/agent_d
327
379
 
328
380
  - injects `new_agent(...)`, `step(...)` and `step_agent(...)` to build multi-step pipelines;
329
381
  - auto-configures the underlying frameworks (`setup_composable_agents`, `setup_ai_agents`, `setup_cline`);
382
+ - sets default constructor kwargs for the underlying AI framework (`strategy` for AI agents, `api_key` + `cli_options` for Cline agents), which can be overwritten per agent class with the `configure_agent` config DSL;
330
383
  - manages a per-session directory under `Config.data_dir/sessions/<id>`;
331
384
  - prepends `ArtifactContract` + `Resumable` mixins for input/output validation and pause/resume.
332
385
 
@@ -352,7 +405,7 @@ flowchart TD
352
405
 
353
406
  ### Configuration & providers 🔐
354
407
 
355
- [`XAeonAgents::Config`](https://www.rubydoc.info/gems/x-aeon_agents/XAeonAgents/Config) is a singleton holding secrets (`cline_api_key`, `openrouter_api_key`, `github_token`), the data directory, debug flag and per-category `AgentOptions` (model + strategy, e.g. `free_simple`, `free_complex`). LLM access flows through `Providers::Cline` ([`lib/x_aeon_agents/providers/cline.rb`](https://github.com/Muriel-Salvan/x_aeon_agents/blob/main/lib/x_aeon_agents/providers/cline.rb)), an OpenAI-compatible [RubyLLM](https://github.com/crmne/ruby_llm) provider targeting the Cline API.
408
+ [`XAeonAgents::Config`](https://www.rubydoc.info/gems/x-aeon_agents/XAeonAgents/Config) is a singleton holding secrets (`cline_api_key`, `openrouter_api_key`, `github_token`), the data directory and debug flag. Agents' options (model, strategy, ...) can be customized per agent class with the `configure_agent` config DSL. LLM access flows through `Providers::Cline` ([`lib/x_aeon_agents/providers/cline.rb`](https://github.com/Muriel-Salvan/x_aeon_agents/blob/main/lib/x_aeon_agents/providers/cline.rb)), an OpenAI-compatible [RubyLLM](https://github.com/crmne/ruby_llm) provider targeting the Cline API.
356
409
 
357
410
  ### Skills & ERB templating 📚
358
411
 
@@ -2,13 +2,23 @@ module XAeonAgents
2
2
  # Mixin setting up default settings for agents.
3
3
  # This mixin is meant to be the last prepended mixin in all Agent classes.
4
4
  module AgentDefaults
5
+ # Give all agents access to the shared logger instance.
6
+ #
7
+ # @return [Logger] The shared logger instance
8
+ def logger
9
+ Config.logger
10
+ end
11
+
5
12
  class << self
6
- # Get the singleton session ID.
7
- # If it is the first time it is invoked, use a default session ID.
13
+ # @return [String] The singleton session ID. If it is the first time it is invoked, use a default session ID.
8
14
  def singleton_session_id
9
15
  @singleton_session_id ||= Time.now.utc.strftime('%Y-%m-%d-%H-%M-%S-%N')
10
16
  end
17
+
18
+ # @return [Array<Agent>] List of root agents (not instantiated from another agent).
19
+ attr_accessor :root_agents
11
20
  end
21
+ AgentDefaults.root_agents = []
12
22
 
13
23
  # Instantiate a new agent.
14
24
  # Transfer the same session to the new agent.
@@ -18,7 +28,7 @@ module XAeonAgents
18
28
  # @param kwargs [Hash] Constructor kwargs
19
29
  # @return [ComposableAgents::Agent] The new agent
20
30
  def new_agent(agent_class, *args, **kwargs)
21
- agent_class.new(*args, session_id: @session_id, **kwargs)
31
+ agent_class.new(*args, session_id: @session_id, parent_agent: self, **kwargs)
22
32
  end
23
33
 
24
34
  # Hook called when this mixin is prepended in a class
@@ -32,17 +42,33 @@ module XAeonAgents
32
42
  Module.new do
33
43
  # Constructor
34
44
  #
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)
45
+ # @param args [Array] Agent's constructor arguments.
46
+ # @param session_id [String, nil] Specific X-Aeon session id to be used, or nil if none.
47
+ # @param parent_agent [Agent, nil] Agent that is initializing this agent, or nil if none.
48
+ # @param kwargs [Array] Agent's constructor kwargs.
49
+ def initialize(*args, session_id: nil, parent_agent: nil, **kwargs)
50
+ AgentDefaults.root_agents << self if parent_agent.nil?
39
51
  # If we inherit from some frameworks initialize them now.
40
52
  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
53
+ kwargs_from_agent_defaults =
54
+ case self
55
+ when ComposableAgents::AiAgents::Agent
56
+ Config.setup_ai_agents
57
+ {
58
+ strategy: ComposableAgents::PromptRenderingStrategy::Markdown
59
+ }
60
+ when ComposableAgents::Cline::Agent
61
+ Config.setup_cline
62
+ {
63
+ api_key: Config.cline_api_key,
64
+ cli_options: Config.default_cline_cli_args
65
+ }
66
+ else
67
+ {}
68
+ end
69
+ kwargs_from_config = kwargs_from_agent_defaults
70
+ Config.agent_config_procs(self.class.name.split('::').last.to_sym).each do |config_proc|
71
+ kwargs_from_config = kwargs_from_config.merge(config_proc.call(kwargs_from_config))
46
72
  end
47
73
  @session_id = session_id || AgentDefaults.singleton_session_id
48
74
  @session_dir = "#{Config.data_dir}/sessions/#{@session_id}"
@@ -50,9 +76,56 @@ module XAeonAgents
50
76
  *args,
51
77
  composable_agents_dir: "#{@session_dir}/composable_agents",
52
78
  run_id: "#{@session_id}-#{kwargs[:name] || self.class.name.split('::').last}",
53
- **kwargs
79
+ logger: Config.logger,
80
+ **kwargs_from_config.merge(kwargs)
54
81
  )
55
82
  end
83
+
84
+ # Define a task that is resumable and that will log big steps of an agent.
85
+ # A task can be nested in other tasks.
86
+ #
87
+ # @param task_ref [Symbol, ComposableAgents::Agent] Task reference: can be an ID or an Agent to be run.
88
+ # @param name [String] Task name (used in status and logs).
89
+ # @param intent [String] Task intent (used in logs).
90
+ # @param kwargs [Hash{Symbol => Object}] Additional input artifacts to merge before the task executes.
91
+ # @yield The code called for this task if it is not an Agent.
92
+ def task(
93
+ task_ref = :task,
94
+ name: task_ref.is_a?(ComposableAgents::Agent) ? task_ref.name : task_ref.to_s,
95
+ intent: 'Execute',
96
+ **kwargs,
97
+ &
98
+ )
99
+ @step_metadata = {
100
+ name:,
101
+ intent:
102
+ }
103
+ artifacts_before = @artifacts.clone
104
+ logger.info "[Task #{name}] - #{intent}"
105
+ if task_ref.is_a?(Symbol)
106
+ step(task_ref, **kwargs, &)
107
+ else
108
+ step_agent(task_ref, **kwargs)
109
+ end
110
+ added_artifacts = @artifacts.keys - artifacts_before.keys
111
+ logger.info "[Task #{name}] - Created #{added_artifacts.size} new artifacts: #{added_artifacts.join(', ')}"
112
+ end
113
+
114
+ private
115
+
116
+ # Override record_step to inject the metadata into the step node.
117
+ #
118
+ # @param step_name [Symbol] Name of the step, mirroring the one used by the persisted steps.
119
+ # @param agent [ComposableAgents::Agent, nil] The agent run by this step, or nil for plain steps.
120
+ # @param extra_input_artifacts [Hash{Symbol => Object}] Input artifacts given to the step.
121
+ # @yield The code of the step to be executed
122
+ def record_step(step_name:, agent:, extra_input_artifacts:, &block)
123
+ super do
124
+ @current_step_node[:metadata] = @step_metadata if @step_metadata
125
+ @step_metadata = nil
126
+ block&.call
127
+ end
128
+ end
56
129
  end
57
130
  )
58
131
  end
@@ -69,11 +69,6 @@ module XAeonAgents
69
69
  Always provide the final result in your response.
70
70
  Always validate your answer with checking the code and running it if possible.
71
71
  EO_CONSTRAINTS
72
- skills: %w[
73
- applying-ruby-conventions
74
- applying-test-conventions
75
- enforcing-project-rules
76
- ],
77
72
  **agent_params
78
73
  )
79
74
  end
@@ -24,25 +24,32 @@ module XAeonAgents
24
24
  #
25
25
  # @return [Hash{Symbol => Object}] Output artifacts content
26
26
  def run
27
+ super
27
28
  case @stage
28
29
  when :all
29
- Helpers.git.add(all: true)
30
+ task(:git_add, name: 'Git add', intent: 'Stage all modifications') do
31
+ Helpers.git.add(all: true)
32
+ end
30
33
  when :if_empty
31
- Helpers.git.add(all: true) if Helpers.git_diff_cached.empty?
34
+ if Helpers.git_diff_cached.empty?
35
+ task(:git_add, name: 'Git add', intent: 'Stage all modifications as nothing was staged previously') do
36
+ Helpers.git.add(all: true)
37
+ end
38
+ end
32
39
  when :none
33
40
  # Do nothing
34
41
  else
35
42
  raise "Unknown staging strategy: #{@stage}"
36
43
  end
37
44
  if Helpers.git_diff_cached.empty?
38
- log_debug 'Nothing to commit'
45
+ logger.info 'Nothing to commit'
39
46
  else
40
47
  git_diff_interpreter_agent = GitDiffInterpreterAgent.new
41
- git_diff_interpreter_agent_output = git_diff_interpreter_agent.run(git_ref_base: 'cached')
48
+ task(git_diff_interpreter_agent, intent: 'Analyze staged git diffs', git_ref_base: 'cached')
42
49
  content = <<~EO_COMMIT
43
- #{git_diff_interpreter_agent_output[:one_line_summary].strip}
50
+ #{@artifacts[:one_line_summary].strip}
44
51
 
45
- #{git_diff_interpreter_agent_output[:change_intent].strip}
52
+ #{@artifacts[:change_intent].strip}
46
53
 
47
54
  Co-authored by X-Aeon AI Agents:
48
55
  #{
@@ -52,17 +59,19 @@ module XAeonAgents
52
59
  }
53
60
  EO_COMMIT
54
61
  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
- )
62
+ task(:user_review, name: 'Commit comment user review', intent: 'Ask user to review the commit comment') do
63
+ content, _user_prompt = Helpers.review_content(
64
+ name: 'commit.md',
65
+ description: 'Git commit comment',
66
+ editable: true,
67
+ content:
68
+ )
69
+ end
61
70
  end
62
- Helpers.git.commit(content)
63
-
64
- puts
65
- puts 'Commit created successfully.'
71
+ task(:git_commit, name: 'Git commit', intent: 'Create a commit') do
72
+ Helpers.git.commit(content)
73
+ end
74
+ logger << 'Commit created successfully.'
66
75
  end
67
76
  {}
68
77
  end