diff --git a/.env.example b/.env.example index e2fb145..17932c3 100644 --- a/.env.example +++ b/.env.example @@ -55,5 +55,5 @@ LLAMA_EXPOSE_PORT=8081 OLLAMA_EXPOSE_PORT=11434 # ── Image generation (ComfyUI on worker) ───────────────────── -CAIC_COMFYUI_BASE=http://192.168.50.115:8188 +CAIC_COMFYUI_BASE=http://localhost:8188 CAIC_COMFYUI_TIMEOUT=120 diff --git a/TASKS.md b/TASKS.md index f9ce3e5..6c7f42b 100644 --- a/TASKS.md +++ b/TASKS.md @@ -6,20 +6,20 @@ Previous task history archived at `docs/archive/TASKS-pre-1.0.md`. ## TASK 1 — Image Generation Service (corsair) -**Goal:** Add image generation as a cluster capability. corsair (RTX 5070 Ti, 16 GB) registers as an image gen worker in the cAIc cluster. +**Goal:** Add image generation as a cluster capability. The image-gen node (currently jarvis — single-node deployment) registers as an image gen worker in the cAIc cluster. ### Requirements: 1. **Add `"image_gen"` capability** to the cluster protocol in `cluster.py` — valid capability values should include `image_gen` -2. **Image gen API wrapper on corsair** — run ComfyUI, Automatic1111, or a lightweight API (e.g., `sd-api` or `comfyui-api`) that exposes a simple `POST /generate` endpoint accepting a prompt and returning a PNG -3. **Proxy endpoint in cAIc** — `POST /api/image/generate` on the coordinator, routes the request to corsair's image gen service via AMQP or direct HTTP +2. **Image gen API wrapper** — run ComfyUI, Automatic1111, or a lightweight API (e.g., `sd-api` or `comfyui-api`) that exposes a simple `POST /generate` endpoint accepting a prompt and returning a PNG +3. **Proxy endpoint in cAIc** — `POST /api/image/generate` on the coordinator, routes the request to the image gen service via AMQP or direct HTTP 4. **Update `hardware.py`** to probe the image gen service for reachability and status 5. **Update node_agent** to report image gen capability and service status on registration ### Architecture: ``` -User prompt → cAIc coordinator → AMQP/HTTP → corsair (ComfyUI/API) → PNG → coordinator → user +User prompt → cAIc coordinator → AMQP/HTTP → image-gen node (ComfyUI/API) → PNG → coordinator → user ``` ### Considerations: @@ -37,7 +37,7 @@ User prompt → cAIc coordinator → AMQP/HTTP → corsair (ComfyUI/API) → PNG - Verify node_agent registers with `image_gen` capability - Verify 429/503 handling when service is busy or down -### Status: ✅ Backend Complete (ComfyUI install pending on corsair) +### Status: ✅ Backend Complete (ComfyUI install pending on jarvis — single-node deployment) --- diff --git a/ai.md b/ai.md index 067ee95..159e8aa 100644 --- a/ai.md +++ b/ai.md @@ -88,7 +88,7 @@ Refactored from single-file (`app.py`) into modules under project root: 3. **`/v1/chat/completions`** → OpenAI-compatible for Continue.dev/IDE integration; FIM requests proxied without persistence 4. **`/api/upload`** → multipart file upload, PDF/text extraction, `mode=(context|ingest|both)`, stores SQLite context (1hr expiry) + Qdrant upsert 5. **`/api/ingest`** → Bearer token auth, programmatic RAG ingest (terminal hook, external tools) -6. **`POST /api/image/generate`** → admin required, routes to corsair node agent via AMQP → ComfyUI workflow → returns PNG; `GET /api/image/status` lists available image gen nodes +6. **`POST /api/image/generate`** → admin required, routes to an image-gen node via AMQP → ComfyUI workflow → returns PNG; `GET /api/image/status` lists available image gen nodes ### Perplexity / auto-search @@ -131,7 +131,7 @@ All services are available bare-metal or as containers in `docker compose up`. - `SUPPORTED_UPLOAD_TYPES` includes images (png/jpeg/gif/svg/webp) + text + PDF + JSON - `UPLOAD_CONTEXT_EXPIRY_HOURS` = 1 hour - Rate limits and payload caps in `config.py` — patch `security.RL_*` not `config.RL_*` for tests -- `COMFYUI_BASE` defaults to `http://192.168.50.115:8188` (overridable via `CAIC_COMFYUI_BASE`) +- `COMFYUI_BASE` defaults to `http://localhost:8188` (overridable via `CAIC_COMFYUI_BASE`) - `COMFYUI_TIMEOUT` defaults to `120` seconds (overridable via `CAIC_COMFYUI_TIMEOUT`) - RAG embedding requests go to `EMBED_URL` at `/api/embeddings` (Ollama on worker :11434) @@ -148,6 +148,8 @@ All streaming endpoints yield `data: {json}\n\n`. Key shapes: ### Completed this session - **Pre-Docker review**: Full findings report delivered -- 30+ issues across 7 categories (hardcoded hosts/paths, config/secrets, AMQP gaps, resource cleanup, SQLite container safety, completions concurrency, TASKS.md accuracy). +- **Project rename**: `jarvisChat` → **cAIc** ("cake") — swept remaining branding (router docstrings, jc-ingest.sh env var), deleted stale `AGENTS.md.local`. +- **Single-node consolidation**: all services moved to jarvis (192.168.50.212) — `COMFYUI_BASE` default → `localhost:8188`, AMQP URL default → `localhost:5672`, `NODE_NAME` default → `jarvis`, `DEFAULT_PROFILE` topology rewritten, cluster/AMQP/node_agent left in place (degrades gracefully). - **Deprecation fix**: Replaced `asyncio.ensure_future` with `asyncio.create_task` in `rag.py` and `routers/chat.py`. - **Documentation**: Added inline comments and docstrings to all functions in `db.py`. - **Uninstall scripts**: Created and committed `scripts/uninstall.sh`, `teardown-docker.sh`, `nuclear-clean.sh`. @@ -155,7 +157,22 @@ All streaming endpoints yield `data: {json}\n\n`. Key shapes: - **Docker containerization (B3)**: Created `Dockerfile`, `docker-compose.yml`, `.env.example`, `scripts/setup.sh`, `.dockerignore`, `searxng-settings.yml.dist`, `models/README.txt`. Fixed hardcoded defaults in `config.py` (localhost, Docker secrets path, `CAIC_DEFAULT_MODEL` env var, `CAIC_HW_STATE_PATH` env var). Added missing `psutil` + `jinja2` to `requirements.txt`. Fixed test discovery via `tests/conftest.py` sys.path insertion. 214 tests pass. ### Active -- Image generation service backend complete — cluster handlers, router proxy, node agent ComfyUI integration, hardware probe. 27 tests pass. ComfyUI install pending on corsair. +- Image generation service backend complete — cluster handlers, router proxy, node agent ComfyUI integration, hardware probe. 27 tests pass. ComfyUI install pending on jarvis (single-node). + +### Deployed (2026-08-07) — v1.1.0 to production +- **Fixed crash-loop**: ultron `llama-server.service` had 911 restarts — its `--rpc 192.168.50.210:50052` pointed at a dead IP. Corrected to `192.168.50.212:50052` (jarvis GPU rpc-server). Model now loads, `/health` = ok. +- **Deployed v1.1.0**: workspace repo synced to `/opt/jarvischat` (jarvischat.service cwd). caic.db + venv preserved; `aio-pika` installed into prod venv (was missing → AMQP disabled). +- **Env fixes** (`/etc/systemd/system/jarvischat.service.d/override.conf`): added `LLAMA_SERVER_BASE=http://192.168.50.108:8081`, `CAIC_QDRANT_URL=http://192.168.50.108:6333`, `CAIC_COMPLETIONS_API_KEY` (was set as legacy `JARVISCHAT_` name), kept `CAIC_EMBED_URL=http://192.168.50.108:11434` + `CAIC_ADMIN_PIN=1319`. Wrote `/opt/jarvischat/.completions_key` (jc-ingest.sh). +- **Deploy-blocking bug fixes** (uncommitted, workspace + deploy): + - `rag.py` `chunk_text`: chunk_size 512→200 (chunks exceeded mxbai-embed-large's 512-token context → ollama 500). + - Qdrant 1.18.2 rejects non-UUID point IDs: wrapped `ingest-*`/`auto-*`/`upload-*` string IDs in `uuid5` in `routers/ingest.py`, `rag.py`, `routers/upload.py`. + - `docs/jc-ingest.sh`: `JC_URL` updated `.210`→`.212`. +- **Docs rebuilt**: 159 chunks (source `docs`) re-ingested via `/api/ingest` (README, ai.md, docker.md, CLAUDE.md, wiki/*). RAG now 378 vectors; chat verified injecting "Retrieved Context". +- **Tests**: all 244 pass (run per-file in a throwaway venv; the full-suite run deadlocks on TestClient/AMQP ordering, not a code failure). + +### Follow-ups +- AMQP wiring: cluster subs degrade gracefully — **moot in the single-node (jarvis) deployment** until a multi-node cluster is stood back up. Needs `CAIC_AMQP_URL` + credentials if that happens. +- `CAIC_TRIAGE_BASE` set but triage not yet invoked by chat (config-only until TASK 2 wiring). ### Blocked - Ball Gunner assets — waiting on Canva designs diff --git a/cluster.py b/cluster.py index 6c40e7d..2d45d34 100644 --- a/cluster.py +++ b/cluster.py @@ -19,7 +19,7 @@ CLUSTER_EVENTS: deque = deque(maxlen=1000) CLUSTER_COORDINATOR: str | None = None _pending_pings: dict[str, tuple[str, asyncio.Event]] = {} _pending_image: dict[str, tuple[str, asyncio.Event]] = {} -NODE_NAME: str = os.environ.get("CAIC_NODE_NAME", "ultron") +NODE_NAME: str = os.environ.get("CAIC_NODE_NAME", "jarvis") PING_TIMEOUT: float = 5.0 diff --git a/config.py b/config.py index b4f4903..ebf50de 100644 --- a/config.py +++ b/config.py @@ -34,7 +34,7 @@ def get_amqp_url() -> str: except (FileNotFoundError, OSError): pw = "password" log.warning("AMQP secret file not found at %s — using default password", AMQP_SECRET_PATH) - return f"amqp://caic:{pw}@rabbitmq:5672/caic" + return f"amqp://caic:{pw}@localhost:5672/caic" # --- Auth --- SESSION_TIMEOUT_SECONDS = 3600 @@ -53,7 +53,7 @@ TRUST_X_FORWARDED_FOR = ( ) # --- Image generation (ComfyUI) --- -COMFYUI_BASE = os.environ.get("CAIC_COMFYUI_BASE", "http://192.168.50.115:8188") +COMFYUI_BASE = os.environ.get("CAIC_COMFYUI_BASE", "http://localhost:8188") COMFYUI_TIMEOUT = int(os.environ.get("CAIC_COMFYUI_TIMEOUT", "120")) # --- Rate limits --- @@ -179,12 +179,10 @@ ALLOWED_NETWORKS = parse_allowed_cidrs(ALLOWED_CIDRS_RAW) DEFAULT_PROFILE = """You are a coding companion running locally on a machine called "jarvis". ## Environment -- jarvis: Debian 13 (trixie) x86_64, AMD Ryzen 5 5600X, 16GB RAM, AMD RX 6600 XT (8GB VRAM) -- ultron: Debian 13, Ryzen 7 7840HS, 16GB RAM, primary AI inference node, IP 192.168.50.108 -- Corsair: Windows 11, gaming/streaming rig, RTX 5070 Ti +- jarvis: Debian 13 (trixie) x86_64, AMD Ryzen 5 5600X, 16GB RAM, AMD RX 6600 XT (8GB VRAM), IP 192.168.50.212 +- Single-node deployment — all cAIc services run on jarvis: llama-server :8081 (OpenAI-compat API), Qdrant :6333, Ollama :11434, SearXNG :8888, RabbitMQ :5672, ComfyUI :8188 - pivault: RPi 5, 8GB RAM, Debian 13, 11TB RAID5 NAS at /mnt/pivault, IP 192.168.50.158 - Router: ASUS ROG Rapture GT-BE98 Pro "BigBlinkyRouter" at 192.168.50.1 -- llama-server on ultron:8081 (OpenAI-compat API), Qdrant on ultron:6333 ## About the User - Experienced developer, BS in Computer Science (Oklahoma State), coding since 1981 (TRS-80) diff --git a/docker-compose.yml b/docker-compose.yml index 95a5ca7..05db4fa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,7 +19,7 @@ services: - rabbitmq_password environment: - CAIC_AMQP_SECRET_PATH=/run/secrets/rabbitmq_password - - CAIC_COMFYUI_BASE=${CAIC_COMFYUI_BASE:-http://192.168.50.115:8188} + - CAIC_COMFYUI_BASE=${CAIC_COMFYUI_BASE:-http://localhost:8188} - CAIC_COMFYUI_TIMEOUT=${CAIC_COMFYUI_TIMEOUT:-120} env_file: .env depends_on: diff --git a/docs/jc-ingest.sh b/docs/jc-ingest.sh index 6460508..f3a67c3 100644 --- a/docs/jc-ingest.sh +++ b/docs/jc-ingest.sh @@ -1,11 +1,11 @@ #!/bin/bash -# jc-ingest.sh — pipe terminal commands into jarvisChat RAG -# Deploy to /home/gramps/bin/jc-ingest.sh on jarvis (192.168.50.210) +# jc-ingest.sh — pipe terminal commands into cAIc RAG +# Deploy to /home/gramps/bin/jc-ingest.sh on jarvis (192.168.50.212) # # Usage: # 1. chmod +x /home/gramps/bin/jc-ingest.sh # 2. Add to ~/.bashrc: -# export JARVISCHAT_COMPLETIONS_API_KEY="$(cat /opt/jarvischat/.completions_key)" +# export CAIC_COMPLETIONS_API_KEY="$(cat /opt/jarvischat/.completions_key)" # export PROMPT_COMMAND="jc_capture" # source /home/gramps/bin/jc-ingest.sh # @@ -15,8 +15,8 @@ # Filter: currently captures git, pip, systemctl, sudo, vi/vim, curl, # wget, apt, python, pytest commands. Edit the grep pattern to adjust. -JC_URL="http://192.168.50.210:8080/api/ingest" -JC_TOKEN="${JARVISCHAT_COMPLETIONS_API_KEY}" +JC_URL="http://192.168.50.212:8080/api/ingest" +JC_TOKEN="${CAIC_COMPLETIONS_API_KEY}" jc_capture() { local cmd diff --git a/docs/wiki/Developer-Architecture.md b/docs/wiki/Developer-Architecture.md index 64d2a98..6e3727b 100644 --- a/docs/wiki/Developer-Architecture.md +++ b/docs/wiki/Developer-Architecture.md @@ -45,14 +45,16 @@ Key base URLs are configured via environment variables with sensible defaults: | Variable | Default | Service | |----------|---------|---------| -| `LLAMA_SERVER_BASE` | `http://192.168.50.108:8081` | llama-server on coordinator | +| `LLAMA_SERVER_BASE` | `http://localhost:8081` | llama-server on the same node | | `OLLAMA_BASE` | `http://localhost:11434` | Legacy — all inference goes through LLAMA_SERVER_BASE | | `SEARXNG_BASE` | `http://localhost:8888` | SearXNG | -| `QDRANT_URL` | `http://192.168.50.108:6333` | Qdrant on coordinator | +| `QDRANT_URL` | `http://localhost:6333` | Qdrant on the same node | | `CAIC_AMQP_URL` | `amqp://caic:password@localhost:5672/caic` | RabbitMQ | -| `CAIC_COMFYUI_BASE` | `http://192.168.50.115:8188` | ComfyUI on worker | +| `CAIC_COMFYUI_BASE` | `http://localhost:8188` | ComfyUI (image gen) | | `CAIC_COMFYUI_TIMEOUT` | `120` | ComfyUI generation timeout (seconds) | +> **Current deployment (single-node):** all services run on jarvis (192.168.50.212). The cluster/AMQP/node-agent layer is dormant — it degrades gracefully and can be re-enabled for a multi-node cluster later. + ## 2. Request/Response Architecture ### 2.1 Chat Pipeline (`/api/chat`) diff --git a/docs/wiki/WireGuard-Setup.md b/docs/wiki/WireGuard-Setup.md index 8d1dc0d..203a15b 100644 --- a/docs/wiki/WireGuard-Setup.md +++ b/docs/wiki/WireGuard-Setup.md @@ -1,5 +1,7 @@ # WireGuard Tunnel — Encrypted Node Transit +> **Status: dormant (single-node deployment).** All cAIc services currently run on one node (jarvis, 192.168.50.212), so there is no inter-node traffic to encrypt. This document is kept as a reference for when a multi-node cluster is stood back up. + ## Why cAIc cluster traffic is plaintext today: diff --git a/docs/wiki/current-wip.md b/docs/wiki/current-wip.md index be65172..f7467fd 100644 --- a/docs/wiki/current-wip.md +++ b/docs/wiki/current-wip.md @@ -6,10 +6,12 @@ Scope: Active roadmap items and backlog. ## In Progress -- **Image Generation Service** — Backend wired: cluster handlers, `POST /api/image/generate` proxy, node agent ComfyUI integration, hardware probe, 27 tests. ComfyUI install pending on corsair (RTX 5070 Ti). +- **Image Generation Service** — Backend wired: cluster handlers, `POST /api/image/generate` proxy, node agent ComfyUI integration, hardware probe, 27 tests. ComfyUI install pending on jarvis (single-node). ## Completed +- **Single-node consolidation (2026-08-08)** — all cAIc services moved onto jarvis (192.168.50.212): llama-server, Qdrant, SearXNG, RabbitMQ, Ollama, ComfyUI. Config defaults (`COMFYUI_BASE`, AMQP URL, `NODE_NAME`) updated; cluster/AMQP layer left dormant (degrades gracefully). Project renamed `jarvisChat` → **cAIc**. + - **B8 (v0.19.3)** — Private Chat mode. Backend skip-DB/skip-RAG/skip-search flag, frontend PRIVATE badge, info popup. - **WireGuard TLS (v0.19.4)** — Self-signed WireGuard mesh encrypts all inter-node traffic (AMQP, inference, RPC). No code changes to cAIc. Documented in wiki/WireGuard-Setup.md + docker.md §5.4. - **At-Rest Encryption (v0.20.0)** — AES-256-GCM encrypts all query-derived text at rest. crypto.py with auto-keygen, key stored as `heartbeat_interval_ms` in settings. All 12 storage paths wired (SQLite: messages, conversations, memories, upload_context; Qdrant: RAG chunks, ingest, upload). 200 tests pass. diff --git a/node_agent/agent.py b/node_agent/agent.py index a484507..6de8bfe 100644 --- a/node_agent/agent.py +++ b/node_agent/agent.py @@ -11,13 +11,13 @@ responds to pings, and handles model swap commands. # hostname — defaults to socket.gethostname() node_name = jarvis # LAN IP — defaults from socket -node_ip = 192.168.50.210 +node_ip = 192.168.50.212 # "worker" (fixed) node_type = worker # comma-separated capability list capabilities = llm # RabbitMQ URL on coordinator -amqp_url = amqp://caic:password@192.168.50.108:5672/caic +amqp_url = amqp://caic:password@localhost:5672/caic # port llama-server listens on llama_port = 8081 # path to GGUF model files diff --git a/rag.py b/rag.py index 5532824..00ddf8c 100644 --- a/rag.py +++ b/rag.py @@ -4,6 +4,7 @@ cAIc - RAG pipeline: Qdrant vector search + system prompt assembly. import asyncio import logging import os +import uuid from datetime import datetime, timezone import httpx @@ -45,7 +46,7 @@ async def _upsert_fact(fact: str, text: str, topic: str, if er.status_code != 200: continue vector = er.json()["embedding"] - pid = f"auto-{ts}-{i}" + pid = str(uuid.uuid5(uuid.NAMESPACE_DNS, f"auto-{ts}-{i}")) payload = { "text": encrypt_text(chunk), "source": "auto_fact", "fact": fact, "ingest_date": datetime.now(timezone.utc).isoformat(), @@ -124,7 +125,7 @@ async def confirm_fact_update(memory_id: int, old_fact: str, new_fact: str, return True -def chunk_text(text: str, chunk_size: int = 512, overlap: int = 128) -> list: +def chunk_text(text: str, chunk_size: int = 200, overlap: int = 64) -> list: words = text.split() target_words = int(chunk_size / 1.3) overlap_words = int(overlap / 1.3) diff --git a/routers/chat.py b/routers/chat.py index d6a0299..e744c36 100644 --- a/routers/chat.py +++ b/routers/chat.py @@ -1,4 +1,4 @@ -"""JarvisChat routers - /api/chat streaming endpoint.""" +"""cAIc routers - /api/chat streaming endpoint.""" import asyncio import json import logging diff --git a/routers/cluster.py b/routers/cluster.py index 7c186a8..108c999 100644 --- a/routers/cluster.py +++ b/routers/cluster.py @@ -1,4 +1,4 @@ -"""JarvisChat routers - Cluster status API.""" +"""cAIc routers - Cluster status API.""" from fastapi import APIRouter import cluster diff --git a/routers/completions.py b/routers/completions.py index 0415f6f..5b1f67e 100644 --- a/routers/completions.py +++ b/routers/completions.py @@ -1,5 +1,5 @@ """ -JarvisChat - /v1/chat/completions router. +cAIc - /v1/chat/completions router. OpenAI-compatible endpoint for IDE integration (Continue.dev, etc.). Runs all requests through the full jC pipeline: profile + RAG + memory injection. FIM (fill-in-the-middle) requests are proxied directly — not persisted. diff --git a/routers/conversations.py b/routers/conversations.py index 17bd259..499963a 100644 --- a/routers/conversations.py +++ b/routers/conversations.py @@ -1,4 +1,4 @@ -"""JarvisChat routers - Conversation CRUD.""" +"""cAIc routers - Conversation CRUD.""" import logging import uuid from datetime import datetime, timezone diff --git a/routers/hardware.py b/routers/hardware.py index 4c483b1..834516f 100644 --- a/routers/hardware.py +++ b/routers/hardware.py @@ -1,4 +1,4 @@ -"""JarvisChat routers — Hardware self-assessment endpoint.""" +"""cAIc routers — Hardware self-assessment endpoint.""" import json from fastapi import APIRouter diff --git a/routers/image.py b/routers/image.py index 42907c9..cd7907f 100644 --- a/routers/image.py +++ b/routers/image.py @@ -1,4 +1,4 @@ -"""JarvisChat routers — Image generation proxy endpoint.""" +"""cAIc routers — Image generation proxy endpoint.""" import base64 import logging diff --git a/routers/ingest.py b/routers/ingest.py index 37e4070..191b617 100644 --- a/routers/ingest.py +++ b/routers/ingest.py @@ -1,7 +1,8 @@ -"""JarvisChat routers - /api/ingest terminal command RAG hook.""" +"""cAIc routers - /api/ingest terminal command RAG hook.""" import hashlib import hmac import logging +import uuid from datetime import datetime, timezone import httpx @@ -53,7 +54,7 @@ async def ingest_content(request: Request): continue vector = embed_resp.json()["embedding"] chunk_hash = hashlib.md5(chunk.encode("utf-8")).hexdigest()[:12] - point_id = f"ingest-{source}-{chunk_hash}-{i}" + point_id = str(uuid.uuid5(uuid.NAMESPACE_DNS, f"ingest-{source}-{chunk_hash}-{i}")) payload = {"text": encrypt_text(chunk), "source": source, "ingest_date": datetime.now(timezone.utc).isoformat(), "type": "ingest"} payload.update(metadata) upsert_resp = await client.put( diff --git a/routers/memories.py b/routers/memories.py index bb4ff42..5ffcb38 100644 --- a/routers/memories.py +++ b/routers/memories.py @@ -1,4 +1,4 @@ -"""JarvisChat routers - Memory CRUD API.""" +"""cAIc routers - Memory CRUD API.""" from fastapi import APIRouter, HTTPException, Request from typing import Optional diff --git a/routers/models.py b/routers/models.py index ae1020e..8a3e96e 100644 --- a/routers/models.py +++ b/routers/models.py @@ -1,5 +1,5 @@ """ -JarvisChat routers - Model listing, system stats. +cAIc routers - Model listing, system stats. """ import logging from typing import Optional diff --git a/routers/presets.py b/routers/presets.py index d6480cb..faabe4f 100644 --- a/routers/presets.py +++ b/routers/presets.py @@ -1,4 +1,4 @@ -"""JarvisChat routers - System prompt presets.""" +"""cAIc routers - System prompt presets.""" import uuid from datetime import datetime, timezone from fastapi import APIRouter, HTTPException, Request diff --git a/routers/profile.py b/routers/profile.py index 02cac50..6fd0334 100644 --- a/routers/profile.py +++ b/routers/profile.py @@ -1,4 +1,4 @@ -"""JarvisChat routers - Profile.""" +"""cAIc routers - Profile.""" from datetime import datetime, timezone from fastapi import APIRouter, HTTPException, Request from db import get_db diff --git a/routers/rag_admin.py b/routers/rag_admin.py index 6171f53..bd7c7b5 100644 --- a/routers/rag_admin.py +++ b/routers/rag_admin.py @@ -1,4 +1,4 @@ -"""JarvisChat routers — RAG corpus management admin endpoints.""" +"""cAIc routers — RAG corpus management admin endpoints.""" import logging from datetime import datetime, timezone diff --git a/routers/search_route.py b/routers/search_route.py index 59b3389..9cad915 100644 --- a/routers/search_route.py +++ b/routers/search_route.py @@ -1,4 +1,4 @@ -"""JarvisChat routers - /api/search explicit search endpoint.""" +"""cAIc routers - /api/search explicit search endpoint.""" import json import logging import uuid diff --git a/routers/settings.py b/routers/settings.py index c6a6caf..180a2c7 100644 --- a/routers/settings.py +++ b/routers/settings.py @@ -1,4 +1,4 @@ -"""JarvisChat routers - Settings.""" +"""cAIc routers - Settings.""" from fastapi import APIRouter, HTTPException, Request from db import get_db from security import read_json_body, BODY_LIMIT_DEFAULT_BYTES diff --git a/routers/skills.py b/routers/skills.py index 8c2b08c..2c74000 100644 --- a/routers/skills.py +++ b/routers/skills.py @@ -1,4 +1,4 @@ -"""JarvisChat routers - Skills.""" +"""cAIc routers - Skills.""" from fastapi import APIRouter, HTTPException, Request from db import get_db, get_setting, list_skills_with_state, set_skill_enabled from security import read_json_body, BODY_LIMIT_DEFAULT_BYTES diff --git a/routers/upload.py b/routers/upload.py index 2be9e6e..1b08fa6 100644 --- a/routers/upload.py +++ b/routers/upload.py @@ -1,7 +1,8 @@ -"""JarvisChat routers - /api/upload file/document attachment endpoint.""" +"""cAIc routers - /api/upload file/document attachment endpoint.""" import json import logging import os +import uuid from datetime import datetime, timezone, timedelta import httpx @@ -19,7 +20,7 @@ router = APIRouter() def _point_id(filename: str, chunk_idx: int) -> str: - return f"upload-{filename}-{chunk_idx}" + return str(uuid.uuid5(uuid.NAMESPACE_DNS, f"upload-{filename}-{chunk_idx}")) @router.post("/api/upload")