|
| 1 | +# GitHub Copilot Instructions for LocalGPT |
| 2 | + |
| 3 | +This file provides guidance to GitHub Copilot when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +LocalGPT is a local-only AI assistant built in Rust with persistent markdown-based memory and optional autonomous operation via heartbeat. It runs entirely on your machine with no cloud dependency required. |
| 8 | + |
| 9 | +## Quick Reference |
| 10 | + |
| 11 | +### Build & Test Commands |
| 12 | + |
| 13 | +```bash |
| 14 | +# Build |
| 15 | +cargo build # Debug build (default-members = cli) |
| 16 | +cargo build --release # Release build |
| 17 | +cargo build --workspace # Build all crates |
| 18 | + |
| 19 | +# Test |
| 20 | +cargo test --workspace # All tests |
| 21 | +cargo test -p localgpt-core # Single crate |
| 22 | +cargo test -- --nocapture # Show stdout |
| 23 | + |
| 24 | +# Lint (REQUIRED before commits) |
| 25 | +cargo clippy --workspace |
| 26 | +cargo fmt --check |
| 27 | + |
| 28 | +# Run |
| 29 | +cargo run -- chat # Interactive chat |
| 30 | +cargo run -- ask "question" # Single question |
| 31 | +cargo run -- daemon start # HTTP server + Telegram bot + heartbeat |
| 32 | +``` |
| 33 | + |
| 34 | +### Cross-platform Validation |
| 35 | + |
| 36 | +```bash |
| 37 | +# Mobile cross-compile checks (required for core changes) |
| 38 | +cargo check -p localgpt-mobile --target aarch64-apple-ios |
| 39 | +cargo check -p localgpt-mobile --target aarch64-apple-ios-sim |
| 40 | +``` |
| 41 | + |
| 42 | +## Architecture |
| 43 | + |
| 44 | +### Workspace Structure (6 crates) |
| 45 | + |
| 46 | +``` |
| 47 | +crates/ |
| 48 | +├── core/ # localgpt-core — shared library (agent, memory, config, security) |
| 49 | +├── cli/ # localgpt-cli — binary with clap CLI, desktop GUI, dangerous tools |
| 50 | +├── server/ # localgpt-server — HTTP/WS API, Telegram bot, optional WASM web UI |
| 51 | +├── sandbox/ # localgpt-sandbox — Landlock/Seatbelt process sandboxing |
| 52 | +├── mobile/ # localgpt-mobile — UniFFI bindings for iOS/Android |
| 53 | +└── gen/ # localgpt-gen — Bevy 3D scene generation binary |
| 54 | +``` |
| 55 | + |
| 56 | +### Dependency Rules |
| 57 | + |
| 58 | +**CRITICAL**: `localgpt-core` must have zero platform-specific dependencies. It must compile cleanly for `aarch64-apple-ios` and `aarch64-linux-android`. No clap, eframe, axum, teloxide, landlock, nix, etc. |
| 59 | + |
| 60 | +``` |
| 61 | +localgpt-cli ──→ localgpt-core |
| 62 | + ──→ localgpt-server ──→ localgpt-core |
| 63 | + ──→ localgpt-sandbox ──→ localgpt-core |
| 64 | +
|
| 65 | +localgpt-mobile ──→ localgpt-core (default-features = false, embeddings-openai) |
| 66 | +localgpt-gen ──→ localgpt-core |
| 67 | +``` |
| 68 | + |
| 69 | +### Feature Flags (`localgpt-core`) |
| 70 | + |
| 71 | +| Feature | Default | Purpose | |
| 72 | +|---------|---------|---------| |
| 73 | +| `embeddings-local` | yes | fastembed/ONNX local embeddings | |
| 74 | +| `embeddings-openai` | no | OpenAI API embeddings (mobile uses this) | |
| 75 | +| `embeddings-gguf` | no | llama.cpp GGUF embeddings | |
| 76 | +| `embeddings-none` | no | FTS5 keyword search only | |
| 77 | +| `claude-cli` | yes | ClaudeCliProvider (subprocess-based, excluded on mobile) | |
| 78 | + |
| 79 | +Mobile crate uses `default-features = false, features = ["embeddings-openai"]` to exclude native dependencies. |
| 80 | + |
| 81 | +## Key Design Patterns |
| 82 | + |
| 83 | +### Tool Safety Split |
| 84 | +- `Agent::new()` creates safe tools only (memory_search, memory_get, web_fetch, web_search) |
| 85 | +- CLI injects dangerous tools (bash, read_file, write_file, edit_file) via `agent.extend_tools(create_cli_tools())` |
| 86 | +- Server agents intentionally only get safe tools |
| 87 | + |
| 88 | +### Thread Safety |
| 89 | +- Agent is NOT `Send+Sync` due to SQLite |
| 90 | +- Use `AgentHandle` (`Arc<tokio::sync::Mutex<Agent>>`) for mobile/server |
| 91 | +- HTTP handler uses `spawn_blocking` |
| 92 | + |
| 93 | +### Bevy Main Thread |
| 94 | +- Bevy must own the main thread (macOS windowing/GPU requirement) |
| 95 | +- Gen mode spawns tokio on a background thread |
| 96 | + |
| 97 | +### Session Management |
| 98 | +- When approaching context limits, compaction triggers a memory flush first |
| 99 | +- LLM saves important context to MEMORY.md before messages are truncated |
| 100 | +- New sessions automatically load `MEMORY.md`, recent daily logs, `HEARTBEAT.md` |
| 101 | + |
| 102 | +### Path Expansion |
| 103 | +- All tools use `shellexpand::tilde()` for `~` in paths |
| 104 | + |
| 105 | +### Provider Routing |
| 106 | +Model prefix determines LLM provider: |
| 107 | +- `claude-cli/*` → Claude CLI |
| 108 | +- `gpt-*`/`openai/*` → OpenAI |
| 109 | +- `claude-*`/`anthropic/*` → Anthropic API |
| 110 | +- `glm-*`/`glm/*` → GLM (Z.AI) |
| 111 | +- `ollama/*` → Ollama |
| 112 | + |
| 113 | +## Coding Standards |
| 114 | + |
| 115 | +### General Guidelines |
| 116 | +- Follow Rust idioms and best practices |
| 117 | +- Use `anyhow::Result` for application errors, `thiserror` for library errors |
| 118 | +- Prefer `tracing` macros over `println!` for logging |
| 119 | +- Use structured logging with context fields |
| 120 | +- All public APIs should have documentation comments |
| 121 | + |
| 122 | +### Error Handling |
| 123 | +- Propagate errors with `?` operator where appropriate |
| 124 | +- Provide context with `.context()` or `.with_context()` |
| 125 | +- Use specific error types for recoverable errors |
| 126 | +- Fatal errors should be logged with `tracing::error!` before panicking |
| 127 | + |
| 128 | +### Testing |
| 129 | +- Unit tests go in `#[cfg(test)] mod tests` at end of file |
| 130 | +- Integration tests go in `tests/` directory |
| 131 | +- Use `#[tokio::test]` for async tests |
| 132 | +- Mock external dependencies (filesystem, network, LLM APIs) |
| 133 | + |
| 134 | +### Commit Conventions |
| 135 | +- Use conventional commit format: `type(scope): description` |
| 136 | +- Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore` |
| 137 | +- Keep commits atomic and focused |
| 138 | +- Reference issue numbers in commit messages |
| 139 | + |
| 140 | +## Security Considerations |
| 141 | + |
| 142 | +### Sandbox |
| 143 | +- Every shell command runs inside OS-level sandbox (Landlock on Linux, Seatbelt on macOS) |
| 144 | +- Sandbox denies access to `~/.ssh`, `~/.aws`, `~/.gnupg`, `~/.docker` |
| 145 | +- Network syscalls blocked by default |
| 146 | +- rlimits: 120s timeout, 1MB output cap, 50MB file size, 64 process limit |
| 147 | + |
| 148 | +### Protected Files |
| 149 | +The agent is blocked from writing to: |
| 150 | +- `LocalGPT.md` |
| 151 | +- `.localgpt_manifest.json` |
| 152 | +- `IDENTITY.md` |
| 153 | +- `localgpt.device.key` |
| 154 | +- `localgpt.audit.jsonl` |
| 155 | + |
| 156 | +### Prompt Injection Defenses |
| 157 | +- Strip known LLM control tokens from tool outputs |
| 158 | +- Detect injection phrases with regex scanning |
| 159 | +- Wrap external content in XML delimiters |
| 160 | +- All security events logged to append-only, hash-chained audit file |
| 161 | + |
| 162 | +## Configuration |
| 163 | + |
| 164 | +Default config location: `~/.localgpt/config.toml` (see `config.example.toml`) |
| 165 | + |
| 166 | +Key settings: |
| 167 | +- `agent.default_model` — Determines provider (default: `claude-cli/opus`) |
| 168 | +- `memory.workspace` — Workspace directory (default: `~/.localgpt/workspace`) |
| 169 | +- `memory.embedding_provider` — `"local"` (default), `"openai"`, or `"none"` |
| 170 | +- `server.port` — HTTP server port (default: 31327) |
| 171 | + |
| 172 | +Workspace path resolution: `LOCALGPT_WORKSPACE` env > `LOCALGPT_PROFILE` env > `memory.workspace` config > `~/.localgpt/workspace` |
| 173 | + |
| 174 | +## Common Tasks |
| 175 | + |
| 176 | +### Adding a New Tool |
| 177 | +1. Define tool in `crates/core/src/agent/tools/` |
| 178 | +2. Implement `Tool` trait with name, description, parameters, and execute |
| 179 | +3. Add to appropriate tool factory (safe vs dangerous) |
| 180 | +4. Add tests for tool execution and error handling |
| 181 | + |
| 182 | +### Adding a New LLM Provider |
| 183 | +1. Create new provider struct in `crates/core/src/agent/providers/` |
| 184 | +2. Implement `LLMProvider` trait |
| 185 | +3. Add provider to `create_provider()` match in `providers/mod.rs` |
| 186 | +4. Add config section to `config.example.toml` |
| 187 | +5. Update documentation and model routing logic |
| 188 | + |
| 189 | +### Adding a New Command |
| 190 | +1. Define command in `crates/core/src/commands.rs` |
| 191 | +2. Implement handler in CLI (`crates/cli/src/main.rs`) or server |
| 192 | +3. Add to help text and documentation |
| 193 | +4. Write integration test |
| 194 | + |
| 195 | +### Mobile Changes |
| 196 | +1. Make changes in `localgpt-core` with `default-features = false` |
| 197 | +2. Verify no platform-specific deps: `cargo check -p localgpt-mobile --target aarch64-apple-ios` |
| 198 | +3. Rebuild mobile crate: `cargo build -p localgpt-mobile` |
| 199 | +4. Regenerate UniFFI bindings (Swift/Kotlin) |
| 200 | + |
| 201 | +## Validation Checklist |
| 202 | + |
| 203 | +Before submitting a PR: |
| 204 | + |
| 205 | +- [ ] `cargo fmt --check` passes |
| 206 | +- [ ] `cargo clippy --workspace` has no warnings |
| 207 | +- [ ] `cargo test --workspace` passes |
| 208 | +- [ ] If core changes: `cargo check -p localgpt-mobile --target aarch64-apple-ios` succeeds |
| 209 | +- [ ] Documentation updated (if public API changed) |
| 210 | +- [ ] CHANGELOG.md updated (if user-facing changes) |
| 211 | +- [ ] Security considerations reviewed (if touching tool execution, sandbox, or memory) |
| 212 | + |
| 213 | +## Documentation |
| 214 | + |
| 215 | +- **CLAUDE.md** — Detailed technical reference for Claude Code agent |
| 216 | +- **README.md** — User-facing project overview and quick start |
| 217 | +- **docs/architecture.md** — System architecture and design decisions |
| 218 | +- **docs/RFC-LocalGPT-Security-Policy.md** — Security policy specification |
| 219 | +- **docs/gen-audio.md** — Gen mode audio system documentation |
| 220 | +- **docs/web-search.md** — Web search provider setup guide |
| 221 | +- **config.example.toml** — Example configuration with all options |
| 222 | + |
| 223 | +## Resources |
| 224 | + |
| 225 | +- Repository: https://github.com/localgpt-app/localgpt |
| 226 | +- Website: https://localgpt.app |
| 227 | +- Discord: https://discord.gg/yMQ8tfxG |
| 228 | +- License: Apache-2.0 |
| 229 | + |
| 230 | +## Notes for AI Assistants |
| 231 | + |
| 232 | +When working on this codebase: |
| 233 | +1. Always run tests after making changes |
| 234 | +2. Check cross-compilation for mobile if you touch `localgpt-core` |
| 235 | +3. Respect the tool safety split — don't add dangerous tools to safe contexts |
| 236 | +4. Preserve thread safety invariants (Agent not Send+Sync) |
| 237 | +5. Don't break the mobile build by adding platform-specific deps to core |
| 238 | +6. Follow the existing code style and patterns |
| 239 | +7. Add appropriate logging and error context |
| 240 | +8. Consider security implications of changes to tools, sandbox, or memory system |
0 commit comments