hellochusquis 0.6.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.
- hellochusquis-0.6.0/LICENSE +21 -0
- hellochusquis-0.6.0/PKG-INFO +151 -0
- hellochusquis-0.6.0/README.md +133 -0
- hellochusquis-0.6.0/cli.py +61 -0
- hellochusquis-0.6.0/core/agent.py +189 -0
- hellochusquis-0.6.0/core/builder.py +239 -0
- hellochusquis-0.6.0/core/history.py +12 -0
- hellochusquis-0.6.0/core/learning.py +126 -0
- hellochusquis-0.6.0/core/memory.py +56 -0
- hellochusquis-0.6.0/core/planner.py +109 -0
- hellochusquis-0.6.0/core/plugins.py +93 -0
- hellochusquis-0.6.0/core/provider.py +157 -0
- hellochusquis-0.6.0/core/setup.py +180 -0
- hellochusquis-0.6.0/hellochusquis.egg-info/PKG-INFO +151 -0
- hellochusquis-0.6.0/hellochusquis.egg-info/SOURCES.txt +28 -0
- hellochusquis-0.6.0/hellochusquis.egg-info/dependency_links.txt +1 -0
- hellochusquis-0.6.0/hellochusquis.egg-info/entry_points.txt +2 -0
- hellochusquis-0.6.0/hellochusquis.egg-info/requires.txt +5 -0
- hellochusquis-0.6.0/hellochusquis.egg-info/top_level.txt +6 -0
- hellochusquis-0.6.0/main.py +115 -0
- hellochusquis-0.6.0/pyproject.toml +34 -0
- hellochusquis-0.6.0/setup.cfg +4 -0
- hellochusquis-0.6.0/tools/base.py +21 -0
- hellochusquis-0.6.0/tools/code.py +16 -0
- hellochusquis-0.6.0/tools/files.py +70 -0
- hellochusquis-0.6.0/tools/shell.py +22 -0
- hellochusquis-0.6.0/ui/terminal.py +57 -0
- hellochusquis-0.6.0/web/index.html +450 -0
- hellochusquis-0.6.0/web/server.py +98 -0
- hellochusquis-0.6.0/workspace/manager.py +30 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Arnau Moyano
|
|
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.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hellochusquis
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: A powerful terminal AI agent with multi-provider fallback, plugin system, and web interface
|
|
5
|
+
Author: aminoy77
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/aminoy77/HelloChusquis
|
|
8
|
+
Keywords: ai,agent,cli,llm,automation
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: rich>=13.0.0
|
|
13
|
+
Requires-Dist: pyyaml>=6.0
|
|
14
|
+
Requires-Dist: httpx>=0.24.0
|
|
15
|
+
Requires-Dist: fastapi>=0.100.0
|
|
16
|
+
Requires-Dist: uvicorn>=0.23.0
|
|
17
|
+
Dynamic: license-file
|
|
18
|
+
|
|
19
|
+
# HelloChusquis
|
|
20
|
+
|
|
21
|
+
A powerful terminal AI agent built in Python with web interface, multi-provider fallback, plugin system, persistent memory, and auto-learning.
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
- π€ **AI Agent** β chat in terminal or browser with full tool access
|
|
26
|
+
- π **Multi-provider fallback** β automatically switches between providers when one fails
|
|
27
|
+
- π§© **Plugin system** β install plugins with one command, build your own
|
|
28
|
+
- π§ **Persistent memory** β remembers past conversations and learns from them
|
|
29
|
+
- π **Task planner** β detects complex tasks and executes them step by step
|
|
30
|
+
- π **Web interface** β chat from your browser with sidebar showing status
|
|
31
|
+
- π **Real file creation** β generates real PDF and Word documents
|
|
32
|
+
- π **Browser control** β search the web and extract content from pages
|
|
33
|
+
|
|
34
|
+
## Supported Providers
|
|
35
|
+
|
|
36
|
+
OpenRouter, Ollama Cloud, Anthropic Claude, OpenAI, Google Gemini, Groq, xAI (Grok), Perplexity, Qwen, MiniMax, Mistral, DeepSeek, Cohere, Together AI, Fireworks AI, Novita AI, and more.
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
### Option 1 β Download ZIP
|
|
41
|
+
|
|
42
|
+
1. Go to [github.com/aminoy77/HelloChusquis](https://github.com/aminoy77/HelloChusquis)
|
|
43
|
+
2. Click **Code β Download ZIP**
|
|
44
|
+
3. Unzip the file
|
|
45
|
+
4. Open terminal in the unzipped folder
|
|
46
|
+
5. Run:
|
|
47
|
+
```bash
|
|
48
|
+
pip install -e .
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Option 2 β Clone repo
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
git clone https://github.com/aminoy77/HelloChusquis.git
|
|
55
|
+
cd HelloChusquis
|
|
56
|
+
pip install -e .
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## First Run
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
hellochusquis
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
First run will launch the setup wizard to configure your providers. It is recommended to add at least 2 providers for automatic fallback.
|
|
66
|
+
|
|
67
|
+
Get free API keys at:
|
|
68
|
+
- [openrouter.ai](https://openrouter.ai) β access 300+ models, many free
|
|
69
|
+
- [console.groq.com](https://console.groq.com) β fastest free tier
|
|
70
|
+
- [ollama.com](https://ollama.com) β cloud models
|
|
71
|
+
|
|
72
|
+
## Usage
|
|
73
|
+
|
|
74
|
+
### Terminal
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
hellochusquis # Start chat in terminal
|
|
78
|
+
hellochusquis web # Start web interface (opens browser)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Chat Commands
|
|
82
|
+
|
|
83
|
+
| Command | Description |
|
|
84
|
+
|---|---|
|
|
85
|
+
| `/help` | Show available commands |
|
|
86
|
+
| `/status` | Show provider status |
|
|
87
|
+
| `/clear` | Clear conversation history |
|
|
88
|
+
| `/plan <task>` | Force planning mode for a task |
|
|
89
|
+
| `π` or `+` | Positive feedback on last response |
|
|
90
|
+
| `π` or `-` | Negative feedback on last response |
|
|
91
|
+
| `exit` | Exit and save memory |
|
|
92
|
+
|
|
93
|
+
### Terminal Commands
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
hellochusquis install # Install a plugin
|
|
97
|
+
hellochusquis uninstall # Remove a plugin
|
|
98
|
+
hellochusquis plugins # List installed plugins
|
|
99
|
+
hellochusquis build # Build a new plugin with AI
|
|
100
|
+
hellochusquis learn # Show learned patterns and rules
|
|
101
|
+
hellochusquis web # Start web interface
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Plugins
|
|
105
|
+
|
|
106
|
+
Install plugins from the public registry:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
hellochusquis install weather
|
|
110
|
+
hellochusquis install stocks
|
|
111
|
+
hellochusquis install browser
|
|
112
|
+
hellochusquis install pdf
|
|
113
|
+
hellochusquis install docx
|
|
114
|
+
hellochusquis install crypto
|
|
115
|
+
hellochusquis install calculator
|
|
116
|
+
hellochusquis install worldclock
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Browse all available plugins at [github.com/aminoy77/Hellochusquis-plugins](https://github.com/aminoy77/HelloChusquis-plugins.git)
|
|
120
|
+
|
|
121
|
+
### Build your own plugin
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
hellochusquis build
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The AI will research the API, write the plugin code, test it, and ask if you want to submit it to the public registry.
|
|
128
|
+
|
|
129
|
+
## Web Interface
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
hellochusquis web
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Opens a web chat at `http://localhost:8000` with:
|
|
136
|
+
- Chat interface with tool call visualization
|
|
137
|
+
- Sidebar with provider status, installed plugins, memory stats, and learned patterns
|
|
138
|
+
|
|
139
|
+
## How it works
|
|
140
|
+
|
|
141
|
+
**Provider fallback** β if a provider hits rate limits or times out, HelloChusquis automatically switches to the next one. Providers that support tool calling are prioritized for tasks that need tools.
|
|
142
|
+
|
|
143
|
+
**Task planner** β for complex tasks, HelloChusquis generates a step-by-step plan, shows it to you for confirmation, then executes each step automatically.
|
|
144
|
+
|
|
145
|
+
**Memory** β at the end of each session, HelloChusquis summarizes the conversation and stores it. Next session it remembers what you discussed.
|
|
146
|
+
|
|
147
|
+
**Auto-learning** β after each session, the agent analyzes what worked and what didn't, and improves its behavior over time.
|
|
148
|
+
|
|
149
|
+
## License
|
|
150
|
+
|
|
151
|
+
MIT
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# HelloChusquis
|
|
2
|
+
|
|
3
|
+
A powerful terminal AI agent built in Python with web interface, multi-provider fallback, plugin system, persistent memory, and auto-learning.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- π€ **AI Agent** β chat in terminal or browser with full tool access
|
|
8
|
+
- π **Multi-provider fallback** β automatically switches between providers when one fails
|
|
9
|
+
- π§© **Plugin system** β install plugins with one command, build your own
|
|
10
|
+
- π§ **Persistent memory** β remembers past conversations and learns from them
|
|
11
|
+
- π **Task planner** β detects complex tasks and executes them step by step
|
|
12
|
+
- π **Web interface** β chat from your browser with sidebar showing status
|
|
13
|
+
- π **Real file creation** β generates real PDF and Word documents
|
|
14
|
+
- π **Browser control** β search the web and extract content from pages
|
|
15
|
+
|
|
16
|
+
## Supported Providers
|
|
17
|
+
|
|
18
|
+
OpenRouter, Ollama Cloud, Anthropic Claude, OpenAI, Google Gemini, Groq, xAI (Grok), Perplexity, Qwen, MiniMax, Mistral, DeepSeek, Cohere, Together AI, Fireworks AI, Novita AI, and more.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
### Option 1 β Download ZIP
|
|
23
|
+
|
|
24
|
+
1. Go to [github.com/aminoy77/HelloChusquis](https://github.com/aminoy77/HelloChusquis)
|
|
25
|
+
2. Click **Code β Download ZIP**
|
|
26
|
+
3. Unzip the file
|
|
27
|
+
4. Open terminal in the unzipped folder
|
|
28
|
+
5. Run:
|
|
29
|
+
```bash
|
|
30
|
+
pip install -e .
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Option 2 β Clone repo
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git clone https://github.com/aminoy77/HelloChusquis.git
|
|
37
|
+
cd HelloChusquis
|
|
38
|
+
pip install -e .
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## First Run
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
hellochusquis
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
First run will launch the setup wizard to configure your providers. It is recommended to add at least 2 providers for automatic fallback.
|
|
48
|
+
|
|
49
|
+
Get free API keys at:
|
|
50
|
+
- [openrouter.ai](https://openrouter.ai) β access 300+ models, many free
|
|
51
|
+
- [console.groq.com](https://console.groq.com) β fastest free tier
|
|
52
|
+
- [ollama.com](https://ollama.com) β cloud models
|
|
53
|
+
|
|
54
|
+
## Usage
|
|
55
|
+
|
|
56
|
+
### Terminal
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
hellochusquis # Start chat in terminal
|
|
60
|
+
hellochusquis web # Start web interface (opens browser)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Chat Commands
|
|
64
|
+
|
|
65
|
+
| Command | Description |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `/help` | Show available commands |
|
|
68
|
+
| `/status` | Show provider status |
|
|
69
|
+
| `/clear` | Clear conversation history |
|
|
70
|
+
| `/plan <task>` | Force planning mode for a task |
|
|
71
|
+
| `π` or `+` | Positive feedback on last response |
|
|
72
|
+
| `π` or `-` | Negative feedback on last response |
|
|
73
|
+
| `exit` | Exit and save memory |
|
|
74
|
+
|
|
75
|
+
### Terminal Commands
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
hellochusquis install # Install a plugin
|
|
79
|
+
hellochusquis uninstall # Remove a plugin
|
|
80
|
+
hellochusquis plugins # List installed plugins
|
|
81
|
+
hellochusquis build # Build a new plugin with AI
|
|
82
|
+
hellochusquis learn # Show learned patterns and rules
|
|
83
|
+
hellochusquis web # Start web interface
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Plugins
|
|
87
|
+
|
|
88
|
+
Install plugins from the public registry:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
hellochusquis install weather
|
|
92
|
+
hellochusquis install stocks
|
|
93
|
+
hellochusquis install browser
|
|
94
|
+
hellochusquis install pdf
|
|
95
|
+
hellochusquis install docx
|
|
96
|
+
hellochusquis install crypto
|
|
97
|
+
hellochusquis install calculator
|
|
98
|
+
hellochusquis install worldclock
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Browse all available plugins at [github.com/aminoy77/Hellochusquis-plugins](https://github.com/aminoy77/HelloChusquis-plugins.git)
|
|
102
|
+
|
|
103
|
+
### Build your own plugin
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
hellochusquis build
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The AI will research the API, write the plugin code, test it, and ask if you want to submit it to the public registry.
|
|
110
|
+
|
|
111
|
+
## Web Interface
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
hellochusquis web
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Opens a web chat at `http://localhost:8000` with:
|
|
118
|
+
- Chat interface with tool call visualization
|
|
119
|
+
- Sidebar with provider status, installed plugins, memory stats, and learned patterns
|
|
120
|
+
|
|
121
|
+
## How it works
|
|
122
|
+
|
|
123
|
+
**Provider fallback** β if a provider hits rate limits or times out, HelloChusquis automatically switches to the next one. Providers that support tool calling are prioritized for tasks that need tools.
|
|
124
|
+
|
|
125
|
+
**Task planner** β for complex tasks, HelloChusquis generates a step-by-step plan, shows it to you for confirmation, then executes each step automatically.
|
|
126
|
+
|
|
127
|
+
**Memory** β at the end of each session, HelloChusquis summarizes the conversation and stores it. Next session it remembers what you discussed.
|
|
128
|
+
|
|
129
|
+
**Auto-learning** β after each session, the agent analyzes what worked and what didn't, and improves its behavior over time.
|
|
130
|
+
|
|
131
|
+
## License
|
|
132
|
+
|
|
133
|
+
MIT
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
sys.path.insert(0, os.path.dirname(__file__))
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main():
|
|
7
|
+
args = sys.argv[1:]
|
|
8
|
+
|
|
9
|
+
if args and args[0] == "install" and len(args) > 1:
|
|
10
|
+
from core.plugins import install_plugin
|
|
11
|
+
install_plugin(args[1])
|
|
12
|
+
return
|
|
13
|
+
|
|
14
|
+
if args and args[0] == "uninstall" and len(args) > 1:
|
|
15
|
+
from core.plugins import uninstall_plugin
|
|
16
|
+
uninstall_plugin(args[1])
|
|
17
|
+
return
|
|
18
|
+
|
|
19
|
+
if args and args[0] == "plugins":
|
|
20
|
+
from core.plugins import list_plugins
|
|
21
|
+
list_plugins()
|
|
22
|
+
return
|
|
23
|
+
|
|
24
|
+
if args and args[0] == "build":
|
|
25
|
+
from core.setup import ensure_config
|
|
26
|
+
from core.provider import ProviderPool
|
|
27
|
+
ensure_config()
|
|
28
|
+
pool = ProviderPool()
|
|
29
|
+
from core.builder import build_plugin
|
|
30
|
+
build_plugin(pool)
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
if args and args[0] == "learn":
|
|
34
|
+
from core.setup import ensure_config
|
|
35
|
+
from core.learning import load_learnings
|
|
36
|
+
from rich.console import Console
|
|
37
|
+
import json
|
|
38
|
+
ensure_config()
|
|
39
|
+
console = Console()
|
|
40
|
+
learnings = load_learnings()
|
|
41
|
+
console.print("\n[bold]Current learnings:[/bold]")
|
|
42
|
+
console.print_json(json.dumps(learnings, indent=2, ensure_ascii=False))
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
if args and args[0] == "web":
|
|
46
|
+
import webbrowser
|
|
47
|
+
from rich.console import Console
|
|
48
|
+
console = Console()
|
|
49
|
+
console.print("[cyan]Starting HelloChusquis web interface...[/cyan]")
|
|
50
|
+
console.print("[dim]Open: http://localhost:8000[/dim]")
|
|
51
|
+
webbrowser.open("http://localhost:8000")
|
|
52
|
+
from web.server import start
|
|
53
|
+
start()
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
from main import main as run
|
|
57
|
+
run()
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if __name__ == "__main__":
|
|
61
|
+
main()
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import core.memory as memory
|
|
3
|
+
import core.learning as learning
|
|
4
|
+
from core.provider import ProviderPool
|
|
5
|
+
from core.history import History
|
|
6
|
+
from tools.shell import ShellTool
|
|
7
|
+
from tools.files import FilesTool
|
|
8
|
+
from tools.code import CodeTool
|
|
9
|
+
from workspace.manager import WorkspaceManager
|
|
10
|
+
from core.plugins import load_plugins
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
TOOLS_SCHEMA = [
|
|
14
|
+
{
|
|
15
|
+
"type": "function",
|
|
16
|
+
"function": {
|
|
17
|
+
"name": "shell",
|
|
18
|
+
"description": "Execute a terminal command",
|
|
19
|
+
"parameters": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"properties": {
|
|
22
|
+
"command": {"type": "string", "description": "The command to run"}
|
|
23
|
+
},
|
|
24
|
+
"required": ["command"]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"type": "function",
|
|
30
|
+
"function": {
|
|
31
|
+
"name": "code",
|
|
32
|
+
"description": "Execute Python code",
|
|
33
|
+
"parameters": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"properties": {
|
|
36
|
+
"code": {"type": "string", "description": "Python code to execute"}
|
|
37
|
+
},
|
|
38
|
+
"required": ["code"]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"type": "function",
|
|
44
|
+
"function": {
|
|
45
|
+
"name": "files",
|
|
46
|
+
"description": "Read, write, delete, list files in the workspace",
|
|
47
|
+
"parameters": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"properties": {
|
|
50
|
+
"action": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"enum": ["read", "write", "delete", "list", "create_dir"]
|
|
53
|
+
},
|
|
54
|
+
"path": {"type": "string"},
|
|
55
|
+
"content": {"type": "string", "description": "Required for write"}
|
|
56
|
+
},
|
|
57
|
+
"required": ["action", "path"]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class Agent:
|
|
65
|
+
def __init__(self, config: dict):
|
|
66
|
+
self.pool = ProviderPool()
|
|
67
|
+
self.history = History()
|
|
68
|
+
self.workspace = WorkspaceManager(config["settings"]["workspace_dirs"])
|
|
69
|
+
self.shell = ShellTool()
|
|
70
|
+
self.files = FilesTool(config["settings"]["workspace_dirs"])
|
|
71
|
+
self.code = CodeTool()
|
|
72
|
+
self.system_prompt = config["agent"]["system_prompt"]
|
|
73
|
+
self.workspace_dirs = config["settings"]["workspace_dirs"]
|
|
74
|
+
|
|
75
|
+
# Cargar memoria de sesiones anteriores
|
|
76
|
+
summary = memory.load_summary()
|
|
77
|
+
if summary:
|
|
78
|
+
self.system_prompt += f"\n\nWhat you remember from past sessions:\n{summary}"
|
|
79
|
+
|
|
80
|
+
# Cargar learnings
|
|
81
|
+
learnings = learning.load_learnings()
|
|
82
|
+
learning_prompt = learning.build_learning_prompt(learnings)
|
|
83
|
+
if learning_prompt:
|
|
84
|
+
self.system_prompt += f"\n\n{learning_prompt}"
|
|
85
|
+
|
|
86
|
+
# Cargar plugins
|
|
87
|
+
self.plugins = load_plugins()
|
|
88
|
+
for plugin in self.plugins:
|
|
89
|
+
TOOLS_SCHEMA.append(plugin["schema"])
|
|
90
|
+
|
|
91
|
+
# Informar al agente quΓ© plugins tiene disponibles
|
|
92
|
+
if self.plugins:
|
|
93
|
+
plugin_names = ", ".join(p["name"] for p in self.plugins)
|
|
94
|
+
self.system_prompt += f"\n\nInstalled plugins available as tools: {plugin_names}. Use them directly without asking the user to install anything."
|
|
95
|
+
|
|
96
|
+
def _dispatch_tool(self, name: str, args: dict):
|
|
97
|
+
if name == "shell":
|
|
98
|
+
return self.shell.run(**args)
|
|
99
|
+
elif name == "code":
|
|
100
|
+
return self.code.run(**args)
|
|
101
|
+
elif name == "files":
|
|
102
|
+
path = args.get("path", "")
|
|
103
|
+
if not self.workspace.is_allowed(path):
|
|
104
|
+
granted = self.workspace.request_access(path)
|
|
105
|
+
if not granted:
|
|
106
|
+
from tools.base import ToolResult
|
|
107
|
+
return ToolResult(success=False, output="", error="Access denied by user")
|
|
108
|
+
self.files.allow_dir(path)
|
|
109
|
+
return self.files.run(**args)
|
|
110
|
+
|
|
111
|
+
for plugin in self.plugins:
|
|
112
|
+
if plugin["name"] == name:
|
|
113
|
+
try:
|
|
114
|
+
result_text = plugin["run"](**args)
|
|
115
|
+
from tools.base import ToolResult
|
|
116
|
+
return ToolResult(success=True, output=str(result_text))
|
|
117
|
+
except Exception as e:
|
|
118
|
+
from tools.base import ToolResult
|
|
119
|
+
return ToolResult(success=False, output="", error=str(e))
|
|
120
|
+
|
|
121
|
+
from tools.base import ToolResult
|
|
122
|
+
return ToolResult(success=False, output="", error=f"Unknown tool: {name}")
|
|
123
|
+
|
|
124
|
+
def run(self, user_input: str) -> str:
|
|
125
|
+
self.history.add("user", user_input)
|
|
126
|
+
|
|
127
|
+
messages = [
|
|
128
|
+
{"role": "system", "content": (
|
|
129
|
+
self.system_prompt +
|
|
130
|
+
f"\n\nWorkspace directories: {', '.join(self.workspace_dirs)}. "
|
|
131
|
+
"Always use absolute paths when calling file tools. "
|
|
132
|
+
"Only use tools when strictly necessary. Never use shell or code tools just to print or display text."
|
|
133
|
+
)},
|
|
134
|
+
*self.history.get()
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
while True:
|
|
138
|
+
response = self.pool.chat_with_retry(messages, tools=TOOLS_SCHEMA)
|
|
139
|
+
message = response["choices"][0]["message"]
|
|
140
|
+
|
|
141
|
+
if not message.get("tool_calls"):
|
|
142
|
+
content = message.get("content", "")
|
|
143
|
+
self.history.add("assistant", content)
|
|
144
|
+
return content
|
|
145
|
+
|
|
146
|
+
messages.append(message)
|
|
147
|
+
|
|
148
|
+
for tc in message["tool_calls"]:
|
|
149
|
+
tool_name = tc["function"]["name"]
|
|
150
|
+
tool_args = json.loads(tc["function"]["arguments"])
|
|
151
|
+
|
|
152
|
+
from ui.terminal import print_tool_call, print_tool_result
|
|
153
|
+
print_tool_call(tool_name, tool_args)
|
|
154
|
+
result = self._dispatch_tool(tool_name, tool_args)
|
|
155
|
+
print_tool_result(result.success, result.output)
|
|
156
|
+
|
|
157
|
+
messages.append({
|
|
158
|
+
"role": "tool",
|
|
159
|
+
"tool_call_id": tc["id"],
|
|
160
|
+
"content": result.output if result.success else f"ERROR: {result.error}"
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
def summarize_and_save(self, retention_days: int = 30):
|
|
164
|
+
messages = self.history.get()
|
|
165
|
+
if not messages:
|
|
166
|
+
return
|
|
167
|
+
|
|
168
|
+
memory.save_session(messages)
|
|
169
|
+
|
|
170
|
+
summary_prompt = (
|
|
171
|
+
"Summarize the key facts, tasks completed, and important context "
|
|
172
|
+
"from this conversation in 3-5 bullet points. Be very concise. "
|
|
173
|
+
"This will be injected into future sessions as memory.\n\n"
|
|
174
|
+
+ "\n".join(f"{m['role']}: {m['content'][:200]}" for m in messages)
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
try:
|
|
178
|
+
response = self.pool.chat_with_retry([
|
|
179
|
+
{"role": "user", "content": summary_prompt}
|
|
180
|
+
])
|
|
181
|
+
summary = response["choices"][0]["message"]["content"]
|
|
182
|
+
memory.save_summary(summary)
|
|
183
|
+
except Exception:
|
|
184
|
+
pass
|
|
185
|
+
|
|
186
|
+
# Analizar y aprender de la sesiΓ³n
|
|
187
|
+
learning.analyze_and_learn(messages, self.pool)
|
|
188
|
+
|
|
189
|
+
memory.cleanup_old_sessions(retention_days)
|