mforege 0.1.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.
- mforege-0.1.0/LICENSE +21 -0
- mforege-0.1.0/PKG-INFO +265 -0
- mforege-0.1.0/README.md +228 -0
- mforege-0.1.0/app/__init__.py +3 -0
- mforege-0.1.0/app/agent/__init__.py +10 -0
- mforege-0.1.0/app/agent/agent.py +431 -0
- mforege-0.1.0/app/agent/long_term_memory.py +261 -0
- mforege-0.1.0/app/agent/memory.py +108 -0
- mforege-0.1.0/app/agent/tools.py +264 -0
- mforege-0.1.0/app/llm/__init__.py +6 -0
- mforege-0.1.0/app/llm/client.py +149 -0
- mforege-0.1.0/app/tools/__init__.py +28 -0
- mforege-0.1.0/app/tools/system_tools.py +972 -0
- mforege-0.1.0/app/tools/web_search.py +107 -0
- mforege-0.1.0/app/ui.py +237 -0
- mforege-0.1.0/main.py +334 -0
- mforege-0.1.0/mforege.egg-info/PKG-INFO +265 -0
- mforege-0.1.0/mforege.egg-info/SOURCES.txt +30 -0
- mforege-0.1.0/mforege.egg-info/dependency_links.txt +1 -0
- mforege-0.1.0/mforege.egg-info/entry_points.txt +2 -0
- mforege-0.1.0/mforege.egg-info/requires.txt +10 -0
- mforege-0.1.0/mforege.egg-info/top_level.txt +2 -0
- mforege-0.1.0/pyproject.toml +52 -0
- mforege-0.1.0/setup.cfg +4 -0
- mforege-0.1.0/tests/test_agent.py +261 -0
- mforege-0.1.0/tests/test_discovery_tools.py +160 -0
- mforege-0.1.0/tests/test_llm_client.py +120 -0
- mforege-0.1.0/tests/test_long_term_memory.py +210 -0
- mforege-0.1.0/tests/test_memory.py +76 -0
- mforege-0.1.0/tests/test_system_tools.py +493 -0
- mforege-0.1.0/tests/test_tools.py +101 -0
- mforege-0.1.0/tests/test_web_search.py +99 -0
mforege-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Munjur
|
|
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.
|
mforege-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mforege
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MForege โ a personal AI agent CLI with tools, memory, and an IDE-style terminal UI
|
|
5
|
+
Author-email: Munjur Alom <munjuralom.devs@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/munjurdev/MForege
|
|
8
|
+
Project-URL: Repository, https://github.com/munjurdev/MForege
|
|
9
|
+
Project-URL: Issues, https://github.com/munjurdev/MForege/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/munjurdev/MForege/releases
|
|
11
|
+
Keywords: ai,agent,cli,assistant,llm,openai,ollama,groq,tools,chatbot
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Software Development
|
|
23
|
+
Classifier: Topic :: Utilities
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: openai==3.13.0
|
|
28
|
+
Requires-Dist: python-decouple==3.8
|
|
29
|
+
Requires-Dist: exa-py==2.20.0
|
|
30
|
+
Requires-Dist: prompt_toolkit==3.0.53
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest==8.4.2; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-asyncio>=1.0; extra == "dev"
|
|
34
|
+
Requires-Dist: build; extra == "dev"
|
|
35
|
+
Requires-Dist: twine; extra == "dev"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
# MForege โ AI Agent CLI
|
|
39
|
+
|
|
40
|
+
[](https://pypi.org/project/mforege/)
|
|
41
|
+
[](https://pypi.org/project/mforege/)
|
|
42
|
+
[](LICENSE)
|
|
43
|
+
|
|
44
|
+
A command-line AI agent with a transparent, IDE-style interface: live tool
|
|
45
|
+
activity, colored diffs on every file change, mission plans, and long-term
|
|
46
|
+
memory. Supports OpenAI, Ollama (free & local), and any OpenAI-compatible
|
|
47
|
+
API (Groq, Together, etc.).
|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install mforege
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Or with [pipx](https://pipx.pypa.io) (recommended for CLIs โ isolated env,
|
|
56
|
+
command on PATH everywhere):
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pipx install mforege
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Or straight from source:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install git+https://github.com/munjurdev/MForege.git
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Features
|
|
69
|
+
|
|
70
|
+
### Agent core
|
|
71
|
+
|
|
72
|
+
- **Full tool loop** โ when the model calls a tool, the result is sent back so
|
|
73
|
+
the model can use it in its answer (streaming and non-streaming); up to 10
|
|
74
|
+
rounds per message, configurable via `AgentConfig.max_tool_rounds`
|
|
75
|
+
- **Streaming output** โ responses appear token by token, with a
|
|
76
|
+
`thinking Ns...` timer while the model works
|
|
77
|
+
- **Personality + response control** โ friendly, witty, emoji-moderate; short
|
|
78
|
+
answers for casual chat, clarifying questions for ambiguous or underspecified
|
|
79
|
+
requests (never dumps giant tutorials or acts on invented details)
|
|
80
|
+
|
|
81
|
+
### Tools
|
|
82
|
+
|
|
83
|
+
| Tool | Purpose |
|
|
84
|
+
|------|---------|
|
|
85
|
+
| `list_files` | List directories (workspace-confined) |
|
|
86
|
+
| `read_file` | Read text files with line numbers; `offset`/`limit` windows for big files |
|
|
87
|
+
| `search_code` | Regex search across the project (`file:line: match`), noise dirs skipped |
|
|
88
|
+
| `glob_files` | Find files by pattern, recursively (`**/*.py`), newest first |
|
|
89
|
+
| `run_command` | Shell commands with a 3-tier safety model |
|
|
90
|
+
| `create_file` | New files (parent folders auto-created) |
|
|
91
|
+
| `edit_file` | Exact, unique-snippet replacement |
|
|
92
|
+
| `todo_plan` | Visible step-by-step mission plan |
|
|
93
|
+
| `calculator` | Safe AST-based math (no `eval`) |
|
|
94
|
+
| `get_current_time` | Current date/time |
|
|
95
|
+
| `web_search` | Live web search via Exa (needs `EXA_API_KEY`) |
|
|
96
|
+
|
|
97
|
+
### Safety
|
|
98
|
+
|
|
99
|
+
- **Destructive commands blocked** outright (`rm -rf`, `git push --force`,
|
|
100
|
+
`format`, ...)
|
|
101
|
+
- **Mutating actions require approval** โ file writes/edits show a colored
|
|
102
|
+
diff before you confirm; commands show the exact line to be run
|
|
103
|
+
- **Fail-closed** โ without a confirmation handler, mutating operations refuse
|
|
104
|
+
rather than run unconfirmed
|
|
105
|
+
- **Workspace-confined** โ path tools only operate inside the folder you
|
|
106
|
+
choose at launch; `../` and symlink escapes are rejected
|
|
107
|
+
- **Timeouts & caps** โ 30s command timeout, tool output capped so the context
|
|
108
|
+
window never balloons
|
|
109
|
+
|
|
110
|
+
### Chat-style interface (prompt_toolkit)
|
|
111
|
+
|
|
112
|
+
- **Bottom input box** โ the input stays pinned at the bottom like a chat app;
|
|
113
|
+
the transcript scrolls above it
|
|
114
|
+
- **Live activity stream** โ every tool call prints as `ยท tool(args) โ (0.3s)`
|
|
115
|
+
- **Thinking timer** โ `thinking Ns...` runs until the first token arrives
|
|
116
|
+
- **Colored diffs** โ `+` green / `-` red, shown before approval *and* in the
|
|
117
|
+
transcript after the edit lands
|
|
118
|
+
- **Plan statusline** โ `[Plan 2/5] next: write the test` after each reply
|
|
119
|
+
- **Status bar** โ model, workspace, and shortcut hints always visible
|
|
120
|
+
- **Keys** โ Enter sends, Alt+Enter adds a newline, Ctrl+C quits
|
|
121
|
+
- **Slash commands** โ `/help`, `/plan`, `/tools`, `/memory`, `/forget`,
|
|
122
|
+
`/clear`, `/exit`
|
|
123
|
+
|
|
124
|
+
### Memory
|
|
125
|
+
|
|
126
|
+
- **Conversation memory** โ history per session, `clear` resets it
|
|
127
|
+
- **Long-term memory** โ after each reply a side-call asks *"did I learn
|
|
128
|
+
anything durable?"*; facts (name, projects, preferences) are saved to
|
|
129
|
+
`data/memory.json` (git-ignored) and injected into future sessions.
|
|
130
|
+
Personalized greeting on startup ("Welcome back, Munjur! ๐")
|
|
131
|
+
|
|
132
|
+
### Resilience
|
|
133
|
+
|
|
134
|
+
- Request timeouts + automatic retries with backoff for transient failures
|
|
135
|
+
- Friendly errors for missing keys or Ollama not running
|
|
136
|
+
- UTF-8 output on Windows (emoji-safe), clean async shutdown
|
|
137
|
+
|
|
138
|
+
## Setup
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
python -m venv env
|
|
142
|
+
env/Scripts/activate # Windows (bash: source env/Scripts/activate)
|
|
143
|
+
pip install -r requirements.txt
|
|
144
|
+
pip install -e . # installs the `mforege` command
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
After `pip install -e .`, MForege works from **any** terminal โ including VS
|
|
148
|
+
Code's โ with the venv activated:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
mforege # in any folder (uses MForege's own .env)
|
|
152
|
+
mforege --workspace "C:\path\to\project" # work inside another project
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Backends
|
|
156
|
+
|
|
157
|
+
**OpenAI** โ put your key in `.env`:
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
OPENAI_API_KEY=sk-...
|
|
161
|
+
LLM_MODEL=gpt-4o-mini
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Ollama (free, local)** โ install from https://ollama.com, then:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
ollama pull llama3
|
|
168
|
+
mforege --backend ollama --model llama3
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Custom (e.g., Groq)**:
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
API_KEY=gsk_...
|
|
175
|
+
BASE_URL=https://api.groq.com/openai/v1
|
|
176
|
+
LLM_MODEL=llama-3.1-8b-instant
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Web search (optional)
|
|
180
|
+
|
|
181
|
+
1. Get a free API key at https://dashboard.exa.ai
|
|
182
|
+
2. Add to `.env`: `EXA_API_KEY=your_key`
|
|
183
|
+
3. Restart the CLI
|
|
184
|
+
|
|
185
|
+
### Workspace
|
|
186
|
+
|
|
187
|
+
MForege can only read/write inside one folder โ the one you choose:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
mforege --workspace "C:\path\to\your\project"
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
The header shows the active workspace. To work in a different folder, restart
|
|
194
|
+
with a different `--workspace` (or set `WORKSPACE` in `.env`).
|
|
195
|
+
|
|
196
|
+
## Run
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
python main.py # from the project folder
|
|
200
|
+
mforege # from ANY folder (after pip install -e .)
|
|
201
|
+
mforege --backend ollama --model llama3
|
|
202
|
+
mforege --workspace "C:\path\to\your\project"
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
`.env` resolution: if the current folder has a `.env`, it wins; otherwise
|
|
206
|
+
MForege falls back to its own `.env` โ so API keys are found no matter where
|
|
207
|
+
you launch it. Workspace defaults to the current directory.
|
|
208
|
+
|
|
209
|
+
## CLI commands
|
|
210
|
+
|
|
211
|
+
| Command | Action |
|
|
212
|
+
|----------|--------------------------------------------|
|
|
213
|
+
| `/help` | Show the command menu |
|
|
214
|
+
| `/plan` | Show the current mission plan |
|
|
215
|
+
| `/tools` | List registered tools |
|
|
216
|
+
| `/memory`| Show what MForege remembers about you |
|
|
217
|
+
| `/forget`| Wipe long-term memory |
|
|
218
|
+
| `/clear` | Reset conversation (current session) |
|
|
219
|
+
| `/exit` | Quit (plain `exit` also works) |
|
|
220
|
+
|
|
221
|
+
## Example session
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
Welcome back, Munjur! ๐
|
|
225
|
+
(I remember 2 things)
|
|
226
|
+
|
|
227
|
+
You: create utils.py with a greet function, then test it
|
|
228
|
+
Assistant: thinking 2s...
|
|
229
|
+
ยท todo_plan(action=set) โ (0.0s)
|
|
230
|
+
ยท create_file(path=utils.py) โ (0.0s)
|
|
231
|
+
[?] MForege wants to: CREATE file 'utils.py' (95 chars)
|
|
232
|
+
@@ -0,0 +1,3 @@
|
|
233
|
+
+def greet(name):
|
|
234
|
+
+ return f"Hello, {name}!"
|
|
235
|
+
Allow? [y/N]: y
|
|
236
|
+
โ Edit applied:
|
|
237
|
+
@@ -0,0 +1,3 @@
|
|
238
|
+
+def greet(name):
|
|
239
|
+
...
|
|
240
|
+
[Plan 2/4] next: run the tests
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Adding your own tool
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
from app.agent.tools import create_tool
|
|
247
|
+
|
|
248
|
+
async def get_weather(city: str):
|
|
249
|
+
return f"Sunny in {city}, 25C"
|
|
250
|
+
|
|
251
|
+
agent.register_tools(create_tool("get_weather", "Get weather for a city", get_weather))
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Tests
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
env/Scripts/python -m pytest
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
161 tests covering conversation memory, the tool registry, the safe
|
|
261
|
+
calculator, the web search tool, long-term memory (store, injection,
|
|
262
|
+
extraction), system tools (path confinement, command classification,
|
|
263
|
+
confirmation flow โ sync and async, diffs, notifications), discovery tools
|
|
264
|
+
(search/glob/read windows), the todo plan, and the agent's tool-call loop โ
|
|
265
|
+
all with a mocked LLM, no network needed.
|
mforege-0.1.0/README.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# MForege โ AI Agent CLI
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/mforege/)
|
|
4
|
+
[](https://pypi.org/project/mforege/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
A command-line AI agent with a transparent, IDE-style interface: live tool
|
|
8
|
+
activity, colored diffs on every file change, mission plans, and long-term
|
|
9
|
+
memory. Supports OpenAI, Ollama (free & local), and any OpenAI-compatible
|
|
10
|
+
API (Groq, Together, etc.).
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install mforege
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or with [pipx](https://pipx.pypa.io) (recommended for CLIs โ isolated env,
|
|
19
|
+
command on PATH everywhere):
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pipx install mforege
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or straight from source:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install git+https://github.com/munjurdev/MForege.git
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
### Agent core
|
|
34
|
+
|
|
35
|
+
- **Full tool loop** โ when the model calls a tool, the result is sent back so
|
|
36
|
+
the model can use it in its answer (streaming and non-streaming); up to 10
|
|
37
|
+
rounds per message, configurable via `AgentConfig.max_tool_rounds`
|
|
38
|
+
- **Streaming output** โ responses appear token by token, with a
|
|
39
|
+
`thinking Ns...` timer while the model works
|
|
40
|
+
- **Personality + response control** โ friendly, witty, emoji-moderate; short
|
|
41
|
+
answers for casual chat, clarifying questions for ambiguous or underspecified
|
|
42
|
+
requests (never dumps giant tutorials or acts on invented details)
|
|
43
|
+
|
|
44
|
+
### Tools
|
|
45
|
+
|
|
46
|
+
| Tool | Purpose |
|
|
47
|
+
|------|---------|
|
|
48
|
+
| `list_files` | List directories (workspace-confined) |
|
|
49
|
+
| `read_file` | Read text files with line numbers; `offset`/`limit` windows for big files |
|
|
50
|
+
| `search_code` | Regex search across the project (`file:line: match`), noise dirs skipped |
|
|
51
|
+
| `glob_files` | Find files by pattern, recursively (`**/*.py`), newest first |
|
|
52
|
+
| `run_command` | Shell commands with a 3-tier safety model |
|
|
53
|
+
| `create_file` | New files (parent folders auto-created) |
|
|
54
|
+
| `edit_file` | Exact, unique-snippet replacement |
|
|
55
|
+
| `todo_plan` | Visible step-by-step mission plan |
|
|
56
|
+
| `calculator` | Safe AST-based math (no `eval`) |
|
|
57
|
+
| `get_current_time` | Current date/time |
|
|
58
|
+
| `web_search` | Live web search via Exa (needs `EXA_API_KEY`) |
|
|
59
|
+
|
|
60
|
+
### Safety
|
|
61
|
+
|
|
62
|
+
- **Destructive commands blocked** outright (`rm -rf`, `git push --force`,
|
|
63
|
+
`format`, ...)
|
|
64
|
+
- **Mutating actions require approval** โ file writes/edits show a colored
|
|
65
|
+
diff before you confirm; commands show the exact line to be run
|
|
66
|
+
- **Fail-closed** โ without a confirmation handler, mutating operations refuse
|
|
67
|
+
rather than run unconfirmed
|
|
68
|
+
- **Workspace-confined** โ path tools only operate inside the folder you
|
|
69
|
+
choose at launch; `../` and symlink escapes are rejected
|
|
70
|
+
- **Timeouts & caps** โ 30s command timeout, tool output capped so the context
|
|
71
|
+
window never balloons
|
|
72
|
+
|
|
73
|
+
### Chat-style interface (prompt_toolkit)
|
|
74
|
+
|
|
75
|
+
- **Bottom input box** โ the input stays pinned at the bottom like a chat app;
|
|
76
|
+
the transcript scrolls above it
|
|
77
|
+
- **Live activity stream** โ every tool call prints as `ยท tool(args) โ (0.3s)`
|
|
78
|
+
- **Thinking timer** โ `thinking Ns...` runs until the first token arrives
|
|
79
|
+
- **Colored diffs** โ `+` green / `-` red, shown before approval *and* in the
|
|
80
|
+
transcript after the edit lands
|
|
81
|
+
- **Plan statusline** โ `[Plan 2/5] next: write the test` after each reply
|
|
82
|
+
- **Status bar** โ model, workspace, and shortcut hints always visible
|
|
83
|
+
- **Keys** โ Enter sends, Alt+Enter adds a newline, Ctrl+C quits
|
|
84
|
+
- **Slash commands** โ `/help`, `/plan`, `/tools`, `/memory`, `/forget`,
|
|
85
|
+
`/clear`, `/exit`
|
|
86
|
+
|
|
87
|
+
### Memory
|
|
88
|
+
|
|
89
|
+
- **Conversation memory** โ history per session, `clear` resets it
|
|
90
|
+
- **Long-term memory** โ after each reply a side-call asks *"did I learn
|
|
91
|
+
anything durable?"*; facts (name, projects, preferences) are saved to
|
|
92
|
+
`data/memory.json` (git-ignored) and injected into future sessions.
|
|
93
|
+
Personalized greeting on startup ("Welcome back, Munjur! ๐")
|
|
94
|
+
|
|
95
|
+
### Resilience
|
|
96
|
+
|
|
97
|
+
- Request timeouts + automatic retries with backoff for transient failures
|
|
98
|
+
- Friendly errors for missing keys or Ollama not running
|
|
99
|
+
- UTF-8 output on Windows (emoji-safe), clean async shutdown
|
|
100
|
+
|
|
101
|
+
## Setup
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
python -m venv env
|
|
105
|
+
env/Scripts/activate # Windows (bash: source env/Scripts/activate)
|
|
106
|
+
pip install -r requirements.txt
|
|
107
|
+
pip install -e . # installs the `mforege` command
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
After `pip install -e .`, MForege works from **any** terminal โ including VS
|
|
111
|
+
Code's โ with the venv activated:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
mforege # in any folder (uses MForege's own .env)
|
|
115
|
+
mforege --workspace "C:\path\to\project" # work inside another project
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Backends
|
|
119
|
+
|
|
120
|
+
**OpenAI** โ put your key in `.env`:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
OPENAI_API_KEY=sk-...
|
|
124
|
+
LLM_MODEL=gpt-4o-mini
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Ollama (free, local)** โ install from https://ollama.com, then:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
ollama pull llama3
|
|
131
|
+
mforege --backend ollama --model llama3
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Custom (e.g., Groq)**:
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
API_KEY=gsk_...
|
|
138
|
+
BASE_URL=https://api.groq.com/openai/v1
|
|
139
|
+
LLM_MODEL=llama-3.1-8b-instant
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Web search (optional)
|
|
143
|
+
|
|
144
|
+
1. Get a free API key at https://dashboard.exa.ai
|
|
145
|
+
2. Add to `.env`: `EXA_API_KEY=your_key`
|
|
146
|
+
3. Restart the CLI
|
|
147
|
+
|
|
148
|
+
### Workspace
|
|
149
|
+
|
|
150
|
+
MForege can only read/write inside one folder โ the one you choose:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
mforege --workspace "C:\path\to\your\project"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The header shows the active workspace. To work in a different folder, restart
|
|
157
|
+
with a different `--workspace` (or set `WORKSPACE` in `.env`).
|
|
158
|
+
|
|
159
|
+
## Run
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
python main.py # from the project folder
|
|
163
|
+
mforege # from ANY folder (after pip install -e .)
|
|
164
|
+
mforege --backend ollama --model llama3
|
|
165
|
+
mforege --workspace "C:\path\to\your\project"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
`.env` resolution: if the current folder has a `.env`, it wins; otherwise
|
|
169
|
+
MForege falls back to its own `.env` โ so API keys are found no matter where
|
|
170
|
+
you launch it. Workspace defaults to the current directory.
|
|
171
|
+
|
|
172
|
+
## CLI commands
|
|
173
|
+
|
|
174
|
+
| Command | Action |
|
|
175
|
+
|----------|--------------------------------------------|
|
|
176
|
+
| `/help` | Show the command menu |
|
|
177
|
+
| `/plan` | Show the current mission plan |
|
|
178
|
+
| `/tools` | List registered tools |
|
|
179
|
+
| `/memory`| Show what MForege remembers about you |
|
|
180
|
+
| `/forget`| Wipe long-term memory |
|
|
181
|
+
| `/clear` | Reset conversation (current session) |
|
|
182
|
+
| `/exit` | Quit (plain `exit` also works) |
|
|
183
|
+
|
|
184
|
+
## Example session
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
Welcome back, Munjur! ๐
|
|
188
|
+
(I remember 2 things)
|
|
189
|
+
|
|
190
|
+
You: create utils.py with a greet function, then test it
|
|
191
|
+
Assistant: thinking 2s...
|
|
192
|
+
ยท todo_plan(action=set) โ (0.0s)
|
|
193
|
+
ยท create_file(path=utils.py) โ (0.0s)
|
|
194
|
+
[?] MForege wants to: CREATE file 'utils.py' (95 chars)
|
|
195
|
+
@@ -0,0 +1,3 @@
|
|
196
|
+
+def greet(name):
|
|
197
|
+
+ return f"Hello, {name}!"
|
|
198
|
+
Allow? [y/N]: y
|
|
199
|
+
โ Edit applied:
|
|
200
|
+
@@ -0,0 +1,3 @@
|
|
201
|
+
+def greet(name):
|
|
202
|
+
...
|
|
203
|
+
[Plan 2/4] next: run the tests
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Adding your own tool
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
from app.agent.tools import create_tool
|
|
210
|
+
|
|
211
|
+
async def get_weather(city: str):
|
|
212
|
+
return f"Sunny in {city}, 25C"
|
|
213
|
+
|
|
214
|
+
agent.register_tools(create_tool("get_weather", "Get weather for a city", get_weather))
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Tests
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
env/Scripts/python -m pytest
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
161 tests covering conversation memory, the tool registry, the safe
|
|
224
|
+
calculator, the web search tool, long-term memory (store, injection,
|
|
225
|
+
extraction), system tools (path confinement, command classification,
|
|
226
|
+
confirmation flow โ sync and async, diffs, notifications), discovery tools
|
|
227
|
+
(search/glob/read windows), the todo plan, and the agent's tool-call loop โ
|
|
228
|
+
all with a mocked LLM, no network needed.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AI Agent Package
|
|
3
|
+
"""
|
|
4
|
+
from ..llm import LLMClient
|
|
5
|
+
from .agent import Agent, AgentConfig
|
|
6
|
+
from .memory import ConversationMemory, Message
|
|
7
|
+
from .long_term_memory import LongTermMemory
|
|
8
|
+
from .tools import Tool, ToolRegistry, CalculatorTool, TimeTool
|
|
9
|
+
|
|
10
|
+
__all__ = ["Agent", "AgentConfig", "LLMClient", "ConversationMemory", "Message", "LongTermMemory", "Tool", "ToolRegistry", "CalculatorTool", "TimeTool"]
|