# Agent Backend MVP ## Run (Local) ```bash python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt uvicorn app.main:app --reload --port 15000 ``` ## Run (Docker Compose) 1. Fill env values: ```bash cp .env.example .env ``` Set `GIGACHAT_TOKEN` in `.env`. 2. Start: ```bash docker compose up --build ``` - Public API: `http://localhost:15000/api/*` - PostgreSQL + pgvector runs in `db` service on `localhost:5432` Stop: ```bash docker compose down ``` ## Public API - `POST /api/rag/sessions` - `POST /api/rag/sessions/{rag_session_id}/changes` - `GET /api/rag/sessions/{rag_session_id}/jobs/{index_job_id}` - `GET /api/rag/sessions/{rag_session_id}/jobs/{index_job_id}/events` (SSE progress) - `POST /api/chat/dialogs` - `POST /api/chat/messages` - `GET /api/tasks/{task_id}` - `GET /api/events?task_id=...` - `POST /api/index/snapshot` - `POST /api/index/changes` - `GET /api/index/jobs/{index_job_id}` - `GET /api/index/jobs/{index_job_id}/events` (legacy SSE progress) RAG indexing SSE events (`/api/rag/sessions/{rag_session_id}/jobs/{index_job_id}/events`): - `index_status`: `{"index_job_id","status","total_files",...}` - `index_progress`: `{"index_job_id","current_file_index","total_files","processed_files","current_file_path","current_file_name"}` - `terminal`: `{"index_job_id","status":"done|error",...}` (final event; stream closes after this event) ## Session Model - `rag_session_id`: identifies indexed project chunks in RAG. - `dialog_session_id`: identifies one independent dialog context within a `rag_session_id`. - Multiple dialogs can share one `rag_session_id`. Recommended flow: 1. call `POST /api/rag/sessions` after project selection; 2. wait for indexing job completion; 3. call `POST /api/chat/dialogs` with `rag_session_id`; 4. call `POST /api/chat/messages` with `dialog_session_id` + `rag_session_id`. `/api/chat/messages` supports explicit routing hint: - `mode: "auto" | "project_qa" | "project_edits" | "docs_generation" | "qa"` - Legacy aliases are still accepted: `code_change`, `analytics_review`. ## Persistence Persisted in PostgreSQL: - `rag_sessions`, `rag_chunks`, `rag_index_jobs` - `dialog_sessions`, `chat_messages` - `router_context` (agent routing context per dialog session) - LangGraph checkpoints via `PostgresSaver` (thread id = `dialog_session_id`) Notes: - RAG vectors are stored in `pgvector` column (`rag_chunks.embedding`). - Agent context/history is restored after restart for same `dialog_session_id`. ## Agent Runtime - Router + context store (`app/modules/agent/engine/router/*`) - LangGraph flow execution (`app/modules/agent/engine/graphs/*`) - Route selection: - `default/general` -> answer flow - `project/qa` -> answer flow - `project/edits` -> conservative changeset flow for non-code file updates (hybrid output: `proposed_content` + `hunks`) - `docs/generation` -> answer and/or changeset flow - LLM provider: GigaChat (`chat/completions`) - Prompts for graph LLM nodes: `app/modules/agent/prompts/*.txt` - `general_answer.txt` - `project_answer.txt` - `project_edits_plan.txt` - `project_edits_hunks.txt` - `project_edits_self_check.txt` - `docs_generation.txt` - `docs_execution_summary.txt` ## Modules Structure - `app/modules/chat/*`: chat API, tasks, session-scoped orchestration, event streaming. - `app/modules/agent/*`: intent router, LangGraph flows, confluence integration, changeset validation. - `app/modules/rag/*`: indexing API/jobs and retrieval service. - `app/modules/shared/*`: cross-module primitives (event bus, retry, idempotency). - `app/modules/contracts.py`: fixed inter-module contracts (`AgentRunner`, `RagRetriever`, `RagIndexer`). ## Module Boundaries - `chat` depends on contract `AgentRunner`, but not on concrete `agent` internals. - `agent` depends on contract `RagRetriever`, but not on `rag` indexing internals. - `rag` exposes public/internal API and service implementation. - wiring is centralized in `app/modules/application.py`. ## Internal API (for integration) - `POST /internal/rag/index/snapshot` - `POST /internal/rag/index/changes` - `GET /internal/rag/index/jobs/{index_job_id}` - `POST /internal/rag/retrieve` - `POST /internal/tools/confluence/fetch` ## Environment - `.env.example` contains full list of parameters. - `.env` is used by Docker Compose for `db` and `backend`. - `GIGACHAT_TOKEN`: Basic credentials for OAuth exchange (required for LLM/embeddings). - `DATABASE_URL`: PostgreSQL DSN, default `postgresql+psycopg://agent:agent@db:5432/agent`. - `GIGACHAT_AUTH_URL`: default `https://ngw.devices.sberbank.ru:9443/api/v2/oauth`. - `GIGACHAT_API_URL`: default `https://gigachat.devices.sberbank.ru/api/v1`. - `GIGACHAT_SCOPE`: default `GIGACHAT_API_PERS`. - `GIGACHAT_SSL_VERIFY`: `true|false`, default `true`. - `GIGACHAT_MODEL`: chat model name, default `GigaChat`. - `GIGACHAT_EMBEDDING_MODEL`: embedding model name, default `Embeddings`. - `AGENT_PROMPTS_DIR`: optional override path for prompt files. Troubleshooting: - If indexing shows `failed_files > 0` and `indexed_files = 0`, check backend logs for TLS/auth errors to GigaChat. - In corporate environments with custom TLS chain, set `GIGACHAT_SSL_VERIFY=false` (or install proper CA certs in container).