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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -0
- data/README.md +73 -20
- data/lib/x_aeon_agents/agent_defaults.rb +86 -13
- data/lib/x_aeon_agents/agents/coder_agent.rb +0 -5
- data/lib/x_aeon_agents/agents/committer_agent.rb +25 -16
- data/lib/x_aeon_agents/agents/developer_agent.rb +98 -89
- data/lib/x_aeon_agents/agents/documenter_agent.rb +0 -6
- data/lib/x_aeon_agents/agents/executor_agent.rb +7 -0
- data/lib/x_aeon_agents/agents/feedback_analyst_agent.rb +1 -6
- data/lib/x_aeon_agents/agents/git_diff_interpreter_agent.rb +9 -4
- data/lib/x_aeon_agents/agents/issue_implementer_agent.rb +21 -8
- data/lib/x_aeon_agents/agents/plan_generator_agent.rb +2 -7
- data/lib/x_aeon_agents/agents/planner_agent.rb +37 -22
- data/lib/x_aeon_agents/agents/pull_request_creator_agent.rb +21 -13
- data/lib/x_aeon_agents/agents/readme/about_analyzer_agent.rb +1 -1
- data/lib/x_aeon_agents/agents/readme/contributing_agent.rb +1 -1
- data/lib/x_aeon_agents/agents/readme/development_agent.rb +1 -1
- data/lib/x_aeon_agents/agents/readme/documentation_agent.rb +1 -1
- data/lib/x_aeon_agents/agents/readme/features_agent.rb +1 -1
- data/lib/x_aeon_agents/agents/readme/how_it_works_agent.rb +1 -1
- data/lib/x_aeon_agents/agents/readme/license_agent.rb +1 -1
- data/lib/x_aeon_agents/agents/readme/public_api_agent.rb +1 -1
- data/lib/x_aeon_agents/agents/readme/quick_start_agent.rb +1 -1
- data/lib/x_aeon_agents/agents/readme/requirements_agent.rb +1 -1
- data/lib/x_aeon_agents/agents/readme_generator_agent.rb +41 -23
- data/lib/x_aeon_agents/agents/review_resolver_agent.rb +67 -62
- data/lib/x_aeon_agents/agents/review_responder_agent.rb +1 -1
- data/lib/x_aeon_agents/agents/skill_generator_agent.rb +36 -32
- data/lib/x_aeon_agents/agents/skill_installer_agent.rb +30 -22
- data/lib/x_aeon_agents/agents/task_starter_agent.rb +61 -7
- data/lib/x_aeon_agents/cli.rb +19 -7
- data/lib/x_aeon_agents/config.rb +127 -18
- data/lib/x_aeon_agents/config_dsl.rb +90 -0
- data/lib/x_aeon_agents/helpers.rb +3 -26
- data/lib/x_aeon_agents/logger.rb +457 -13
- data/lib/x_aeon_agents/version.rb +1 -1
- metadata +90 -6
- 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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a3ff43b4352a549cc20bf1b286d89aa551f549c6109811c7456c3393e39f3184
|
|
4
|
+
data.tar.gz: 5671b1fe28a848307a12316ce54e962db5a67c3a6b0872c6f3034ca0c7c2478e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
- `
|
|
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
|
|
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
|
-
#
|
|
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
|
|
38
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
45
|
+
logger.info 'Nothing to commit'
|
|
39
46
|
else
|
|
40
47
|
git_diff_interpreter_agent = GitDiffInterpreterAgent.new
|
|
41
|
-
|
|
48
|
+
task(git_diff_interpreter_agent, intent: 'Analyze staged git diffs', git_ref_base: 'cached')
|
|
42
49
|
content = <<~EO_COMMIT
|
|
43
|
-
#{
|
|
50
|
+
#{@artifacts[:one_line_summary].strip}
|
|
44
51
|
|
|
45
|
-
#{
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|