botiasloop 0.0.1 → 0.0.7
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.
- checksums.yaml +4 -4
- data/LICENSE +7 -0
- data/README.md +266 -122
- data/bin/botiasloop +65 -15
- data/lib/botiasloop/agent.rb +25 -12
- data/lib/botiasloop/auto_label.rb +117 -0
- data/lib/botiasloop/channels/base.rb +48 -44
- data/lib/botiasloop/channels/cli.rb +14 -18
- data/lib/botiasloop/channels/telegram.rb +95 -42
- data/lib/botiasloop/channels_manager.rb +23 -30
- data/lib/botiasloop/chat.rb +122 -0
- data/lib/botiasloop/commands/archive.rb +34 -11
- data/lib/botiasloop/commands/compact.rb +1 -1
- data/lib/botiasloop/commands/context.rb +6 -6
- data/lib/botiasloop/commands/conversations.rb +11 -6
- data/lib/botiasloop/commands/label.rb +9 -11
- data/lib/botiasloop/commands/new.rb +2 -2
- data/lib/botiasloop/commands/status.rb +2 -2
- data/lib/botiasloop/commands/switch.rb +5 -7
- data/lib/botiasloop/commands/verbose.rb +29 -0
- data/lib/botiasloop/commands.rb +1 -0
- data/lib/botiasloop/config.rb +16 -0
- data/lib/botiasloop/conversation.rb +100 -11
- data/lib/botiasloop/database.rb +16 -4
- data/lib/botiasloop/human_id.rb +58 -0
- data/lib/botiasloop/logger.rb +45 -0
- data/lib/botiasloop/loop.rb +88 -7
- data/lib/botiasloop/systemd_service.rb +20 -10
- data/lib/botiasloop/tools/shell.rb +5 -0
- data/lib/botiasloop/version.rb +1 -1
- data/lib/botiasloop.rb +8 -1
- metadata +46 -27
- data/lib/botiasloop/conversation_manager.rb +0 -225
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 19ce350bd375ddbae065af8ff880cfe1f4f01c1d53b0b865caec2d577119c7bc
|
|
4
|
+
data.tar.gz: 41021e8b39ce89d96b04000d2c9d6e23f78672915561d5c17ee81846faf87ed3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d017fa894d1c47e03ef694b3f25a4144e84b5dc0a8b645add7e871062bf7cb754a65febf450ab5964c273196bebbbda7481a1da5f738fd125058b909ddb0b213
|
|
7
|
+
data.tar.gz: c848deadc5eb12e6aa07ffb539bd11a6cb3c2559a88a24285cb7768694c5818f7c9e6b21bffea5dbd6bffe862cfd3a800f130ef0543d6afa65fe77140be41d4f
|
data/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright (c) 2026 Tobias Feistmantl
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
|
@@ -1,62 +1,25 @@
|
|
|
1
|
-
# BotiasLoop
|
|
2
|
-
|
|
3
|
-
A minimal agentic AI application built on the ReAct (Reasoning + Acting) loop pattern. BotiasLoop provides an AI agent with shell access and web search capabilities via OpenRouter, designed for dedicated infrastructure following the Rails Doctrine.
|
|
1
|
+
# 🤖 BotiasLoop
|
|
4
2
|
|
|
5
3
|
[](https://www.ruby-lang.org/)
|
|
4
|
+
[](https://rubygems.org/gems/botiasloop)
|
|
6
5
|
[](LICENSE)
|
|
7
6
|
[](https://github.com/standardrb/standard)
|
|
7
|
+
[]()
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Following the Rails Doctrine:
|
|
14
|
-
- **Optimize for programmer happiness**: Beautiful, readable Ruby code
|
|
15
|
-
- **Convention over Configuration**: Sensible defaults, minimal setup required
|
|
16
|
-
- **The menu is omakase**: Curated stack (ruby_llm, StandardRB, RSpec)
|
|
17
|
-
- **No one paradigm**: Practical over pure - use what works
|
|
18
|
-
|
|
19
|
-
## Features
|
|
20
|
-
|
|
21
|
-
### Core
|
|
22
|
-
- **ReAct Loop**: AI reasons, acts using tools, observes results, and repeats
|
|
23
|
-
- **Shell Access**: Execute any shell command (full system access)
|
|
24
|
-
- **Web Search**: Search the web via SearXNG
|
|
25
|
-
- **Conversation Persistence**: SQLite-backed conversation storage with UUID tracking
|
|
26
|
-
- **Token Tracking**: Monitor input/output tokens per conversation
|
|
27
|
-
|
|
28
|
-
### Channels
|
|
29
|
-
- **CLI Mode**: Interactive REPL for local usage
|
|
30
|
-
- **Telegram Bot**: Chat with the agent via Telegram
|
|
31
|
-
- **Multi-Channel**: Run multiple channels simultaneously
|
|
32
|
-
- **Boot Auto-Start**: systemd service with automatic startup on boot
|
|
33
|
-
|
|
34
|
-
### Commands
|
|
35
|
-
Slash commands for conversation management:
|
|
36
|
-
- `/new` - Start a new conversation
|
|
37
|
-
- `/switch <label|uuid>` - Switch to a different conversation
|
|
38
|
-
- `/label <name>` - Label the current conversation
|
|
39
|
-
- `/conversations` - List all conversations
|
|
40
|
-
- `/reset` - Clear current conversation history
|
|
41
|
-
- `/compact` - Summarize and archive old messages
|
|
42
|
-
- `/status` - Show current model, token usage
|
|
43
|
-
- `/archive` - Archive old conversations
|
|
44
|
-
- `/system_prompt` - Show current system prompt
|
|
45
|
-
- `/help` - Show available commands
|
|
46
|
-
|
|
47
|
-
### Skills System
|
|
48
|
-
Skills follow the [agentskills.io](https://agentskills.io) specification:
|
|
49
|
-
- Load default skills from `data/skills/`
|
|
50
|
-
- Load custom skills from `~/skills/`
|
|
51
|
-
- Progressive disclosure: name/description in system prompt, full content on demand
|
|
52
|
-
- Includes `skill-creator` skill for creating new skills
|
|
9
|
+
> **Think. Act. Repeat.**
|
|
10
|
+
>
|
|
11
|
+
> A minimal agentic AI application built on the ReAct (Reasoning + Acting) loop pattern.
|
|
53
12
|
|
|
54
|
-
|
|
13
|
+
BotiasLoop gives your AI agent **full shell access** and **web search capabilities** via multiple LLM providers. Designed for dedicated infrastructure following the Rails Doctrine — beautiful code, sensible defaults, sharp knives.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 🚀 Installation
|
|
55
18
|
|
|
56
19
|
### Prerequisites
|
|
57
20
|
|
|
58
21
|
- Ruby 3.4 or higher
|
|
59
|
-
-
|
|
22
|
+
- API key from your preferred LLM provider (see supported providers below)
|
|
60
23
|
- (Optional) SearXNG instance for web search
|
|
61
24
|
|
|
62
25
|
### Via RubyGems
|
|
@@ -87,38 +50,115 @@ mise install
|
|
|
87
50
|
mise exec ruby -- bundle install
|
|
88
51
|
```
|
|
89
52
|
|
|
90
|
-
|
|
53
|
+
---
|
|
91
54
|
|
|
92
|
-
|
|
55
|
+
## ⚡ Quick Start
|
|
93
56
|
|
|
94
|
-
```
|
|
95
|
-
#
|
|
96
|
-
|
|
97
|
-
openrouter:
|
|
98
|
-
api_key: "your-openrouter-api-key" # Or set BOTIASLOOP_API_KEY env var
|
|
99
|
-
model: "moonshotai/kimi-k2.5" # Any OpenRouter model
|
|
57
|
+
```bash
|
|
58
|
+
# 1. Configure your API key
|
|
59
|
+
export BOTIASLOOP_API_KEY="your-api-key"
|
|
100
60
|
|
|
101
|
-
#
|
|
102
|
-
|
|
103
|
-
web_search:
|
|
104
|
-
searxng_url: "http://localhost:8080" # Your SearXNG instance
|
|
61
|
+
# 2. Start chatting
|
|
62
|
+
botiasloop cli
|
|
105
63
|
|
|
106
|
-
#
|
|
107
|
-
|
|
64
|
+
# 3. Ask anything!
|
|
65
|
+
You: What's the weather in Tokyo?
|
|
108
66
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
67
|
+
Agent: I'll search for the current weather in Tokyo for you.
|
|
68
|
+
|
|
69
|
+
[Tool] Executing web_search with arguments: {"query"=>"current weather Tokyo Japan"}
|
|
70
|
+
|
|
71
|
+
The weather in Tokyo is currently...
|
|
114
72
|
```
|
|
115
73
|
|
|
116
|
-
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## ✨ Features
|
|
77
|
+
|
|
78
|
+
### 🧠 Core Capabilities
|
|
79
|
+
|
|
80
|
+
- **ReAct Loop** — AI reasons, acts using tools, observes results, and repeats
|
|
81
|
+
- **12+ LLM Providers** — OpenRouter, OpenAI, Anthropic, Gemini, DeepSeek, Mistral, Perplexity, Ollama, and more
|
|
82
|
+
- **Shell Access** — Execute any shell command (full system access)
|
|
83
|
+
- **Web Search** — Search the web via SearXNG integration
|
|
84
|
+
- **Token Tracking** — Monitor input/output tokens per conversation
|
|
85
|
+
|
|
86
|
+
### 💬 Channels & Interfaces
|
|
87
|
+
|
|
88
|
+
- **CLI Mode** — Interactive REPL for local usage
|
|
89
|
+
- **Telegram Bot** — Chat with your agent anywhere
|
|
90
|
+
- **Multi-Channel** — Run CLI + Telegram simultaneously
|
|
91
|
+
- **One-Shot Mode** — Single command execution
|
|
92
|
+
|
|
93
|
+
### 🗄️ Conversation Management
|
|
94
|
+
|
|
95
|
+
- **Persistent Storage** — JSONL-backed conversation history
|
|
96
|
+
- **UUID Tracking** — Every conversation has a unique ID
|
|
97
|
+
- **Auto-Labeling** — Conversations get human-readable names
|
|
98
|
+
- **Conversation Switching** — Jump between active chats
|
|
99
|
+
- **Archiving** — Keep your workspace clean
|
|
100
|
+
|
|
101
|
+
### 🛠️ Built-in Tools
|
|
102
|
+
|
|
103
|
+
| Tool | Description |
|
|
104
|
+
|------|-------------|
|
|
105
|
+
| 🔧 `shell` | Execute any shell command |
|
|
106
|
+
| 🔍 `web_search` | Search the web via SearXNG |
|
|
107
|
+
|
|
108
|
+
### 📚 Skills System
|
|
109
|
+
|
|
110
|
+
Skills follow the [agentskills.io](https://agentskills.io) specification:
|
|
111
|
+
|
|
112
|
+
- Load default skills from `data/skills/`
|
|
113
|
+
- Load custom skills from `~/skills/`
|
|
114
|
+
- Progressive disclosure: name/description in system prompt, full content on demand
|
|
115
|
+
- Includes `skill-creator` skill for creating new skills
|
|
116
|
+
|
|
117
|
+
### ⌨️ Slash Commands
|
|
118
|
+
|
|
119
|
+
Manage conversations with intuitive commands:
|
|
120
|
+
|
|
121
|
+
| Command | Description |
|
|
122
|
+
|---------|-------------|
|
|
123
|
+
| `/new` | Start a new conversation |
|
|
124
|
+
| `/switch <label\|uuid>` | Switch to a different conversation |
|
|
125
|
+
| `/label <name>` | Label the current conversation |
|
|
126
|
+
| `/conversations` | List all conversations |
|
|
127
|
+
| `/reset` | Clear current conversation history |
|
|
128
|
+
| `/compact` | Summarize and archive old messages |
|
|
129
|
+
| `/status` | Show current model, token usage |
|
|
130
|
+
| `/archive` | Archive old conversations |
|
|
131
|
+
| `/system_prompt` | Show current system prompt |
|
|
132
|
+
| `/verbose` | Toggle verbose mode (show tool calls) |
|
|
133
|
+
| `/help` | Show available commands |
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 🎨 Philosophy
|
|
138
|
+
|
|
139
|
+
### Sharp Knives 🔪
|
|
140
|
+
|
|
141
|
+
BotiasLoop intentionally provides **full shell access without restrictions**. This is a feature, not a bug. It's designed for dedicated infrastructure where raw power is needed, not personal devices.
|
|
117
142
|
|
|
118
|
-
|
|
119
|
-
-
|
|
143
|
+
The agent can:
|
|
144
|
+
- Execute any shell command
|
|
145
|
+
- Read, write, and delete any file
|
|
146
|
+
- Install software
|
|
147
|
+
- Modify system configuration
|
|
148
|
+
- Access network resources
|
|
149
|
+
|
|
150
|
+
### Rails Doctrine 🚂
|
|
120
151
|
|
|
121
|
-
|
|
152
|
+
Following the [Rails Doctrine](https://rubyonrails.org/doctrine):
|
|
153
|
+
|
|
154
|
+
- **Optimize for programmer happiness** — Beautiful, readable Ruby code
|
|
155
|
+
- **Convention over Configuration** — Sensible defaults, minimal setup required
|
|
156
|
+
- **The menu is omakase** — Curated stack (ruby_llm, StandardRB, RSpec)
|
|
157
|
+
- **No one paradigm** — Practical over pure - use what works
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## 📖 Usage
|
|
122
162
|
|
|
123
163
|
### CLI Mode
|
|
124
164
|
|
|
@@ -130,6 +170,14 @@ botiasloop cli
|
|
|
130
170
|
|
|
131
171
|
Exit with: `exit`, `quit`, `\q`, or Ctrl+C
|
|
132
172
|
|
|
173
|
+
### One-Shot Mode
|
|
174
|
+
|
|
175
|
+
Send a single message:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
botiasloop "What's the weather in Tokyo?"
|
|
179
|
+
```
|
|
180
|
+
|
|
133
181
|
### Gateway Mode (Telegram Bot)
|
|
134
182
|
|
|
135
183
|
Start the gateway to enable Telegram and other channels:
|
|
@@ -143,17 +191,10 @@ botiasloop gateway enable # Install and enable boot auto-start
|
|
|
143
191
|
botiasloop gateway start # Start the service now
|
|
144
192
|
botiasloop gateway status # Check service status
|
|
145
193
|
botiasloop gateway stop # Stop the service
|
|
194
|
+
botiasloop gateway logs # View service logs
|
|
146
195
|
botiasloop gateway disable # Disable boot auto-start and uninstall
|
|
147
196
|
```
|
|
148
197
|
|
|
149
|
-
### One-Shot Mode
|
|
150
|
-
|
|
151
|
-
Send a single message:
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
botiasloop "What's the weather in Tokyo?"
|
|
155
|
-
```
|
|
156
|
-
|
|
157
198
|
### Example Session
|
|
158
199
|
|
|
159
200
|
```bash
|
|
@@ -182,12 +223,120 @@ You: /label my-project
|
|
|
182
223
|
|
|
183
224
|
Agent: **Conversation labeled as `my-project`**
|
|
184
225
|
|
|
226
|
+
You: /verbose
|
|
227
|
+
|
|
228
|
+
Agent: **Verbose mode enabled** — You will now see reasoning and tool execution details.
|
|
229
|
+
|
|
185
230
|
You: exit
|
|
186
231
|
|
|
187
232
|
Goodbye!
|
|
188
233
|
```
|
|
189
234
|
|
|
190
|
-
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## ⚙️ Configuration
|
|
238
|
+
|
|
239
|
+
Create `~/.config/botiasloop/config.yml`:
|
|
240
|
+
|
|
241
|
+
### OpenRouter (Recommended)
|
|
242
|
+
|
|
243
|
+
```yaml
|
|
244
|
+
providers:
|
|
245
|
+
openrouter:
|
|
246
|
+
api_key: "your-openrouter-api-key"
|
|
247
|
+
model: "moonshotai/kimi-k2.5"
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### OpenAI
|
|
251
|
+
|
|
252
|
+
```yaml
|
|
253
|
+
providers:
|
|
254
|
+
openai:
|
|
255
|
+
api_key: "your-openai-api-key"
|
|
256
|
+
model: "gpt-4o"
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Anthropic
|
|
260
|
+
|
|
261
|
+
```yaml
|
|
262
|
+
providers:
|
|
263
|
+
anthropic:
|
|
264
|
+
api_key: "your-anthropic-api-key"
|
|
265
|
+
model: "claude-3-5-sonnet-20241022"
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Ollama (Local)
|
|
269
|
+
|
|
270
|
+
```yaml
|
|
271
|
+
providers:
|
|
272
|
+
ollama:
|
|
273
|
+
api_base: "http://localhost:11434/v1"
|
|
274
|
+
model: "llama3.2"
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Full Configuration Example
|
|
278
|
+
|
|
279
|
+
```yaml
|
|
280
|
+
# Required: Provider configuration
|
|
281
|
+
providers:
|
|
282
|
+
openrouter:
|
|
283
|
+
api_key: "your-api-key"
|
|
284
|
+
model: "moonshotai/kimi-k2.5"
|
|
285
|
+
|
|
286
|
+
# Optional: Web search configuration
|
|
287
|
+
tools:
|
|
288
|
+
web_search:
|
|
289
|
+
searxng_url: "http://localhost:8080"
|
|
290
|
+
|
|
291
|
+
# Optional: Maximum ReAct iterations (default: 20)
|
|
292
|
+
max_iterations: 20
|
|
293
|
+
|
|
294
|
+
# Optional: Telegram channel
|
|
295
|
+
channels:
|
|
296
|
+
telegram:
|
|
297
|
+
bot_token: "your-telegram-bot-token"
|
|
298
|
+
allowed_users: [] # Empty = allow all, or list specific user IDs
|
|
299
|
+
|
|
300
|
+
# Optional: Logging
|
|
301
|
+
logger:
|
|
302
|
+
level: "info" # debug, info, warn, error
|
|
303
|
+
destination: "stdout" # stdout, stderr, or path to log file
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Environment Variables
|
|
307
|
+
|
|
308
|
+
Environment variables override config file values:
|
|
309
|
+
|
|
310
|
+
| Variable | Description |
|
|
311
|
+
|----------|-------------|
|
|
312
|
+
| `BOTIASLOOP_API_KEY` | API key for the active provider |
|
|
313
|
+
| `BOTIASLOOP_SEARXNG_URL` | SearXNG URL for web search |
|
|
314
|
+
| `BOTIASLOOP_LOG_LEVEL` | Log level (debug, info, warn, error) |
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## 🔒 Security
|
|
319
|
+
|
|
320
|
+
⚠️ **IMPORTANT**: BotiasLoop provides **full shell access**. The AI agent can:
|
|
321
|
+
- Execute any shell command
|
|
322
|
+
- Read, write, and delete any file
|
|
323
|
+
- Install software
|
|
324
|
+
- Modify system configuration
|
|
325
|
+
- Access network resources
|
|
326
|
+
|
|
327
|
+
**Use only on dedicated infrastructure**, never on personal devices or production systems containing sensitive data.
|
|
328
|
+
|
|
329
|
+
### Future Security Features (Roadmap)
|
|
330
|
+
|
|
331
|
+
- Sandboxed execution (Docker/Firejail)
|
|
332
|
+
- Command whitelist/blacklist
|
|
333
|
+
- Confirmation for destructive operations
|
|
334
|
+
- Read-only mode option
|
|
335
|
+
- Secret management integration
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## 🛠️ Development
|
|
191
340
|
|
|
192
341
|
### Setup
|
|
193
342
|
|
|
@@ -237,7 +386,9 @@ bundle exec standardrb --fix
|
|
|
237
386
|
bundle exec rake
|
|
238
387
|
```
|
|
239
388
|
|
|
240
|
-
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## 📁 Architecture
|
|
241
392
|
|
|
242
393
|
```
|
|
243
394
|
botiasloop/
|
|
@@ -249,7 +400,9 @@ botiasloop/
|
|
|
249
400
|
│ ├── agent.rb # Main orchestrator
|
|
250
401
|
│ ├── loop.rb # ReAct cycle implementation
|
|
251
402
|
│ ├── config.rb # Configuration management
|
|
252
|
-
│ ├── conversation.rb # Conversation persistence
|
|
403
|
+
│ ├── conversation.rb # Conversation persistence
|
|
404
|
+
│ ├── conversation_manager.rb # Multi-conversation management
|
|
405
|
+
│ ├── auto_label.rb # Auto-labeling conversations
|
|
253
406
|
│ ├── tool.rb # Base tool class
|
|
254
407
|
│ ├── tools/
|
|
255
408
|
│ │ ├── registry.rb # Tool registration
|
|
@@ -267,45 +420,32 @@ botiasloop/
|
|
|
267
420
|
│ │ ├── base.rb # Channel base class
|
|
268
421
|
│ │ ├── cli.rb # CLI channel
|
|
269
422
|
│ │ └── telegram.rb # Telegram bot
|
|
270
|
-
│
|
|
423
|
+
│ ├── channels_manager.rb # Multi-channel orchestration
|
|
424
|
+
│ └── systemd_service.rb # Service management
|
|
271
425
|
├── data/
|
|
272
426
|
│ └── skills/ # Default skills
|
|
273
427
|
├── spec/ # Test suite
|
|
274
428
|
└── README.md # This file
|
|
275
429
|
```
|
|
276
430
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
⚠️ **IMPORTANT**: BotiasLoop provides full shell access. The AI agent can:
|
|
280
|
-
- Execute any shell command
|
|
281
|
-
- Read, write, and delete any file
|
|
282
|
-
- Install software
|
|
283
|
-
- Modify system configuration
|
|
284
|
-
- Access network resources
|
|
285
|
-
|
|
286
|
-
**Use only on dedicated infrastructure**, never on personal devices or production systems containing sensitive data.
|
|
431
|
+
---
|
|
287
432
|
|
|
288
|
-
|
|
289
|
-
- Sandboxed execution (Docker/Firejail)
|
|
290
|
-
- Command whitelist/blacklist
|
|
291
|
-
- Confirmation for destructive operations
|
|
292
|
-
- Read-only mode option
|
|
293
|
-
- Secret management integration
|
|
433
|
+
## 🗺️ Roadmap
|
|
294
434
|
|
|
295
|
-
|
|
435
|
+
See [ROADMAP.md](ROADMAP.md) for detailed planned features:
|
|
296
436
|
|
|
297
|
-
|
|
437
|
+
- **Persistent Memory** — Vector database for semantic search
|
|
438
|
+
- **Custom Tools** — Load tools from `~/tools/`
|
|
439
|
+
- **Conversation Compaction** — Automatic summarization
|
|
440
|
+
- **Subagents** — Specialized agent instances
|
|
441
|
+
- **Streaming Responses** — Real-time token display
|
|
442
|
+
- **Multi-Modal** — Image analysis, audio transcription
|
|
443
|
+
- **Web Dashboard** — Browser-based management UI
|
|
444
|
+
- **Plugin System** — Load plugins from gems
|
|
298
445
|
|
|
299
|
-
|
|
300
|
-
- **Custom Tools**: Load tools from `~/tools/`
|
|
301
|
-
- **Conversation Compaction**: Automatic summarization
|
|
302
|
-
- **Subagents**: Specialized agent instances
|
|
303
|
-
- **Streaming Responses**: Real-time token display
|
|
304
|
-
- **Multi-Modal**: Image analysis, audio transcription
|
|
305
|
-
- **Web Dashboard**: Browser-based management UI
|
|
306
|
-
- **Plugin System**: Load plugins from gems
|
|
446
|
+
---
|
|
307
447
|
|
|
308
|
-
## Contributing
|
|
448
|
+
## 🤝 Contributing
|
|
309
449
|
|
|
310
450
|
1. Fork the repository
|
|
311
451
|
2. Create a feature branch
|
|
@@ -319,24 +459,28 @@ See [ROADMAP.md](ROADMAP.md) for detailed planned features including:
|
|
|
319
459
|
|
|
320
460
|
### Development Principles
|
|
321
461
|
|
|
322
|
-
- **Test-First
|
|
323
|
-
- **Sharp Knives
|
|
324
|
-
- **Rails Doctrine
|
|
325
|
-
- **Privacy First
|
|
326
|
-
- **Unix Philosophy
|
|
462
|
+
- **Test-First** — All features built using TDD
|
|
463
|
+
- **Sharp Knives** — Keep raw power, minimal restrictions
|
|
464
|
+
- **Rails Doctrine** — Optimize for programmer happiness
|
|
465
|
+
- **Privacy First** — Local-first, user-controlled data
|
|
466
|
+
- **Unix Philosophy** — Do one thing well, compose with other tools
|
|
467
|
+
|
|
468
|
+
---
|
|
327
469
|
|
|
328
|
-
## License
|
|
470
|
+
## 📜 License
|
|
329
471
|
|
|
330
|
-
MIT License
|
|
472
|
+
MIT License — see [LICENSE](LICENSE) file for details.
|
|
473
|
+
|
|
474
|
+
---
|
|
331
475
|
|
|
332
|
-
## Credits
|
|
476
|
+
## 🙏 Credits
|
|
333
477
|
|
|
334
478
|
Built by [Tobias Feistmantl](https://github.com/0x7466) with inspiration from nanobot and the Ruby on Rails doctrine.
|
|
335
479
|
|
|
336
480
|
Powered by:
|
|
337
|
-
- [ruby_llm](https://github.com/crmne/ruby_llm)
|
|
338
|
-
- [OpenRouter](https://openrouter.ai/)
|
|
339
|
-
- [SearXNG](https://docs.searxng.org/)
|
|
481
|
+
- [ruby_llm](https://github.com/crmne/ruby_llm) — Unified LLM API
|
|
482
|
+
- [OpenRouter](https://openrouter.ai/) — Unified LLM API gateway
|
|
483
|
+
- [SearXNG](https://docs.searxng.org/) — Privacy-respecting metasearch
|
|
340
484
|
|
|
341
485
|
---
|
|
342
486
|
|
data/bin/botiasloop
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
require_relative "../lib/botiasloop"
|
|
5
5
|
|
|
6
|
+
# Initialize global config instance
|
|
7
|
+
Botiasloop::Config.instance = Botiasloop::Config.new
|
|
8
|
+
|
|
6
9
|
def print_help
|
|
7
10
|
puts "botiasloop - Minimal agentic AI with ReAct loop"
|
|
8
11
|
puts
|
|
@@ -22,11 +25,16 @@ def print_help
|
|
|
22
25
|
puts " stop Stop the systemd service"
|
|
23
26
|
puts " restart Restart the systemd service"
|
|
24
27
|
puts " status Show systemd service status"
|
|
28
|
+
puts " logs Show service logs (journalctl)"
|
|
25
29
|
puts " enable Install and enable systemd service (auto-start on login)"
|
|
26
30
|
puts " disable Disable and uninstall systemd service"
|
|
31
|
+
puts
|
|
32
|
+
puts "Logs Options:"
|
|
33
|
+
puts " -f, --follow Follow log output in real-time"
|
|
34
|
+
puts " -n, --lines N Show last N lines (default: 50)"
|
|
27
35
|
end
|
|
28
36
|
|
|
29
|
-
def start_gateway
|
|
37
|
+
def start_gateway
|
|
30
38
|
# Check if any channels are configured (excluding CLI)
|
|
31
39
|
available_channels = Botiasloop::Channels.registry.channels.except(:cli)
|
|
32
40
|
|
|
@@ -36,10 +44,10 @@ def start_gateway(config)
|
|
|
36
44
|
exit 1
|
|
37
45
|
end
|
|
38
46
|
|
|
39
|
-
manager = Botiasloop::ChannelsManager.new
|
|
47
|
+
manager = Botiasloop::ChannelsManager.new
|
|
40
48
|
|
|
41
49
|
# Start all channels and wait
|
|
42
|
-
manager.
|
|
50
|
+
manager.start_listening.wait
|
|
43
51
|
end
|
|
44
52
|
|
|
45
53
|
if ARGV[0] == "-h" || ARGV[0] == "--help"
|
|
@@ -47,10 +55,8 @@ if ARGV[0] == "-h" || ARGV[0] == "--help"
|
|
|
47
55
|
elsif ARGV[0] == "-v" || ARGV[0] == "--version"
|
|
48
56
|
puts "botiasloop #{Botiasloop::VERSION}"
|
|
49
57
|
elsif ARGV[0] == "gateway"
|
|
50
|
-
config = Botiasloop::Config.new
|
|
51
|
-
|
|
52
58
|
if ARGV[1] == "start"
|
|
53
|
-
service = Botiasloop::SystemdService.new
|
|
59
|
+
service = Botiasloop::SystemdService.new
|
|
54
60
|
if service.systemd_available?
|
|
55
61
|
begin
|
|
56
62
|
service.start
|
|
@@ -64,7 +70,7 @@ elsif ARGV[0] == "gateway"
|
|
|
64
70
|
exit 1
|
|
65
71
|
end
|
|
66
72
|
elsif ARGV[1] == "stop"
|
|
67
|
-
service = Botiasloop::SystemdService.new
|
|
73
|
+
service = Botiasloop::SystemdService.new
|
|
68
74
|
if service.systemd_available?
|
|
69
75
|
begin
|
|
70
76
|
service.stop
|
|
@@ -78,7 +84,7 @@ elsif ARGV[0] == "gateway"
|
|
|
78
84
|
exit 1
|
|
79
85
|
end
|
|
80
86
|
elsif ARGV[1] == "restart"
|
|
81
|
-
service = Botiasloop::SystemdService.new
|
|
87
|
+
service = Botiasloop::SystemdService.new
|
|
82
88
|
if service.systemd_available?
|
|
83
89
|
begin
|
|
84
90
|
service.restart
|
|
@@ -92,7 +98,7 @@ elsif ARGV[0] == "gateway"
|
|
|
92
98
|
exit 1
|
|
93
99
|
end
|
|
94
100
|
elsif ARGV[1] == "status"
|
|
95
|
-
service = Botiasloop::SystemdService.new
|
|
101
|
+
service = Botiasloop::SystemdService.new
|
|
96
102
|
if service.systemd_available?
|
|
97
103
|
status = service.status
|
|
98
104
|
puts "Service status: #{status[:message]}"
|
|
@@ -101,8 +107,53 @@ elsif ARGV[0] == "gateway"
|
|
|
101
107
|
puts "Error: systemd is not available on this system"
|
|
102
108
|
exit 1
|
|
103
109
|
end
|
|
110
|
+
elsif ARGV[1] == "logs"
|
|
111
|
+
service = Botiasloop::SystemdService.new
|
|
112
|
+
if service.systemd_available?
|
|
113
|
+
# Parse logs options
|
|
114
|
+
follow = false
|
|
115
|
+
lines = 50
|
|
116
|
+
|
|
117
|
+
# Parse arguments from ARGV[2..] to support both -n 100 and --lines 100 formats
|
|
118
|
+
i = 2
|
|
119
|
+
while i < ARGV.length
|
|
120
|
+
arg = ARGV[i]
|
|
121
|
+
|
|
122
|
+
if arg == "-f" || arg == "--follow"
|
|
123
|
+
follow = true
|
|
124
|
+
i += 1
|
|
125
|
+
elsif arg == "-n" || arg == "--lines"
|
|
126
|
+
if i + 1 >= ARGV.length
|
|
127
|
+
puts "Error: #{arg} requires a value"
|
|
128
|
+
exit 1
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
lines_str = ARGV[i + 1]
|
|
132
|
+
unless lines_str.match(/^\d+$/)
|
|
133
|
+
puts "Error: Invalid number of lines: #{lines_str}"
|
|
134
|
+
exit 1
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
lines = lines_str.to_i
|
|
138
|
+
i += 2
|
|
139
|
+
else
|
|
140
|
+
puts "Unknown option: #{arg}"
|
|
141
|
+
exit 1
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
begin
|
|
146
|
+
service.logs(follow: follow, lines: lines)
|
|
147
|
+
rescue Botiasloop::SystemdError => e
|
|
148
|
+
puts "Error: #{e.message}"
|
|
149
|
+
exit 1
|
|
150
|
+
end
|
|
151
|
+
else
|
|
152
|
+
puts "Error: systemd is not available on this system"
|
|
153
|
+
exit 1
|
|
154
|
+
end
|
|
104
155
|
elsif ARGV[1] == "enable"
|
|
105
|
-
service = Botiasloop::SystemdService.new
|
|
156
|
+
service = Botiasloop::SystemdService.new
|
|
106
157
|
if service.systemd_available?
|
|
107
158
|
begin
|
|
108
159
|
service.install unless service.installed?
|
|
@@ -118,7 +169,7 @@ elsif ARGV[0] == "gateway"
|
|
|
118
169
|
exit 1
|
|
119
170
|
end
|
|
120
171
|
elsif ARGV[1] == "disable"
|
|
121
|
-
service = Botiasloop::SystemdService.new
|
|
172
|
+
service = Botiasloop::SystemdService.new
|
|
122
173
|
if service.systemd_available?
|
|
123
174
|
begin
|
|
124
175
|
if service.installed?
|
|
@@ -136,13 +187,12 @@ elsif ARGV[0] == "gateway"
|
|
|
136
187
|
exit 1
|
|
137
188
|
end
|
|
138
189
|
else
|
|
139
|
-
start_gateway
|
|
190
|
+
start_gateway
|
|
140
191
|
end
|
|
141
192
|
elsif ARGV[0] == "cli"
|
|
142
193
|
# CLI interactive mode
|
|
143
|
-
|
|
144
|
-
cli_channel
|
|
145
|
-
cli_channel.start
|
|
194
|
+
cli_channel = Botiasloop::Channels::CLI.new
|
|
195
|
+
cli_channel.start_listening
|
|
146
196
|
elsif ARGV.empty? || ARGV[0] == "help"
|
|
147
197
|
# Default to help when no args or explicit help command
|
|
148
198
|
print_help
|