Appearance
AI Router
Агент — отдельная версионируемая
AgentDefinition, исполняемая черезrunner-agentили внешний A2A endpoint. Ассистент — карточкаAssistant(ai_chat_agents) для персонализации чата. Это разные каталоги и API.
Назначение
Центральный сервис работы с LLM в платформе Unishift. Маршрутизирует запросы к нескольким провайдерам (OpenAI, Anthropic, Google, Ollama и OpenAI-compatible эндпоинты вроде Yandex AI Studio), управляет чатами и knowledge base (RAG) на основе hybrid-поиска: PostgreSQL FTS + pgvector, слияние через Reciprocal Rank Fusion (RRF), опциональный LLM-rerank и переформулировка запросов.
Порты
- HTTP: 8101
- БД:
ai_router_db
Ключевые возможности
- Мультипровайдерность: OpenAI, Anthropic, Google, Ollama за единым API (Yandex AI Studio / Alice AI — через vendor
openai+ custombase_url) - Capabilities провайдера:
chat,embed,planner,diagram,fill,decision - Sidecar-провайдеры planner / diagram / fill / embed — upsert при старте, только если задан URL (
LLAMA_PLANNER_URL,LLAMA_DIAGRAM_URL,LLAMA_FILL_URL,LLAMA_EMBED_URL). Вdevops/prodэти URL пустые: стартовый стек без моделей и без провайдеров. Как поставить модели и Bosun: Локальные модели. - Decision-gate (опционально): decision-модель Bosun v3.1 0.6B на отдельном llama.cpp-сайдкаре (
DECISION_URL, compose-профильdecision, см.devops/prod/llama-decision/README.md). Перед planner отвечает на два noul-вопроса по семействам с побочным эффектом, которые есть в каталоге. Уверенное «да» (conf ≥ 0.85) командует одиночный tool (create_drawio,create_pptx,create_file,run_command,run_flow). Для заметки, задачи и таблицы то же «да» только открывает глаголы (создать или изменить), а конкретный tool выбирает planner. Иначе семейство убирается из каталога. Если команды нет, один choice-вопрос (tool_pick) выбирает инструмент из оставшегося короткого списка, включая MCP иask_user. Уверенный ответ (conf ≥ 0.70) оставляет в каталоге только его. Слабый ответ список не режет. Любая ошибка или отсутствие провайдера — planner работает как раньше. Клиент:pkg/decision(масочный softmax по top-k логитам с консервативным хвостом); GGUF требует патча decision-токенов (patch_gguf.py). Тот же sidecar доступен снаружи какPOST /api/v1/decide(узел Flow Manager Классификатор /aiClassifyNode, модель Bosun). - Local planner — вход по умолчанию, если есть tools (
mode=chatиmode=sub-agent): sidecar в циклеPlanTraced → exec → PlanTraced(до 4 раундов) выбирает tools, в том числе MCP (retrieve_tools→call_tool_read). Chat-LLM только синтезирует ответ, без MCP-схем. Таймаут sidecarLLAMA_PLANNER_TIMEOUT(по умолчанию 45s). Skip только:plan/obs, draft-редакторы, clarify-first, capabilitydiagram. Fallback в chat-loop — без MCP tools. Forced tool — pin в loop при fallback. - Режимы чата:
chat,multi-agent(оркестрация субагентов),plan(планирование задач, сценариев и презентаций в markdown),obs(observability/анализ логов и метрик через MCP),spec(постановка ТЗ и спецификаций с фиксацией в заметки/файлы). Кастомизируются карточкой режима вНастройки → AI Router → Процесс. Как менять промпты, скиллы и шаблон spec/plan: Управление ответами. - Multi-agent: оркестратор делегирует через
spawn_agent. Несколько вызовов в одном шаге модели идут параллельно (лимитAI_SUB_AGENT_MAX_PARALLEL, по умолчанию 3). На ход не большеAI_SUB_AGENT_MAX_SPAWNS(6) иAI_SUB_AGENT_TOKEN_BUDGETтокенов детей (120000). Повтор того же slug и задачи пропускается. Таймаут ребёнкаAI_SUB_AGENT_TIMEOUT(3m) наследуется от контекста родительского хода. Обычный пользователь запускает только ассистентов изshared_user_ids; админ — любой активный. - Результат
spawn_agent— JSON:status=success | failed | needs_clarification | skipped,child_chat_id,output/summary,artifacts,questions,error,error_code.needs_clarificationпродолжает тот же дочерний чат:ask_user, затем сноваspawn_agentсchild_chat_idиclarification. Длинный ответ сохраняется файлом через storage, оркестратор получает сводку и ссылку. - Маршрутизация модели суб-агента:
provider_id+modelна карточке, иначе sidecar поprovider_capability(diagram,planner,fill), иначе провайдер родительского чата. Каталог для оркестратора кэшируется по пользователю и сбрасывается при изменении карточки (ai.assistant.catalog.invalidate). - События NATS:
ai.chat.agent.started,ai.chat.agent.progress,ai.chat.agent.completed.chat_id— дочерний чат,parent_chat_id— оркестратор. Вai_audit_eventsу ребёнкаparent_chat_idиspawn_id; у родителяchild_tokens_totalиchild_duration_msне складываются в егоtokens_total. - Чаты с историей сообщений, стримингом ответа и reasoning (
thinking). Продуктовое описание поверхностей: AI-чат - Function calling — вызов инструментов из чата (tool calls)
- Diagram-агент: инструменты draw.io / BPMN (
create_drawio,update_drawio, …) - RAG / Knowledge base:
- ingest с очисткой текста, чанкованием и эмбеддингами
- hybrid retrieval (FTS + vector) + RRF
- score threshold, LLM-rerank, query rewriting, multi-hop
- цитирование источников и anti-hallucination system prompt
- space-scoped ACL: scope
space-{uuid}привязан к workspace; поиск фильтруется по spaces, доступным текущему пользователю - автосинхронизация заметок (
documents→ RAG) через NATS
- CRUD провайдеров для администраторов (модели, API-ключи, base URL, egress через proxy-manager)
- Учёт вызовов: сохранение истории, токенов, длительности и статистики по пользователю
- Двойная аутентификация: JWT (пользователи) и Service Token (сервисы)
- Ролевая модель: управление провайдерами требует роль
admin - Публикация NATS-событий: стриминг чанков, статусы обработки, tool-call'ы
- Swagger UI, health checks
Платформа агентов
AI Router хранит определения, неизменяемые версии и durable runs. Сам agent loop выполняется DB-free бинарником runner-agent; AI Router выдаёт короткоживущий job token и остаётся policy proxy для LLM, tools, scopes и финализации артефактов. Inline fallback отсутствует: без подключённого runner с требуемыми capabilities агент помечается недоступным.
| API | Назначение |
|---|---|
GET/POST /api/v1/agents | каталог и создание определения |
POST /api/v1/agents/:slug/versions | публикация immutable version |
POST /api/v1/agents/:slug/runs | durable запуск |
GET /api/v1/agents/runs/:runId | статус и progress |
POST /api/v1/agents/runs/:runId/cancel | отмена |
POST /api/v1/agents/import | импорт .usagent; неизвестная подпись → quarantine |
POST /api/v1/agents/import/cursor | безопасный импорт Cursor ZIP как inert draft |
POST /api/v1/agents/admin/endpoints | регистрация и pin A2A Agent Card |
Встроенные версии artifact-pptx, artifact-drawio и artifact-bpmn возвращают typed IR. После проверки схемы AI Router вызывает детерминированный finalizer (create_pptx, create_drawio, create_bpmn). Legacy chat modes chat, multi-agent, plan, obs, spec продолжают работать независимо.
Формат пакета и trust model: Агенты платформы. Публичный каталог пакетов: unishift.ru/agents. Установка раннера: Agent Runner.
Провайдеры
Админский CRUD — /api/v1/providers (роль admin). Полный список методов — в Swagger.
Запросы провайдера с use_proxy: true уходят через proxy-manager: клиент вызывает GET /api/v1/proxies/next по каждому тегу из proxy_tags и берёт первый здоровый адрес. SOCKS4 для этих вызовов не используется. Пустой proxy_tags при включённом прокси — ошибка валидации.
| Поле | Описание |
|---|---|
use_proxy | Включить egress через пул. По умолчанию false |
proxy_tags | Теги пула. Обязателен, если use_proxy |
proxy_on_unavailable | direct (по умолчанию) — запрос напрямую, если прокси нет; fail — ошибка |
Адрес сервиса: PROXY_MANAGER_SERVICE_URL (по умолчанию http://localhost:8114).
Проверка соединения до сохранения: POST /api/v1/providers/connection/test (admin). Тело то же, что у POST /providers/models/preview: vendor, api_key, base_url; если ключ и URL пустые, а задан provider_id — берётся сохранённый провайдер. Таймаут 30 с. HTTP 200 и при неудаче: { "ok": false, "models": [], "message": "…" }. message: models_endpoint_missing — у вендора нет /models, соединение при этом не считается успешным.
RAG / Knowledge base
Пайплайн
Ingest Retrieval Generation
─────── ───────── ──────────
clean text ──► chunk ──► rewrite query ──► system prompt
embed ──► store FTS + vector ──► RRF ──► (anti-hallucination
(pgvector + tsvector) [rerank] ──► [multi-hop] + cite sources)- Ingest — документ чистится (HTML/шум), режется на чанки с overlap, для каждого чанка считаются эмбеддинги и заполняется
content_tsv(FTS). - Retrieval — сырой вопрос опционально переписывается LLM; параллельно ищутся кандидаты по FTS и по cosine similarity; списки сливаются RRF; при включённом rerank LLM оставляет top-N; при слабом recall — второй hop.
- Generation — в чат с привязанными scopes подмешивается жёсткий system prompt («отвечай только по документам», «цитируй Source»), tool
search_knowledge_baseвозвращает чанки в формате с заголовком источника.
Ingest
POST /api/v1/rag/documents
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
scope | string | да | Область знаний (space-{uuid} или legacy id) |
title | string | да | Заголовок документа (попадает в метаданные чанков) |
content | string | да | Текст / markdown / HTML |
content_type | string | нет | text (default), markdown, html, json, yaml, config, code |
source_id | string | нет | Внешний id (UUID заметки) — upsert по (scope, source_id) |
space_id | uuid | нет | Workspace id (должен совпадать с space-* scope) |
metadata | object | нет | Доп. поля чанков: category, author, date, … |
При ingest:
- upsert: если задан
source_id— по(scope, source_id); иначе по(scope, title)(legacy). В ответеupdated: trueпри обновлении.document_countувеличивается только при создании. - для
space-*scopes требуется доступ пользователя к соответствующему space (через spaces API +SERVICE_TOKEN) - для
text/markdownHTML и script/style вырезаются, пробелы нормализуются json,yaml,config,codeсохраняют отступы и переносы как в исходникеmarkdownрежется по заголовкам#;htmlпарсится в markdown-ish (заголовки/списки) и тоже режется по заголовкам;text— по абзацам;json/yaml/config/codeидут одним куском. Крупные секции дополнительно режутся поRAG_CHUNK_MAX_SIZEс overlap.- в metadata чанка всегда пишутся
title,content_type,scope,ingested_at - FTS-индекс (
content_tsv) обновляется триггером БД - векторы пишутся в
document_chunk_embeddings_{dim}(не в колонку чанка), dim берётся из embed-провайдера, привязанного к scope
Embeddings (multi-dim + per-scope)
Разные модели эмбеддингов несовместимы. Поддерживаемые размерности: 256 / 768 / 1536 — отдельные таблицы document_chunk_embeddings_{256|768|1536} + HNSW.
| Сущность | Поля |
|---|---|
Embed-провайдер (type=embed) | embedding_dim, default_model (doc), query_model (search), is_default (пресет для новых scopes) |
| Scope | embedding_provider_id, embedding_dim (immutable после create) |
Правила:
- при создании scope выбирается embed (или берётся
is_default); embedding_dimкопируется с провайдера и не меняется;- сменить провайдера на scope можно только с той же dim → авто-reindex;
- ingest использует
default_model; search —query_model||default_model; - поиск по нескольким scopes группирует их по провайдеру и сливает через RRF с FTS.
POST /rag/scopes/:scope/reindex — пересчитать векторы текущим провайдером scope.
Yandex embeddings
Отдельного vendor нет: vendor=openai. base_url можно оставить OpenAI-совместимым (https://ai.api.cloud.yandex.net/v1) — для эмбеддингов ai-router всё равно ходит в нативный https://llm.api.cloud.yandex.net/foundationModels/v1/textEmbedding (modelUri + text, заголовок Api-Key для ключей AQVN…).
| Поле | Значение |
|---|---|
embedding_dim | 256 |
default_model | emb://<folder_id>/text-search-doc/latest |
query_model | emb://<folder_id>/text-search-query/latest |
Preview /models у Yandex часто отдаёт 404 — UI позволяет ввести URI вручную. Без query_model поиск деградирует (query и documents в разных пространствах Yandex).
Проверьте, что скоуп (например tt) привязан именно к этому embed-провайдеру, а не к чатовому. Ingest берёт провайдера из настроек скоупа.
Space scopes и ACL
Конвенция имени: space-{spaceUUID}.
GET /rag/scopesвозвращает:- все
space-*для spaces, доступных пользователю (owner или shared); - админам — все существующие scopes (общие и space);
- общие (не
space-*) scopes, пошаренные пользователю (shared_user_ids); - legacy scopes, в которых у пользователя есть собственные документы.
- все
- Space scopes auto-provision при list (alias = имя space).
- Общую базу можно открыть выбранным пользователям через
shared_user_idsнаPUT /rag/scopes/:scope. Доступ к space-базам по-прежнему через ACL пространства. SearchKnowledgeBase/ toolsearch_knowledge_baseпринимаютuser_idна бэкенде и отбрасывают недоступные space scopes. Пошаренные общие scopes ищутся целиком (без фильтраowner_id). Legacy scopes без шаринга — только среди документов сowner_id = user.- AI-чат в Notes подставляет
defaultScopes = ["space-{currentSpaceId}"].
Синхронизация заметок
Сервис documents публикует NATS-события:
| Subject | Когда |
|---|---|
documents.created | создание / duplicate |
documents.updated | patch |
documents.deleted | soft/hard delete |
ai-router подписан и делает trusted ingest / delete по (scope=space-{spaceID}, source_id=documentID).
Retrieval
Поиск вызывается tool'ом search_knowledge_base (чат с scopes) или через usecase SearchKnowledgeBase(userID, …).
| Шаг | Описание | Конфиг |
|---|---|---|
| ACL filter | пересечение запрошенных scopes с доступными spaces / шарингом / admin | — |
| Query rewrite | LLM исправляет опечатки / раскрывает аббревиатуры | RAG_QUERY_REWRITE_ENABLED |
| FTS | websearch_to_tsquery('simple') + ts_rank_cd | — |
| Vector | cosine distance (<=>), отсев по similarity | RAG_VECTOR_MIN_SCORE |
| RRF | score = Σ 1/(k + rank) | RAG_RRF_CONSTANT, RAG_CANDIDATE_LIMIT |
| Rerank | LLM listwise ranking top-кандидатов → top-N | RAG_RERANK_ENABLED |
| Multi-hop | повторный поиск с другим rewrite при слабом recall | RAG_MULTI_HOP_ENABLED |
Формат результата для LLM:
Source: «FAQ» [category=support, author=team]
текст чанка…Scopes
| Метод | Путь | Описание |
|---|---|---|
GET | /rag/scopes | Список scopes, доступных текущему пользователю (админ — все) |
GET | /rag/scopes/:scope | Настройки одного scope (403 без доступа) |
PUT | /rag/scopes/:scope | Upsert alias / description / system_prompt / default_origin / embedding_provider_id / shared_user_ids |
POST | /rag/scopes/:scope/reindex | Пересчитать embeddings scope |
DELETE | /rag/scopes/:scope | Удалить документы и чанки scope |
DELETE | /rag/scopes/:scope/settings | Удалить только настройки scope |
system_prompt scope дополняет дефолтный anti-hallucination prompt, а не заменяет его.
Конфигурация
| Переменная | По умолчанию | Описание |
|---|---|---|
PORT | 8101 | Порт HTTP-сервера |
DB_* | — | PostgreSQL (DB_NAME=ai_router_db) |
JWT_SECRET | — | Валидация JWT |
SERVICE_TOKEN | — | Межсервисный токен (ACL через spaces, sync) |
AGENT_PACKS_DIR | packs/usagent вверх по дереву от cwd | Каталог исходников .usagent. ai-router загружает их при старте |
AI_DEFAULT_PROVIDER | openai | Провайдер по умолчанию |
AI_REQUEST_TIMEOUT | 120s | Timeout запросов к LLM |
AI_MAX_RETRIES | 3 | Число повторов при ошибке |
RAG_CANDIDATE_LIMIT | 20 | Сколько кандидатов брать из FTS и из vector до RRF |
RAG_DEFAULT_LIMIT | 5 | Лимит результатов по умолчанию |
RAG_VECTOR_MIN_SCORE | 0.2 | Мин. cosine similarity (0 = без порога) |
RAG_RRF_CONSTANT | 60 | Константа k в формуле RRF |
RAG_RERANK_ENABLED | true | LLM-rerank кандидатов после RRF |
RAG_QUERY_REWRITE_ENABLED | true | Переформулировка запроса перед поиском |
RAG_MULTI_HOP_ENABLED | true | Повторный поиск при слабом recall |
RAG_CHUNK_MAX_SIZE | 2000 | Размер чанка при ingest (символы) |
RAG_CHUNK_OVERLAP | 200 | Overlap чанков (символы) |
MESSAGING_URL | nats://localhost:4222 | NATS URL |
PROXY_MANAGER_SERVICE_URL | http://localhost:8114 | Базовый URL proxy-manager для egress провайдеров |
SERVER_WRITE_TIMEOUT | 300s | Write timeout (длинный под стриминг) |
Для снижения latency на retrieval можно отключить тяжёлые шаги:
bash
RAG_RERANK_ENABLED=false
RAG_QUERY_REWRITE_ENABLED=false
RAG_MULTI_HOP_ENABLED=falseКвоты и маршрутизация моделей
- Лимиты: месячные потолки токенов на пользователя (
quota_user_monthly_tokens) и на пространство (quota_space_monthly_tokens), порог предупреждения (quota_warn_percent, по умолчанию 80%). Значение0выключает проверку по оси. Персональный потолок (ai_user_settings.monthly_token_quota) при> 0подменяет глобальный пользовательский лимит. - Двухэтапный контроль:
- Перед ходом пользователя в
SendMessage(при превышении — HTTP 402quota_exceeded, сообщение не сохраняется, текст в композере остаётся). - Перед каждым шагом вызова модели в цикле инструментов (при превышении — цикл прерывается с уведомлением).
- Перед ходом пользователя в
- Слоты маршрутизации:
strong(route_strong_provider_id,route_strong_model) — сильная модель исключительно для режимовspecиplan.cheap(route_chat_provider_id,route_chat_model) — дешёвая модель для обычного чата, выполнения шагов плана иobs.
- API:
GET/PUT /api/v1/settings/quotas,GET/PUT /api/v1/settings/users/:userId/quota(рольadmin). - Отчёт: «Мониторинг → Токены» (
/monitoring/tokens) с фильтром по диапазону дат, группировкой по пространствам и выгрузкой CSV для финансового учёта.
API (кратко)
Assistants (каталог карточек)
Каталог кастомных ассистентов (Assistant, таблица ai_chat_agents):
GET /api/v1/assistants— список (доступ зависит отshared_user_ids)GET /api/v1/assistants/:id— карточка ассистента
Примечание: после установки каталог пуст; карточки pptx/drawio/bpmn/doc-generator/code-* миграциями не создаются.
RAG (/api/v1/rag)
| Метод | Путь | Описание |
|---|---|---|
POST | /rag/documents | Ingest документа |
GET | /rag/scopes | Список scopes |
GET | /rag/scopes/:scope | Настройки scope |
PUT | /rag/scopes/:scope | Upsert настроек scope |
POST | /rag/scopes/:scope/reindex | Reindex embeddings scope |
DELETE | /rag/scopes/:scope | Удалить документы scope |
DELETE | /rag/scopes/:scope/settings | Удалить настройки scope |
Decision (/api/v1/decide)
POST /decide — классификатор (capability=decision, типично Bosun). Тело: { state, questions[] } с типами choice / score / noul. Ответ: { answers[{question,chosen,confidence,slots_found}], provider, model }. Используется узлом Flow Manager Классификатор (aiClassifyNode). Без активного decision-провайдера — 404.
Полный список эндпоинтов (провайдеры, чаты, completions) — в Swagger UI: http://localhost:8101/swagger/index.html.
Prompt traces (debug)
Глобальный сбор трейса хода чата. По умолчанию выключен.
- Вкл: Settings → AI Router → Tools → Collect prompt traces (
PUT /api/v1/settings/prompt-trace, рольadmin). - Хранение: таблица
ai_turn_traces(JSONB payload, FK наmessages), флагmessages.has_trace. - Просмотр: Monitoring → Chats → кнопка Trace у ответа ассистента → модалка. API:
GET /admin/chats/:chatId/messages/:messageId/trace(секцияmonitoring_chats). - В payload: runtime (mode/model/tools/skills), фрагменты system prompt по источнику, метод выбора skills, tool defs, шаги LLM (
role+ provider/model:planner,chat,planner_synth,diagram_synth,plan_synth,obs_synth,evidence_synth; messages in / response out), финальный ответ. - Содержит пользовательский и системный текст — не держать включённым в проде без нужды. Старые трейсы остаются после выключения сбора.
- Логи
PROMPT_TRACE=trueне связаны с этим UI.
Журнал ИБ (AI Audit Journal)
Отдельный неизменяемый (append-only) журнал для информационной безопасности. В отличие от Prompt Traces, журнал всегда включён и регистрирует каждый ход AI без сохранения текста запроса или ответа.
- Что пишется:
- Субъект и контекст:
user_id,chat_id,message_id,origin,mode, карточка ассистента (agent_id,agent_slug). - Пространства и права:
space_ids(извлечённые изspace-{uuid}), полный список выданныхscopes. - Модели: реально задействованные модели с ролями (chat, planner, diagram, synth и др.) и вендорами.
- Инструменты: выданные имена tools и вызванные tools со статусом (
ok,denied,error). Аргументы и результаты вызовов не пишутся. - RAG-источники: идентификаторы документов (
document_id,source_id,title,scope), попавших в контекст. Текст чанков не пишется. - Метрики: токены (prompt, completion, total), длительность, статус (
completed,failed), код ошибки. - Хеши:
content_fingerprint(SHA-256 текста пользователя для линковки с DLP Guard) и детерминированныйrow_hash(SHA-256) записи.
- Субъект и контекст:
- Неизменяемость: таблица
ai_audit_eventsзащищена триггером PostgreSQL (BEFORE UPDATEблокирует любые изменения;BEFORE DELETEблокирует удаление без флага сессииai_router.audit_purge = 'on'). - Срок хранения (retention): параметр
audit_retention_days(по умолчанию 365 дней,0— бессрочно). Фоновый воркер раз в сутки очищает устаревшие записи и сохраняет квитанцию с типомretention_purge(с указанием диапазонаseqи количества удалённых строк). - Экспорт в SIEM:
- Pull:
GET /api/v1/admin/audit/turns?cursor=(NDJSON, доступ по секцииmonitoring_security). - Push: фоновый воркер отправляет пачки NDJSON на
AUDIT_SIEM_URL(с токеномAUDIT_SIEM_TOKEN) и автоматически продвигает курсорaudit_siem_cursor.
- Pull:
- UI: доступен в
Мониторинг → Журнал AI(/monitoring/ai-audit, секцияmonitoring_security). На этой же странице настраивается срок хранения и доступен ручной запуск purge.
Function calling / Tools
Инструменты регистрируются в internal/infrastructure/tools и подключаются через ToolRegistry в container. Клиент передаёт имена в tools[] на send message; при наличии scopes автоматически добавляется search_knowledge_base.
| Tool | Side effects | Назначение |
|---|---|---|
run_command | command-manager: create job | Запуск команды по имени/UUID |
search_commands | read-only | Поиск команд перед запуском |
get_job_status / get_job_logs / stop_job | read / command-manager | Статус, логи, стоп job |
run_flow | flow-manager: test pipeline | Запуск/тест процесса |
write_starlark_code / test_starlark_code | none / TryCodeNode | Scaffold и прогон Starlark |
create_task / update_task / search_tasks / get_task / change_task_status | task-tracker | Задачи в space |
create_note / update_note / search_notes / get_note | documents | Заметки |
create_drawio / update_drawio / read_drawio | documents (draw.io) | Диаграммы; capability diagram |
create_bpmn / update_bpmn / read_bpmn | documents (BPMN) | Процессные схемы |
create_pptx / update_pptx / read_pptx | documents / storage | Презентации; рендер из slideLayouts шаблона (pptx_template), вписывание текста по метрикам шрифта |
search_media / get_media_file | spark-grid | Медиатека пространства |
search_tables / get_table / create_table / *_table_rows | data-tables | Таблицы в space |
search_env / create_env / update_env | env-manager | Секреты и конфиги |
web_search / fetch_url | SearXNG / HTTP | Поиск в вебе и загрузка URL |
update_command_draft / update_note_draft / update_flow_draft / update_skill_draft | none (UI patch) | Черновики в открытый редактор |
search_knowledge_base | RAG read | Поиск по scopes (авто при scopes) |
ask_user | UI clarify | Уточняющий вопрос пользователю |
UI-patch tools (update_*_draft) возвращают JSON; фронт слушает NATS ai.chat.tool.call / ai.chat.tool.result и применяет поля в открытый редактор.
PPTX-рендер и шаблоны
create_pptx принимает компактный IR (theme + slides, без координат). Рендер:
- Шаблон —
.pptxс настоящимиslideLayoutи placeholder (p:ph). Built-in: 4 темы (corporate|dark|minimal|pitch), генерируются кодом (BuildTemplate, 10 layout'ов). Загруженный черезSettings → AI Router → Templatesфайл становитсяpptx_template(base64-пакет вai_asset_catalog.body, ≤10MB, meta хранит маппинг canonical layout → layout шаблона). Рендер по slug:theme = <slug>. Тегdefaultу шаблона делает его рендером дек без явной темы. - Сборка — слайд ссылается на layout шаблона и содержит только заполненные placeholder-шейпы: геометрия/стили наследуются от layout и master. Пустые слоты не эмитятся; карточки/колонки без контента дропаются.
- Вписывание текста — advance-таблицы Calibri (regular/bold, латиница + кириллица + CJK-эвристика) → симуляция переноса → подбор размера из лестницы (−10% шаг до 12pt), затем
normAutofit fontScale.vertOverflowclip больше не используется — текст уменьшается, а не обрезается. - Выбор темы — explicit slug → keywords каталога → FNV-ротация по тексту запроса (деки не «слипаются» в одной теме). Промпт архитектора предписывает выбирать тему по тону, enum в schema отсортирован.
Пакет деки дублируется в ppt/unishift/deck.json — веб-превью читает его напрямую из zip.
Режимы AI-чата (Chat Modes & Pipelines)
AI Router поддерживает 6 пайплайнов выполнения чата (mode), которые определяют доступность инструментов, глубину планирования, лимит шагов (MaxSteps) и встроенные системные промпты. Выполнение каждого режима настраивается карточкой в Настройки → AI Router → Процесс (/settings/ai-router/pipeline, таблица ai_pipeline_graphs): скиллы режима, MaxSteps, промпт цикла.
Режим (mode) | Ключевое назначение | Planner / Router | MaxSteps | Итоговые артефакты / Поведение |
|---|---|---|---|---|
chat | Обычный диалог, Q&A и быстрая работа с контекстом | Маленький planner (если есть tools) | ~3–6 | Прямой ответ, короткие вызовы read-only инструментов |
multi-agent | Комплексные и разветвлённые задачи с декомпозицией | Multi-agent orchestrator (spawn_agent) | ~12 | Автоматический спавн изолированных дочерних субагентов и сборка их результатов |
plan | Проектирование архитектуры, планов реализации и презентаций | Пропускает planner (LLM пишет plan.md) | ~10 | Создание/обновление файлов plan.md, интерактивное уточнение (clarify-first), слайды PowerPoint (create_pptx) |
obs | Диагностика инфраструктуры, логов, метрик и трейсов | Пропускает planner, использует Obs MCP | ~10 | Сбор метрик и логов через MCP Gateway / Grafana / Prometheus without destructive mutations |
spec | Формирование спецификаций, ТЗ и описаний сервисов | Пропускает planner, подключает RAG/код | ~10 | Автоматическое сохранение итоговой спецификации в заметку (create_note) или файл (create_file) |
sub-agent | Выбранный Assistant или дочерний spawn | Наследует agent loop | ~10 | Tools/skills/MCP только из этого ассистента (mcp_slugs). Пикер с agent_id идёт сюда, не в оркестратор. Spawn от multi-agent — тот же runtime, чат read-only. |
Детальное описание режимов
1. Режим Chat (mode=chat)
- Назначение: Быстрые ответы на вопросы, генерация текста, простые разовые команды.
- Особенности: Использует короткий цикл диалога. Если к чату подключены инструменты, входным узлом становится локальный Planner, который определяет необходимые вызовы перед генерацией ответа.
2. Режим Multi-Agent (mode=multi-agent)
- Назначение: Решение крупных составных задач, требующих параллельной или последовательной работы узкоспециализированных агентов.
- Особенности: Оркестратор анализирует запрос и каталог доступных ассистентов. Через инструмент
spawn_agentон создает изолированные дочерние чаты (mode=sub-agent), передает им контекст, дожидается выполнения и синтезирует финальный ответ. Выбор конкретного ассистента в пикере (agent_id) не включает оркестратор: ход идёт какsub-agentс MCP изmcp_slugsэтогоAssistant, без полного реестра gateway.
3. Режим Plan (mode=plan)
- Назначение: Разработка планов интеграций, декомпозиция релизов, создание структуры презентаций.
- Особенности:
- Clarify-first: если запрос неоднозначен, сначала задаются уточняющие вопросы через
ask_user. - Pinned plan.md: итоговый план сохраняется как закрепеленный документ; повторные правки перезаписывают его без мусора в истории.
- PPTX Generation: если в плане описываются слайды, активируется рендер презентаций через
create_pptx.
- Clarify-first: если запрос неоднозначен, сначала задаются уточняющие вопросы через
4. Режим Observability (mode=obs)
- Назначение: Мониторинг, анализ сбоев, просмотр метрик и логов в реальном времени.
- Где доступен: только в общем чате (без space scope); внутри пространства режим недоступен. MCP-серверы — все включённые в MCP Gateway, а не привязанные к пространству.
- Особенности: Подключает MCP-инструменты наблюдаемости (Grafana, Prometheus, Sentry, Jaeger). Исключает мутирующие инструменты, отдавая приоритет безопасному сбору фактов и визуализации состояния.
5. Режим Spec (mode=spec)
- Назначение: Составление регламентов, архитектурных спецификаций и технических заданий.
- Особенности: Активно задействует RAG и поиск по исходному коду. После согласования текста автоматически создает заметку в пространстве (
create_note) или сохраняет файл. - Шаблон: markdown
kind: unishift-specв prompt Chat Loop. Скиллы —graph.skill_slugsпайплайна spec; после установки список пустой. Правка — Управление ответами.create_taskвыключен.
Sidecar GGUF через ush platform enable llama-planner больше не ставится. Planner, diagram, fill, embed и Bosun подключаются вручную. Подробнее: Локальные модели.
Starlark
См. starlark-api.md — модуль up.ai_router (провайдеры, чаты, ingest_document с metadata, scopes).