forgecodecli 0.1.0__tar.gz → 0.2.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.
- forgecodecli-0.2.0/PKG-INFO +198 -0
- forgecodecli-0.2.0/README.md +180 -0
- forgecodecli-0.2.0/forgecodecli/agent.py +215 -0
- forgecodecli-0.2.0/forgecodecli/cli.py +389 -0
- forgecodecli-0.2.0/forgecodecli/git_tools.py +69 -0
- forgecodecli-0.2.0/forgecodecli/path_resolver.py +24 -0
- forgecodecli-0.2.0/forgecodecli/tools.py +180 -0
- forgecodecli-0.2.0/forgecodecli.egg-info/PKG-INFO +198 -0
- {forgecodecli-0.1.0 → forgecodecli-0.2.0}/forgecodecli.egg-info/SOURCES.txt +2 -0
- {forgecodecli-0.1.0 → forgecodecli-0.2.0}/forgecodecli.egg-info/requires.txt +3 -0
- forgecodecli-0.2.0/pyproject.toml +23 -0
- forgecodecli-0.1.0/PKG-INFO +0 -127
- forgecodecli-0.1.0/README.md +0 -111
- forgecodecli-0.1.0/forgecodecli/agent.py +0 -144
- forgecodecli-0.1.0/forgecodecli/cli.py +0 -210
- forgecodecli-0.1.0/forgecodecli/tools.py +0 -74
- forgecodecli-0.1.0/forgecodecli.egg-info/PKG-INFO +0 -127
- forgecodecli-0.1.0/pyproject.toml +0 -27
- {forgecodecli-0.1.0 → forgecodecli-0.2.0}/forgecodecli/__init__.py +0 -0
- {forgecodecli-0.1.0 → forgecodecli-0.2.0}/forgecodecli/config.py +0 -0
- {forgecodecli-0.1.0 → forgecodecli-0.2.0}/forgecodecli/secrets.py +0 -0
- {forgecodecli-0.1.0 → forgecodecli-0.2.0}/forgecodecli.egg-info/dependency_links.txt +0 -0
- {forgecodecli-0.1.0 → forgecodecli-0.2.0}/forgecodecli.egg-info/entry_points.txt +0 -0
- {forgecodecli-0.1.0 → forgecodecli-0.2.0}/forgecodecli.egg-info/top_level.txt +0 -0
- {forgecodecli-0.1.0 → forgecodecli-0.2.0}/setup.cfg +0 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: forgecodecli
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A minimal agentic CLI for forging code
|
|
5
|
+
Author: Sudhanshu
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: typer[all]>=0.9.0
|
|
10
|
+
Requires-Dist: openai>=1.0.0
|
|
11
|
+
Requires-Dist: keyring>=24.0.0
|
|
12
|
+
Provides-Extra: dev
|
|
13
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
14
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
15
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
16
|
+
Provides-Extra: anthropic
|
|
17
|
+
Requires-Dist: anthropic>=0.25.0; extra == "anthropic"
|
|
18
|
+
|
|
19
|
+
# ForgeCodeCLI
|
|
20
|
+
|
|
21
|
+
An agentic, file-aware command-line tool that lets you manage and modify your codebase using natural language — powered by LLMs.
|
|
22
|
+
|
|
23
|
+
It acts as a safe, deterministic AI agent that can read files, create/delete directories, and write code only through explicit tools, not raw hallucination.
|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
- ✅ **Agentic workflow** - LLM decides actions, CLI executes them safely
|
|
28
|
+
- ✅ **File operations** - Read, list, create, write, delete, move files & directories
|
|
29
|
+
- ✅ **Undo support** - Reverse the last file operation with `undo`
|
|
30
|
+
- ✅ **Multi-provider LLMs** - Gemini, OpenAI (GPT), Anthropic (Claude), Groq
|
|
31
|
+
- ✅ **Model selection** - Choose specific models for each provider
|
|
32
|
+
- ✅ **Secure storage** - API keys stored in system keyring (no env vars)
|
|
33
|
+
- ✅ **Deterministic** - Rule-based execution with validation
|
|
34
|
+
- ✅ **Interactive CLI** - Real-time agent feedback
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
Requires Python 3.9+
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install forgecodecli
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Optional:** For Anthropic (Claude) support, install with the anthropic extra:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install forgecodecli[anthropic]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Or install later when prompted during setup.
|
|
51
|
+
|
|
52
|
+
## Quick Start
|
|
53
|
+
|
|
54
|
+
### Initialize (one-time setup)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
forgecodecli init
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
You will be prompted to:
|
|
61
|
+
|
|
62
|
+
1. **Select LLM Provider**
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
1) Google Gemini
|
|
66
|
+
2) OpenAI
|
|
67
|
+
3) Anthropic (Claude)
|
|
68
|
+
4) Groq
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
2. **Select Model** (varies by provider)
|
|
72
|
+
- Gemini: `gemini-2.5-flash`, `gemini-2.0-flash`, `gemini-1.5-pro`
|
|
73
|
+
- OpenAI: `gpt-4o`, `gpt-4-turbo`, `gpt-3.5-turbo`
|
|
74
|
+
- Claude: `claude-3-5-sonnet`, `claude-3-opus`, `claude-3-haiku`
|
|
75
|
+
- Groq: `llama-3.3-70b`, `mixtral-8x7b`, `gemma2-9b-it`
|
|
76
|
+
|
|
77
|
+
3. **Enter API Key** (stored securely in system keyring)
|
|
78
|
+
|
|
79
|
+
### Start the agent
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
forgecodecli
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
You are now in interactive agent mode. Example commands:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
create a folder src/app with main.py that prints "Hello World"
|
|
89
|
+
read the config.py file
|
|
90
|
+
list all files in src
|
|
91
|
+
delete old_backup folder
|
|
92
|
+
move test.py to tests/test.py
|
|
93
|
+
undo
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Type `help` for built-in commands, or press `Ctrl + C` to exit.
|
|
97
|
+
|
|
98
|
+
## Reset Configuration
|
|
99
|
+
|
|
100
|
+
To remove all configuration and API keys:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
forgecodecli reset
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Security
|
|
107
|
+
|
|
108
|
+
- API keys are stored using the system keyring
|
|
109
|
+
- No API keys are written to config files or environment variables
|
|
110
|
+
- Config files contain only non-sensitive metadata
|
|
111
|
+
|
|
112
|
+
## How It Works
|
|
113
|
+
|
|
114
|
+
1. You enter a natural language command
|
|
115
|
+
2. The LLM decides the next valid action
|
|
116
|
+
3. ForgeCodeCLI executes the action with validation
|
|
117
|
+
4. The agent receives feedback and responds
|
|
118
|
+
5. Process repeats until agent provides an answer
|
|
119
|
+
|
|
120
|
+
**Safety mechanisms:**
|
|
121
|
+
|
|
122
|
+
- Action limit of 2 per request (prevents infinite loops)
|
|
123
|
+
- Conversation context maintained for agent awareness
|
|
124
|
+
- All operations logged and reversible with `undo`
|
|
125
|
+
- Strict tool validation
|
|
126
|
+
|
|
127
|
+
## Supported Actions
|
|
128
|
+
|
|
129
|
+
The agent can execute these operations:
|
|
130
|
+
|
|
131
|
+
**File Operations:**
|
|
132
|
+
| Action | Description |
|
|
133
|
+
|--------|-------------|
|
|
134
|
+
| `read_file` | Read and display file contents |
|
|
135
|
+
| `list_files` | List files in a directory |
|
|
136
|
+
| `create_dir` | Create new directories |
|
|
137
|
+
| `write_file` | Create and write files |
|
|
138
|
+
| `delete_file` | Delete files permanently |
|
|
139
|
+
| `delete_dir` | Delete directories |
|
|
140
|
+
| `move_file` | Move or rename files |
|
|
141
|
+
| `move_dir` | Move or rename directories |
|
|
142
|
+
| `undo` | Reverse the last operation |
|
|
143
|
+
|
|
144
|
+
**Git Operations:**
|
|
145
|
+
| Action | Description |
|
|
146
|
+
|--------|-------------|
|
|
147
|
+
| `git_init` | Initialize git repository |
|
|
148
|
+
| `git_add` | Stage files for commit |
|
|
149
|
+
| `git_commit` | Commit staged changes |
|
|
150
|
+
| `git_push` | Push to remote repository |
|
|
151
|
+
| `git_set_origin` | Set remote repository URL |
|
|
152
|
+
| `git_status` | Show repository status |
|
|
153
|
+
| `git_log` | View commit history |
|
|
154
|
+
| `git_branch` | Manage branches |
|
|
155
|
+
| `git_pull` | Pull from remote |
|
|
156
|
+
| `git_clone` | Clone a repository |
|
|
157
|
+
|
|
158
|
+
All actions are executed safely with validation and error handling.
|
|
159
|
+
|
|
160
|
+
## Roadmap
|
|
161
|
+
|
|
162
|
+
### ✅ v1 (Released)
|
|
163
|
+
|
|
164
|
+
- Basic file operations (read, list, create, write)
|
|
165
|
+
- Gemini support
|
|
166
|
+
- Interactive CLI
|
|
167
|
+
|
|
168
|
+
### ✅ v2 (Released)
|
|
169
|
+
|
|
170
|
+
- **Undo functionality** - Stack-based operation reversal
|
|
171
|
+
- **Delete & move operations** - Full file/directory manipulation
|
|
172
|
+
- **Multi-provider support** - Gemini, OpenAI, Anthropic, Groq
|
|
173
|
+
- **Model selection** - Choose specific models per provider
|
|
174
|
+
- **Auto-install SDKs** - Anthropic SDK installs on demand
|
|
175
|
+
- **Fixed agent loop** - Proper conversation flow with max actions
|
|
176
|
+
|
|
177
|
+
### ✅ v3 (Current)
|
|
178
|
+
|
|
179
|
+
- **Git operations** - init, add, commit, push, pull, status, log, branch, clone, set_origin
|
|
180
|
+
- **Git workflow support** - Full version control integration
|
|
181
|
+
- **Repository management** - Clone and manage git repos
|
|
182
|
+
|
|
183
|
+
### 🚀 v4 (Planned)
|
|
184
|
+
|
|
185
|
+
- Copy files/directories
|
|
186
|
+
- Full undo/redo history (not just last operation)
|
|
187
|
+
- File search capabilities
|
|
188
|
+
- Code generation templates
|
|
189
|
+
- Batch operations
|
|
190
|
+
- Backup/snapshot functionality
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
MIT License
|
|
195
|
+
|
|
196
|
+
## Author
|
|
197
|
+
|
|
198
|
+
Built by Sudhanshu
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# ForgeCodeCLI
|
|
2
|
+
|
|
3
|
+
An agentic, file-aware command-line tool that lets you manage and modify your codebase using natural language — powered by LLMs.
|
|
4
|
+
|
|
5
|
+
It acts as a safe, deterministic AI agent that can read files, create/delete directories, and write code only through explicit tools, not raw hallucination.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- ✅ **Agentic workflow** - LLM decides actions, CLI executes them safely
|
|
10
|
+
- ✅ **File operations** - Read, list, create, write, delete, move files & directories
|
|
11
|
+
- ✅ **Undo support** - Reverse the last file operation with `undo`
|
|
12
|
+
- ✅ **Multi-provider LLMs** - Gemini, OpenAI (GPT), Anthropic (Claude), Groq
|
|
13
|
+
- ✅ **Model selection** - Choose specific models for each provider
|
|
14
|
+
- ✅ **Secure storage** - API keys stored in system keyring (no env vars)
|
|
15
|
+
- ✅ **Deterministic** - Rule-based execution with validation
|
|
16
|
+
- ✅ **Interactive CLI** - Real-time agent feedback
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
Requires Python 3.9+
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install forgecodecli
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Optional:** For Anthropic (Claude) support, install with the anthropic extra:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install forgecodecli[anthropic]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Or install later when prompted during setup.
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
### Initialize (one-time setup)
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
forgecodecli init
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
You will be prompted to:
|
|
43
|
+
|
|
44
|
+
1. **Select LLM Provider**
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
1) Google Gemini
|
|
48
|
+
2) OpenAI
|
|
49
|
+
3) Anthropic (Claude)
|
|
50
|
+
4) Groq
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
2. **Select Model** (varies by provider)
|
|
54
|
+
- Gemini: `gemini-2.5-flash`, `gemini-2.0-flash`, `gemini-1.5-pro`
|
|
55
|
+
- OpenAI: `gpt-4o`, `gpt-4-turbo`, `gpt-3.5-turbo`
|
|
56
|
+
- Claude: `claude-3-5-sonnet`, `claude-3-opus`, `claude-3-haiku`
|
|
57
|
+
- Groq: `llama-3.3-70b`, `mixtral-8x7b`, `gemma2-9b-it`
|
|
58
|
+
|
|
59
|
+
3. **Enter API Key** (stored securely in system keyring)
|
|
60
|
+
|
|
61
|
+
### Start the agent
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
forgecodecli
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
You are now in interactive agent mode. Example commands:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
create a folder src/app with main.py that prints "Hello World"
|
|
71
|
+
read the config.py file
|
|
72
|
+
list all files in src
|
|
73
|
+
delete old_backup folder
|
|
74
|
+
move test.py to tests/test.py
|
|
75
|
+
undo
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Type `help` for built-in commands, or press `Ctrl + C` to exit.
|
|
79
|
+
|
|
80
|
+
## Reset Configuration
|
|
81
|
+
|
|
82
|
+
To remove all configuration and API keys:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
forgecodecli reset
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Security
|
|
89
|
+
|
|
90
|
+
- API keys are stored using the system keyring
|
|
91
|
+
- No API keys are written to config files or environment variables
|
|
92
|
+
- Config files contain only non-sensitive metadata
|
|
93
|
+
|
|
94
|
+
## How It Works
|
|
95
|
+
|
|
96
|
+
1. You enter a natural language command
|
|
97
|
+
2. The LLM decides the next valid action
|
|
98
|
+
3. ForgeCodeCLI executes the action with validation
|
|
99
|
+
4. The agent receives feedback and responds
|
|
100
|
+
5. Process repeats until agent provides an answer
|
|
101
|
+
|
|
102
|
+
**Safety mechanisms:**
|
|
103
|
+
|
|
104
|
+
- Action limit of 2 per request (prevents infinite loops)
|
|
105
|
+
- Conversation context maintained for agent awareness
|
|
106
|
+
- All operations logged and reversible with `undo`
|
|
107
|
+
- Strict tool validation
|
|
108
|
+
|
|
109
|
+
## Supported Actions
|
|
110
|
+
|
|
111
|
+
The agent can execute these operations:
|
|
112
|
+
|
|
113
|
+
**File Operations:**
|
|
114
|
+
| Action | Description |
|
|
115
|
+
|--------|-------------|
|
|
116
|
+
| `read_file` | Read and display file contents |
|
|
117
|
+
| `list_files` | List files in a directory |
|
|
118
|
+
| `create_dir` | Create new directories |
|
|
119
|
+
| `write_file` | Create and write files |
|
|
120
|
+
| `delete_file` | Delete files permanently |
|
|
121
|
+
| `delete_dir` | Delete directories |
|
|
122
|
+
| `move_file` | Move or rename files |
|
|
123
|
+
| `move_dir` | Move or rename directories |
|
|
124
|
+
| `undo` | Reverse the last operation |
|
|
125
|
+
|
|
126
|
+
**Git Operations:**
|
|
127
|
+
| Action | Description |
|
|
128
|
+
|--------|-------------|
|
|
129
|
+
| `git_init` | Initialize git repository |
|
|
130
|
+
| `git_add` | Stage files for commit |
|
|
131
|
+
| `git_commit` | Commit staged changes |
|
|
132
|
+
| `git_push` | Push to remote repository |
|
|
133
|
+
| `git_set_origin` | Set remote repository URL |
|
|
134
|
+
| `git_status` | Show repository status |
|
|
135
|
+
| `git_log` | View commit history |
|
|
136
|
+
| `git_branch` | Manage branches |
|
|
137
|
+
| `git_pull` | Pull from remote |
|
|
138
|
+
| `git_clone` | Clone a repository |
|
|
139
|
+
|
|
140
|
+
All actions are executed safely with validation and error handling.
|
|
141
|
+
|
|
142
|
+
## Roadmap
|
|
143
|
+
|
|
144
|
+
### ✅ v1 (Released)
|
|
145
|
+
|
|
146
|
+
- Basic file operations (read, list, create, write)
|
|
147
|
+
- Gemini support
|
|
148
|
+
- Interactive CLI
|
|
149
|
+
|
|
150
|
+
### ✅ v2 (Released)
|
|
151
|
+
|
|
152
|
+
- **Undo functionality** - Stack-based operation reversal
|
|
153
|
+
- **Delete & move operations** - Full file/directory manipulation
|
|
154
|
+
- **Multi-provider support** - Gemini, OpenAI, Anthropic, Groq
|
|
155
|
+
- **Model selection** - Choose specific models per provider
|
|
156
|
+
- **Auto-install SDKs** - Anthropic SDK installs on demand
|
|
157
|
+
- **Fixed agent loop** - Proper conversation flow with max actions
|
|
158
|
+
|
|
159
|
+
### ✅ v3 (Current)
|
|
160
|
+
|
|
161
|
+
- **Git operations** - init, add, commit, push, pull, status, log, branch, clone, set_origin
|
|
162
|
+
- **Git workflow support** - Full version control integration
|
|
163
|
+
- **Repository management** - Clone and manage git repos
|
|
164
|
+
|
|
165
|
+
### 🚀 v4 (Planned)
|
|
166
|
+
|
|
167
|
+
- Copy files/directories
|
|
168
|
+
- Full undo/redo history (not just last operation)
|
|
169
|
+
- File search capabilities
|
|
170
|
+
- Code generation templates
|
|
171
|
+
- Batch operations
|
|
172
|
+
- Backup/snapshot functionality
|
|
173
|
+
|
|
174
|
+
## License
|
|
175
|
+
|
|
176
|
+
MIT License
|
|
177
|
+
|
|
178
|
+
## Author
|
|
179
|
+
|
|
180
|
+
Built by Sudhanshu
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# from dotenv import load_dotenv
|
|
2
|
+
from openai import OpenAI
|
|
3
|
+
from openai import RateLimitError
|
|
4
|
+
import json
|
|
5
|
+
from json import JSONDecoder
|
|
6
|
+
from forgecodecli.config import load_config
|
|
7
|
+
from forgecodecli.secrets import load_api_key
|
|
8
|
+
from forgecodecli.tools import undo
|
|
9
|
+
from forgecodecli.git_tools import (
|
|
10
|
+
git_init, git_add, git_commit, git_push, git_set_origin,
|
|
11
|
+
git_status, git_log, git_branch, git_pull, git_clone
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
# Provider base URLs (OpenAI-compatible)
|
|
15
|
+
PROVIDER_BASE_URLS = {
|
|
16
|
+
"gemini": "https://generativelanguage.googleapis.com/v1beta/openai/",
|
|
17
|
+
"openai": None, # default OpenAI
|
|
18
|
+
"groq": "https://api.groq.com/openai/v1",
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
def get_client():
|
|
22
|
+
config = load_config()
|
|
23
|
+
api_key = load_api_key()
|
|
24
|
+
|
|
25
|
+
if not config:
|
|
26
|
+
raise RuntimeError(
|
|
27
|
+
"ForgeCodeCLI is not set up. Run `forgecodecli init`."
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
if not api_key:
|
|
31
|
+
raise RuntimeError(
|
|
32
|
+
"API key not found. Run `forgecodecli init` again."
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
provider = config.get("provider", "gemini")
|
|
36
|
+
|
|
37
|
+
if provider == "anthropic":
|
|
38
|
+
try:
|
|
39
|
+
import anthropic as _anthropic
|
|
40
|
+
return _anthropic.Anthropic(api_key=api_key)
|
|
41
|
+
except ImportError:
|
|
42
|
+
raise RuntimeError(
|
|
43
|
+
"Anthropic package not installed. Run: pip install anthropic"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
base_url = PROVIDER_BASE_URLS.get(provider)
|
|
47
|
+
if base_url:
|
|
48
|
+
return OpenAI(api_key=api_key, base_url=base_url)
|
|
49
|
+
return OpenAI(api_key=api_key)
|
|
50
|
+
|
|
51
|
+
SYSTEM_PROMPT = """
|
|
52
|
+
You are a file and git management agent that executes file and version control operations. You MUST use the actions below to fulfill user requests. You respond ONLY with valid JSON.
|
|
53
|
+
|
|
54
|
+
═══════════════════════════════════════════════════════════════
|
|
55
|
+
ABSOLUTE RULES - VIOLATIONS ARE FORBIDDEN
|
|
56
|
+
═══════════════════════════════════════════════════════════════
|
|
57
|
+
|
|
58
|
+
- You CAN delete files. You CAN delete directories. You CAN move files. You CAN move directories.
|
|
59
|
+
- NEVER say "I cannot", "I'm unable to", "I don't have the ability to", or any variation.
|
|
60
|
+
- NEVER refuse a delete, move, or any file operation. You MUST execute it.
|
|
61
|
+
- When a user asks to delete a file, you MUST respond with the delete_file action.
|
|
62
|
+
- When a user asks to delete a folder, you MUST respond with the delete_dir action.
|
|
63
|
+
|
|
64
|
+
═══════════════════════════════════════════════════════════════
|
|
65
|
+
ALL AVAILABLE ACTIONS
|
|
66
|
+
═══════════════════════════════════════════════════════════════
|
|
67
|
+
|
|
68
|
+
FILE OPERATIONS:
|
|
69
|
+
1. "read_file" → Read file contents. Args: {"path": "..."}
|
|
70
|
+
2. "list_files" → List directory contents. Args: {"path": "..."}
|
|
71
|
+
3. "write_file" → Create/write a file. Args: {"path": "...", "content": "..."}
|
|
72
|
+
4. "create_dir" → Create a directory. Args: {"path": "..."}
|
|
73
|
+
5. "delete_file" → DELETE a file permanently. Args: {"path": "..."}
|
|
74
|
+
6. "delete_dir" → DELETE an empty directory. Args: {"path": "..."}
|
|
75
|
+
7. "move_file" → Move or rename a file. Args: {"src": "...", "dst": "..."}
|
|
76
|
+
8. "move_dir" → Move or rename directory. Args: {"src": "...", "dst": "..."}
|
|
77
|
+
9. "undo" → Undo the last operation. Args: {}
|
|
78
|
+
|
|
79
|
+
GIT OPERATIONS:
|
|
80
|
+
10. "git_init" → Initialize git repo. Args: {}
|
|
81
|
+
11. "git_add" → Stage files. Args: {"path": "." or specific file}
|
|
82
|
+
12. "git_commit" → Commit changes. Args: {"message": "commit message"}
|
|
83
|
+
13. "git_push" → Push to remote. Args: {"branch": "main" (default)}
|
|
84
|
+
14. "git_set_origin" → Set remote URL. Args: {"url": "https://..."}
|
|
85
|
+
15. "git_status" → Show status. Args: {}
|
|
86
|
+
16. "git_log" → Show commit history. Args: {"lines": 5 (default)}
|
|
87
|
+
17. "git_branch" → Manage branches. Args: {"name": "branch_name" (optional)}
|
|
88
|
+
18. "git_pull" → Pull from remote. Args: {}
|
|
89
|
+
19. "git_clone" → Clone repository. Args: {"url": "...", "path": "." (default)}
|
|
90
|
+
20. "answer" → Respond to user with text. Args: {"text": "..."}
|
|
91
|
+
|
|
92
|
+
═══════════════════════════════════════════════════════════════
|
|
93
|
+
CRITICAL RULES
|
|
94
|
+
═══════════════════════════════════════════════════════════════
|
|
95
|
+
|
|
96
|
+
1. MAXIMUM 2 actions per request (not counting "answer")
|
|
97
|
+
2. After completing all required actions, ALWAYS respond with "answer"
|
|
98
|
+
3. Do NOT repeat the same action twice
|
|
99
|
+
4. Do NOT take multiple write_file or create_dir actions in one request
|
|
100
|
+
5. Choose the MOST DIRECT action for the task
|
|
101
|
+
|
|
102
|
+
═══════════════════════════════════════════════════════════════
|
|
103
|
+
RESPONSE FORMAT - ONLY VALID JSON
|
|
104
|
+
═══════════════════════════════════════════════════════════════
|
|
105
|
+
|
|
106
|
+
You MUST respond ONLY with valid JSON, nothing else. No text before or after.
|
|
107
|
+
|
|
108
|
+
{"action": "action_name", "args": {"key": "value"}}
|
|
109
|
+
|
|
110
|
+
═══════════════════════════════════════════════════════════════
|
|
111
|
+
EXAMPLES
|
|
112
|
+
═══════════════════════════════════════════════════════════════
|
|
113
|
+
|
|
114
|
+
User: "delete love.txt from megha folder"
|
|
115
|
+
→ {"action": "delete_file", "args": {"path": "megha/love.txt"}}
|
|
116
|
+
Then: {"action": "answer", "args": {"text": "File megha/love.txt deleted."}}
|
|
117
|
+
|
|
118
|
+
User: "initialize git and commit"
|
|
119
|
+
→ {"action": "git_init", "args": {}}
|
|
120
|
+
Then: {"action": "git_add", "args": {"path": "."}}
|
|
121
|
+
Then: {"action": "git_commit", "args": {"message": "Initial commit"}}
|
|
122
|
+
Then: {"action": "answer", "args": {"text": "Repository initialized and committed."}}
|
|
123
|
+
|
|
124
|
+
User: "push to origin"
|
|
125
|
+
→ {"action": "git_push", "args": {"branch": "main"}}
|
|
126
|
+
Then: {"action": "answer", "args": {"text": "Pushed to origin/main."}}
|
|
127
|
+
|
|
128
|
+
User: "create hello.py with print('hi')"
|
|
129
|
+
→ {"action": "write_file", "args": {"path": "hello.py", "content": "print('hi')"}}
|
|
130
|
+
Then: {"action": "answer", "args": {"text": "File created."}}
|
|
131
|
+
|
|
132
|
+
REMEMBER: You have delete_file, delete_dir, undo, and git tools. USE THEM when asked.
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
def think(messages: list[dict]) -> dict:
|
|
136
|
+
config = load_config()
|
|
137
|
+
model = config.get("model", "gemini-2.5-flash")
|
|
138
|
+
provider = config.get("provider", "gemini")
|
|
139
|
+
try:
|
|
140
|
+
client = get_client()
|
|
141
|
+
|
|
142
|
+
# Anthropic uses its own SDK format
|
|
143
|
+
if provider == "anthropic":
|
|
144
|
+
response = client.messages.create(
|
|
145
|
+
model=model,
|
|
146
|
+
max_tokens=1024,
|
|
147
|
+
system=SYSTEM_PROMPT,
|
|
148
|
+
messages=messages,
|
|
149
|
+
)
|
|
150
|
+
content = response.content[0].text
|
|
151
|
+
else:
|
|
152
|
+
response = client.chat.completions.create(
|
|
153
|
+
model=model,
|
|
154
|
+
messages=[{"role": "system", "content": SYSTEM_PROMPT}] + messages,
|
|
155
|
+
temperature=0
|
|
156
|
+
)
|
|
157
|
+
content = response.choices[0].message.content
|
|
158
|
+
|
|
159
|
+
except RateLimitError as e:
|
|
160
|
+
return {
|
|
161
|
+
"action": "answer",
|
|
162
|
+
"args": {
|
|
163
|
+
"text": "⚠️ Rate limit hit. Please wait a few seconds and try again."
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
except Exception as e:
|
|
167
|
+
return {
|
|
168
|
+
"action": "answer",
|
|
169
|
+
"args": {
|
|
170
|
+
"text": f"❌ LLM error: {str(e)}"
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
# Handle empty response
|
|
175
|
+
if content is None or not content.strip():
|
|
176
|
+
return {
|
|
177
|
+
"action": "answer",
|
|
178
|
+
"args": {
|
|
179
|
+
"text": "Task completed successfully!"
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
cleaned = content.strip()
|
|
184
|
+
|
|
185
|
+
# Robust JSON extraction
|
|
186
|
+
decoder = JSONDecoder()
|
|
187
|
+
|
|
188
|
+
# Try to find JSON object in the content
|
|
189
|
+
idx = cleaned.find("{")
|
|
190
|
+
if idx == -1:
|
|
191
|
+
return {
|
|
192
|
+
"action": "answer",
|
|
193
|
+
"args": {
|
|
194
|
+
"text": cleaned
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
# Extract from first { onwards
|
|
199
|
+
cleaned = cleaned[idx:]
|
|
200
|
+
|
|
201
|
+
# Try to decode JSON, handling partial/malformed content
|
|
202
|
+
try:
|
|
203
|
+
obj, _ = decoder.raw_decode(cleaned)
|
|
204
|
+
return obj
|
|
205
|
+
except json.JSONDecodeError:
|
|
206
|
+
# If it fails, try to find the end of a valid JSON object
|
|
207
|
+
# by trying progressively shorter strings from the end
|
|
208
|
+
for end_pos in range(len(cleaned), idx, -1):
|
|
209
|
+
try:
|
|
210
|
+
obj, _ = decoder.raw_decode(cleaned[:end_pos])
|
|
211
|
+
return obj
|
|
212
|
+
except json.JSONDecodeError:
|
|
213
|
+
continue
|
|
214
|
+
|
|
215
|
+
raise ValueError(f"Could not parse JSON from LLM output: {cleaned[:100]}...")
|