webxos commited on
Commit
903a77f
·
verified ·
1 Parent(s): a9842d5

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +122 -189
README.md CHANGED
@@ -8,7 +8,7 @@ dependencies: gcc, libcurl, bc, cJSON
8
  persistence: shadowclaw.bin
9
  ---
10
 
11
- # Shadowclaw v1.3 (Testing)
12
 
13
  <div style="max-width: 100%; overflow-x: auto; background: #f6f8fa; padding: 4px; border-radius: 4px;">
14
  <pre style="font-family: 'Courier New', monospace; font-size: clamp(4px, 2vw, 10px); line-height: 1.2; margin: 0;">
@@ -35,246 +35,179 @@ Low-power edge nodes: self-hosted persistent AI, no cloud.
35
 
36
  ---
37
 
38
- ## Repository Structure
39
-
40
- ```
41
- shadowclaw/
42
- ├── shadowclaw.c # main program: arena, tools, LLM glue, event loop
43
- ├── Makefile # simple build file
44
- ├── cJSON.c # lightweigt JSON parser (from cJSON library)
45
- └── cJSON.h # cJSON header
46
- ```
47
-
48
- ---
49
-
50
  ## Features
51
 
52
- - **Growable shadow arena** – all objects stored in one contiguous block with hidden headers.
53
- - **Persistent memory** – saves and loads full arena to/from `shadowclaw.bin`.
54
- - **Tool use** – shell, file I/O, HTTP GET, math (via `bc`).
55
- - **Ollama integration** – talk to any model running locally.
56
- - **Blob storage** – system prompts, user messages, assistant replies, tool calls, results.
57
- - **Tiny footprint** – stripped binary 100–200 KiB.
 
 
 
 
58
 
59
  ---
60
 
61
- ## Requirements
62
-
63
- - Linux (developed on Debian, should work on most Unix‑likes)
64
- - `gcc`, `make`, `libcurl4-openssl-dev`, `bc`
65
- - [Ollama](https://ollama.com/) running locally (default `http://localhost:11434`) with a model pulled (e.g. `llama3.2`)
66
 
67
- Install build dependencies on Debian/Ubuntu:
68
-
69
- ```bash
70
- sudo apt update
71
- sudo apt install build-essential libcurl4-openssl-dev bc
72
- ```
 
73
 
74
  ---
75
 
76
- ## Define your model:
77
-
78
- - **Change Ollama endpoint/model**: edit `ollama_endpoint` and `ollama_model` in `shadowclaw.c`.
79
-
80
- Find this line (507) in the shadowclaw.c file:
81
-
82
- ```bash
83
- // --------------------------------------------------------------------
84
- // Main (with slash commands from v1.2.2)
85
- // --------------------------------------------------------------------
86
- int main(int argc, char **argv) {
87
- const char *state_file = "shadowclaw.bin";
88
- const char *ollama_endpoint = "http://localhost:11434";
89
- const char *ollama_model = "qwen2.5:0.5b"; // change as needed
90
- ```
91
-
92
- Adjust the model endpoint in "ollama_model = "qwen2.5:0.5b";" to meet your model.
93
 
94
- - **Add new tools**: extend the `tools` array in `shadowclaw.c` with a name and a function that takes a `const char*` argument and returns a `char*` (must be `malloc`ed, the caller will `free` it).
95
 
96
- ---
97
-
98
- ## How It Works
99
-
100
- ### Shadow Arena
101
-
102
- All dynamic data lives in a single `realloc`‑ed block.
103
- A `ShadowHeader` is stored **immediately before** the user‑visible pointer.
104
- This header holds capacity, used length, a magic number, and a dirty flag.
105
-
106
- ```
107
- +-------------------+---------------------+
108
- | ShadowHeader | payload (blobs) |
109
- +-------------------+---------------------+
110
- ^
111
- `- pointer returned to user
112
- ```
113
-
114
- ### Blob Format
115
-
116
- Each item (system prompt, user message, tool result, etc.) is stored as:
117
-
118
- ```
119
- +------------+------+------+-----------------+
120
- | BlobHeader | kind | id | payload (bytes) |
121
- +------------+------+------+-----------------+
122
  ```
123
 
124
- - `BlobHeader` contains the payload size, kind, and a 64‑bit ID.
125
- - The payload is arbitrary data (null‑terminated strings for most kinds).
126
-
127
- ### Persistence
128
 
129
- -The whole arena (header + payload) is written to `shadowclaw.bin` with `fwrite`.
130
 
131
- -On startup, if the file exists and has a valid magic number, it is loaded back.
132
-
133
- -All conversations and tool results are automatically saved to `shadowclaw.bin` and reloaded on restart.
134
-
135
- ---
136
-
137
- # Updated 3/3/2026: Shadowclaw v1.3
138
-
139
- ### Built‑in Slash Commands
140
-
141
- Type any of these commands directly at the `>` prompt – they are handled without invoking the LLM.
142
-
143
- | Command | Description |
144
- |-----------|-------------|
145
- | `/help` | Show this help message. |
146
- | `/tools` | List all available tools (shell, file I/O, HTTP, math, `list_dir`). |
147
- | `/state` | Display current arena memory statistics (capacity, used bytes, dirty flag). |
148
- | `/clear` | Clear the conversation history while retaining the system prompt. |
149
- | `/chat` | Remind you that you are already in chat mode (the default behaviour). |
150
- | `/exit` | Quit Shadowclaw. |
151
-
152
- ## Build
153
 
154
  ```bash
155
- cd /Home/User/Shadowclaw # The folder you have the files located.
 
 
156
  ```
157
 
158
- ```bash
159
- make clean && make
160
- ```
161
-
162
- ## Run
163
 
164
  ```bash
165
- ./shadowclaw
 
166
  ```
167
 
168
- Use the slash commands above to get started – even without Ollama running, you can explore the built‑in features.
169
 
170
- When your agent is running you should be able to use /help and see (example):
171
 
172
- ```bash
173
- ┌──(kali㉿user)-[~/shadowclaw]
174
- └─$ ./shadowclaw
175
- ShadowClaw ready. Type your message (Ctrl-D to exit)
176
- /help
177
- Shadowclaw commands:
178
- /help Show this help
179
- /tools List available tools
180
- /state Show arena memory stats
181
- /clear Clear conversation history (keeps system prompt)
182
- /chat Remind you that chat mode is active
183
- /exit Exit Shadowclaw
184
- ```
185
 
186
- ## Notes
187
 
188
- -If Ollama is not running, you’ll see LLM call failed.
189
 
190
- -Tool arguments can be a JSON array – they will be joined with spaces (useful if your model outputs "args":["arg1","arg2"]).
191
 
192
- -All conversations and tool results are saved in shadowclaw.bin and reloaded on restart.
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
  ---
195
 
196
- ## How Tool Arguments Work
197
-
198
- Shadowclaw processes tool calls by parsing JSON, where the args value is passed as a string to the function, executing it, and appending the result as a kind 5 blob for the next prompt. It supports a fallback where the model outputs args as an array (e.g., [arg1, arg2]), allowing for flexible input handling when standard JSON encoding fails.
199
-
200
- -Tool Call Flow: The agent parses the JSON block, executes the tool, and appends the result.
201
-
202
- -Result Visibility: The tool output is visible to the model in the next prompt.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
- -Fallback Mechanism: If JSON parsing fails, Shadowclaw interprets args as an array.
205
 
206
- -Alternative Tooling: In some scenarios, tool calls can be handled as a single string to avoid parsing errors.
207
 
208
- This system helps in handling malformed JSON, which occasionally occurs with certain LLM providers, ensuring the tool call succeeds.
209
 
210
  ```json
211
- {"tool":"write_file","args":["notes.txt","Hello world"]}
 
 
 
 
 
 
 
212
  ```
213
 
214
- Shadowclaw automatically **joins the array elements with spaces**, so the tool receives a single string `"notes.txt Hello world"`. This makes the agent robust to different model behaviours to ensure:
215
-
216
- - **Simplicity** most tools only need a single string argument (a command, a filename, a URL).
217
- - **Flexibility**if a tool needs multiple pieces of information (like `write_file` needing a filename **and** content), we use a simple delimiter (newline). The LLM can learn this pattern from the system prompt.
218
- - **Lightweight Design** – no complex argument schemas, no extra JSON nesting. The entire tool call is tiny.
219
- - **Args are always a single string** to keep things simple.
220
- - **Multiple values are encoded with delimiters** (like newline) – the tool and LLM agree on the format.
221
- - **Shadowclaw’s niche** is minimalism: a single binary with persistent memory, running anywhere, with just enough tools to be genuinely useful.
222
 
223
- You can easily add new tools by editing the `tools` array each new function opens up more automation possibilities for your unique environment.
224
 
225
  ---
226
 
227
- ## Niche Use Cases
228
-
229
- Shadowclaw is designed for **minimal, self‑contained AI agents** running on resource‑constrained or air‑gapped systems.
230
- Its toolset is deliberately small but powerful enough to automate many tasks without spawning heavy processes.
231
 
232
- | Tool | What it does | Example args | Unique Niche Use |
233
- |------|--------------|--------------|------------------|
234
- | `shell` | Executes any shell command | `"ls -la /home"` | Automate system maintenance, run scripts, control services on a headless Raspberry Pi or embedded Linux device. |
235
- | `read_file` | Reads a file from disk | `"/etc/passwd"` | Inspect configuration files, read logs, retrieve data for the LLM to analyse – all without a web interface. |
236
- | `write_file` | Writes content to a file (args: `filename\ncontent`) | `"notes.txt\nBuy milk"` | Create notes, write configuration files, save results – perfect for offline data logging. |
237
- | `http_get` | Fetches a URL (via libcurl) | `"https://api.example.com/data"` | Retrieve weather, fetch RSS feeds, call local REST APIs – even on devices with no browser, just a network stack. |
238
- | `math` | Evaluates an expression using `bc` | `"2 + 2 * 5"` | Let the LLM do arithmetic, unit conversions, or simple calculations without relying on external tools. |
239
- | `list_dir` | Lists directory contents | `"/home/user"` | Explore filesystem, find documents, check available storage – all natively, without forking a shell. |
240
 
241
- ---
242
-
243
- ## Niche Use Case Examples:
 
 
244
 
245
- ### 1. Raspberry Pi Zero / IoT Sensor Node
246
- - **Tool used:** `shell` + `write_file`
247
- - **Flow:** LLM asks to read a temperature sensor via a shell script, then logs the value to a file.
248
- - **Why Shadowclaw?** Runs in <200KB RAM, no Python, no bloat. Persistent memory keeps the last readings.
249
 
250
- ### 2. Air‑Gapped Engineering Workstation
251
- - **Tool used:** `http_get` + `math` + `read_file`
252
- - **Flow:** Engineer asks for a component value calculation; LLM fetches a local datasheet via HTTP, reads a config file, does the math, and writes a report.
253
- - **Why Shadowclaw?** No cloud, no internet required. All data stays on the machine.
254
 
255
- ### 3. Embedded Router Automation
256
- - **Tool used:** `shell` + `list_dir`
257
- - **Flow:** Network admin asks for a list of active interfaces; LLM runs `ifconfig` and parses the output, then suggests a config change.
258
- - **Why Shadowclaw?** Tiny binary fits in router storage (often just a few MB). Uses curl for local API calls.
259
 
260
- ### 4. Low‑Power Field Logger
261
- - **Tool used:** `write_file` + `math`
262
- - **Flow:** A solar‑powered device collects environmental data; Shadowclaw can process and store it locally, then answer queries about trends.
263
- - **Why Shadowclaw?** No database needed just a binary and a single file (`shadowclaw.bin`) for persistence.
 
264
 
265
  ---
266
 
267
- ## Credits
268
 
269
- - **Tsoding** – for the “insane shadow data trick” (the header‑before‑data arena idea).
270
- - **cJSON** – Dave Gamble and contributors – the minimal JSON parser used.
271
- - **Ollama** HTTP requests via curl.
272
- - **Vibe Code** - xAI Grok 4.20 and Deepseek AI
273
- - **Openclaw**
274
- - **webXOS**
275
- ---
 
 
 
276
 
277
- ## License
278
 
279
- This project is released under the open sourced MIT License.
280
- cJSON is also MIT licensed.
 
8
  persistence: shadowclaw.bin
9
  ---
10
 
11
+ # Shadowclaw v3.4 (Testing)
12
 
13
  <div style="max-width: 100%; overflow-x: auto; background: #f6f8fa; padding: 4px; border-radius: 4px;">
14
  <pre style="font-family: 'Courier New', monospace; font-size: clamp(4px, 2vw, 10px); line-height: 1.2; margin: 0;">
 
35
 
36
  ---
37
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  ## Features
39
 
40
+ - **🧠 Local LLM integration** – works with any Ollama model (default: `tinyllama:1.1b`).
41
+ - **🔧 Built‑in tools** – `file_read`, `file_write`, `http_get`, `math`, `list_dir`, `shell` (disabled by default), and more.
42
+ - ** Cron jobs** – schedule recurring tasks using `@every N[s/m/h]`, `@hourly`, `@daily`, `@weekly`.
43
+ - **🌐 Webhooks** – trigger HTTP POST calls on tool execution or cron events.
44
+ - **🎓 Dynamic skills** – create reusable multi‑step workflows without recompiling.
45
+ - **💾 Core memory** – persistent key‑value storage (JSON) that survives across sessions.
46
+ - **📜 Soul file** – Markdown export of all memories (conversation, skills, crons, webhooks, core memory).
47
+ - **🎨 Colored TUI** – optional GNU readline support for line editing and history.
48
+ - **⚡ Thread‑safe** – cron jobs run in a separate thread, tool calls are queued.
49
+ - **🛡️ Security** – path sandboxing, domain allowlist, shell opt‑in, dry‑run mode.
50
 
51
  ---
52
 
53
+ ## 📦 Requirements
 
 
 
 
54
 
55
+ - **Linux / macOS / WSL** (tested on Ubuntu 22.04, Kali)
56
+ - **Ollama** (running locally) – optional, the agent can run in `--no-llm` mode
57
+ - **Dependencies**:
58
+ - `libcurl` (HTTP requests)
59
+ - `libpthread` (threading)
60
+ - `libreadline` (optional, for TUI enhancements)
61
+ - `gcc` or `clang` with C99 support
62
 
63
  ---
64
 
65
+ ## Installation + Launch
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
+ *Put all files into a single folder on your system*
68
 
69
+ ```bash
70
+ cd ~/shadowclaw (The folder you put the files in)
71
+ make clean && make
72
+ ./start.sh
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  ```
74
 
75
+ ## Setup your local Ollama model
 
 
 
76
 
77
+ *Shadowclaw is set to use qwen2.5:0.5b as a default, to change this:*
78
 
79
+ Find line 633 in the shadowclaw.c file:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  ```bash
82
+ static const char *ollama_endpoint = "http://localhost:11434";
83
+ static const char *ollama_model = "qwen2.5:0.5b"; (Change this to desired model)
84
+ static long llm_connect_timeout = 15;
85
  ```
86
 
87
+ Also line 16 in the start.sh file:
 
 
 
 
88
 
89
  ```bash
90
+ OLLAMA_ENDPOINT="${OLLAMA_ENDPOINT:-http://localhost:11434}"
91
+ OLLAMA_MODEL="${OLLAMA_MODEL:-qwen2.5:0.5b}" (Change this to desired model)
92
  ```
93
 
94
+ ---
95
 
96
+ ### First start
97
 
98
+ - The agent creates `shadowclaw.bin` (binary state) and a folder `shadowclaw_data/` containing `shadowsoul.md`.
99
+ - If Ollama is not reachable, it automatically falls back to `--no-llm` mode.
100
+ - A default heartbeat cron job (`@every 120s`) is added automatically to keep the soul file updated.
 
 
 
 
 
 
 
 
 
 
101
 
102
+ ---
103
 
104
+ ## Interactive Commands
105
 
106
+ Shadowclaw understands both natural language (sent to the LLM) and slash commands.
107
 
108
+ | Command | Description |
109
+ |---------|-------------|
110
+ | `/help` | Show help and list all commands. |
111
+ | `/tools` | List available built‑in tools. |
112
+ | `/state` | Show arena memory usage and soul file stats. |
113
+ | `/clear` | Erase conversation history (keeps system prompt and core memory). |
114
+ | `/exit` | Quit the agent. |
115
+ | `/loop <schedule> <tool> [args]` | Schedule a recurring task. Examples:<br>`/loop 30m http_get https://example.com`<br>`/loop daily math "1+1"` |
116
+ | `/crons` | List all scheduled cron jobs. |
117
+ | `/webhooks` | Show registered webhooks. |
118
+ | `/skills` | List dynamic skills. |
119
+ | `/compact` | Manually compact the arena (remove deleted blobs). |
120
+ | `/soul` | Display information about `shadowsoul.md`. |
121
 
122
  ---
123
 
124
+ ## 🛠️ Tools
125
+
126
+ Tools are invoked by the LLM during the “plan” phase. Each tool is described in the LLM prompt with its parameters and an example.
127
+
128
+ | Tool | Description | Example args |
129
+ |------|-------------|---------------|
130
+ | `file_read` | Read a file (max 10 MB, path must be inside CWD). | `notes.txt` |
131
+ | `file_write` | Write content to a file (overwrites). | `output.txt Hello world` |
132
+ | `http_get` | HTTP GET to an allowed domain (see `allowed_domains` in source). | `https://example.com/data` |
133
+ | `math` | Evaluate arithmetic expression. | `(2+3)*4` |
134
+ | `list_dir` | List directory contents. | `.` or `/home/user` |
135
+ | `webhook_add` | Register a webhook (JSON: `{"url":"...","event":"..."}`). | `{"url":"http://...","event":"tool:http_get"}` |
136
+ | `cron_add` | Add a cron job (JSON: `{"schedule":"...","tool":"...","args":"..."}`). | `{"schedule":"@every 30m","tool":"math","args":"1+1"}` |
137
+ | `cron_list` | List all cron jobs. | (none) |
138
+ | `cron_remove` | Remove cron jobs containing a substring in their JSON representation. | `@every` |
139
+ | `skill_add` | Create a dynamic skill (JSON with `name`, `desc`, `steps` array, optionally `interpreter_command`). | See below. |
140
+ | `skill_run` | Run a skill by name. | `weather London` |
141
+ | `list_skills` | List all available skills. | (none) |
142
+ | `update_core_memory` | Merge JSON object into core memory. | `{"user_name":"Alice","preferences":{"theme":"dark"}}` |
143
+ | `recall` | Search conversation history for a keyword. | `project` |
144
+ | `heartbeat` | Internal (used by cron). | (none) |
145
+
146
+ > **Security:** The `shell` tool is compiled out by default. To enable it, add `-DENABLE_SHELL_TOOL` to `CFLAGS` and understand the risks.
147
 
148
+ ---
149
 
150
+ ## Dynamic Skills
151
 
152
+ Skills are sequences of tool calls stored in the arena as `BLOB_KIND_SKILL`. Example creation:
153
 
154
  ```json
155
+ {
156
+ "name": "weather",
157
+ "desc": "Get weather for a city",
158
+ "steps": [
159
+ {"tool": "http_get", "args": "https://wttr.in/{0}"},
160
+ {"tool": "file_write", "args": "/tmp/weather.txt {result}"}
161
+ ]
162
+ }
163
  ```
164
 
165
+ Placeholders supported:
166
+ - `{args}` – the whole argument string passed to `skill_run`
167
+ - `{0}`, `{1}`, positional arguments (split by spaces)
168
+ - `{result}`output of the previous step
 
 
 
 
169
 
170
+ Skills can also delegate to an external interpreter command (e.g., a Python script) via the optional `interpreter_command` field.
171
 
172
  ---
173
 
174
+ ## Soul File
 
 
 
175
 
176
+ All persistent memories are written to `shadowclaw_data/shadowsoul.md` in Markdown format. It contains:
 
 
 
 
 
 
 
177
 
178
+ - `## Core Memory` – JSON key‑value store.
179
+ - `## Skills` – list of registered skills (JSON).
180
+ - `## Cron Jobs` all scheduled jobs.
181
+ - `## Webhooks` – registered webhooks.
182
+ - `## Conversation Log` – user, assistant, tool calls, and results.
183
 
184
+ The file is updated every 5 writes (write‑behind) and immediately after important events.
 
 
 
185
 
186
+ ---
 
 
 
187
 
188
+ ## ⚙️ Configuration via Environment Variables
 
 
 
189
 
190
+ | Variable | Default | Description |
191
+ |----------|---------|-------------|
192
+ | `SHADOWCLAW_CONNECT_TIMEOUT` | 10 | Seconds to wait for Ollama connection. |
193
+ | `SHADOWCLAW_TOTAL_TIMEOUT` | 120 | Total LLM request timeout (increased on retries). |
194
+ | `SHADOWCLAW_RETRY_ATTEMPTS` | 3 | Number of retries with exponential backoff. |
195
 
196
  ---
197
 
198
+ ## 📁 Project Structure
199
 
200
+ ```
201
+ shadowclaw/
202
+ ├── shadowclaw.c # Main program, arena, tools, cron, LLM
203
+ ├── interpreter.c # Local command interpreter (used in --no-llm mode)
204
+ ├── interpreter.h # Header for interpreter
205
+ ├── cJSON.c / cJSON.h # JSON library
206
+ ├── Makefile # Build instructions
207
+ ├── start.sh # Helper startup script (checks dependencies)
208
+ └── README.md # This file
209
+ ```
210
 
211
+ ## 📄 License
212
 
213
+ MIT License.