aru-code 0.1.0__tar.gz → 0.3.0__tar.gz
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.
- {aru_code-0.1.0 → aru_code-0.3.0}/LICENSE +21 -21
- {aru_code-0.1.0 → aru_code-0.3.0}/PKG-INFO +19 -60
- {aru_code-0.1.0 → aru_code-0.3.0}/README.md +15 -58
- aru_code-0.3.0/aru/__init__.py +1 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/agents/base.py +10 -1
- aru_code-0.3.0/aru/agents/executor.py +58 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/cli.py +81 -1
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/config.py +2 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/providers.py +1 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/tools/ast_tools.py +2 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/tools/gitignore.py +2 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/tools/mcp_client.py +2 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/tools/tasklist.py +2 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru_code.egg-info/PKG-INFO +19 -60
- {aru_code-0.1.0 → aru_code-0.3.0}/pyproject.toml +5 -3
- aru_code-0.1.0/aru/__init__.py +0 -1
- aru_code-0.1.0/aru/agents/executor.py +0 -32
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/agents/__init__.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/agents/planner.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/context.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/tools/__init__.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/tools/codebase.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru/tools/ranker.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru_code.egg-info/SOURCES.txt +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru_code.egg-info/dependency_links.txt +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru_code.egg-info/entry_points.txt +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru_code.egg-info/requires.txt +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/aru_code.egg-info/top_level.txt +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/setup.cfg +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_agents_base.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_ast_tools.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_cli.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_cli_advanced.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_cli_base.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_cli_completers.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_cli_new.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_cli_run_cli.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_cli_session.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_cli_shell.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_codebase.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_config.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_context.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_executor.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_gitignore.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_main.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_mcp_client.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_planner.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_providers.py +0 -0
- {aru_code-0.1.0 → aru_code-0.3.0}/tests/test_ranker.py +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Estevao
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Estevao
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aru-code
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: A Claude Code clone built with Agno agents
|
|
5
5
|
Author-email: Estevao <estevaofon@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -11,9 +11,11 @@ Keywords: ai,coding-assistant,claude,cli,agents
|
|
|
11
11
|
Classifier: Development Status :: 3 - Alpha
|
|
12
12
|
Classifier: Environment :: Console
|
|
13
13
|
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
15
17
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
16
|
-
Requires-Python: >=3.
|
|
18
|
+
Requires-Python: >=3.11
|
|
17
19
|
Description-Content-Type: text/markdown
|
|
18
20
|
License-File: LICENSE
|
|
19
21
|
Requires-Dist: agno<3,>=2.5.10
|
|
@@ -50,6 +52,10 @@ An intelligent coding assistant for the terminal, powered by LLMs and [Agno](htt
|
|
|
50
52
|
|
|
51
53
|
|
|
52
54
|
|
|
55
|
+
https://github.com/user-attachments/assets/17674bfc-3d49-4e25-bdc7-dc445d5a089d
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
53
59
|
## Highlights
|
|
54
60
|
|
|
55
61
|
- **Multi-Agent Architecture** — Specialized agents for planning, execution, and conversation
|
|
@@ -65,7 +71,7 @@ An intelligent coding assistant for the terminal, powered by LLMs and [Agno](htt
|
|
|
65
71
|
### 1. Install
|
|
66
72
|
|
|
67
73
|
```bash
|
|
68
|
-
pip install -
|
|
74
|
+
pip install aru-code
|
|
69
75
|
```
|
|
70
76
|
|
|
71
77
|
> **Requirements:** Python 3.13+
|
|
@@ -74,13 +80,7 @@ pip install -e .
|
|
|
74
80
|
|
|
75
81
|
Aru uses **Claude Sonnet 4.6** from Anthropic as the default model. You need an [Anthropic API key](https://console.anthropic.com/) to get started.
|
|
76
82
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
cp .env.example .env
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
Edit the `.env` with your key:
|
|
83
|
+
Set your API key as an environment variable or create a `.env` file in your project directory:
|
|
84
84
|
|
|
85
85
|
```env
|
|
86
86
|
ANTHROPIC_API_KEY=sk-ant-your-key-here
|
|
@@ -94,50 +94,7 @@ ANTHROPIC_API_KEY=sk-ant-your-key-here
|
|
|
94
94
|
aru
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
To use aru as a global command in the terminal, create a dedicated virtual environment and a wrapper script:
|
|
100
|
-
|
|
101
|
-
<details>
|
|
102
|
-
<summary><strong>Windows</strong></summary>
|
|
103
|
-
|
|
104
|
-
1. Create the virtual environment and install:
|
|
105
|
-
```bash
|
|
106
|
-
python -m venv C:\aru-env
|
|
107
|
-
C:\aru-env\Scripts\pip install -e C:\path\to\aru
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
2. Create `aru.bat` in a folder on your `PATH` (e.g., `C:\Users\<user>\bin\`):
|
|
111
|
-
```bat
|
|
112
|
-
@echo off
|
|
113
|
-
C:\aru-env\Scripts\python -m aru.cli %*
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
</details>
|
|
117
|
-
|
|
118
|
-
<details>
|
|
119
|
-
<summary><strong>Linux / macOS</strong></summary>
|
|
120
|
-
|
|
121
|
-
1. Create the virtual environment and install:
|
|
122
|
-
```bash
|
|
123
|
-
python3 -m venv ~/.aru-env
|
|
124
|
-
~/.aru-env/bin/pip install -e /path/to/aru
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
2. Create the script `~/.local/bin/aru`:
|
|
128
|
-
```bash
|
|
129
|
-
#!/bin/bash
|
|
130
|
-
~/.aru-env/bin/python -m aru.cli "$@"
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
3. Make it executable:
|
|
134
|
-
```bash
|
|
135
|
-
chmod +x ~/.local/bin/aru
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
</details>
|
|
139
|
-
|
|
140
|
-
Done — now `aru` works from any directory.
|
|
97
|
+
That's it — `aru` is available globally after install.
|
|
141
98
|
|
|
142
99
|
## Usage
|
|
143
100
|
|
|
@@ -187,15 +144,15 @@ By default, aru uses **Claude Sonnet 4.6** (Anthropic). You can switch to any su
|
|
|
187
144
|
| Provider | Command | API Key (`.env`) | Extra Installation |
|
|
188
145
|
|----------|---------|-------------------|------------------|
|
|
189
146
|
| **Anthropic** | `/model anthropic/claude-sonnet-4-6` | `ANTHROPIC_API_KEY` | — (included) |
|
|
190
|
-
| **Ollama** | `/model ollama/llama3.1` | — (local) | `pip install -
|
|
191
|
-
| **OpenAI** | `/model openai/gpt-4o` | `OPENAI_API_KEY` | `pip install -
|
|
192
|
-
| **Groq** | `/model groq/llama-3.3-70b-versatile` | `GROQ_API_KEY` | `pip install -
|
|
193
|
-
| **OpenRouter** | `/model openrouter/deepseek/deepseek-chat-v3-0324` | `OPENROUTER_API_KEY` | `pip install -
|
|
147
|
+
| **Ollama** | `/model ollama/llama3.1` | — (local) | `pip install "aru-code[ollama]"` |
|
|
148
|
+
| **OpenAI** | `/model openai/gpt-4o` | `OPENAI_API_KEY` | `pip install "aru-code[openai]"` |
|
|
149
|
+
| **Groq** | `/model groq/llama-3.3-70b-versatile` | `GROQ_API_KEY` | `pip install "aru-code[groq]"` |
|
|
150
|
+
| **OpenRouter** | `/model openrouter/deepseek/deepseek-chat-v3-0324` | `OPENROUTER_API_KEY` | `pip install "aru-code[openai]"` |
|
|
194
151
|
|
|
195
152
|
To install all providers at once:
|
|
196
153
|
|
|
197
154
|
```bash
|
|
198
|
-
pip install -
|
|
155
|
+
pip install "aru-code[all-providers]"
|
|
199
156
|
```
|
|
200
157
|
|
|
201
158
|
#### Ollama (local models)
|
|
@@ -370,7 +327,9 @@ aru-code/
|
|
|
370
327
|
## Development
|
|
371
328
|
|
|
372
329
|
```bash
|
|
373
|
-
#
|
|
330
|
+
# Clone and install in editable mode with dev dependencies
|
|
331
|
+
git clone https://github.com/estevaofon/aru.git
|
|
332
|
+
cd aru
|
|
374
333
|
pip install -e ".[dev]"
|
|
375
334
|
|
|
376
335
|
# Run tests
|
|
@@ -6,6 +6,10 @@ An intelligent coding assistant for the terminal, powered by LLMs and [Agno](htt
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
https://github.com/user-attachments/assets/17674bfc-3d49-4e25-bdc7-dc445d5a089d
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
9
13
|
## Highlights
|
|
10
14
|
|
|
11
15
|
- **Multi-Agent Architecture** — Specialized agents for planning, execution, and conversation
|
|
@@ -21,7 +25,7 @@ An intelligent coding assistant for the terminal, powered by LLMs and [Agno](htt
|
|
|
21
25
|
### 1. Install
|
|
22
26
|
|
|
23
27
|
```bash
|
|
24
|
-
pip install -
|
|
28
|
+
pip install aru-code
|
|
25
29
|
```
|
|
26
30
|
|
|
27
31
|
> **Requirements:** Python 3.13+
|
|
@@ -30,13 +34,7 @@ pip install -e .
|
|
|
30
34
|
|
|
31
35
|
Aru uses **Claude Sonnet 4.6** from Anthropic as the default model. You need an [Anthropic API key](https://console.anthropic.com/) to get started.
|
|
32
36
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
cp .env.example .env
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Edit the `.env` with your key:
|
|
37
|
+
Set your API key as an environment variable or create a `.env` file in your project directory:
|
|
40
38
|
|
|
41
39
|
```env
|
|
42
40
|
ANTHROPIC_API_KEY=sk-ant-your-key-here
|
|
@@ -50,50 +48,7 @@ ANTHROPIC_API_KEY=sk-ant-your-key-here
|
|
|
50
48
|
aru
|
|
51
49
|
```
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
To use aru as a global command in the terminal, create a dedicated virtual environment and a wrapper script:
|
|
56
|
-
|
|
57
|
-
<details>
|
|
58
|
-
<summary><strong>Windows</strong></summary>
|
|
59
|
-
|
|
60
|
-
1. Create the virtual environment and install:
|
|
61
|
-
```bash
|
|
62
|
-
python -m venv C:\aru-env
|
|
63
|
-
C:\aru-env\Scripts\pip install -e C:\path\to\aru
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
2. Create `aru.bat` in a folder on your `PATH` (e.g., `C:\Users\<user>\bin\`):
|
|
67
|
-
```bat
|
|
68
|
-
@echo off
|
|
69
|
-
C:\aru-env\Scripts\python -m aru.cli %*
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
</details>
|
|
73
|
-
|
|
74
|
-
<details>
|
|
75
|
-
<summary><strong>Linux / macOS</strong></summary>
|
|
76
|
-
|
|
77
|
-
1. Create the virtual environment and install:
|
|
78
|
-
```bash
|
|
79
|
-
python3 -m venv ~/.aru-env
|
|
80
|
-
~/.aru-env/bin/pip install -e /path/to/aru
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
2. Create the script `~/.local/bin/aru`:
|
|
84
|
-
```bash
|
|
85
|
-
#!/bin/bash
|
|
86
|
-
~/.aru-env/bin/python -m aru.cli "$@"
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
3. Make it executable:
|
|
90
|
-
```bash
|
|
91
|
-
chmod +x ~/.local/bin/aru
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
</details>
|
|
95
|
-
|
|
96
|
-
Done — now `aru` works from any directory.
|
|
51
|
+
That's it — `aru` is available globally after install.
|
|
97
52
|
|
|
98
53
|
## Usage
|
|
99
54
|
|
|
@@ -143,15 +98,15 @@ By default, aru uses **Claude Sonnet 4.6** (Anthropic). You can switch to any su
|
|
|
143
98
|
| Provider | Command | API Key (`.env`) | Extra Installation |
|
|
144
99
|
|----------|---------|-------------------|------------------|
|
|
145
100
|
| **Anthropic** | `/model anthropic/claude-sonnet-4-6` | `ANTHROPIC_API_KEY` | — (included) |
|
|
146
|
-
| **Ollama** | `/model ollama/llama3.1` | — (local) | `pip install -
|
|
147
|
-
| **OpenAI** | `/model openai/gpt-4o` | `OPENAI_API_KEY` | `pip install -
|
|
148
|
-
| **Groq** | `/model groq/llama-3.3-70b-versatile` | `GROQ_API_KEY` | `pip install -
|
|
149
|
-
| **OpenRouter** | `/model openrouter/deepseek/deepseek-chat-v3-0324` | `OPENROUTER_API_KEY` | `pip install -
|
|
101
|
+
| **Ollama** | `/model ollama/llama3.1` | — (local) | `pip install "aru-code[ollama]"` |
|
|
102
|
+
| **OpenAI** | `/model openai/gpt-4o` | `OPENAI_API_KEY` | `pip install "aru-code[openai]"` |
|
|
103
|
+
| **Groq** | `/model groq/llama-3.3-70b-versatile` | `GROQ_API_KEY` | `pip install "aru-code[groq]"` |
|
|
104
|
+
| **OpenRouter** | `/model openrouter/deepseek/deepseek-chat-v3-0324` | `OPENROUTER_API_KEY` | `pip install "aru-code[openai]"` |
|
|
150
105
|
|
|
151
106
|
To install all providers at once:
|
|
152
107
|
|
|
153
108
|
```bash
|
|
154
|
-
pip install -
|
|
109
|
+
pip install "aru-code[all-providers]"
|
|
155
110
|
```
|
|
156
111
|
|
|
157
112
|
#### Ollama (local models)
|
|
@@ -326,7 +281,9 @@ aru-code/
|
|
|
326
281
|
## Development
|
|
327
282
|
|
|
328
283
|
```bash
|
|
329
|
-
#
|
|
284
|
+
# Clone and install in editable mode with dev dependencies
|
|
285
|
+
git clone https://github.com/estevaofon/aru.git
|
|
286
|
+
cd aru
|
|
330
287
|
pip install -e ".[dev]"
|
|
331
288
|
|
|
332
289
|
# Run tests
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.0"
|
|
@@ -92,6 +92,12 @@ Define 1-10 concrete subtasks for the current step. Then execute them in order,
|
|
|
92
92
|
calling `update_task` to mark each as "completed" or "failed" as you go. \
|
|
93
93
|
When all subtasks are done, STOP. Do not add extra actions beyond the task list.
|
|
94
94
|
|
|
95
|
+
## Subtask granularity — CRITICAL
|
|
96
|
+
Each subtask should touch at most **3-4 files**. If the step involves many files, \
|
|
97
|
+
split into subtasks grouped by concern (e.g. "Create model files", "Create route files", \
|
|
98
|
+
"Update config and main"). Batch independent file writes using `write_files` or `edit_files` \
|
|
99
|
+
to minimize tool calls. Batch independent file writes using `write_files` or `edit_files` to minimize tool calls.
|
|
100
|
+
|
|
95
101
|
## Guidelines
|
|
96
102
|
- Read files before editing them
|
|
97
103
|
- Use edit_file for targeted changes (preferred over rewriting entire files)
|
|
@@ -129,7 +135,10 @@ Only output text AFTER all subtasks are finished — a brief summary of what was
|
|
|
129
135
|
Text output is ONLY for the final result or when you hit a blocker that needs user input.
|
|
130
136
|
|
|
131
137
|
**Never retry failed shell commands with alternative syntax.** If a command fails, diagnose \
|
|
132
|
-
the error — do not try `cmd /c`, absolute paths, or other wrappers hoping one works
|
|
138
|
+
the error — do not try `cmd /c`, absolute paths, or other wrappers hoping one works.
|
|
139
|
+
|
|
140
|
+
**Tool call limit**: If you see "Tool call limit reached" errors, STOP trying to use tools immediately. \
|
|
141
|
+
Output a summary of what you accomplished so far and what remains. Do NOT retry rejected tool calls.\
|
|
133
142
|
"""
|
|
134
143
|
|
|
135
144
|
# General-purpose agent (combines read + write, conversational)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""Executor agent - implements changes based on plans or direct instructions."""
|
|
2
|
+
|
|
3
|
+
from agno.agent import Agent
|
|
4
|
+
from agno.compression.manager import CompressionManager
|
|
5
|
+
from agno.utils.log import log_warning
|
|
6
|
+
|
|
7
|
+
from aru.agents.base import build_instructions
|
|
8
|
+
from aru.providers import create_model
|
|
9
|
+
from aru.tools.codebase import EXECUTOR_TOOLS, _get_small_model_ref
|
|
10
|
+
|
|
11
|
+
# Max chars for truncation fallback when compression fails
|
|
12
|
+
_TRUNCATE_FALLBACK = 3000
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class _SafeCompressionManager(CompressionManager):
|
|
16
|
+
"""CompressionManager that truncates on failure instead of leaving messages uncompressed.
|
|
17
|
+
|
|
18
|
+
Agno's default behavior: if compression returns None, the message stays with
|
|
19
|
+
compressed_content=None → should_compress() fires again → infinite retry loop.
|
|
20
|
+
This subclass marks failed messages with a truncated version so the loop moves on.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
async def acompress(self, messages, run_metrics=None):
|
|
24
|
+
# Track which messages are currently uncompressed
|
|
25
|
+
before = {id(m) for m in messages if m.role == "tool" and m.compressed_content is None}
|
|
26
|
+
await super().acompress(messages, run_metrics=run_metrics)
|
|
27
|
+
# Any message still uncompressed after super() = compression failed
|
|
28
|
+
for msg in messages:
|
|
29
|
+
if id(msg) in before and msg.compressed_content is None:
|
|
30
|
+
content_str = str(msg.content or "")
|
|
31
|
+
msg.compressed_content = content_str[:_TRUNCATE_FALLBACK] + (
|
|
32
|
+
"... [truncated, compression failed]" if len(content_str) > _TRUNCATE_FALLBACK else ""
|
|
33
|
+
)
|
|
34
|
+
log_warning(f"Compression fallback (truncate) for {msg.tool_name}")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def create_executor(model_ref: str = "anthropic/claude-sonnet-4-5", extra_instructions: str = "") -> Agent:
|
|
38
|
+
"""Create and return the executor agent.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
model_ref: Provider/model reference (e.g., "anthropic/claude-sonnet-4-5", "ollama/llama3.1").
|
|
42
|
+
extra_instructions: Additional instructions to append.
|
|
43
|
+
"""
|
|
44
|
+
return Agent(
|
|
45
|
+
name="Executor",
|
|
46
|
+
model=create_model(model_ref, max_tokens=8192),
|
|
47
|
+
tools=EXECUTOR_TOOLS,
|
|
48
|
+
instructions=build_instructions("executor", extra_instructions),
|
|
49
|
+
markdown=True,
|
|
50
|
+
# Compress tool results after 5 uncompressed tool calls to save tokens
|
|
51
|
+
compress_tool_results=True,
|
|
52
|
+
compression_manager=_SafeCompressionManager(
|
|
53
|
+
model=create_model(_get_small_model_ref(), max_tokens=2048),
|
|
54
|
+
compress_tool_results=True,
|
|
55
|
+
compress_tool_results_limit=15,
|
|
56
|
+
),
|
|
57
|
+
tool_call_limit=None,
|
|
58
|
+
)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Interactive CLI for aru - a Claude Code clone."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import asyncio
|
|
4
6
|
import hashlib
|
|
5
7
|
import json
|
|
@@ -982,6 +984,7 @@ def _show_help(config: AgentConfig | None):
|
|
|
982
984
|
table.add_row("/sessions", "List recent sessions")
|
|
983
985
|
table.add_row("/commands", "List custom commands")
|
|
984
986
|
table.add_row("/skills", "List available skills")
|
|
987
|
+
table.add_row("/mcp", "List loaded MCP tools")
|
|
985
988
|
table.add_row("/help", "Show this help")
|
|
986
989
|
table.add_row("/quit", "Exit aru")
|
|
987
990
|
table.add_row("! <cmd>", "Run shell command")
|
|
@@ -1068,6 +1071,7 @@ class AgentRunResult:
|
|
|
1068
1071
|
"""Result from run_agent_capture including text output and tool call history."""
|
|
1069
1072
|
content: str | None = None
|
|
1070
1073
|
tool_calls: list[str] = field(default_factory=list)
|
|
1074
|
+
stalled: bool = False
|
|
1071
1075
|
|
|
1072
1076
|
def with_tools_summary(self) -> str | None:
|
|
1073
1077
|
"""Return content with appended tool call summary for session history."""
|
|
@@ -1254,6 +1258,7 @@ async def run_agent_capture(agent, message: str, session: "Session | None" = Non
|
|
|
1254
1258
|
console.print()
|
|
1255
1259
|
final_content = None
|
|
1256
1260
|
collected_tool_calls: list[str] = []
|
|
1261
|
+
_stalled = False
|
|
1257
1262
|
|
|
1258
1263
|
try:
|
|
1259
1264
|
from aru.tools.codebase import set_display, set_live
|
|
@@ -1318,12 +1323,20 @@ async def run_agent_capture(agent, message: str, session: "Session | None" = Non
|
|
|
1318
1323
|
tasklist_set_live(live)
|
|
1319
1324
|
tasklist_set_display(display)
|
|
1320
1325
|
accumulated = ""
|
|
1326
|
+
# Stall detection: count consecutive events without useful work
|
|
1327
|
+
# When tool_call_limit is hit, Agno silently rejects tool calls and
|
|
1328
|
+
# keeps calling the model in a loop. We detect this by tracking
|
|
1329
|
+
# consecutive events that aren't tool starts/completions/content.
|
|
1330
|
+
_stall_counter = 0
|
|
1331
|
+
_stalled = False
|
|
1332
|
+
_STALL_LIMIT = 20 # break after 20 non-useful events (prevents infinite loop)
|
|
1321
1333
|
async for event in agent.arun(agent_input, stream=True, stream_events=True, yield_run_output=True):
|
|
1322
1334
|
if isinstance(event, RunOutput):
|
|
1323
1335
|
run_output = event
|
|
1324
1336
|
break
|
|
1325
1337
|
|
|
1326
1338
|
if isinstance(event, ToolCallStartedEvent):
|
|
1339
|
+
_stall_counter = 0
|
|
1327
1340
|
if hasattr(event, "tool") and event.tool:
|
|
1328
1341
|
tool_name = event.tool.tool_name or "tool"
|
|
1329
1342
|
tool_args = event.tool.tool_args or None
|
|
@@ -1345,6 +1358,7 @@ async def run_agent_capture(agent, message: str, session: "Session | None" = Non
|
|
|
1345
1358
|
live.update(display)
|
|
1346
1359
|
|
|
1347
1360
|
elif isinstance(event, ToolCallCompletedEvent):
|
|
1361
|
+
_stall_counter = 0
|
|
1348
1362
|
if hasattr(event, "tool") and event.tool:
|
|
1349
1363
|
tool_id = getattr(event.tool, "tool_call_id", None) or getattr(event.tool, "tool_name", "tool")
|
|
1350
1364
|
else:
|
|
@@ -1365,6 +1379,7 @@ async def run_agent_capture(agent, message: str, session: "Session | None" = Non
|
|
|
1365
1379
|
live.update(display)
|
|
1366
1380
|
|
|
1367
1381
|
elif isinstance(event, RunContentEvent):
|
|
1382
|
+
_stall_counter = 0
|
|
1368
1383
|
if hasattr(event, "content") and event.content:
|
|
1369
1384
|
accumulated += event.content
|
|
1370
1385
|
unflushed = accumulated[display._flushed_len:]
|
|
@@ -1391,6 +1406,17 @@ async def run_agent_capture(agent, message: str, session: "Session | None" = Non
|
|
|
1391
1406
|
display.set_content(accumulated)
|
|
1392
1407
|
live.update(display)
|
|
1393
1408
|
|
|
1409
|
+
else:
|
|
1410
|
+
# Unknown/internal event (e.g. model cycling after tool_call_limit)
|
|
1411
|
+
_stall_counter += 1
|
|
1412
|
+
if _stall_counter >= _STALL_LIMIT:
|
|
1413
|
+
_stalled = True
|
|
1414
|
+
live.console.print(
|
|
1415
|
+
"[yellow]Agent stalled (tool call limit likely reached). "
|
|
1416
|
+
"Moving on.[/yellow]"
|
|
1417
|
+
)
|
|
1418
|
+
break
|
|
1419
|
+
|
|
1394
1420
|
set_live(None)
|
|
1395
1421
|
set_display(None)
|
|
1396
1422
|
|
|
@@ -1425,7 +1451,7 @@ async def run_agent_capture(agent, message: str, session: "Session | None" = Non
|
|
|
1425
1451
|
console.print(f"[red]Error: {escape(str(e))}[/red]")
|
|
1426
1452
|
|
|
1427
1453
|
console.print()
|
|
1428
|
-
return AgentRunResult(content=final_content, tool_calls=collected_tool_calls)
|
|
1454
|
+
return AgentRunResult(content=final_content, tool_calls=collected_tool_calls, stalled=_stalled)
|
|
1429
1455
|
|
|
1430
1456
|
|
|
1431
1457
|
def ask_yes_no(prompt: str) -> bool:
|
|
@@ -1533,6 +1559,59 @@ async def execute_plan_steps(session: Session, executor_factory) -> str | None:
|
|
|
1533
1559
|
run_result = await run_agent_capture(executor, step_prompt, session, lightweight=True)
|
|
1534
1560
|
content = run_result.content
|
|
1535
1561
|
|
|
1562
|
+
# If agent stalled (tool call limit loop), show progress and let user decide
|
|
1563
|
+
if run_result.stalled:
|
|
1564
|
+
from aru.tools.tasklist import get_task_store
|
|
1565
|
+
store = get_task_store()
|
|
1566
|
+
all_tasks = store.get_all()
|
|
1567
|
+
done = [t for t in all_tasks if t["status"] == "completed"]
|
|
1568
|
+
pending = [t for t in all_tasks if t["status"] not in ("completed", "failed")]
|
|
1569
|
+
|
|
1570
|
+
console.print(f"\n[yellow]Step {step.index} stalled (tool call limit reached).[/yellow]")
|
|
1571
|
+
if done:
|
|
1572
|
+
console.print(f" [green]Completed:[/green] {len(done)}/{len(all_tasks)} subtasks")
|
|
1573
|
+
if pending:
|
|
1574
|
+
console.print(f" [yellow]Pending:[/yellow]")
|
|
1575
|
+
for t in pending:
|
|
1576
|
+
console.print(f" - {t.get('description', t.get('id', '?'))}")
|
|
1577
|
+
|
|
1578
|
+
if get_skip_permissions():
|
|
1579
|
+
step.status = "failed"
|
|
1580
|
+
continue
|
|
1581
|
+
|
|
1582
|
+
console.print("\n[bold]Options:[/bold]")
|
|
1583
|
+
console.print(" [cyan](r)[/cyan] Retry step with additional instructions")
|
|
1584
|
+
console.print(" [cyan](s)[/cyan] Skip to next step")
|
|
1585
|
+
console.print(" [cyan](a)[/cyan] Abort plan execution")
|
|
1586
|
+
try:
|
|
1587
|
+
choice = console.input("[bold yellow]Choice (r/s/a):[/bold yellow] ").strip().lower()
|
|
1588
|
+
except (EOFError, KeyboardInterrupt):
|
|
1589
|
+
choice = "a"
|
|
1590
|
+
|
|
1591
|
+
if choice in ("r", "retry"):
|
|
1592
|
+
try:
|
|
1593
|
+
extra = console.input("[bold cyan]Additional instructions:[/bold cyan] ").strip()
|
|
1594
|
+
except (EOFError, KeyboardInterrupt):
|
|
1595
|
+
extra = ""
|
|
1596
|
+
if extra:
|
|
1597
|
+
# Re-run the same step with user's extra context appended
|
|
1598
|
+
step.status = "in_progress"
|
|
1599
|
+
reset_task_store()
|
|
1600
|
+
retry_prompt = step_prompt + f"\n\n## Additional Instructions\n{extra}"
|
|
1601
|
+
executor = executor_factory()
|
|
1602
|
+
run_result = await run_agent_capture(executor, retry_prompt, session, lightweight=True)
|
|
1603
|
+
content = run_result.content
|
|
1604
|
+
# Fall through to normal completion check below
|
|
1605
|
+
else:
|
|
1606
|
+
step.status = "failed"
|
|
1607
|
+
continue
|
|
1608
|
+
elif choice in ("s", "skip"):
|
|
1609
|
+
step.status = "failed"
|
|
1610
|
+
continue
|
|
1611
|
+
else:
|
|
1612
|
+
step.status = "failed"
|
|
1613
|
+
break
|
|
1614
|
+
|
|
1536
1615
|
# Check task store as ground truth for step completion
|
|
1537
1616
|
from aru.tools.tasklist import get_task_store
|
|
1538
1617
|
store = get_task_store()
|
|
@@ -1665,6 +1744,7 @@ async def run_cli(skip_permissions: bool = False, resume_id: str | None = None):
|
|
|
1665
1744
|
# Apply default model from config if set
|
|
1666
1745
|
if config.model_defaults.get("default"):
|
|
1667
1746
|
session.model_ref = config.model_defaults["default"]
|
|
1747
|
+
_sync_model(session)
|
|
1668
1748
|
_render_home(session, skip_permissions)
|
|
1669
1749
|
|
|
1670
1750
|
# Wire file-mutation callback so context cache (tree/git) is invalidated
|
|
@@ -219,6 +219,7 @@ def resolve_model_ref(model_ref: str) -> tuple[str, str]:
|
|
|
219
219
|
|
|
220
220
|
if "/" in model_ref:
|
|
221
221
|
provider_key, model_name = model_ref.split("/", 1)
|
|
222
|
+
provider_key = provider_key.lower()
|
|
222
223
|
else:
|
|
223
224
|
# Could be a provider name (use its default) or unknown
|
|
224
225
|
if model_ref in _providers:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aru-code
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: A Claude Code clone built with Agno agents
|
|
5
5
|
Author-email: Estevao <estevaofon@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -11,9 +11,11 @@ Keywords: ai,coding-assistant,claude,cli,agents
|
|
|
11
11
|
Classifier: Development Status :: 3 - Alpha
|
|
12
12
|
Classifier: Environment :: Console
|
|
13
13
|
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
15
17
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
16
|
-
Requires-Python: >=3.
|
|
18
|
+
Requires-Python: >=3.11
|
|
17
19
|
Description-Content-Type: text/markdown
|
|
18
20
|
License-File: LICENSE
|
|
19
21
|
Requires-Dist: agno<3,>=2.5.10
|
|
@@ -50,6 +52,10 @@ An intelligent coding assistant for the terminal, powered by LLMs and [Agno](htt
|
|
|
50
52
|
|
|
51
53
|
|
|
52
54
|
|
|
55
|
+
https://github.com/user-attachments/assets/17674bfc-3d49-4e25-bdc7-dc445d5a089d
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
53
59
|
## Highlights
|
|
54
60
|
|
|
55
61
|
- **Multi-Agent Architecture** — Specialized agents for planning, execution, and conversation
|
|
@@ -65,7 +71,7 @@ An intelligent coding assistant for the terminal, powered by LLMs and [Agno](htt
|
|
|
65
71
|
### 1. Install
|
|
66
72
|
|
|
67
73
|
```bash
|
|
68
|
-
pip install -
|
|
74
|
+
pip install aru-code
|
|
69
75
|
```
|
|
70
76
|
|
|
71
77
|
> **Requirements:** Python 3.13+
|
|
@@ -74,13 +80,7 @@ pip install -e .
|
|
|
74
80
|
|
|
75
81
|
Aru uses **Claude Sonnet 4.6** from Anthropic as the default model. You need an [Anthropic API key](https://console.anthropic.com/) to get started.
|
|
76
82
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
cp .env.example .env
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
Edit the `.env` with your key:
|
|
83
|
+
Set your API key as an environment variable or create a `.env` file in your project directory:
|
|
84
84
|
|
|
85
85
|
```env
|
|
86
86
|
ANTHROPIC_API_KEY=sk-ant-your-key-here
|
|
@@ -94,50 +94,7 @@ ANTHROPIC_API_KEY=sk-ant-your-key-here
|
|
|
94
94
|
aru
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
To use aru as a global command in the terminal, create a dedicated virtual environment and a wrapper script:
|
|
100
|
-
|
|
101
|
-
<details>
|
|
102
|
-
<summary><strong>Windows</strong></summary>
|
|
103
|
-
|
|
104
|
-
1. Create the virtual environment and install:
|
|
105
|
-
```bash
|
|
106
|
-
python -m venv C:\aru-env
|
|
107
|
-
C:\aru-env\Scripts\pip install -e C:\path\to\aru
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
2. Create `aru.bat` in a folder on your `PATH` (e.g., `C:\Users\<user>\bin\`):
|
|
111
|
-
```bat
|
|
112
|
-
@echo off
|
|
113
|
-
C:\aru-env\Scripts\python -m aru.cli %*
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
</details>
|
|
117
|
-
|
|
118
|
-
<details>
|
|
119
|
-
<summary><strong>Linux / macOS</strong></summary>
|
|
120
|
-
|
|
121
|
-
1. Create the virtual environment and install:
|
|
122
|
-
```bash
|
|
123
|
-
python3 -m venv ~/.aru-env
|
|
124
|
-
~/.aru-env/bin/pip install -e /path/to/aru
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
2. Create the script `~/.local/bin/aru`:
|
|
128
|
-
```bash
|
|
129
|
-
#!/bin/bash
|
|
130
|
-
~/.aru-env/bin/python -m aru.cli "$@"
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
3. Make it executable:
|
|
134
|
-
```bash
|
|
135
|
-
chmod +x ~/.local/bin/aru
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
</details>
|
|
139
|
-
|
|
140
|
-
Done — now `aru` works from any directory.
|
|
97
|
+
That's it — `aru` is available globally after install.
|
|
141
98
|
|
|
142
99
|
## Usage
|
|
143
100
|
|
|
@@ -187,15 +144,15 @@ By default, aru uses **Claude Sonnet 4.6** (Anthropic). You can switch to any su
|
|
|
187
144
|
| Provider | Command | API Key (`.env`) | Extra Installation |
|
|
188
145
|
|----------|---------|-------------------|------------------|
|
|
189
146
|
| **Anthropic** | `/model anthropic/claude-sonnet-4-6` | `ANTHROPIC_API_KEY` | — (included) |
|
|
190
|
-
| **Ollama** | `/model ollama/llama3.1` | — (local) | `pip install -
|
|
191
|
-
| **OpenAI** | `/model openai/gpt-4o` | `OPENAI_API_KEY` | `pip install -
|
|
192
|
-
| **Groq** | `/model groq/llama-3.3-70b-versatile` | `GROQ_API_KEY` | `pip install -
|
|
193
|
-
| **OpenRouter** | `/model openrouter/deepseek/deepseek-chat-v3-0324` | `OPENROUTER_API_KEY` | `pip install -
|
|
147
|
+
| **Ollama** | `/model ollama/llama3.1` | — (local) | `pip install "aru-code[ollama]"` |
|
|
148
|
+
| **OpenAI** | `/model openai/gpt-4o` | `OPENAI_API_KEY` | `pip install "aru-code[openai]"` |
|
|
149
|
+
| **Groq** | `/model groq/llama-3.3-70b-versatile` | `GROQ_API_KEY` | `pip install "aru-code[groq]"` |
|
|
150
|
+
| **OpenRouter** | `/model openrouter/deepseek/deepseek-chat-v3-0324` | `OPENROUTER_API_KEY` | `pip install "aru-code[openai]"` |
|
|
194
151
|
|
|
195
152
|
To install all providers at once:
|
|
196
153
|
|
|
197
154
|
```bash
|
|
198
|
-
pip install -
|
|
155
|
+
pip install "aru-code[all-providers]"
|
|
199
156
|
```
|
|
200
157
|
|
|
201
158
|
#### Ollama (local models)
|
|
@@ -370,7 +327,9 @@ aru-code/
|
|
|
370
327
|
## Development
|
|
371
328
|
|
|
372
329
|
```bash
|
|
373
|
-
#
|
|
330
|
+
# Clone and install in editable mode with dev dependencies
|
|
331
|
+
git clone https://github.com/estevaofon/aru.git
|
|
332
|
+
cd aru
|
|
374
333
|
pip install -e ".[dev]"
|
|
375
334
|
|
|
376
335
|
# Run tests
|
|
@@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "aru-code"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "A Claude Code clone built with Agno agents"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
11
|
-
requires-python = ">=3.
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
12
|
authors = [
|
|
13
13
|
{ name = "Estevao", email = "estevaofon@gmail.com" },
|
|
14
14
|
]
|
|
@@ -17,7 +17,9 @@ classifiers = [
|
|
|
17
17
|
"Development Status :: 3 - Alpha",
|
|
18
18
|
"Environment :: Console",
|
|
19
19
|
"Intended Audience :: Developers",
|
|
20
|
-
"Programming Language :: Python :: 3.
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Programming Language :: Python :: 3.13",
|
|
21
23
|
"Topic :: Software Development :: Libraries :: Application Frameworks",
|
|
22
24
|
]
|
|
23
25
|
|
aru_code-0.1.0/aru/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.0"
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"""Executor agent - implements changes based on plans or direct instructions."""
|
|
2
|
-
|
|
3
|
-
from agno.agent import Agent
|
|
4
|
-
from agno.compression.manager import CompressionManager
|
|
5
|
-
|
|
6
|
-
from aru.agents.base import build_instructions
|
|
7
|
-
from aru.providers import create_model
|
|
8
|
-
from aru.tools.codebase import EXECUTOR_TOOLS, _get_small_model_ref
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def create_executor(model_ref: str = "anthropic/claude-sonnet-4-5", extra_instructions: str = "") -> Agent:
|
|
12
|
-
"""Create and return the executor agent.
|
|
13
|
-
|
|
14
|
-
Args:
|
|
15
|
-
model_ref: Provider/model reference (e.g., "anthropic/claude-sonnet-4-5", "ollama/llama3.1").
|
|
16
|
-
extra_instructions: Additional instructions to append.
|
|
17
|
-
"""
|
|
18
|
-
return Agent(
|
|
19
|
-
name="Executor",
|
|
20
|
-
model=create_model(model_ref, max_tokens=8192),
|
|
21
|
-
tools=EXECUTOR_TOOLS,
|
|
22
|
-
instructions=build_instructions("executor", extra_instructions),
|
|
23
|
-
markdown=True,
|
|
24
|
-
# Compress tool results after 5 uncompressed tool calls to save tokens
|
|
25
|
-
compress_tool_results=True,
|
|
26
|
-
compression_manager=CompressionManager(
|
|
27
|
-
model=create_model(_get_small_model_ref(), max_tokens=1024),
|
|
28
|
-
compress_tool_results=True,
|
|
29
|
-
compress_tool_results_limit=15,
|
|
30
|
-
),
|
|
31
|
-
tool_call_limit=15,
|
|
32
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|