Skip to content

Commit aebf030

Browse files
Merge branch 'bpsaog' of github.com:joaopauloschuler/beyond-python-smolagents into bpsaog
2 parents c7f163f + d0050b2 commit aebf030

24 files changed

Lines changed: 1162 additions & 14 deletions

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ limitations under the License.
2727
* 🔌 **MCP server integration:** Connect any [Model Context Protocol](https://modelcontextprotocol.io) server as a tool source via the `--mcp` CLI flag. Supports both HTTP (Streamable HTTP) and stdio-based servers.
2828
* 👁️ **Image loading:** Agents can load and visually inspect image files (plots, screenshots, diagrams) via the built-in `load_image` tool — always available, no flags needed.
2929
* 🎨 **Image tools:** Visual image diffing (`diff_images`), OCR text extraction from images (`screen_ocr`), and a canvas for drawing shapes, text, and annotations (`canvas_create`, `canvas_draw`) — always available.
30+
* 🖵 **Tmux multi-screen:** Agents can create and operate multiple independent shell sessions concurrently via tmux (`--tmux` flag or `BPSA_TMUX=1`). Run builds, servers, and tests in parallel across named screen sessions.
3031
* 🎤 **Dictation input:** Dictate prompts via microphone using Whisper or ElevenLabs transcription (`/dictation` command, requires `BPSA_DICTATION_TRANSCRIBER` env var).
3132
***Native Python execution:** Execute Python code natively via `exec` for unrestricted processing.
3233
* 🌍 **Multi-language support:** Code in multiple languages beyond Python (Pascal, PHP, C++, Java and more).
@@ -94,6 +95,7 @@ $ bpsa --load-instructions # Load CLAUDE.md, AGENTS.md, etc. at startup
9495
$ bpsa --browser # Enable Playwright browser integration
9596
$ bpsa --gui-x11 # Enable native GUI interaction (xdotool/ImageMagick)
9697
$ bpsa --image # Enable image analysis and drawing tools
98+
$ bpsa --tmux # Enable tmux multi-screen tools
9799
$ bpsa --mcp http://localhost:8000/mcp # Connect an HTTP MCP server
98100
$ bpsa --mcp 'npx -y @modelcontextprotocol/server-filesystem /' # Connect a stdio MCP server
99101
```

docs/CLI.md

Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ These variables enable optional tool sets. Each corresponds to a CLI flag. Setti
7373
| `BPSA_BROWSER` | `--browser` | Enable Playwright browser integration (navigate, click, type, etc.) |
7474
| `BPSA_GUI` | `--gui-x11` | Enable native GUI interaction tools (screenshot, click, type via xdotool/ImageMagick on X11) |
7575
| `BPSA_IMAGE` | `--image` | Enable image analysis and drawing tools (diff_images, screen_ocr, canvas drawing) |
76+
| `BPSA_TMUX` | `--tmux` | Enable tmux multi-screen tools (create, send, read, list, destroy, wait) |
7677

7778
### Context Compression Variables
7879

@@ -199,6 +200,51 @@ Use `prompt_toolkit` for:
199200
| `/verbose` | Toggle verbose output |
200201
| `/dictation [on\|off]` | Toggle dictation (requires `BPSA_DICTATION_TRANSCRIBER`) |
201202

203+
## Tmux Multi-Screen Tools
204+
205+
The `--tmux` flag (or `BPSA_TMUX=1` env var) enables tools that let the agent create and operate multiple independent shell sessions concurrently via tmux. This is useful for running long-running processes (servers, builds, file watchers) in parallel while the agent continues other work.
206+
207+
**Requires:** `tmux` installed on the system.
208+
209+
```bash
210+
bpsa --tmux
211+
212+
# Or via environment variable:
213+
export BPSA_TMUX=1
214+
bpsa
215+
```
216+
217+
### Available Tools
218+
219+
| Tool | Description |
220+
|------|-------------|
221+
| `tmux_create(session_name, command?)` | Create a new named screen session (default command: `bash`) |
222+
| `tmux_send(session_name, text, press_enter?)` | Send keystrokes to a session (default: presses Enter after text) |
223+
| `tmux_read(session_name, lines?)` | Read the current screen content / scrollback (default: 100 lines, max: 2000) |
224+
| `tmux_list()` | List all active agent screen sessions |
225+
| `tmux_destroy(session_name)` | Kill a session and all its processes |
226+
| `tmux_wait(session_name, pattern, timeout?, interval?)` | Poll until a text pattern appears (default: 60s timeout, 1s interval) |
227+
228+
### Example Agent Workflow
229+
230+
```
231+
tmux_create("server")
232+
tmux_send("server", "python app.py")
233+
tmux_wait("server", "Listening on port 8080")
234+
235+
tmux_create("tests")
236+
tmux_send("tests", "pytest tests/ -v")
237+
tmux_wait("tests", "passed")
238+
tmux_read("tests")
239+
240+
tmux_destroy("server")
241+
tmux_destroy("tests")
242+
```
243+
244+
### Session Namespacing
245+
246+
All sessions are automatically prefixed with `bpsa_` internally to avoid collisions with user tmux sessions. The agent uses short names (e.g., `server`) while tmux sees `bpsa_server`. Sessions are automatically cleaned up when the process exits.
247+
202248
## MCP Server Integration
203249

204250
The `--mcp` flag connects [Model Context Protocol](https://modelcontextprotocol.io) servers as additional tool sources. Tools exposed by MCP servers are automatically available to the agent alongside the built-in tools.
@@ -236,8 +282,250 @@ Priority (highest to lowest):
236282
3. Config file (`~/.bpsa.yaml`)
237283
4. Built-in defaults
238284

285+
## Utility CLIs
286+
287+
Beyond the main `bpsa` REPL, the project ships lightweight CLI wrappers around commonly used tools from `bp_tools.py`. All are installed automatically via `pip install` and support `--help`.
288+
289+
### Quick Reference
290+
291+
| Command | Description |
292+
|---------|-------------|
293+
| `bptree` | Directory tree with line counts and optional function signatures |
294+
| `bpgrep` | Search for text patterns in files with extension filtering |
295+
| `bppack` | Pack a folder's source code into a single tagged string |
296+
| `bpunpack` | Reconstruct source files from a packed string |
297+
| `bploc` | Lines-of-code summary broken down by file type |
298+
| `bpdiff` | Compare two files or two folders (unified diff) |
299+
| `bpsig` | Extract function/class signatures from a source file |
300+
| `bppas` | Extract Pascal unit interface sections from a folder |
301+
302+
Entry points in `pyproject.toml`:
303+
```toml
304+
[project.scripts]
305+
bptree = "smolagents.bp_tree_cli:main"
306+
bpgrep = "smolagents.bp_grep_cli:main"
307+
bppack = "smolagents.bp_pack_cli:main"
308+
bpunpack = "smolagents.bp_unpack_cli:main"
309+
bploc = "smolagents.bp_loc_cli:main"
310+
bpdiff = "smolagents.bp_diff_cli:main"
311+
bpsig = "smolagents.bp_sig_cli:main"
312+
bppas = "smolagents.bp_pas_cli:main"
313+
```
314+
315+
---
316+
317+
### `bptree` — Directory Tree
318+
319+
Displays a tree view of a directory with source-file line counts and optional function signatures. Skips common build/artifact folders by default.
320+
321+
```bash
322+
bptree [FOLDER] [-d DEPTH] [--no-files] [-s] [--skip-dirs DIRS]
323+
```
324+
325+
| Flag | Description |
326+
|------|-------------|
327+
| `FOLDER` | Root folder (default: `.`) |
328+
| `-d`, `--depth N` | Max depth to traverse (default: 6) |
329+
| `--no-files` | Show only directories, hide files |
330+
| `-s`, `--signatures` | Show function/class signatures inline |
331+
| `--skip-dirs d1,d2` | Comma-separated dirs to show but not traverse |
332+
333+
```bash
334+
# Basic tree of src/ with depth 2
335+
bptree src/ -d 2
336+
337+
# Tree with function signatures
338+
bptree . -s
339+
340+
# Directories only, skip vendor
341+
bptree . --no-files --skip-dirs vendor,tmp
342+
```
343+
344+
---
345+
346+
### `bpgrep` — Search in Files
347+
348+
Searches for a text pattern in files within a folder (or a single file). Returns matching lines with file paths and line numbers.
349+
350+
```bash
351+
bpgrep PATTERN [PATH] [-e EXTS] [-c] [-m MAX]
352+
```
353+
354+
| Flag | Description |
355+
|------|-------------|
356+
| `PATTERN` | Text pattern to search for |
357+
| `PATH` | Folder or file to search (default: `.`) |
358+
| `-e`, `--extensions` | Comma-separated extensions to filter (e.g. `py,js,ts`) |
359+
| `-c`, `--case-sensitive` | Case-sensitive search (default: case-insensitive) |
360+
| `-m`, `--max-results N` | Maximum results to return (default: 50) |
361+
362+
```bash
363+
# Search for "def main" in Python files
364+
bpgrep "def main" src/ -e py
365+
366+
# Case-sensitive search with limit
367+
bpgrep "TODO" . -c -m 20
368+
```
369+
370+
---
371+
372+
### `bppack` — Pack Source Code
373+
374+
Packs all source files in a folder into a single string with `<file filename="...">...</file>` XML-like tags. Useful for feeding entire projects to LLMs or creating context dumps.
375+
376+
```bash
377+
bppack FOLDER [-e EXTS] [--strip-pascal-comments] [--exclude ITEMS] [-o FILE]
378+
```
379+
380+
| Flag | Description |
381+
|------|-------------|
382+
| `FOLDER` | Root folder to scan |
383+
| `-e`, `--extensions` | Comma-separated extensions to include (default: common source extensions) |
384+
| `--strip-pascal-comments` | Remove Pascal comments from `.pas`/`.inc` files |
385+
| `--exclude` | Comma-separated files/folders to exclude |
386+
| `-o`, `--output FILE` | Write to a file instead of stdout |
387+
388+
```bash
389+
# Pack src/ to a file
390+
bppack src/ -o context.txt
391+
392+
# Pack only Python and JS files
393+
bppack . -e py,js --exclude __pycache__,node_modules
394+
```
395+
396+
---
397+
398+
### `bpunpack` — Unpack Source Code
399+
400+
Reconstructs source files from a packed string produced by `bppack`. Reads from a file or stdin.
401+
402+
```bash
403+
bpunpack [INPUT] [-o DIR] [--no-overwrite] [-q]
404+
```
405+
406+
| Flag | Description |
407+
|------|-------------|
408+
| `INPUT` | Packed file to read (default: stdin) |
409+
| `-o`, `--output-dir DIR` | Base directory to write into (default: `.`) |
410+
| `--no-overwrite` | Skip files that already exist |
411+
| `-q`, `--quiet` | Suppress status messages |
412+
413+
```bash
414+
# Unpack from file into output/
415+
bpunpack context.txt -o output/
416+
417+
# Pipe from bppack
418+
bppack src/ | bpunpack -o copy/
419+
420+
# Unpack without overwriting existing files
421+
bpunpack context.txt --no-overwrite
422+
```
423+
424+
---
425+
426+
### `bploc` — Lines of Code
427+
428+
Counts lines of code broken down by file extension. Skips hidden files and directories.
429+
430+
```bash
431+
bploc [FOLDER] [-e EXTS]
432+
```
433+
434+
| Flag | Description |
435+
|------|-------------|
436+
| `FOLDER` | Root folder to analyze (default: `.`) |
437+
| `-e`, `--extensions` | Comma-separated extensions to count (default: `py,js,java,cpp,c,php,rb`) |
438+
439+
```bash
440+
# Count lines in current project
441+
bploc
442+
443+
# Count only Python and TypeScript
444+
bploc src/ -e py,ts
445+
```
446+
447+
Example output:
448+
```
449+
.py 23985 lines
450+
total 23985 lines
451+
```
452+
453+
---
454+
455+
### `bpdiff` — Compare Files or Folders
456+
457+
Compares two files or two folders and shows differences in unified diff format. For folders, only source code files are compared.
458+
459+
```bash
460+
bpdiff PATH1 PATH2 [-c CONTEXT]
461+
```
462+
463+
| Flag | Description |
464+
|------|-------------|
465+
| `PATH1` | First file or folder |
466+
| `PATH2` | Second file or folder |
467+
| `-c`, `--context N` | Context lines around differences (default: 3) |
468+
469+
```bash
470+
# Compare two files
471+
bpdiff old_version.py new_version.py
472+
473+
# Compare two folders with more context
474+
bpdiff project_v1/ project_v2/ -c 5
475+
```
476+
477+
---
478+
479+
### `bpsig` — Function Signatures
480+
481+
Extracts function and class signatures from a source file without showing the implementation. Supports Python, JavaScript/TypeScript, Java, PHP, Pascal, C/C++, Markdown (section headers), and a generic fallback.
482+
483+
```bash
484+
bpsig FILE [-l LANGUAGE]
485+
```
486+
487+
| Flag | Description |
488+
|------|-------------|
489+
| `FILE` | Source file to extract signatures from |
490+
| `-l`, `--language` | Programming language (auto-detected from extension if omitted) |
491+
492+
```bash
493+
# Auto-detect language
494+
bpsig src/main.py
495+
496+
# Explicit language
497+
bpsig utils.inc -l pascal
498+
```
499+
500+
---
501+
502+
### `bppas` — Pascal Interfaces
503+
504+
Extracts the interface sections (between `interface` and `implementation` keywords) from Pascal source files in a folder. Output uses `<pascal_interface filename="...">` tags.
505+
506+
```bash
507+
bppas FOLDER [--strip-comments] [-o FILE]
508+
```
509+
510+
| Flag | Description |
511+
|------|-------------|
512+
| `FOLDER` | Root folder to scan for `.pas`, `.inc`, `.pp`, `.lpr`, `.dpr` files |
513+
| `--strip-comments` | Remove Pascal comments from extracted interfaces |
514+
| `-o`, `--output FILE` | Write to a file instead of stdout |
515+
516+
```bash
517+
# Extract interfaces
518+
bppas pascal_src/
519+
520+
# Strip comments and save to file
521+
bppas lib/ --strip-comments -o interfaces.txt
522+
```
523+
524+
---
525+
239526
## Dependencies
240527

241528
- `prompt_toolkit` - REPL input handling (optional, falls back to basic `input()`)
242529
- `rich` - Output formatting (already a project dependency)
243530
- `argparse` - CLI argument parsing (stdlib)
531+
- `tmux` - Multi-screen session management (optional, required for `--tmux`)

pyproject.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,5 +164,13 @@ lines-after-imports = 2
164164
[project.scripts]
165165
smolagent = "smolagents.cli:main"
166166
bpsa = "smolagents.bp_cli:main"
167+
bptree = "smolagents.bp_tree_cli:main"
168+
bpgrep = "smolagents.bp_grep_cli:main"
169+
bppack = "smolagents.bp_pack_cli:main"
170+
bpunpack = "smolagents.bp_unpack_cli:main"
171+
bploc = "smolagents.bp_loc_cli:main"
172+
bpdiff = "smolagents.bp_diff_cli:main"
173+
bpsig = "smolagents.bp_sig_cli:main"
174+
bppas = "smolagents.bp_pas_cli:main"
167175
webagent = "smolagents.vision_web_browser:main"
168176
ad-infinitum = "smolagents.bp_ad_infinitum:main"

src/smolagents/bp_ad_infinitum.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# BPSA - Beyond Python SmolAgents
2+
# https://github.com/joaopauloschuler/beyond-python-smolagents
3+
#
4+
# Copyright (c) 2024-2026 Joao Paulo Schwarz Schuler and others.
5+
# Refer to the git commit history for individual authorship.
6+
# Licensed under the Apache License, Version 2.0
17

28
#!/usr/bin/env python
39
# coding=utf-8

0 commit comments

Comments
 (0)