wisemonkey 2026.6.16__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.
Files changed (52) hide show
  1. wisemonkey-2026.6.16/.env.example +3 -0
  2. wisemonkey-2026.6.16/.gitignore +16 -0
  3. wisemonkey-2026.6.16/.python-version +1 -0
  4. wisemonkey-2026.6.16/AGENTS.md +160 -0
  5. wisemonkey-2026.6.16/LICENSE +21 -0
  6. wisemonkey-2026.6.16/MANIFEST.in +8 -0
  7. wisemonkey-2026.6.16/PKG-INFO +351 -0
  8. wisemonkey-2026.6.16/README.md +330 -0
  9. wisemonkey-2026.6.16/agent/__init__.py +12 -0
  10. wisemonkey-2026.6.16/agent/__main__.py +212 -0
  11. wisemonkey-2026.6.16/agent/agent.py +376 -0
  12. wisemonkey-2026.6.16/agent/commands.py +709 -0
  13. wisemonkey-2026.6.16/agent/config.py +265 -0
  14. wisemonkey-2026.6.16/agent/console.py +88 -0
  15. wisemonkey-2026.6.16/agent/core.py +561 -0
  16. wisemonkey-2026.6.16/agent/mcp.py +252 -0
  17. wisemonkey-2026.6.16/agent/memory.py +407 -0
  18. wisemonkey-2026.6.16/agent/router.py +776 -0
  19. wisemonkey-2026.6.16/agent/skills.py +92 -0
  20. wisemonkey-2026.6.16/agent/startup.py +120 -0
  21. wisemonkey-2026.6.16/agent/tools.py +151 -0
  22. wisemonkey-2026.6.16/agent/tui.py +315 -0
  23. wisemonkey-2026.6.16/agent/update.py +178 -0
  24. wisemonkey-2026.6.16/agent/utils.py +98 -0
  25. wisemonkey-2026.6.16/agent/vectorstore.py +193 -0
  26. wisemonkey-2026.6.16/banner.png +0 -0
  27. wisemonkey-2026.6.16/banner.svg +449 -0
  28. wisemonkey-2026.6.16/config.yaml +50 -0
  29. wisemonkey-2026.6.16/icon.png +0 -0
  30. wisemonkey-2026.6.16/icon.svg +339 -0
  31. wisemonkey-2026.6.16/install.sh +94 -0
  32. wisemonkey-2026.6.16/justfile +34 -0
  33. wisemonkey-2026.6.16/pyproject.toml +31 -0
  34. wisemonkey-2026.6.16/screenshot.jpg +0 -0
  35. wisemonkey-2026.6.16/skills/create-plan.md +74 -0
  36. wisemonkey-2026.6.16/skills/example.md +23 -0
  37. wisemonkey-2026.6.16/skills/rolldice.md +14 -0
  38. wisemonkey-2026.6.16/tests/__init__.py +0 -0
  39. wisemonkey-2026.6.16/tests/conftest.py +81 -0
  40. wisemonkey-2026.6.16/tests/test_config.py +111 -0
  41. wisemonkey-2026.6.16/tests/test_core.py +193 -0
  42. wisemonkey-2026.6.16/tests/test_memory.py +201 -0
  43. wisemonkey-2026.6.16/tests/test_skills.py +131 -0
  44. wisemonkey-2026.6.16/tests/test_tools.py +115 -0
  45. wisemonkey-2026.6.16/tools/__init__.py +1 -0
  46. wisemonkey-2026.6.16/tools/basic.py +64 -0
  47. wisemonkey-2026.6.16/tools/files.py +537 -0
  48. wisemonkey-2026.6.16/tools/memory.py +99 -0
  49. wisemonkey-2026.6.16/tools/network.py +77 -0
  50. wisemonkey-2026.6.16/tools/terminal.py +254 -0
  51. wisemonkey-2026.6.16/tools/vectorstore.py +62 -0
  52. wisemonkey-2026.6.16/uv.lock +2251 -0
@@ -0,0 +1,3 @@
1
+ # Copy this file to .env and fill in your key.
2
+ # The openai package will read OPENAI_API_KEY automatically.
3
+ OPENAI_API_KEY=
@@ -0,0 +1,16 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # dotenv
10
+ .env
11
+
12
+ # Virtual environments
13
+ .venv
14
+
15
+ # Hermes agent
16
+ .hermes
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,160 @@
1
+ # Wisemonkey — Project Guide
2
+
3
+ ## What is this project?
4
+
5
+ Wisemonkey is a simple, extensible CLI AI agent for Linux and macOS terminals. It connects to any OpenAI/Anthropic/Ollama-compatible endpoint and provides session management, persistent memory, vector store document embedding, native + MCP tools, and skills.
6
+
7
+ ## Project Structure
8
+
9
+ ```
10
+ wisemonkey/
11
+ ├── agent/ # Core agent code.
12
+ │ ├── agent.py # Main agent loop, prompt handling, key bindings.
13
+ │ ├── commands.py # Slash commands (e.g. /embed, /quit).
14
+ │ ├── config.py # Configuration loading and handling.
15
+ │ ├── console.py # Rich console output with themed formatting.
16
+ │ ├── core.py # Core agent functions, like API connection and tool calls.
17
+ │ ├── mcp.py # MCP server support.
18
+ │ ├── memory.py # Session memory, paste file creation.
19
+ │ ├── router.py # API router implementation for OpenAI, Ollama, and Anthropic.
20
+ │ ├── skills.py # Skill loading and management.
21
+ │ ├── tools.py # Tool definitions.
22
+ │ ├── update.py # Update management.
23
+ │ ├── utils.py # Utility functions.
24
+ │ └── vectorstore.py # Vector store wrapper.
25
+ ├── tools/ # Tool implementations available to the model.
26
+ │ ├── basic.py # Basic and example tools.
27
+ │ ├── files.py # File read/write tools.
28
+ │ ├── memory.py # search_knowledge tool.
29
+ │ ├── network.py # URL fetching.
30
+ │ ├── terminal.py # Shell command execution.
31
+ │ └── vectorstore.py # Vector store tool handler.
32
+ ├── skills/ # Skill definitions. Add new skills here.
33
+ │ ├── example.md
34
+ │ └── rolldice.md
35
+ ├── tests/ # Contains all `unittest` tests.
36
+ │ └── [...]
37
+ ├── config.yaml # Default config file.
38
+ ├── README.md
39
+ ├── pyproject.toml
40
+ ├── install.sh # Installer script.
41
+ └── .env.example
42
+ ```
43
+
44
+ ## Key Architectural Patterns
45
+
46
+ ### System Prompt Construction (`agent/core.py`)
47
+
48
+ The system prompt is built in `Core._build_system_prompt()` each turn. It assembles, in order:
49
+ 1. Base system prompt from config
50
+ 2. `AGENTS.md` workspace instructions (if found)
51
+ 3. Formatted memory (user profile, notes)
52
+ 4. Chat history
53
+ 5. Loaded skills
54
+
55
+ ### Tool System (`agent/tools.py` + `tools/`)
56
+
57
+ Tools are defined using the `@tool(name, description, parameters)` decorator. They are auto-discovered on startup. Each tool file in `tools/` contains one or more decorated handler functions.
58
+
59
+ ### Slash Commands (`agent/commands.py`)
60
+
61
+ Commands use the `@cmd(name, description, aliases)` decorator and are auto-registered. Each returns `(ok: bool, msg: str, content: str, markdown: str)`.
62
+
63
+ ### Skills (`agent/skills.py` + `skills/`)
64
+
65
+ Skills are `.md` files with YAML frontmatter (`name`, `description`). The body is injected into the system prompt. Follows the agentskills.io standard.
66
+
67
+ ### Memory (`agent/memory.py`)
68
+
69
+ - **User profile** (`user_profile.json`) — set via `set_user_profile` tool
70
+ - **Notes** (`notes.json`) — added via `save_note` tool
71
+ - **Chat history** (`chat_history.json`) — rolling window of recent exchanges
72
+ - All stored per-session under `~/.local/share/wisemonkey/sessions/$SESSION_NAME/`
73
+
74
+ ### Sessions
75
+
76
+ Sessions are directories under `~/.local/share/wisemonkey/sessions/`. Each session has its own memory, chat history, and vector store. Session name defaults to `default`.
77
+
78
+ ## How to Extend
79
+
80
+ ### Adding a Tool
81
+
82
+ 1. Create or edit a file in `tools/`
83
+ 2. Decorate a function with `@tool(name, description, parameters)`
84
+ 3. The tool is auto-discovered — no registration needed
85
+
86
+ ### Adding a Slash Command
87
+
88
+ 1. Add a function in `agent/commands.py`
89
+ 2. Decorate with `@cmd(name, description, aliases=[])`
90
+ 3. Return `(ok, msg, content, markdown)`
91
+
92
+ ### Adding a Skill
93
+
94
+ 1. Create a `.md` file in `skills/` with YAML frontmatter (`name`, `description`)
95
+ 2. The skill body is injected into the system prompt automatically
96
+
97
+ ## Configuration
98
+
99
+ Configuration lives in `$XDG_CONFIG_HOME/wisemonkey/config.yaml` (created on first run). Key sections:
100
+ - `model` — provider, name, base_url, temperature, reasoning
101
+ - `embedding` — embedding model name and endpoint
102
+ - `agent` — max_turns, system_prompt, max_chat_history, vi_mode
103
+
104
+ Run `wisemonkey --onboard` for interactive configuration.
105
+
106
+ ## Development
107
+
108
+ - Requires Python 3.13+ and `uv`
109
+ - Dependencies: `uv sync`
110
+ - Run from source: `uv run wisemonkey`
111
+ - Build: `uv build`
112
+ - Entry point: `agent.__main__:main` → `wisemonkey` CLI command
113
+
114
+ ## Testing
115
+
116
+ Tests use the standard library `unittest` framework. Test files live in `tests/` at the project root, each mirroring the source module it tests.
117
+
118
+ ### Test Structure
119
+
120
+ ```
121
+ tests/
122
+ ├── __init__.py
123
+ ├── conftest.py # Shared fixtures (mock config, temp dirs, singleton resets)
124
+ ├── test_config.py # Config singleton, load/save, dot-notation get/set
125
+ ├── test_core.py # Workspace root finding, context file loading, prompt building
126
+ ├── test_memory.py # Memory, ChatMemory persistence and trimming
127
+ ├── test_skills.py # SkillLoader frontmatter parsing, load_all
128
+ └── test_tools.py # Tool registration, discovery, execution
129
+ ```
130
+
131
+ ### Running Tests
132
+
133
+ ```bash
134
+ # Run all tests
135
+ python -m unittest discover -s tests -v
136
+
137
+ # Run a specific test file
138
+ python -m unittest tests.test_core -v
139
+
140
+ # Run a specific test class
141
+ python -m unittest tests.test_core.TestFindWorkspaceRoot -v
142
+
143
+ # Run a single test
144
+ python -m unittest tests.test_core.TestFindWorkspaceRoot.test_finds_agents_md_in_parent -v
145
+ ```
146
+
147
+ ### Key Patterns
148
+
149
+ - **Reset singletons** — `Config` and `Memory` are singletons; reset them in `setUp`/`tearDown` or via fixtures (`Config._instance = None`, `Memory._instance = None`).
150
+ - **Use `tempfile.mkdtemp()`** — each test gets its own session directory for isolation.
151
+ - **Mock the LLM router** — never hit real API endpoints in tests.
152
+ - **`conftest.py`** — place shared fixtures here (temp dirs, mock config, singleton resets).
153
+
154
+ ## Conventions
155
+
156
+ - Use `pathlib.Path` for filesystem operations
157
+ - Follow XDG Base Directory spec for data/config paths
158
+ - Use `rich` for all console output (via `agent.console`)
159
+ - Tools return plain dicts or strings; the agent serializes as needed
160
+ - Keep the agent loop in `agent/agent.py` separate from core logic in `agent/core.py`
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Toni Sagrista Sellés
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,8 @@
1
+ include README.md
2
+ include LICENSE
3
+ include config.yaml
4
+ include install.sh
5
+ include pyproject.toml
6
+ recursive-include agent *.py
7
+ recursive-include tools *.py
8
+ recursive-include skills *.md
@@ -0,0 +1,351 @@
1
+ Metadata-Version: 2.4
2
+ Name: wisemonkey
3
+ Version: 2026.6.16
4
+ Summary: A simple, extensible, and hackable AI agent for the Linux and macOS terminal
5
+ License-File: LICENSE
6
+ Requires-Python: >=3.13
7
+ Requires-Dist: anthropic>=0.70.0
8
+ Requires-Dist: chromadb>=0.5.0
9
+ Requires-Dist: ollama>=0.4.0
10
+ Requires-Dist: openai>=1.0.0
11
+ Requires-Dist: prompt-toolkit>=3.0.52
12
+ Requires-Dist: pymupdf>=1.24.0
13
+ Requires-Dist: pypubsub>=4.0.7
14
+ Requires-Dist: python-dotenv>=1.0.0
15
+ Requires-Dist: pyyaml>=6.0
16
+ Requires-Dist: rich>=15.0.0
17
+ Requires-Dist: textual>=2.0.0
18
+ Requires-Dist: tiktoken>=0.13.0
19
+ Requires-Dist: xdg-base-dirs>=6.0.2
20
+ Description-Content-Type: text/markdown
21
+
22
+ <h3 align="center"><img src="icon.png" alt="Wisemonkey" width="130px"><br>Wisemonkey - <i>A dead simple CLI agent for Linux and macOS</i></h3>
23
+
24
+ <p align="center">
25
+ <a href="https://codeberg.org/langurmonkey/wisemonkey/releases"><img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fcodeberg.org%2Fapi%2Fv1%2Frepos%2Flangurmonkey%2Fwisemonkey%2Freleases%2Flatest&query=%24.tag_name&label=latest%20release" alt="Latest release" /></a>
26
+ <a href="https://codeberg.org/langurmonkey/wisemonkey/issues"><img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fcodeberg.org%2Fapi%2Fv1%2Frepos%2Flangurmonkey%2Fwisemonkey%2Fissues&query=%24.length&label=open%20issues" alt="Open issues" /></a>
27
+ <a href="https://opensource.org/licenses/MPL-2.0"><img src="https://img.shields.io/badge/license-MIT-brightgreen.svg" alt="License: MPL2.0" /></a>
28
+ <img alt="Static Badge" src="https://img.shields.io/badge/OS-Linux-blue">
29
+ <img alt="Static Badge" src="https://img.shields.io/badge/OS-macOS-yellow">
30
+
31
+ </p>
32
+
33
+ ---
34
+
35
+ [Wisemonkey](https://tonisagrista.com/projects/wisemonkey) is a simple, open, and hackable AI agent for the Linux and macOS terminal. It connects to any service providing an OpenAI, Anthropic, or Ollama-compatible endpoint. It features **session management**, **persistent memory management**, **vector store** for document embedding, native and MCP **tools**, **skills**, and much more.
36
+
37
+ <p align="center">
38
+ <a href="https://asciinema.org/a/8cTlvnN0qFeyflLH" target="_blank"><img src="https://asciinema.org/a/8cTlvnN0qFeyflLH.svg" width="60%"/></a>
39
+ </p>
40
+
41
+ The sections of this document are:
42
+
43
+ - [Quickstart](#quickstart)
44
+ - [Run from source](#run-from-source)
45
+ - [Configuration](#configuration)
46
+ - [Usage and commands](#usage-and-commands)
47
+ - [Global memory](#global-memory)
48
+ - [Rolling chat memory](#rolling-chat-memory)
49
+ - [Extend agent](#extend-agent)
50
+
51
+ ## Quickstart
52
+
53
+ Wisemonkey has been tested to work on Linux and macOS.
54
+
55
+ ### Requirements
56
+
57
+ - Python 3.13+
58
+ - `uv` for dependency management
59
+
60
+ ### Installation
61
+
62
+ Install the agent with:
63
+
64
+ ```bash
65
+ curl -fsSL https://codeberg.org/langurmonkey/wisemonkey/raw/branch/master/install.sh | bash
66
+ ```
67
+
68
+ Launch the onboarding process to configure the agent interactively:
69
+
70
+ ```bash
71
+ wisemonkey --onboard
72
+ ```
73
+
74
+ ### Running
75
+
76
+ Run the agent with the default session:
77
+
78
+ ```bash
79
+ wisemonkey
80
+ ```
81
+
82
+ If you need an API key to access the endpoint, put it in the `.env` file. Wisemonkey looks for the `.env` file in the following locations, in order:
83
+
84
+ - Current directory, `./.env`
85
+ - Config directory, `$XDG_CONFIG_HOME/wisemonkey/.env`
86
+ - Home directory, `$HOME/.env`
87
+
88
+ Create the `.env` file with the API key:
89
+
90
+ ```bash
91
+ echo "OPENAI_API_KEY=your-api-key-here" > .env
92
+ echo "ANTHROPIC_API_KEY=your-api-key-here" > .env
93
+ echo "OLLAMA_API_KEY=your-api-key-here" > .env
94
+ ```
95
+
96
+ > The agent uses `python-dotenv` to load `.env` at startup. The `openai` package reads `OPENAI_API_KEY` from the environment automatically. You can also set `OPENAI_API_KEY` in your shell profile. Same goes for `ANTHROPIC_API_KEY` and `OLLAMA_API_KEY`.
97
+
98
+
99
+ ## Run from source
100
+
101
+ ```bash
102
+ # Clone the repo, then build the project:
103
+ uv build
104
+ # Set API key:
105
+ export OPENAI_API_KEY=your-api-key
106
+ # Run the agent with the default session:
107
+ uv run wisemonkey
108
+ ```
109
+
110
+ ## Configuration
111
+
112
+ You can configure the agent interactively before the first run with `wisemonkey --onboard`. On first run, the configuration file is created in `$XDG_CONFIG_HOME/wisemonkey/config.yaml` from the default configuration (`config.yaml`) in the root of this repository.
113
+
114
+ Additionally, the configuration directory holds the `mcp.json` (see next section), and the `.updates.yml`, which holds information about the last update time and status.
115
+
116
+ ### Model Context Protocol (MCP)
117
+
118
+ Wisemonkey also supports MCP. Use the following commands to manage the MCP integration:
119
+
120
+ - `/mcp`: Show the current MCP configuration
121
+ - `/mcp edit`: Edit the MCP configuration file (`~/.config/wisemonkey/mcp.json`)
122
+ - `/mcp tools`: List all MCP tools available. Alias: `/tools mcp`
123
+
124
+ MCP servers are started when the agent boots. You need to restart the agent if you add new servers.
125
+
126
+ ## Usage and commands
127
+
128
+ Run the agent, and then you can enter your prompt. You can use the following key bindings during input:
129
+
130
+ - <kbd>Alt</kbd> + <kbd>Enter</kbd>: add a new line
131
+ - <kbd>Enter</kbd>: submit the prompt
132
+ - <kbd>Ctrl</kbd> + <kbd>q</kbd>: quit
133
+
134
+ During inference, you can cancel the turn and return to the input prompt with <kbd>Ctrl</kbd> + <kbd>c</kbd>
135
+
136
+ ### Sessions
137
+
138
+ Internally, Wisemonkey uses sessions to separate different memory histories. Sessions are **named by the user**. By default, the agent uses the `default` session. You can start in a different session (either create a new one, or restore it if it exists) by passing its name as a positional argument:
139
+
140
+ ```bash
141
+ # Start in a specific session named 'my-project'
142
+ wisemonkey my-project
143
+ ```
144
+
145
+ The default session's name is `default`, so the following two commands are equivalent:
146
+ ```bash
147
+ # These two commands start the 'default' session
148
+ wisemonkey
149
+ wisemonkey default
150
+ ```
151
+
152
+ You can also list the existing sessions with `-ls`:
153
+
154
+ ```bash
155
+ # List sessions
156
+ wisemonkey --ls
157
+ Sessions:
158
+ - my-project - ~/.local/share/wisemonkey/sessions/my-project
159
+ - default - ~/.local/share/wisemonkey/sessions/default
160
+ ```
161
+
162
+ Sessions contain:
163
+
164
+ - The input history
165
+ - Chat memory (see [chat memory](#chat-memory))
166
+ - Vector store (see [document embedding](#document-embedding))
167
+ - Notes (see [session memory](#session-memory))
168
+ - User profile (see [session memory](#session-memory))
169
+
170
+ For now, the configuration file is the same for all sessions.
171
+
172
+ > Sessions are matched by the directory name in the sessions location (`~/.local/share/wisemonkey/sessions`). You can rename a session by just renaming the directory!
173
+
174
+ ### `vi` mode
175
+
176
+ You can enable `vi` mode for the current session with the [command](#commands) `/vi on`, or permanently in the [configuration](#configuration).
177
+
178
+ **External editor**---In `vi` mode, exit INSERT mode (<kbd>Esc</kbd>), then press <kbd>v</kbd> to edit your prompt in an external editor (uses your `$VISUAL` or `$EDITOR` variable).
179
+
180
+ ### Slash commands
181
+
182
+ There are a few commands available to use in the agent loop. You can list them with `/help`. Also, use `/[command-name] help` (e.g. `/config help`) to show additional help for a command.
183
+
184
+ ## Session memory
185
+
186
+ Persistent memory follows XDG Base Directory spec in `~/.local/share/wisemonkey/session/$SESSION_NAME`:
187
+
188
+ - `user_profile.json`---User information
189
+ - `notes.json`---Persistent notes (added via `save_note` tool)
190
+
191
+ **Lifecycle:**
192
+ - Memory is loaded into the system prompt each turn
193
+ - `save_note` tool adds notes during a session
194
+ - `save_memory` tool explicitly persists memory to disk
195
+ - Memory is auto-saved when the agent exits (interactive mode)
196
+
197
+ ## Document embedding
198
+
199
+ Wisemonkey can embed documents into a per-session vector store, allowing the agent to search and reference their contents during conversation. Use `/embed` to add a document:
200
+
201
+ ```bash
202
+ /embed ~/documents/research_paper.pdf
203
+ /embed ./notes.md
204
+ ```
205
+
206
+ The agent uses the `search_knowledge` tool to query embedded documents when answering questions about previously indexed files. Supported formats include PDF, Markdown, and plain text. Embeddings are powered by the configured embedding model and stored in the session directory under `vectordb/`.
207
+
208
+ ## Chat memory
209
+
210
+ In addition to persistent memory, the agent maintains a **chat history** of recent user input and assistant output pairs. This provides context that survives beyond the LLM's context window. Here is how it works:
211
+
212
+ - Each user message and assistant response is stored in memory
213
+ - Reasoning is omitted from chat memory
214
+ - Automatically compacted when exceeding the configured character limit
215
+ - The user can trigger the compaction any time with `/memory compact`
216
+ - Chat memory is attached to the system prompt on each turn
217
+ - The agent displays the last 10 exchanges, with long messages truncated
218
+
219
+ **Persistence:**
220
+ - Chat history is persisted to `~/.local/share/wisemonkey/session/$SESSION_NAME/chat_history.json`
221
+ - Automatically loaded on startup
222
+ - Saved after every exchange (user input or assistant response)
223
+ - Compacted history is also persisted to disk
224
+
225
+ **Configuration:**
226
+ ```yaml
227
+ agent:
228
+ max_chat_history: 128000 # Maximum history characters to keep for context
229
+ ```
230
+
231
+ ## Structure
232
+
233
+ Wisemonkey is built to be modular and hackable. Here is an overview of the main parts and their mapping to the file system.
234
+
235
+ ```
236
+ wisemonkey/
237
+ ├── agent/ # Core agent code.
238
+ │ ├── agent.py # Main agent loop, prompt handling, key bindings.
239
+ │ ├── commands.py # Slash commands (e.g. /embed, /quit).
240
+ │ ├── config.py # Configuration loading and handling.
241
+ │ ├── console.py # Rich console output with themed formatting.
242
+ │ ├── core.py # Core agent functions, like API connection and tool calls.
243
+ │ ├── mcp.py # MCP server support.
244
+ │ ├── memory.py # Session memory, paste file creation.
245
+ │ ├── router.py # API router implementation for OpenAI, Ollama, and Anthropic.
246
+ │ ├── skills.py # Skill loading and management.
247
+ │ ├── tools.py # Tool definitions.
248
+ │ ├── update.py # Update management.
249
+ │ ├── utils.py # Utility functions.
250
+ │ └── vectorstore.py # Vector store wrapper.
251
+ ├── tools/ # Tool implementations available to the model.
252
+ │ ├── basic.py # Basic and example tools.
253
+ │ ├── files.py # File read/write tools.
254
+ │ ├── memory.py # search_knowledge tool.
255
+ │ ├── network.py # URL fetching.
256
+ │ ├── terminal.py # Shell command execution.
257
+ │ └── vectorstore.py # Vector store tool handler.
258
+ ├── skills/ # Skill definitions. Add new skills here.
259
+ │ ├── example.md
260
+ │ └── rolldice.md
261
+ ├── tests/ # Contains all `unittest` tests.
262
+ │ └── [...]
263
+ ├── config.yaml # Default config file.
264
+ ├── README.md
265
+ ├── pyproject.toml
266
+ ├── install.sh # Installer script.
267
+ └── .env.example
268
+ ```
269
+
270
+ ## Extend the agent
271
+
272
+ This agent is simple enough that it can be easily customized and extended by adding new tools, commands, and skills.
273
+
274
+ If you create a cool new tool, skill, or slash command, consider contributing it via a merge request!
275
+
276
+ ### Adding tools
277
+
278
+ Create a file in `tools/` or use one of the existing ones. To create a tool,
279
+ create a method and decorate it with `@tool(name, description, params)`:
280
+
281
+ ```python
282
+ from agent.tools import tool
283
+
284
+ @tool(
285
+ name="my_tool",
286
+ description="Does something useful. Be exhaustive here, as it is what the LLM will read to know about your tool.",
287
+ parameters={
288
+ "type": "object",
289
+ "properties": {
290
+ "input": {
291
+ "type": "string",
292
+ "description": "The input parameter."
293
+ }
294
+ },
295
+ "required": ["input"],
296
+ },
297
+ )
298
+ def my_handler(args):
299
+ input = args.get("input", "no input provided")
300
+ return {"result": f"{input}"}
301
+ ```
302
+
303
+ Tools are auto-discovered on startup.
304
+
305
+ ### Adding slash commands
306
+
307
+ The process is very similar to tools. You need to create your method, preferably in `agent/commands.py`, and decorate it with `@cmd(name, description, aliases, examples, can_complete)`.
308
+
309
+ A slash command must return, in that order, `ok:bool`, `msg:str`, `content:str`, `markdown:str`:
310
+
311
+ 1. `ok`: a `bool` indicating if the command succeeded or failed.
312
+ 2. `msg`: an optional short status message. It is printed with `OK` or `ERROR`.
313
+ 3. `content`: an optional `str` with the Python Rich-formatted content, it is printed to the output.
314
+ 4. `markdown`: an optional `str` formatted in Markdown, it is printed to the output.
315
+
316
+ ```python
317
+ @cmd(
318
+ "/my-command",
319
+ "This is the description",
320
+ aliases=["/mycmd"],
321
+ )
322
+ def _cmd_my_command(agent, params) -> (bool, str, str, str):
323
+ """This command returns a message but no content"""
324
+ return True, "This is awesome!", None, None
325
+ ```
326
+
327
+ Decorated commands are automatically registered, and auto-completed in the input prompt.
328
+
329
+ ### Adding skills
330
+
331
+ Add a `.md` file in `skills/` with YAML front matter, following the [agentskills.io](https://agentskills.io) standard:
332
+
333
+ ```markdown
334
+ ---
335
+ name: my-skill
336
+ description: What this skill does
337
+ ---
338
+
339
+ # My skill
340
+
341
+ ## When to use
342
+
343
+ ...
344
+
345
+ ## Steps
346
+
347
+ 1. ...
348
+ ```
349
+
350
+ The front matter `name` and `description` are parsed and shown in the
351
+ skills list. The body is injected into the system prompt.