# 1C Agent (подпроект) Этот подпроект — отдельный сервис-агент для 1С с: - хранением состояния `project -> chat -> messages`; - маршрутизацией модели через `registry/index.json` + `runtime_profiles`; - вызовом LLM через настраиваемые провайдеры; - встроенной RAG-подготовкой контекста по `plugins/1c/datasets/prepared/rag_index.json`; - вызовами 1C-адаптера (`/onec-tool` / `adapter_calls`). ## API (коротко) - `GET /v1/health` — здоровье сервиса. - `GET /v1/projects` — список проектов. - `POST /v1/projects` — создать проект. - `GET /v1/projects/{project_id}` — получить проект. - `GET /v1/projects/{project_id}/chats` — список чатов проекта. - `POST /v1/projects/{project_id}/chats` — создать чат. - `GET /v1/projects/{project_id}/chats/{chat_id}` — получить чат. - `GET /v1/projects/{project_id}/chats/{chat_id}/messages` — история сообщений. - `POST /v1/projects/{project_id}/chats/{chat_id}/messages` — добавить message (user/assistant/system/tool). - `GET /v1/projects/{project_id}/chats/{chat_id}/runtime` — показать, как в этом чате разрешается запуск модели (provider/model/model_id/base_url/adapter и настройки). - `POST /v1/projects/{project_id}/chats/{chat_id}/turn` — сделать turn LLM: - принимает `message` - может включать `adapter_calls` (список `{method, params}`) - может включать `use_rag` и RAG-профиль. - `POST /v1/projects/{project_id}/chats/{chat_id}/onec-tool` — прямой вызов адаптера. - `PATCH /v1/projects/{project_id}` — обновить проект (название/описание/metadata). - `PATCH /v1/projects/{project_id}/chats/{chat_id}` — обновить настройки чата. - `DELETE /v1/projects/{project_id}` — удалить проект вместе со всеми чатами/сообщениями. - `DELETE /v1/projects/{project_id}/chats/{chat_id}` — удалить чат и его сообщения. - `GET /v1/state` — диагностика состояния сервиса (запущен, uptime, счётчики, провайдеры). ## Веб-интерфейс - Открой `http://:/` (на тесте: `http://docker-test.cin.su:8090/`), чтобы войти в UI. - UI не требует отдельной авторизации в самом сервисе; доступ регулируется только сетевыми правилами/портом. - API по-прежнему доступен на `/v1/*` для интеграций и для работы без UI. ## Контракт Нормализованный контракт API: [openapi.yaml](openapi.yaml). ## Разделение ответственностей ### Агент (этот сервис) - Определяет сценарий: project/chat/role/memory/tool-call/guardrails. - Собирает prompt: 1) системный prompt проекта/чата, 2) историю чата, 3) RAG-подготовленный контекст (если включён), 4) результаты инструментов. - Вызывает LLM через выбранный провайдер. - Сохраняет сообщение и служебные метаданные. ### Модель - Принимает стандартный диалоговый список сообщений. - Возвращает только сгенерированный текст. - Никакой бизнес-логики 1С в сервисе модели — только reasoning по prompt. ### Логика работы с адаптером в prompt Правила выбора маршрута поиска живут в `plugins/1c/prompts/system.md`, а не в REST/MCP-адаптере. Адаптер должен возвращать структурированные факты и статусы, а агент обязан правильно их интерпретировать. Ключевые правила для агента: - всегда явно передавать `base_id` для live-запросов; - читать известный `module_ref`/read selector напрямую перед глобальным поиском; - не считать `not_found` доказательством отсутствия кода в расширениях или `ConfigCAS`; - считать `partial`, `truncated=true` и timeout неполным результатом; - отделять доказанный факт от гипотезы и показывать конкретный участок кода, если пользователь просит "место". ### Адаптер (1С) - Отвечает за живые данные 1С (`query`, `metadata`, `modules`, и т.д.). - Возвращает строго структурированный JSON. - Не должен быть «зашит» в модель: модель может запрашивать только через инструментовое API. ### RAG - Не является моделью. - Превращает вопрос в релевантный контекст + мета-информацию источников. - Передаётся в модель как системное сообщение с уже собранным `rag_prompt`. ## Что проходит между слоями - `agent -> model`: `{"role":"system"/"user"/"assistant", "content": ...}` + опционально `provider/system` настройки. - `agent -> adapter`: `{"method": "...", "payload": {...}}`. - `adapter -> agent`: structured JSON-ответ (метаданные/результаты запроса/ошибки). - `agent -> клиент`: user message + assistant message + RAG-сводка + tool outputs + guardrail info. ## Быстрый smoke на развернутом сервисе Для проверки продового/тестового инстанса: - `python scripts/smoke_onec_agent_api.py --base-url http://docker-test.cin.su:8090` - По умолчанию скрипт проверяет быстрые роуты (`/health`, `/state`, CRUD, `messages`). - Для live-проверки `/turn` добавь `--with-turn-check` и учти, что первый запуск может идти дольше из‑за холодного инференса. - Быстрый авто-проход "deploy + smoke": - `powershell -File scripts/deploy_onec_agent_test.ps1 -NoBuild` - `powershell -File scripts/deploy_onec_agent_test.ps1` - `powershell -File scripts/deploy_onec_agent_test.ps1 -WithTurnCheck` ## Обновление на `docker-test` без влияния на остальные проекты Деплой скрипт работает только с сервисом `onec-agent`, поэтому на `docker-test` не затрагиваются другие проекты. - Быстрое обновление (с пересборкой): `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_onec_agent_test.ps1` - Обновление только с перезапуском (без сборки): `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_onec_agent_test.ps1 -NoBuild` - Если добавляешь скрипт в задачу по расписанию, используй именно этот файл — он делает деплой + health-check + smoke в одном проходе. ## Автообновление при изменении кода Если хочешь, чтобы агент всегда был в актуальном состоянии после каждой правки его исходников, запусти: - `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/watch_onec_agent_for_test.ps1` Скрипт мониторит каталоги/файлы: - `plugins/1c/agent` - `core/deploy/docker/1c-agent/compose.yaml` - `scripts/deploy_onec_agent_test.ps1` - `scripts/smoke_onec_agent_api.py` При любых изменениях автоматически перезапускает только сервис `onec-agent` на `docker-test`, затем делает health-check и smoke. Для непрерывного режима в фоне: - `Start-Process -FilePath powershell -ArgumentList '-NoProfile','-ExecutionPolicy','Bypass','-File','scripts/watch_onec_agent_for_test.ps1' -WindowStyle Hidden` ## Что хранит агент (сущности) - `Project`: `id`, `name`, `description`, `metadata`, `created_at`, `updated_at`. - `Chat`: `id`, `project_id`, `title`, `provider_id`, `base_url`, `served_model_name`, `model_id`, `temperature`, `max_tokens`, `rag_profile`, `rag_limit`, `system_prompt`, `metadata`, `created_at`, `updated_at`. - `Message`: `id`, `project_id`, `chat_id`, `role`, `content`, `payload` (операционные поля), `created_at`. ## Как подключать другого ИИ в будущем Сервис уже рассчитан на расширение: - в `ONEC_AGENT_PROVIDERS` задаются провайдеры; - у каждого провайдера есть `type`. - сейчас поддержан `openai-compatible`. Когда нужна другая платформа, добавляется новый `type` в диспетчер провайдеров (и, при необходимости, нормализация ответа в единый формат `{"text": "...", "raw": {...}}`).