KnoksPix is an AI-first creative workspace combining:
Demo: View the app in AI Studio
| Area | Highlights |
|---|---|
| Image Editing | Crop, filters, adjustment panel, object layer cards |
| AI Integration | Gemini API for generation (pluggable) |
| Local LLM Option | Optional Starcoder2 backend with SSE streaming, OpenAI-compatible endpoint |
| Performance | Vite + React + Code-splitting |
| Cross Platform | Web, Electron desktop builds, Android (Capacitor) |
| Tooling | Jest tests, GitHub Actions smoke & CI, PR preview deploys |
| Observability | Prometheus metrics, structured logging (backend) |
| Rate Limiting | SlowAPI sliding window on backend |
git clone https://github.com/knoksen/knoksPix.git
cd knoksPix
npm ci
echo "GEMINI_API_KEY=your_key" > .env.local
npm run dev
cp backend/.env.sample backend/.env
# Edit backend/.env as needed (MODEL_ID, tokens, mock mode etc.)
docker compose up --build
# Frontend (separate terminal)
npm run dev
Backend API docs: http://localhost:8000/docs
React + TypeScript + Vite. Core UI elements in components/. State is localized per panel keeping bundle size lean. Tests under tests/ use Jest + React Testing Library.
Build production bundle:
npm run build
Serve locally:
npm run preview
Located in backend/. Provides:
POST /v1/chat/completions – OpenAI-style (stream or non-stream)POST /v1/generate – Simple prompt generation (stream or non-stream)GET /metrics – Prometheus metricsGET /healthz – Liveness checkStreaming uses Server-Sent Events (SSE). Chat endpoint emits OpenAI-compatible chat.completion.chunk objects. Generation endpoint emits { "text": "..." } chunks then [DONE] sentinel.
Mock Mode (no model download): set USE_MOCK_GENERATION=1.
cd backend
python -m venv .venv && source .venv/bin/activate # Windows: .venv\\Scripts\\activate
pip install -r requirements.txt -r requirements-dev.txt
cp .env.sample .env # edit values
uvicorn main:app --reload --port 8000
| Variable | Purpose | Default |
|---|---|---|
MODEL_ID |
HF model id to load | bigcode/starcoder2-3b |
HF_TOKEN |
(Optional) auth for private models | empty |
STARCODER2_API_TOKEN |
Bearer token required by clients | changeme |
USE_MOCK_GENERATION |
Skip model load; return synthetic outputs | 0 |
MAX_NEW_TOKENS_LIMIT |
Hard upper bound user requests | 512 |
RATE_LIMIT |
slowapi rate expression | 100/minute |
LOG_LEVEL |
Logging threshold | INFO |
Chat endpoint (/v1/chat/completions, stream=true):
data: {"id":"...","object":"chat.completion.chunk","choices":[{"delta":{"content":"def"}}]}
data: {"id":"...","object":"chat.completion.chunk","choices":[{"delta":{"content":" add"}}]}
data: {"id":"...","object":"chat.completion.chunk","choices":[{"delta":{}}],"finish_reason":"stop"}
data: [DONE]
Generate endpoint (/v1/generate, stream=true):
data: {"text":"partial token"}
data: {"text":" more"}
data: [DONE]
Both endpoints send text/event-stream; charset=utf-8 and can be consumed with any SSE client. Non‑stream mode aggregates full text in a single JSON object.
Metric names (Prometheus):
http_requests_total / latency histograms (instrumentator defaults)Dashboards: Point Grafana at the Prometheus service (see docker-compose.yml).
--gpus=all (already hinted in compose).MAX_NEW_TOKENS_LIMIT to guard latency & memory.TextIteratorStreamer for finer token pacing (roadmap).Example (chat streaming):
curl -N \
-H "Authorization: Bearer $STARCODER2_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "bigcode/starcoder2-3b",
"messages": [{"role":"user","content":"Write a Python hello world"}],
"stream": true
}' \
http://localhost:8000/v1/chat/completions
Example (generate streaming):
curl -N \
-H "Authorization: Bearer $STARCODER2_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"prompt": "def add(a,b):\n return a+b",
"max_new_tokens": 64,
"stream": true
}' \
http://localhost:8000/v1/generate
from starcoder2_client import ChatClient
client = ChatClient(base_url="http://localhost:8000", token="changeme")
resp = client.chat([{ "role": "user", "content": "Write a Python function add(a,b)." }])
print(resp["choices"][0]["message"]["content"])
Simplified here. Full extended matrices, one‑click buttons, hosting comparisons, and hardening tips moved to docs/DEPLOYMENT.md.
Common quick paths:
| Scenario | Command / Action |
|---|---|
| Local frontend only | npm run dev |
| Local full stack (mock) | (cd backend && USE_MOCK_GENERATION=1 uvicorn main:app --port 8000) & npm run dev |
| Docker backend | docker compose up --build |
| GitHub Pages deploy | Auto on push to main |
| PR preview | Auto Surge URL comment |
See docs/DEPLOYMENT.md for buttons & providers.
Badges:
Frontend (.env.local):
GEMINI_API_KEY=your_key
VITE_API_BASE=http://localhost:8000
Backend (backend/.env): (see backend/.env.sample for full list)
MODEL_ID=bigcode/starcoder2-3b
STARCODER2_API_TOKEN=changeme
USE_MOCK_GENERATION=1
RATE_LIMIT=100/minute
MAX_NEW_TOKENS_LIMIT=512
LOG_LEVEL=INFO
Run UI tests:
npm test
Backend tests (mock mode):
pytest
flowchart LR
A[React/Vite Frontend] -->|Fetch / Chat| B((FastAPI Backend))
B -->|Generation| C[Starcoder2 Model]
B -->|Mock Mode| C2[(In-Memory Mock)]
B -->|/metrics| D[(Prometheus)]
D --> G[Grafana]
B -->|Structured Logs| L[(Log Aggregator)]
| Item | Status | Notes |
|---|---|---|
| README updated | ✅ | Current file |
| License present | ✅ | MIT license in repo |
| Env samples | ✅ | backend/.env.sample |
| CI smoke tests | ✅ | smoke.yml badge passing |
| PR preview pipeline | ✅ | Surge deployment configured |
| Backend health endpoint | ✅ | /healthz present |
| Metrics endpoint | ✅ | /metrics (Prometheus) |
| Rate limiting | ✅ | slowapi configured |
| Streaming verified | ✅ | SSE implemented both endpoints |
| Mock mode | ✅ | USE_MOCK_GENERATION=1 |
| Image assets | ⚠️ | Replace placeholder screenshots |
| Deployment buttons | ✅ | Added Netlify/Vercel/etc |
| Backend tests | ✅ | Mock mode tests present |
| Release workflow | ✅ | Tag push triggers Electron & dist build |
| Dependabot | ✅ | .github/dependabot.yml configured |
| CodeQL scan | ✅ | codeql.yml workflow added |
| SBOM generation | ✅ | sbom.yml workflow (CycloneDX) |
Prerequisites: Node.js 20 or higher
bash
git clone https://github.com/knoksen/knoksPix.git
cd knoksPix
bash
npm ci
.env.local file in the root directoryAdd your Gemini API key: GEMINI_API_KEY=your_api_key_here
Start the development server:
bash
npm run dev
bash
(cd backend && USE_MOCK_GENERATION=1 uvicorn main:app --port 8000)
bash
npm run dev
VITE_API_BASE=http://localhost:8000 in .env.local if calling backend.See Deployment Options for matrix. Production frontend is emitted to dist/.
MIT. See LICENSE.
git checkout -b feat/awesomegit commit -m 'feat: add awesome capability'git push origin feat/awesomeConventional commit prefixes (feat:, fix:, docs:) encouraged. Small, focused PRs merge faster.