101 lines
5.2 KiB
Markdown
101 lines
5.2 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with this repository.
|
|
|
|
## Project Overview
|
|
|
|
**LLM in Text** is an AI-powered Markdown editor built with Vue 3 + Vite (frontend) and FastAPI + Python + Ollama (backend). It provides real-time AI completion suggestions, OCR image recognition, document conversion (PDF/DOCX/PPTX to Markdown), and TTS text-to-speech.
|
|
|
|
- Completion interface uses plain POST/JSON (not SSE). Frontend sends `X-Request-Id` and calls `/v1/completions/cancel` on abort.
|
|
- AI completion is disabled when the document exceeds 32 KB (enforced both in UI and plugin layer).
|
|
- OCR text and doc-block content are injected into completion context as hidden context — they should NOT be rendered as visible user text.
|
|
- `/v1/convert` supports txt, docx, pptx, pdf via MarkItDown. Non-txt files go through Markdown sanitization (image removal, newline compression).
|
|
- `/v1/export/pdf` is called from the frontend but may not be implemented on the backend — verify before debugging PDF export.
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Frontend
|
|
npm install
|
|
npm run dev # Vite dev server on port 5173, proxies /v1 to backend
|
|
|
|
# Backend
|
|
pip install -r backend/requirements.txt
|
|
python backend/main.py # port 8001
|
|
|
|
# Tests (90% coverage gate on backend modules)
|
|
pytest # full suite with coverage
|
|
|
|
# Single test file (faster, no coverage overhead)
|
|
pytest backend/tests/test_prompt.py -v --no-cov
|
|
|
|
# Build for production
|
|
npm run build
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Frontend (`src/`)
|
|
|
|
| Layer | Key Files | Responsibility |
|
|
|-------|-----------|----------------|
|
|
| Entry | `main.js`, `App.vue` | Vue app bootstrap, Pinia + Router mount |
|
|
| Routing | `router/index.js` | `/` → EditorView, `/docs` → DocsView |
|
|
| Editor | `components/MilkdownEditor.vue` | Central control: Crepe editor, plugin registration, upload/export/OCR/TTS/AI toggle, 32 KB limit |
|
|
| Plugins (TypeScript) | `plugins/copilotPlugin.ts` — ghost text, request scheduling, cancel, language detection, hidden context injection |
|
|
| Plugins (TypeScript) | `plugins/docBlockPlugin.ts` — doc-block nodes and rendering |
|
|
| Plugins (TypeScript) | `plugins/mermaidPlugin.ts` — Mermaid diagram preview |
|
|
| Store | `stores/settings.js` | localStorage-persisted settings (theme, modelThinking, debounceMs, privacyMode, language, background*, ttsInstruct) |
|
|
| API | `utils/api.js` — fetchSuggestion, cancel completion, TTS requests; `config.js` — VITE_* env-based URL config |
|
|
| Utilities | `utils/convert.js`, `ocrCache.js`, `docBlock.js`, `i18n.js` |
|
|
|
|
### Backend (`backend/`)
|
|
|
|
| File | Responsibility |
|
|
|------|----------------|
|
|
| `main.py` | FastAPI app, CORS, API key auth, routes: `/v1/completions`, `/v1/ocr`, `/v1/convert`, `/v1/completions/cancel`. TTS routes lazily registered from `tts_asr.py`. |
|
|
| `llm.py` | Async Ollama calls (`call_ollama`, `stream_ollama`) and VLM OCR (`call_vlm_ocr`). Timeout control. |
|
|
| `prompt.py` | Prompt assembly: `build_completion_prompts`, `prepare_prompt_context`. Templates from `prompts/` directory. |
|
|
| `pro_completions.py` | Pro-tier completion endpoint (newer addition). |
|
|
| `tts_asr.py` | TTS text-to-speech. Late-registered routes via `_register_tts_asr_routes`. |
|
|
| `geoip.py` | Client IP location lookup for non-privacy-mode requests. |
|
|
|
|
### Request Flow: Completion
|
|
|
|
```
|
|
MilkdownEditor.vue → copilotPlugin.ts (debounce, abort, language detection)
|
|
→ utils/api.js (fetchSuggestion: generates request_id, AbortSignal, reads settings)
|
|
→ backend/main.py (/v1/completions: auth, prompt context, call_ollama via asyncio.Task)
|
|
→ backend/prompt.py (system + user prompt from prefix/suffix/context)
|
|
→ backend/llm.py (call_ollama to Ollama)
|
|
← JSON { content, request_id }
|
|
→ copilotPlugin.ts (insertGhostText into editor)
|
|
```
|
|
|
|
## Debugging Paths
|
|
|
|
| Issue | Trace Order |
|
|
|-------|-------------|
|
|
| Completion not firing | `MilkdownEditor.vue` → `copilotPlugin.ts` (check enabled, size limit, debounce) |
|
|
| Wrong completion result | `prompt.py` → `llm.py`. Check prompt context and language detection. |
|
|
| Cancel not working | `main.py` request_id lifecycle ↔ frontend `X-Request-Id` + cancel call |
|
|
| OCR empty result | `main.py` base64 decode → `llm.py call_vlm_ocr` |
|
|
| Document conversion dirty | `_sanitize_converted_markdown` in `main.py` |
|
|
|
|
## Naming Conventions (Mixed)
|
|
|
|
- Vue components/views: PascalCase (`MilkdownEditor.vue`)
|
|
- Frontend utils/config: lowercase `.js` (`api.js`, `config.js`)
|
|
- Plugin layer: TypeScript (`.ts`)
|
|
- Python backend: snake_case
|
|
|
|
Follow the style of each file. Do not reformat across directories for consistency. UI copy defaults to Chinese.
|
|
|
|
## Important Rules
|
|
|
|
- Do not modify `milkdown-docs/` (read-only reference).
|
|
- Code and tests override README.md when they conflict — the README is partially outdated.
|
|
- Plugin code (`copilotPlugin.ts`) is state-machine-style: small changes can break subtle interactions. Change one thing at a time and verify in-browser.
|
|
- No hardcoded secrets, empty catch/except blocks, `as any`, or `@ts-ignore` in new code.
|
|
- Subdirectory AGENTS.md files contain more detailed guidance: `./AGENTS.md` (root), `backend/AGENTS.md`, `src/AGENTS.md`, `src/plugins/AGENTS.md`. Read them when working in those areas.
|