Initial ForgeLM import
This commit is contained in:
commit
a392b9dc60
4296 files changed
+1212675
No files matched your search
@@ -0,0 +1,150 @@
|
||||
# Architecture
|
||||
|
||||
**Analysis Date:** 2026-03-28
|
||||
|
||||
## Pattern Overview
|
||||
|
||||
**Overall:** Local-first polyglot workspace with shared contracts and three user surfaces
|
||||
|
||||
**Key Characteristics:**
|
||||
- Keep API contracts in Rust shared types before exposing them to CLI and desktop consumers in `crates/api-contracts/src/lib.rs` and `crates/api-contracts/src/chat.rs`
|
||||
- Keep inference logic behind a single engine/session boundary in `crates/inference-core/src/engine.rs` and `crates/inference-core/src/session.rs`
|
||||
- Keep the desktop app as an orchestration shell that manages process lifecycle, model discovery, and chat persistence in `tauri-app/src/App.tsx` and `tauri-app/src-tauri/src/runtime/mod.rs`
|
||||
|
||||
## Layers
|
||||
|
||||
**Inference Core:**
|
||||
- Purpose: Load GGUF models, own llama context/model pointers, and generate tokens
|
||||
- Location: `crates/inference-core/src/`
|
||||
- Contains: `EngineConfig`, `InferenceEngine`, runtime profiles, sampler config, generation session
|
||||
- Depends on: `crates/llama-sys`, Rust stdlib, `anyhow`, `tracing`
|
||||
- Used by: `crates/inference-server/src/main.rs`
|
||||
|
||||
**HTTP Compatibility Layer:**
|
||||
- Purpose: Adapt OpenAI-like chat/model requests to the local engine
|
||||
- Location: `crates/inference-server/src/`
|
||||
- Contains: env-driven `ServerConfig`, auth/CORS rules, prompt preparation, routing, SSE streaming
|
||||
- Depends on: `crates/inference-core`, `crates/api-contracts`, `crates/metrics`
|
||||
- Used by: local HTTP consumers, CLI, desktop frontend
|
||||
|
||||
**Shared API Contract Layer:**
|
||||
- Purpose: Keep request/response models and error shapes consistent
|
||||
- Location: `crates/api-contracts/src/`
|
||||
- Contains: chat completion structs, model list, health payload, error payloads
|
||||
- Depends on: `serde`, `serde_json`
|
||||
- Used by: server code directly; mirrored conceptually by frontend/CLI callers
|
||||
|
||||
**CLI Surface Layer:**
|
||||
- Purpose: Expose operator workflows and a future control plane over HTTP/local actions
|
||||
- Location: `crates/localllm-cli/src/main.rs`
|
||||
- Contains: command parsing, planning, preview rendering, selective live transport
|
||||
- Depends on: `clap`, `ureq`, `serde_json`
|
||||
- Used by: developers/operators
|
||||
|
||||
**Desktop Backend Layer:**
|
||||
- Purpose: Persist runtime config, discover model files, detect GPU, spawn/stop local API
|
||||
- Location: `tauri-app/src-tauri/src/`
|
||||
- Contains: Tauri commands, runtime state machine, health probing, file dialog integration
|
||||
- Depends on: Tauri runtime, native process and filesystem APIs
|
||||
- Used by: `tauri-app/src/features/runtime/api.ts`
|
||||
|
||||
**Desktop Frontend Layer:**
|
||||
- Purpose: Present runtime controls, model selection, and persistent chat UI
|
||||
- Location: `tauri-app/src/`
|
||||
- Contains: shell layout, runtime manager hooks, chat view, sidebar, markdown rendering, local DB wrapper
|
||||
- Depends on: React, fetch, Tauri invoke bridge, browser storage/CDN-loaded sql.js
|
||||
- Used by: end users of the desktop app
|
||||
|
||||
## Data Flow
|
||||
|
||||
**Local chat request flow:**
|
||||
|
||||
1. `tauri-app/src/components/ChatView.tsx` builds message history from local sql.js storage and posts to `${server}/v1/chat/completions`
|
||||
2. `crates/inference-server/src/routes.rs` validates auth/model/mode, prepares the prompt through `crates/inference-server/src/compat.rs`, and locks the shared `InferenceEngine`
|
||||
3. `crates/inference-core/src/session.rs` tokenizes, pre-fills, samples, and returns streamed or buffered content back through Axum SSE/JSON
|
||||
4. `tauri-app/src/components/ChatView.tsx` parses `<think>...</think>`, stores assistant content plus usage metrics in `tauri-app/src/lib/db.ts`, and updates the UI
|
||||
|
||||
**Runtime management flow:**
|
||||
|
||||
1. `tauri-app/src/features/runtime/useRuntimeManager.ts` bootstraps a `RuntimeSnapshot` from `tauri-app/src/features/runtime/api.ts`
|
||||
2. `tauri-app/src-tauri/src/lib.rs` routes invoke calls into `tauri-app/src-tauri/src/runtime/mod.rs`
|
||||
3. `tauri-app/src-tauri/src/runtime/process.rs` finds and spawns the `localllm` binary, then `tauri-app/src-tauri/src/runtime/health.rs` probes `/health`
|
||||
4. `tauri-app/src/features/runtime/components/RuntimeStatusCard.tsx` and `tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx` render and mutate the runtime state
|
||||
|
||||
**State Management:**
|
||||
- Backend API state is a single shared `AppState` with `Arc<Mutex<InferenceEngine>>` in `crates/inference-server/src/routes.rs`
|
||||
- Desktop runtime state is a single `RuntimeState(pub Mutex<RuntimeInner>)` in `tauri-app/src-tauri/src/runtime/state.rs`
|
||||
- Frontend state is local React hook state; no global store is used in `tauri-app/src/App.tsx`, `tauri-app/src/hooks/useModels.ts`, and `tauri-app/src/features/runtime/useRuntimeManager.ts`
|
||||
- Chat persistence is local-first and browser-backed via `localStorage` + sql.js in `tauri-app/src/lib/db.ts`
|
||||
|
||||
## Key Abstractions
|
||||
|
||||
**InferenceEngine:**
|
||||
- Purpose: Own one loaded model and one llama context
|
||||
- Examples: `crates/inference-core/src/engine.rs`, `crates/inference-core/src/session.rs`
|
||||
- Pattern: Single-owner, RAII-managed native resource wrapper with explicit non-concurrent use
|
||||
|
||||
**ServerConfig / ModelCatalog:**
|
||||
- Purpose: Centralize runtime auth, prompt, CORS, and alias rules
|
||||
- Examples: `crates/inference-server/src/compat.rs`
|
||||
- Pattern: Env-derived compatibility adapter layered in front of the engine
|
||||
|
||||
**RuntimeSnapshot:**
|
||||
- Purpose: Serialize the desktop runtime state into a frontend-safe shape
|
||||
- Examples: `tauri-app/src/features/runtime/types.ts`, `tauri-app/src-tauri/src/runtime/state.rs`
|
||||
- Pattern: Backend source of truth mirrored into a polling frontend hook
|
||||
|
||||
**DB wrapper:**
|
||||
- Purpose: Hide sql.js statement handling and persistence details behind a tiny query/run API
|
||||
- Examples: `tauri-app/src/lib/db.ts`
|
||||
- Pattern: Thin synchronous local repository over browser storage
|
||||
|
||||
## Entry Points
|
||||
|
||||
**HTTP API binary:**
|
||||
- Location: `crates/inference-server/src/main.rs`
|
||||
- Triggers: `cargo run -p inference-server` or spawned local desktop runtime
|
||||
- Responsibilities: read env, load/warm engine, build router, bind network listener
|
||||
|
||||
**CLI binary:**
|
||||
- Location: `crates/localllm-cli/src/main.rs`
|
||||
- Triggers: `cargo run -p localllm-cli -- ...`
|
||||
- Responsibilities: parse commands, build execution plans, optionally perform live HTTP requests
|
||||
|
||||
**Desktop frontend:**
|
||||
- Location: `tauri-app/src/main.tsx` and `tauri-app/src/App.tsx`
|
||||
- Triggers: Vite dev server or Tauri desktop app startup
|
||||
- Responsibilities: render app shell, bootstrap DB/runtime hooks, connect sidebar and chat surface
|
||||
|
||||
**Desktop backend:**
|
||||
- Location: `tauri-app/src-tauri/src/lib.rs`
|
||||
- Triggers: Tauri app startup and frontend `invoke()` calls
|
||||
- Responsibilities: expose commands, manage runtime state, wire OS dialogs/plugins
|
||||
|
||||
## Error Handling
|
||||
|
||||
**Strategy:** Convert most backend failures into typed user-facing snapshots/responses rather than panic paths
|
||||
|
||||
**Patterns:**
|
||||
- API uses `ApiError` + `ErrorResponse` with HTTP status mapping in `crates/inference-server/src/routes.rs`
|
||||
- Desktop runtime stores recoverable errors in `last_error` on `RuntimeSnapshot` in `tauri-app/src-tauri/src/runtime/state.rs`
|
||||
- Frontend fetch and invoke failures typically degrade to fallback state or inline assistant error messages in `tauri-app/src/components/ChatView.tsx` and `tauri-app/src/features/runtime/api.ts`
|
||||
|
||||
## Cross-Cutting Concerns
|
||||
|
||||
**Logging:** `tracing` on Rust services in `crates/inference-server/src/main.rs`; frontend logging is minimal and mostly absent
|
||||
**Validation:** request and mode validation lives in `crates/inference-server/src/compat.rs`; runtime form validation is mostly helper-based in `tauri-app/src/features/runtime/runtime-settings-form.ts`
|
||||
**Authentication:** optional API-key auth is enforced in `crates/inference-server/src/compat.rs`; desktop frontend forwards the configured API key from runtime config in `tauri-app/src/features/runtime/api.ts`
|
||||
|
||||
## Boundaries
|
||||
|
||||
**App boundaries:**
|
||||
- `crates/inference-core/` should stay inference-only and not absorb HTTP/UI concerns
|
||||
- `crates/inference-server/` should stay the public backend boundary and not own chat persistence or desktop state
|
||||
- `crates/localllm-cli/` should stay an operator/client surface and not become the runtime itself
|
||||
- `tauri-app/src-tauri/` should own process/config/filesystem concerns for desktop only
|
||||
- `tauri-app/src/` should stay a consumer/orchestrator over backend contracts and local chat persistence
|
||||
|
||||
---
|
||||
|
||||
*Architecture analysis: 2026-03-28*
|
||||
@@ -0,0 +1,132 @@
|
||||
# Codebase Concerns
|
||||
|
||||
**Analysis Date:** 2026-03-28
|
||||
|
||||
## Tech Debt
|
||||
|
||||
**CLI surface vs real implementation:**
|
||||
- Issue: `crates/localllm-cli/src/main.rs` exposes a broad command tree, but many branches collapse to summary-only behavior instead of real actions
|
||||
- Files: `crates/localllm-cli/src/main.rs`, `docs/cli/overview.md`
|
||||
- Impact: product expectations exceed actual operator capability; docs and UX need constant caveats
|
||||
- Fix approach: split stable commands from roadmap commands, or implement local/config/model actions behind dedicated modules and integration tests
|
||||
|
||||
**Monolithic files in core surfaces:**
|
||||
- Issue: major logic is concentrated in very large files such as `crates/inference-server/src/routes.rs`, `crates/inference-server/src/compat.rs`, `crates/localllm-cli/src/main.rs`, `tauri-app/src/components/ChatView.tsx`, and `tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx`
|
||||
- Files: `crates/inference-server/src/routes.rs`, `crates/inference-server/src/compat.rs`, `crates/localllm-cli/src/main.rs`, `tauri-app/src/components/ChatView.tsx`, `tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx`
|
||||
- Impact: high change risk, harder reviewability, and low reuse of logic across features
|
||||
- Fix approach: extract transport, prompt-building, persistence, and UI section components into smaller feature modules with focused tests
|
||||
|
||||
**Frontend fallback state diverges from desktop source of truth:**
|
||||
- Issue: `tauri-app/src/features/runtime/api.ts` silently falls back to `localStorage` snapshots whenever Tauri invoke fails
|
||||
- Files: `tauri-app/src/features/runtime/api.ts`, `tauri-app/src/features/runtime/runtime-utils.ts`
|
||||
- Impact: browser preview works, but runtime state can drift from the real desktop backend and mask integration failures
|
||||
- Fix approach: make fallback mode explicit in UI and separate browser-demo mode from real desktop mode
|
||||
|
||||
## Known Bugs
|
||||
|
||||
**Local runtime binary name mismatch risk:**
|
||||
- Symptoms: desktop runtime start can fail even when the backend was built, because the Tauri helper looks for `localllm` while the error message tells users to build `inference-server`
|
||||
- Files: `tauri-app/src-tauri/src/runtime/process.rs`, `crates/inference-server/Cargo.toml`
|
||||
- Trigger: building the wrong cargo target or expecting package name and binary name to match
|
||||
- Workaround: build the binary defined in `crates/inference-server/Cargo.toml:8` and ensure `target/release/localllm(.exe)` exists
|
||||
|
||||
**Streaming parser depends on simple line splitting:**
|
||||
- Symptoms: malformed SSE framing or larger edge-case chunks can be ignored silently during streaming
|
||||
- Files: `tauri-app/src/components/ChatView.tsx`, `crates/inference-server/src/routes.rs`
|
||||
- Trigger: partial `data:` framing, unexpected event fields, or non-content deltas
|
||||
- Workaround: disable streaming in the UI when debugging transport issues
|
||||
|
||||
## Security Considerations
|
||||
|
||||
**Remote API keys stored in plain frontend/backend config:**
|
||||
- Risk: remote API keys are stored in desktop runtime config JSON and also surfaced into frontend state
|
||||
- Files: `tauri-app/src-tauri/src/runtime/config.rs`, `tauri-app/src/features/runtime/types.ts`, `tauri-app/src/features/runtime/api.ts`
|
||||
- Current mitigation: password input masks display in `tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx:281`
|
||||
- Recommendations: move secrets to OS keychain/credential store and store only references in app config
|
||||
|
||||
**External CDN dependencies inside desktop app:**
|
||||
- Risk: chat persistence and syntax highlighting depend on runtime-loaded third-party scripts from jsDelivr
|
||||
- Files: `tauri-app/src/lib/db.ts`, `tauri-app/src/lib/markdown.ts`
|
||||
- Current mitigation: markdown output is sanitized with DOMPurify in `tauri-app/src/lib/markdown.ts:68`
|
||||
- Recommendations: vendor `sql.js` and `highlight.js` assets into the app bundle and pin integrity-checked local assets
|
||||
|
||||
## Performance Bottlenecks
|
||||
|
||||
**Single-engine serialized generation:**
|
||||
- Problem: the API holds one `Arc<Mutex<InferenceEngine>>` for all requests
|
||||
- Files: `crates/inference-server/src/routes.rs:31`, `crates/inference-server/src/routes.rs:159`, `crates/inference-server/src/routes.rs:364`
|
||||
- Cause: engine/context are single-owner and not safely concurrent in `crates/inference-core/src/engine.rs`
|
||||
- Improvement path: add queued scheduling or a context/session pool before scaling beyond one active generation
|
||||
|
||||
**Polling-heavy desktop runtime updates:**
|
||||
- Problem: frontend polls runtime snapshot every 3 seconds and models every 30 seconds
|
||||
- Files: `tauri-app/src/features/runtime/useRuntimeManager.ts:33`, `tauri-app/src/hooks/useModels.ts:38`
|
||||
- Cause: no push/event channel between Tauri backend and React frontend
|
||||
- Improvement path: add Tauri event emission or a subscription layer for runtime state and model refresh triggers
|
||||
|
||||
## Fragile Areas
|
||||
|
||||
**Chat request + persistence loop:**
|
||||
- Files: `tauri-app/src/components/ChatView.tsx`, `tauri-app/src/lib/db.ts`, `tauri-app/src/lib/chat.ts`
|
||||
- Why fragile: request orchestration, DB writes, streaming parsing, `<think>` parsing, title updates, and optimistic UI all live in one component
|
||||
- Safe modification: extract persistence, transport, and stream parsing into dedicated hooks/utilities before adding more chat features
|
||||
- Test coverage: no direct tests detected for `tauri-app/src/components/ChatView.tsx`
|
||||
|
||||
**Compatibility layer prompt/tool-call handling:**
|
||||
- Files: `crates/inference-server/src/compat.rs`, `crates/api-contracts/src/chat.rs`
|
||||
- Why fragile: one file owns auth, aliases, prompt shaping, template choice, response finalization, and tool-call compatibility behavior
|
||||
- Safe modification: add focused unit tests around each compatibility branch before extending OpenAI-style contract coverage
|
||||
- Test coverage: partial for contracts in `crates/api-contracts/src/chat.rs`; compatibility file-specific tests are not visible in the analyzed slice
|
||||
|
||||
## Scaling Limits
|
||||
|
||||
**Backend request concurrency:**
|
||||
- Current capacity: effectively one active generation at a time per server process because one engine/context is mutex-locked
|
||||
- Limit: parallel requests queue behind one model context and long generations block others
|
||||
- Scaling path: multi-context pool, worker queue, or multi-process model serving
|
||||
|
||||
**Desktop chat storage:**
|
||||
- Current capacity: local sql.js database exported into one `localStorage` key in `tauri-app/src/lib/db.ts:57`
|
||||
- Limit: browser storage size, serialization overhead, and startup cost grow with chat history
|
||||
- Scaling path: move persistence into native Tauri storage or SQLite through the Rust backend
|
||||
|
||||
## Dependencies at Risk
|
||||
|
||||
**CDN-hosted `sql.js` and `highlight.js`:**
|
||||
- Risk: runtime availability and supply-chain reliability depend on external network/CDN access
|
||||
- Impact: chat history DB boot or syntax highlighting can fail in offline/locked-down environments
|
||||
- Migration plan: bundle assets locally or replace with native persistence plus bundled syntax assets
|
||||
|
||||
## Missing Critical Features
|
||||
|
||||
**No push observability for runtime lifecycle:**
|
||||
- Problem: runtime state changes and server logs are not streamed into the UI
|
||||
- Blocks: rich diagnostics, trustworthy startup progress, and smoother local-runtime UX
|
||||
|
||||
**No model library management workflow:**
|
||||
- Problem: model scanning/import exists, but there is no deeper catalog metadata, download progress, space management, or activation history
|
||||
- Blocks: desktop app becoming a full local-model manager rather than a thin launcher
|
||||
|
||||
## Test Coverage Gaps
|
||||
|
||||
**Chat UI and persistence path:**
|
||||
- What's not tested: chat send/stream/error/edit/delete/memory/persistence flows
|
||||
- Files: `tauri-app/src/components/ChatView.tsx`, `tauri-app/src/components/MessageBubble.tsx`, `tauri-app/src/lib/db.ts`
|
||||
- Risk: regressions in the main user workflow can ship unnoticed
|
||||
- Priority: High
|
||||
|
||||
**CLI live behavior:**
|
||||
- What's not tested: end-to-end live HTTP execution and local action implementations behind `execute_live_command`
|
||||
- Files: `crates/localllm-cli/src/main.rs`
|
||||
- Risk: parser tests pass while actual command behavior remains incomplete or broken
|
||||
- Priority: High
|
||||
|
||||
**Server route integration:**
|
||||
- What's not tested: full Axum route behavior for auth, streaming, aliases, and error payloads against a running router
|
||||
- Files: `crates/inference-server/src/routes.rs`, `crates/inference-server/src/compat.rs`
|
||||
- Risk: contract drift between docs and runtime behavior
|
||||
- Priority: High
|
||||
|
||||
---
|
||||
|
||||
*Concerns audit: 2026-03-28*
|
||||
@@ -0,0 +1,86 @@
|
||||
# Technology Stack
|
||||
|
||||
**Analysis Date:** 2026-03-28
|
||||
|
||||
## Languages
|
||||
|
||||
**Primary:**
|
||||
- Rust 2021 - core backend, inference runtime, CLI, shared contracts, metrics, and Tauri desktop backend in `Cargo.toml`, `crates/inference-server/src/main.rs`, `crates/inference-core/src/engine.rs`, `crates/localllm-cli/src/main.rs`, and `tauri-app/src-tauri/src/lib.rs`
|
||||
- TypeScript 5.5 - desktop frontend, runtime manager UI, chat UI, and tests in `tauri-app/package.json`, `tauri-app/src/App.tsx`, and `tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx`
|
||||
|
||||
**Secondary:**
|
||||
- CSS - hand-authored styling with app-wide tokens and feature CSS modules in `tauri-app/src/index.css`, `tauri-app/src/components/Sidebar.css`, and `tauri-app/src/components/ChatView.css`
|
||||
- Markdown - product and architecture docs in `README.MD`, `docs/api/overview.md`, and `docs/app/overview.md`
|
||||
- Python - benchmark and experiment scripts in `experiments/bench_chat_latency.py`, `experiments/bench_cli_surface.py`, and related files under `experiments/`
|
||||
|
||||
## Runtime
|
||||
|
||||
**Environment:**
|
||||
- Rust toolchain targeting native desktop/server binaries; no workspace-level rust-toolchain file detected
|
||||
- Node.js runtime for Vite/Tauri frontend workflows in `tauri-app/package.json`
|
||||
|
||||
**Package Manager:**
|
||||
- Cargo for Rust workspace dependencies and binaries in `Cargo.toml`
|
||||
- npm is the documented frontend package manager via `README.MD:47`; lockfiles for npm and pnpm are both present in `tauri-app/package-lock.json` and `tauri-app/pnpm-lock.yaml`
|
||||
- Lockfile: present for Rust and frontend in `Cargo.lock` and `tauri-app/package-lock.json`
|
||||
|
||||
## Frameworks
|
||||
|
||||
**Core:**
|
||||
- Axum 0.8 - local HTTP API in `Cargo.toml` and `crates/inference-server/src/routes.rs`
|
||||
- React 18 - desktop UI shell and chat surface in `tauri-app/package.json` and `tauri-app/src/App.tsx`
|
||||
- Tauri 2 - desktop shell, local process control, file dialogs, and frontend-to-Rust command bridge in `tauri-app/src-tauri/Cargo.toml` and `tauri-app/src-tauri/src/lib.rs`
|
||||
- llama.cpp FFI via custom `llama-sys` - model loading and token generation in `crates/inference-core/src/engine.rs` and `crates/inference-core/src/session.rs`
|
||||
|
||||
**Testing:**
|
||||
- Vitest 4 - frontend/unit/component tests in `tauri-app/package.json` and `tauri-app/src/features/runtime/components/RuntimeSurface.test.tsx`
|
||||
- Rust built-in test harness - backend/unit tests co-located in files such as `crates/api-contracts/src/chat.rs` and `tauri-app/src-tauri/src/runtime/state.rs`
|
||||
|
||||
**Build/Dev:**
|
||||
- Vite 5 - frontend dev/build tool in `tauri-app/vite.config.ts`
|
||||
- TypeScript compiler - typecheck step in `tauri-app/package.json:9`
|
||||
- Tauri CLI 2 - desktop dev/build entry in `tauri-app/package.json:11`
|
||||
|
||||
## Key Dependencies
|
||||
|
||||
**Critical:**
|
||||
- `tokio` - async runtime for API server in `Cargo.toml` and `crates/inference-server/src/main.rs`
|
||||
- `tower-http` - CORS and trace middleware in `Cargo.toml` and `crates/inference-server/src/compat.rs`
|
||||
- `serde` / `serde_json` - shared request/response contracts across API, CLI, and Tauri in `crates/api-contracts/src/chat.rs` and `tauri-app/src-tauri/src/runtime/config.rs`
|
||||
- `clap` - CLI command surface in `crates/localllm-cli/src/main.rs`
|
||||
- `ureq` - synchronous HTTP transport for CLI live execution in `crates/localllm-cli/src/main.rs:404`
|
||||
- `marked`, `dompurify`, `highlight.js` - markdown rendering/sanitization/code highlighting in `tauri-app/src/lib/markdown.ts`
|
||||
- `@tauri-apps/api` and `@tauri-apps/plugin-shell` - frontend/Tauri bridge in `tauri-app/package.json` and `tauri-app/src/features/runtime/api.ts`
|
||||
|
||||
**Infrastructure:**
|
||||
- `uuid` - response IDs for chat completions in `crates/inference-server/src/routes.rs:126`
|
||||
- `tracing` and `tracing-subscriber` - backend logging and startup diagnostics in `crates/inference-server/src/main.rs`
|
||||
- `async-stream` - SSE streaming implementation in `crates/inference-server/Cargo.toml` and `crates/inference-server/src/routes.rs:137`
|
||||
|
||||
## Configuration
|
||||
|
||||
**Environment:**
|
||||
- Backend runtime is environment-driven via `LOCALLLM_MODEL`, `LOCALLLM_PROFILE`, `LOCALLLM_ADDR`, `LOCALLLM_GPU_LAYERS`, `LOCALLLM_CTX`, `LOCALLLM_API_KEY`, `LOCALLLM_CORS_ORIGINS`, `LOCALLLM_AUTH_HEADER`, `LOCALLLM_AUTH_SCHEME`, `LOCALLLM_SYSTEM_PROMPT`, and `LOCALLLM_MODEL_ALIASES` in `crates/inference-server/src/main.rs` and `crates/inference-server/src/compat.rs`
|
||||
- Desktop runtime config is persisted as JSON in the app data directory through `tauri-app/src-tauri/src/runtime/config.rs`
|
||||
- Frontend fallback runtime snapshot is persisted in `localStorage` through `tauri-app/src/features/runtime/api.ts`
|
||||
|
||||
**Build:**
|
||||
- Rust workspace build in `Cargo.toml`
|
||||
- Tauri desktop build in `tauri-app/src-tauri/Cargo.toml` and `tauri-app/src-tauri/tauri.conf.json`
|
||||
- Frontend dev server/build in `tauri-app/vite.config.ts` and `tauri-app/package.json`
|
||||
|
||||
## Platform Requirements
|
||||
|
||||
**Development:**
|
||||
- Rust + Cargo for backend and desktop backend in `README.MD:56`
|
||||
- Node.js/npm for the Tauri frontend in `README.MD:57`
|
||||
- Local `.gguf` model for real inference in `README.MD:58`
|
||||
- Optional NVIDIA GPU for accelerated local runtime; CPU fallback profile exists in `README.MD:59` and `crates/inference-core/src/profile.rs`
|
||||
|
||||
**Production:**
|
||||
- Local-first desktop deployment via Tauri app in `tauri-app/`
|
||||
- Local HTTP API deployment as standalone binary `localllm` in `crates/inference-server/Cargo.toml:8`
|
||||
|
||||
---
|
||||
|
||||
*Stack analysis: 2026-03-28*
|
||||
@@ -0,0 +1,154 @@
|
||||
# Codebase Structure
|
||||
|
||||
**Analysis Date:** 2026-03-28
|
||||
|
||||
## Directory Layout
|
||||
|
||||
```text
|
||||
ForgeLM/
|
||||
├── crates/ # Rust workspace crates for backend, engine, CLI, contracts, metrics, FFI
|
||||
├── tauri-app/ # Desktop application with React frontend and Tauri Rust backend
|
||||
├── docs/ # Product, API, CLI, and developer documentation
|
||||
├── experiments/ # Benchmarks and exploratory scripts
|
||||
├── models/ # Local model assets and model notes
|
||||
├── scripts/ # Build helpers
|
||||
├── target/ # Cargo build artifacts
|
||||
└── ui/ # Standalone HTML chat prototype
|
||||
```
|
||||
|
||||
## Directory Purposes
|
||||
|
||||
**`crates/api-contracts/`:**
|
||||
- Purpose: Shared API payload definitions
|
||||
- Contains: request/response/error model types
|
||||
- Key files: `crates/api-contracts/src/chat.rs`, `crates/api-contracts/src/models.rs`, `crates/api-contracts/src/health.rs`
|
||||
|
||||
**`crates/inference-core/`:**
|
||||
- Purpose: Inference engine and generation pipeline
|
||||
- Contains: engine/session/profile/sampler code
|
||||
- Key files: `crates/inference-core/src/engine.rs`, `crates/inference-core/src/session.rs`, `crates/inference-core/src/profile.rs`
|
||||
|
||||
**`crates/inference-server/`:**
|
||||
- Purpose: Public local HTTP API
|
||||
- Contains: Axum bootstrap, routes, compatibility logic
|
||||
- Key files: `crates/inference-server/src/main.rs`, `crates/inference-server/src/routes.rs`, `crates/inference-server/src/compat.rs`
|
||||
|
||||
**`crates/localllm-cli/`:**
|
||||
- Purpose: CLI control surface
|
||||
- Contains: parser, execution preview, live transport, tests in one file
|
||||
- Key files: `crates/localllm-cli/src/main.rs`
|
||||
|
||||
**`tauri-app/src/`:**
|
||||
- Purpose: Desktop frontend
|
||||
- Contains: app shell, components, feature hooks, local persistence, CSS
|
||||
- Key files: `tauri-app/src/App.tsx`, `tauri-app/src/components/ChatView.tsx`, `tauri-app/src/features/runtime/useRuntimeManager.ts`
|
||||
|
||||
**`tauri-app/src-tauri/src/`:**
|
||||
- Purpose: Desktop backend bridge
|
||||
- Contains: runtime lifecycle, GPU/model file commands, Tauri entry points
|
||||
- Key files: `tauri-app/src-tauri/src/lib.rs`, `tauri-app/src-tauri/src/runtime/mod.rs`, `tauri-app/src-tauri/src/model_files.rs`
|
||||
|
||||
## Key File Locations
|
||||
|
||||
**Entry Points:**
|
||||
- `crates/inference-server/src/main.rs`: local HTTP API binary
|
||||
- `crates/localllm-cli/src/main.rs`: CLI binary
|
||||
- `tauri-app/src/main.tsx`: React bootstrap
|
||||
- `tauri-app/src-tauri/src/main.rs`: Tauri desktop bootstrap
|
||||
|
||||
**Configuration:**
|
||||
- `Cargo.toml`: Rust workspace members and shared dependencies
|
||||
- `tauri-app/package.json`: frontend scripts and npm dependencies
|
||||
- `tauri-app/vite.config.ts`: frontend dev/build config
|
||||
- `tauri-app/src-tauri/tauri.conf.json`: desktop packaging/window config
|
||||
|
||||
**Core Logic:**
|
||||
- `crates/inference-core/src/engine.rs`: GGUF load/warmup/context management
|
||||
- `crates/inference-server/src/routes.rs`: endpoint behavior and streaming
|
||||
- `tauri-app/src/components/ChatView.tsx`: chat request/stream/persistence loop
|
||||
- `tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx`: runtime control plane UI
|
||||
|
||||
**Testing:**
|
||||
- `tauri-app/src/features/runtime/components/RuntimeSurface.test.tsx`: runtime UI integration-style tests
|
||||
- `tauri-app/src/features/runtime/runtime-settings-form.test.ts`: form helper tests
|
||||
- `tauri-app/src/hooks/model-selection.test.ts`: model selection helper tests
|
||||
- Rust tests are co-located inside source files such as `crates/api-contracts/src/chat.rs` and `tauri-app/src-tauri/src/runtime/health.rs`
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
**Files:**
|
||||
- Rust uses snake_case modules like `crates/inference-server/src/routes.rs`
|
||||
- Frontend React components use PascalCase files like `tauri-app/src/components/Sidebar.tsx`
|
||||
- Frontend hooks/utilities use camelCase or kebab-lite names like `tauri-app/src/hooks/useModels.ts` and `tauri-app/src/features/runtime/runtime-settings-form.ts`
|
||||
|
||||
**Directories:**
|
||||
- Feature grouping is shallow and domain-oriented: `tauri-app/src/components/`, `tauri-app/src/features/runtime/`, `tauri-app/src/hooks/`, `tauri-app/src/lib/`
|
||||
|
||||
## Where to Add New Code
|
||||
|
||||
**New backend API feature:**
|
||||
- HTTP route/handler: `crates/inference-server/src/routes.rs`
|
||||
- Request validation/prompt compatibility: `crates/inference-server/src/compat.rs`
|
||||
- Shared payload type: `crates/api-contracts/src/`
|
||||
- Engine capability: `crates/inference-core/src/`
|
||||
|
||||
**New desktop runtime feature:**
|
||||
- Frontend runtime UI or hook: `tauri-app/src/features/runtime/`
|
||||
- New Tauri command/runtime backend support: `tauri-app/src-tauri/src/` or `tauri-app/src-tauri/src/runtime/`
|
||||
- Shared runtime type mirrored to frontend: `tauri-app/src/features/runtime/types.ts`
|
||||
|
||||
**New chat/UI feature:**
|
||||
- Chat behavior: `tauri-app/src/components/ChatView.tsx`
|
||||
- Message rendering: `tauri-app/src/components/MessageBubble.tsx`
|
||||
- Shared browser persistence: `tauri-app/src/lib/db.ts` or `tauri-app/src/lib/chat.ts`
|
||||
- Styling: colocated CSS file in `tauri-app/src/components/` or `tauri-app/src/features/runtime/components/`
|
||||
|
||||
**Utilities:**
|
||||
- Frontend shared helpers: `tauri-app/src/lib/` or feature-local helper file under `tauri-app/src/features/runtime/`
|
||||
- Rust cross-cutting helpers: keep crate-local unless multiple crates need them; if shared at API boundary, prefer `crates/api-contracts/`
|
||||
|
||||
## Frontend / Design System Structure
|
||||
|
||||
**Styling model:**
|
||||
- Use CSS custom properties from `tauri-app/src/index.css` as the de facto design token layer
|
||||
- Keep component styling in per-component CSS files such as `tauri-app/src/components/Sidebar.css` and `tauri-app/src/components/ChatView.css`
|
||||
- Reuse the same status colors, radius tokens, and surface variables instead of introducing ad hoc values
|
||||
|
||||
**Component organization:**
|
||||
- Layout shell: `tauri-app/src/App.tsx`
|
||||
- Global navigation and runtime entry: `tauri-app/src/components/Sidebar.tsx`
|
||||
- Core chat surface: `tauri-app/src/components/ChatView.tsx`
|
||||
- Atomic-ish content node: `tauri-app/src/components/MessageBubble.tsx`
|
||||
- Runtime feature subdomain: `tauri-app/src/features/runtime/components/`
|
||||
|
||||
**State boundaries:**
|
||||
- Runtime state lives in `tauri-app/src/features/runtime/useRuntimeManager.ts`
|
||||
- Models state lives in `tauri-app/src/hooks/useModels.ts`
|
||||
- Local DB readiness lives in `tauri-app/src/hooks/useDB.ts`
|
||||
- Chat screen owns message and compose state locally in `tauri-app/src/components/ChatView.tsx`
|
||||
|
||||
## Special Directories
|
||||
|
||||
**`target/`:**
|
||||
- Purpose: Cargo build artifacts and copied runtime DLLs
|
||||
- Generated: Yes
|
||||
- Committed: No
|
||||
|
||||
**`models/`:**
|
||||
- Purpose: local GGUF assets and notes
|
||||
- Generated: No
|
||||
- Committed: Partially; README is committed, model binaries may be local-only depending on workflow
|
||||
|
||||
**`experiments/`:**
|
||||
- Purpose: benchmarks, profiling, and exploratory performance work
|
||||
- Generated: Mixed
|
||||
- Committed: Yes
|
||||
|
||||
**`ui/`:**
|
||||
- Purpose: standalone browser chat prototype separate from the Tauri frontend
|
||||
- Generated: No
|
||||
- Committed: Yes
|
||||
|
||||
---
|
||||
|
||||
*Structure analysis: 2026-03-28*
|
||||
Reference in new issue
Block a user