verysmolcode 0.7.7__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 (43) hide show
  1. verysmolcode-0.7.7/.claude/scheduled_tasks.lock +1 -0
  2. verysmolcode-0.7.7/.claude/settings.json +5 -0
  3. verysmolcode-0.7.7/.github/workflows/CI.yml +170 -0
  4. verysmolcode-0.7.7/.gitignore +29 -0
  5. verysmolcode-0.7.7/.pre-commit-config.yaml +21 -0
  6. verysmolcode-0.7.7/CLAUDE.md +130 -0
  7. verysmolcode-0.7.7/Cargo.lock +1598 -0
  8. verysmolcode-0.7.7/Cargo.toml +39 -0
  9. verysmolcode-0.7.7/LICENSE +21 -0
  10. verysmolcode-0.7.7/PKG-INFO +172 -0
  11. verysmolcode-0.7.7/README.md +153 -0
  12. verysmolcode-0.7.7/pyproject.toml +28 -0
  13. verysmolcode-0.7.7/scripts/pre-commit +35 -0
  14. verysmolcode-0.7.7/src/agent/loop_runner.rs +654 -0
  15. verysmolcode-0.7.7/src/agent/mod.rs +3 -0
  16. verysmolcode-0.7.7/src/api/client.rs +179 -0
  17. verysmolcode-0.7.7/src/api/mod.rs +3 -0
  18. verysmolcode-0.7.7/src/api/models.rs +308 -0
  19. verysmolcode-0.7.7/src/api/types.rs +166 -0
  20. verysmolcode-0.7.7/src/config.rs +71 -0
  21. verysmolcode-0.7.7/src/lib.rs +27 -0
  22. verysmolcode-0.7.7/src/main.rs +24 -0
  23. verysmolcode-0.7.7/src/mcp/client.rs +189 -0
  24. verysmolcode-0.7.7/src/mcp/config.rs +47 -0
  25. verysmolcode-0.7.7/src/mcp/mod.rs +3 -0
  26. verysmolcode-0.7.7/src/mcp/types.rs +57 -0
  27. verysmolcode-0.7.7/src/tools/file_ops.rs +243 -0
  28. verysmolcode-0.7.7/src/tools/git.rs +158 -0
  29. verysmolcode-0.7.7/src/tools/grep.rs +199 -0
  30. verysmolcode-0.7.7/src/tools/mod.rs +5 -0
  31. verysmolcode-0.7.7/src/tools/registry.rs +348 -0
  32. verysmolcode-0.7.7/src/tools/web.rs +170 -0
  33. verysmolcode-0.7.7/src/tui/app.rs +483 -0
  34. verysmolcode-0.7.7/src/tui/commands.rs +173 -0
  35. verysmolcode-0.7.7/src/tui/input.rs +99 -0
  36. verysmolcode-0.7.7/src/tui/mod.rs +80 -0
  37. verysmolcode-0.7.7/src/tui/ui.rs +255 -0
  38. verysmolcode-0.7.7/tests/integration_test.sh +201 -0
  39. verysmolcode-0.7.7/tests/test_api.rs +469 -0
  40. verysmolcode-0.7.7/tests/test_commands.rs +191 -0
  41. verysmolcode-0.7.7/tests/test_config.rs +88 -0
  42. verysmolcode-0.7.7/tests/test_tools.rs +231 -0
  43. verysmolcode-0.7.7/tests/test_vibecoded_app.py +161 -0
@@ -0,0 +1 @@
1
+ {"sessionId":"8c5ab563-a282-44af-a932-2195f10db9be","pid":1049177,"acquiredAt":1773148434698}
@@ -0,0 +1,5 @@
1
+ {
2
+ "enabledPlugins": {
3
+ "ralph-wiggum@claude-code-plugins": true
4
+ }
5
+ }
@@ -0,0 +1,170 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: ['v*']
7
+ pull_request:
8
+ branches: [main]
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ test:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Install Rust
20
+ uses: dtolnay/rust-toolchain@stable
21
+ with:
22
+ components: clippy, rustfmt
23
+
24
+ - name: Cache cargo
25
+ uses: actions/cache@v4
26
+ with:
27
+ path: |
28
+ ~/.cargo/registry
29
+ ~/.cargo/git
30
+ target
31
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
32
+
33
+ - name: Check formatting
34
+ run: cargo fmt -- --check
35
+
36
+ - name: Clippy (strict)
37
+ run: cargo clippy -- -D warnings
38
+
39
+ - name: Run tests
40
+ run: cargo test
41
+
42
+ - name: Build release binary
43
+ run: cargo build --release
44
+
45
+ integration-test:
46
+ runs-on: ubuntu-latest
47
+ if: startsWith(github.ref, 'refs/tags/')
48
+ continue-on-error: true
49
+ needs: [test]
50
+ steps:
51
+ - uses: actions/checkout@v4
52
+
53
+ - name: Install Rust
54
+ uses: dtolnay/rust-toolchain@stable
55
+
56
+ - name: Cache cargo
57
+ uses: actions/cache@v4
58
+ with:
59
+ path: |
60
+ ~/.cargo/registry
61
+ ~/.cargo/git
62
+ target
63
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
64
+
65
+ - name: Install tmux
66
+ run: sudo apt-get install -y tmux
67
+
68
+ - name: Build release binary
69
+ run: cargo build --release
70
+
71
+ - name: Run integration test
72
+ env:
73
+ GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
74
+ run: |
75
+ chmod +x tests/integration_test.sh
76
+ bash tests/integration_test.sh
77
+
78
+ build-wheels:
79
+ runs-on: ${{ matrix.os }}
80
+ if: startsWith(github.ref, 'refs/tags/')
81
+ needs: [test]
82
+ strategy:
83
+ fail-fast: false
84
+ matrix:
85
+ include:
86
+ # x86_64 Linux
87
+ - os: ubuntu-latest
88
+ target: x86_64
89
+ manylinux: auto
90
+ artifact: wheels-linux-x86_64
91
+ # aarch64 Linux (Raspberry Pi 3/4/5, ARM servers)
92
+ # Use manylinux_2_28 for newer GCC that properly defines __ARM_ARCH
93
+ - os: ubuntu-latest
94
+ target: aarch64
95
+ manylinux: 2_28
96
+ artifact: wheels-linux-aarch64
97
+ # armv7 Linux (Raspberry Pi 2/3 32-bit OS)
98
+ - os: ubuntu-latest
99
+ target: armv7
100
+ manylinux: 2_28
101
+ artifact: wheels-linux-armv7
102
+ steps:
103
+ - uses: actions/checkout@v4
104
+ - uses: actions/setup-python@v5
105
+ with:
106
+ python-version: '3.13'
107
+ - name: Build wheels
108
+ uses: PyO3/maturin-action@v1
109
+ with:
110
+ target: ${{ matrix.target }}
111
+ args: --release --out dist --features python -i python3.13
112
+ manylinux: ${{ matrix.manylinux }}
113
+ - name: Upload wheels
114
+ uses: actions/upload-artifact@v4
115
+ with:
116
+ name: ${{ matrix.artifact }}
117
+ path: dist
118
+
119
+ build-sdist:
120
+ runs-on: ubuntu-latest
121
+ if: startsWith(github.ref, 'refs/tags/')
122
+ needs: [test]
123
+ steps:
124
+ - uses: actions/checkout@v4
125
+ - name: Build sdist
126
+ uses: PyO3/maturin-action@v1
127
+ with:
128
+ command: sdist
129
+ args: --out dist
130
+ - name: Upload sdist
131
+ uses: actions/upload-artifact@v4
132
+ with:
133
+ name: sdist
134
+ path: dist
135
+
136
+ test-wheel:
137
+ runs-on: ubuntu-latest
138
+ if: startsWith(github.ref, 'refs/tags/')
139
+ needs: [build-wheels]
140
+ steps:
141
+ - uses: actions/setup-python@v5
142
+ with:
143
+ python-version: '3.13'
144
+ - uses: actions/download-artifact@v4
145
+ with:
146
+ name: wheels-linux-x86_64
147
+ path: dist
148
+ - name: Install wheel and verify
149
+ run: |
150
+ pip install dist/*.whl
151
+ python -c "import verysmolcode; print('Version:', verysmolcode.version())"
152
+
153
+ publish-pypi:
154
+ runs-on: ubuntu-latest
155
+ if: startsWith(github.ref, 'refs/tags/')
156
+ needs: [test-wheel, build-sdist]
157
+ permissions:
158
+ contents: read
159
+ steps:
160
+ - uses: actions/download-artifact@v4
161
+ with:
162
+ path: dist
163
+ merge-multiple: true
164
+ - name: Publish to PyPI
165
+ uses: PyO3/maturin-action@v1
166
+ env:
167
+ MATURIN_PYPI_TOKEN: ${{ secrets.TWINE_PASSWORD }}
168
+ with:
169
+ command: upload
170
+ args: --non-interactive dist/*
@@ -0,0 +1,29 @@
1
+ # Generated by Cargo
2
+ # will have compiled files and executables
3
+ debug
4
+ target
5
+
6
+ # These are backup files generated by rustfmt
7
+ **/*.rs.bk
8
+
9
+ # MSVC Windows builds of rustc generate these, which store debugging information
10
+ *.pdb
11
+
12
+ # Generated by cargo mutants
13
+ # Contains mutation testing data
14
+ **/mutants.out*/
15
+
16
+ # RustRover
17
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
18
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
19
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
20
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
21
+ #.idea/
22
+
23
+ # Python
24
+ __pycache__/
25
+ *.pyc
26
+ *.egg-info/
27
+ dist/
28
+ *.so
29
+ *.whl
@@ -0,0 +1,21 @@
1
+ repos:
2
+ - repo: local
3
+ hooks:
4
+ - id: cargo-clippy
5
+ name: Cargo Clippy (strict)
6
+ entry: bash -c 'source /home/mt/.cargo/env && cargo clippy -- -D warnings'
7
+ language: system
8
+ types: [rust]
9
+ pass_filenames: false
10
+ - id: cargo-test
11
+ name: Cargo Tests
12
+ entry: bash -c 'source /home/mt/.cargo/env && cargo test'
13
+ language: system
14
+ types: [rust]
15
+ pass_filenames: false
16
+ - id: cargo-fmt-check
17
+ name: Cargo Format Check
18
+ entry: bash -c 'source /home/mt/.cargo/env && cargo fmt -- --check'
19
+ language: system
20
+ types: [rust]
21
+ pass_filenames: false
@@ -0,0 +1,130 @@
1
+ # VerySmolCode
2
+ - Repository: https://github.com/marcelotournier/verysmolcode
3
+ - Create VerySmolCode, a rust-based TUI that mimics Claude Code and works with Gemini API free tier. GEMINI_API_KEY is in the env variable
4
+ - TUI must be lightweight enough to run in a memory constrained device such as a raspberrypi 3 (1GB RAM)
5
+ - Make sure this respects the free tier API limits for models. Smarter models get fewer requests: Pro gives 5/min and 25/day, Flash 10/min and 250/day, Flash-Lite 15/min and 1,000/day. We use 6 models (3 from Gemini 3.x, 3 from Gemini 2.5) with independent rate limits per model
6
+ - Use pro for harder tasks and flash for simpler stuff OR fallback to flash if pro is capped
7
+ - Whenever you use flash, use chain-of-thought (<think> xml tokens) to maximize its performance, flash is bad for tasks if it doesn't use CoT.
8
+ - Gemini API documentation at https://ai.google.dev/gemini-api/docs/quickstart#rest
9
+ - Models must have basic tools to manipulate files, grepsearch, edit, read images, do git operations (commit, push, pull, diff, branch, checkout, etc)
10
+ - TUI must have slashcommands to help on configuration
11
+ - TUI must be configurable in terms of how we can tune up or down token consumption - think about the best way to do it
12
+ - Coder agent must mimic what Opencode loop does, adapted by the limitations of tokens for the Google Free tier. CRITICAL: THINK HARD and design a good algorithm on how to optimize tokens and requests and all models available (all per-minute+per-day limits are per model so you can change them when limits are reached)
13
+ - Coder agent must develop AND do a critic if the work is really done
14
+ - Coder agent must not do egregious things in software like deleting stuff from the OS or things like the early days of Claude Code horror stories. Check references on reddit and do not do those...
15
+ - Find creative ways to optimize model limitations. Add MCP access for tools like context7 and other MCPs
16
+ - Add MCP access to playwright from the beginning
17
+ - Add functionality to install MCP servers from slash commands.
18
+ - Design principles:
19
+ - VERY VERY IMPORTANT: Build this with maturin/pyo3 integration so we can pip install this in a raspberry pi later! I want this agent to be very easy to install.
20
+ - No need to be creative. Look at the Gemini CLI, Opencode, Claude Code and Codex source repositories in github and base yourself upon them.
21
+ - CRITICAL REQUIREMENT: All decisions must take into account low end hardware. It should provide a snappy user experience on a Raspberrypi 3
22
+ - CRITICAL: User experience on token consumption should be good as well, the user should not be surprised with "out of tokens" errors
23
+ - Add a friendly UX design in the experience, blueish colors and visually comfortable colors that work well on TMUX limitations. Make the UX good enough to fix a 80 x 30 col terminal
24
+ - How to develop:
25
+ - Start by checking if repo is good (gitignore, etc)
26
+ - Setup rust development env
27
+ - Start with the model wrappers (Nanocode backend), test them, make sure they work
28
+ - After wrappers are minimally functional, develop the frontend TUI
29
+ - Commit and push to remote repo frequently, so you can rollback if needed
30
+ - Keep going without any stops until both backend and frontend are fully functional and can work the FINAL TEST successfully
31
+ - HOW TO TEST:
32
+ - Unit tests: Reach coverage of 100%
33
+ - Integration tests: Run the TUI on TMUX and send a command to build a todo list app in python bottle.py, check outputs for some tasks to see if it worked correctly in the task.
34
+ - HOW TO WORK:
35
+ - You are autonomous to keep going. use Ralph loops. make releases on github for working versions using gh cli tool.
36
+ - Add user documentation in README.md so humans can easily work
37
+ - Add TODO items in this document and modify this document as VerySmolCode evolves.
38
+
39
+ # TODO / Progress Tracker
40
+
41
+ ## Completed (v0.7.4)
42
+ - [x] Repo setup (gitignore, license, maturin/pyo3)
43
+ - [x] Gemini API client with 6-model routing (Gemini 3.x + 2.5)
44
+ - [x] Rate limiting with per-model RPM/RPD tracking
45
+ - [x] Tool system: 18 tools (file read/write/edit, grep, find, git, shell, web fetch, image reading)
46
+ - [x] TUI: blue theme, input history, slash commands, scrolling
47
+ - [x] Agent loop with automatic model fallback (503/429 aware)
48
+ - [x] Deep fallback chain: tries ALL 6 models before giving up
49
+ - [x] Critic verification (cheapest available model reviews completed work)
50
+ - [x] Planning mode (/plan) with read-only tools
51
+ - [x] Chain-of-thought for Flash and Gemini 3.1 Pro models (thinkingConfig)
52
+ - [x] Safety: blocks destructive ops, validates paths
53
+ - [x] MCP client support (stdio JSON-RPC protocol) - wired into agent loop
54
+ - [x] MCP server management (/mcp, /mcp-add, /mcp-rm)
55
+ - [x] Image reading tool (base64 encode + send as InlineData to Gemini)
56
+ - [x] Pre-commit hooks (fmt, clippy, tests)
57
+ - [x] 90 unit tests across 5 test files
58
+ - [x] Integration test (tmux + bottle.py todo app - continue-on-error, API-dependent)
59
+ - [x] README.md documentation
60
+ - [x] CI/CD pipeline: test -> build-wheels -> test-wheel -> publish-pypi
61
+ - [x] Rayon parallelism for grep_search and find_files (leverages multi-core on RPi3)
62
+ - [x] GitHub releases (v0.2.0 through v0.7.4)
63
+ - [x] PyPI publishing pipeline (sdist works, wheel builds need TLS fix)
64
+
65
+ ## In Progress - Token Consumption Optimization (HIGH PRIORITY)
66
+ - [ ] Audit and reduce unnecessary token usage in agent loop
67
+ - Current: Each iteration clones and sends FULL conversation history
68
+ - Current: max_tokens_per_response=4096, auto_compact at 24K tokens
69
+ - Current: Critic sends full conversation again after tool use
70
+ - Issue: Pro only has 25 req/day, Flash 250/day - every wasted request hurts
71
+ - [ ] Add token budget awareness to the agent loop
72
+ - Show remaining requests in TUI prominently
73
+ - Warn user when approaching daily limits
74
+ - Let user choose model tier per request (/fast, /smart)
75
+ - [ ] Smarter conversation compaction
76
+ - Compact tool results aggressively (keep only summaries, not full file contents)
77
+ - Prune thinking tokens from history before resending
78
+ - Truncate large tool results (e.g. grep with 50 matches)
79
+ - [ ] Add /tokens slash command to show detailed usage breakdown
80
+
81
+ ## In Progress - ARM Binary Distribution (HIGH PRIORITY)
82
+ - [ ] Fix ARM wheel cross-compilation in CI
83
+ - ring crate fails in manylinux Docker for aarch64 (#error "ARM assembler must define __ARM_ARCH")
84
+ - native-tls approach fails because manylinux lacks OpenSSL dev headers
85
+ - Options to explore: (1) set CFLAGS=-D__ARM_ARCH=8 for ring, (2) vendored-openssl, (3) before-script-linux to install openssl-dev
86
+ - RPi3 native build works (builds with ring/rustls natively on aarch64)
87
+ - [ ] Verify pip install installs binary wheel (not sdist) on RPi3
88
+ - User has Python 3.13 and RPi3 (aarch64, Debian)
89
+ - Must use venv for testing
90
+ - [ ] Consider building wheels natively on RPi or ARM CI runner as fallback
91
+
92
+ ## Planned
93
+ - [ ] Token usage dashboard in TUI
94
+ - [ ] Configuration editing via slash commands (/config set)
95
+ - [ ] Increase test coverage toward 100%
96
+ - [ ] Wait-and-retry when per-minute rate limit hit (instead of immediate fallback to weaker model)
97
+
98
+ # Lessons Learned
99
+
100
+ ## TLS Crate Selection for Cross-Platform Builds
101
+ - **rustls** (via ring): Works perfectly for ALL native builds (x86_64, aarch64, armv7). Fails to cross-compile for ARM in manylinux Docker containers due to ring's assembly requirements.
102
+ - **native-tls** (via openssl): Requires OpenSSL dev headers at compile time AND OpenSSL library at runtime. Fails in manylinux Docker (no openssl-dev). Also produced "no TLS backend" errors on local machine (v0.7.2-0.7.3 were broken).
103
+ - **Conclusion**: Use rustls (ureq default features) for the binary. Solve cross-compilation separately with CFLAGS or vendored OpenSSL for manylinux Docker builds.
104
+
105
+ ## Gemini API Rate Limits Are Harsh
106
+ - Pro: 5 RPM, 25 RPD - extremely limited. A single complex task with 10+ tool iterations burns nearly half the daily budget.
107
+ - Flash: 10 RPM, 250 RPD - more workable but still tight.
108
+ - Flash-Lite: 15 RPM, 1000 RPD - most budget but least capable.
109
+ - All 6 models have independent limits, giving ~2550 total requests/day.
110
+ - The 3.x preview models may have different/stricter limits than documented. When ALL 6 models return 429, the API key's global quota may be exhausted.
111
+ - Integration tests are inherently flaky because they depend on API availability.
112
+
113
+ ## Agent Loop Token Consumption
114
+ - The agent loop sends full conversation history on EVERY iteration (up to 15 iterations).
115
+ - Tool results (especially grep, read_file) can be very large and stay in conversation history.
116
+ - The critic step adds another full-conversation API call after the agent completes.
117
+ - Auto-compact at 24K tokens helps but doesn't prevent large intermediate states.
118
+ - Need aggressive truncation of tool results and conversation pruning to stay within budget.
119
+
120
+ ## RPi3 Build Considerations
121
+ - RPi3 has 906MB RAM, Cortex-A53 (4 cores). Release builds with LTO use ~422MB RAM.
122
+ - Build needs 2GB swap file to complete. /tmp is 100MB tmpfs - must build in home dir.
123
+ - serde_derive takes ~5 min to compile, full build takes ~30+ min with -j1.
124
+ - Rayon leverages all 4 cores for grep/find, good for runtime performance.
125
+ - Native aarch64 build with ring/rustls works fine - only cross-compilation fails.
126
+
127
+ ## CI Pipeline Design
128
+ - Integration test depends on Gemini API availability. Made it continue-on-error so wheel builds aren't blocked.
129
+ - Wheel builds only depend on unit tests (deterministic) not integration test (flaky).
130
+ - matrix strategy with fail-fast means one arch failure cancels all others. May want to set fail-fast: false.