11 KiB
11 KiB
User Request Pipeline TODO
Этот чеклист описывает оставшиеся задачи по доведению pipeline до чистой архитектуры. Текущее состояние уже рабочее: есть UserRequestPipeline, stage audit, ai_requests, internal artifacts, unified size gate, RAG/STT/final/error/tool-result artifacts и response pipeline. Ниже перечислены задачи, которые ещё нужно сделать, чтобы убрать оставшиеся архитектурные компромиссы.
1. Нормализовать хранение attachments, artifacts и audit
- Создать отдельную таблицу
attachments. - Поля
attachments:id,messageChatId,messageId,direction,scope,kind,artifactKind,fileId,fileUniqueId,fileName,mimeType,cachePath,sizeBytes,sha256,metadata,createdAt. - Создать отдельную таблицу
artifacts. - Поля
artifacts:id,requestId,messageChatId,messageId,kind,stage,attachmentId,payload,createdAt. - Создать отдельную таблицу
request_audit. - Поля
request_audit:id,requestId,messageChatId,messageId,stage,status,startedAt,finishedAt,durationMs,provider,model,details,error. - Оставить обратную совместимость с текущими JSON-полями
messages.attachmentsиmessages.pipelineAudit. - Добавить миграцию: переносить существующие
messages.attachmentsв новую таблицуattachments. - Добавить миграцию: переносить существующие
messages.pipelineAuditв новую таблицуrequest_audit. - Обновить backup/export/import, чтобы новые таблицы попадали в JSON и SQL dump.
- Добавить DAO/store слой:
AttachmentStore,ArtifactStore,RequestAuditStore. - Перевести новые записи на нормализованные таблицы.
- Оставить чтение legacy JSON только как fallback.
2. Сделать единый ArtifactStore API
- Ввести
ArtifactStore.put(...). - Ввести
ArtifactStore.getByRequestId(requestId). - Ввести
ArtifactStore.getByMessage(chatId, messageId). - Ввести
ArtifactStore.getLatestRagForReplyChain(chatId, messageId). - Ввести
ArtifactStore.getTranscriptForMessage(chatId, messageId). - Перевести
rag-artifact-store.tsнаArtifactStore. - Перевести
transcript-artifact-store.tsнаArtifactStore. - Перевести
final-response-artifact-store.tsнаArtifactStore. - Перевести
tool-result-artifact-store.tsнаArtifactStore. - Оставить физические JSON-файлы как storage backend для payload, но регистрировать их в БД.
- Добавить единый size gate для artifact payload до записи файла.
- Добавить cleanup policy для временных/устаревших artifact файлов.
3. Расширить RAG artifact content
- Расширить общий тип
RagArtifact. - Для Ollama сохранять extracted documents.
- Для Ollama сохранять selected chunks.
- Для Ollama сохранять chunk scores.
- Для Ollama сохранять skipped documents и причины пропуска.
- Для Ollama сохранять embedding model,
topK,chunkSize,chunkOverlap,maxContextChars. - Для OpenAI сохранять
vectorStoreIds. - Для OpenAI сохранять source file mapping: local attachment -> uploaded/vector store file.
- Для Mistral сохранять
libraryId. - Для Mistral сохранять uploaded document ids.
- Для Mistral сохранять source file mapping: local attachment -> Mistral document id.
- Добавить единый
providerStateschema для всех providers. - Добавить tests на сериализацию
RagArtifact. - Добавить tests на то, что internal RAG artifacts не попадают обратно в user document context.
4. Вынести provider runners в adapter layer
- Ввести интерфейс
AiProviderAdapter. - Методы adapter-а:
mapMessages,rankTools,callModel,extractTextDelta,extractToolCalls,appendToolResults,finalize. - Реализовать
OpenAiProviderAdapter. - Реализовать
MistralProviderAdapter. - Реализовать
OllamaProviderAdapter. - Перенести provider-specific tool schema mapping внутрь adapter-ов.
- Перенести provider-specific streaming parsing внутрь adapter-ов.
- Перенести provider-specific tool result append внутрь adapter-ов.
- Упростить
runOpenAi,runMistral,runOllamaили заменить их adapter-driven runner-ом. - Оставить compatibility wrappers для текущих imports.
- Добавить tests на adapter contract без реальных API.
5. Сделать tool-ranker полноценным pipeline stage
- Вынести вызов
ToolRanker.selectTools(...)из provider runners. - Добавить stage
tool_rank, который работает через provider adapter. - Добавить stage
filter_tools, который фильтрует provider-specific tools по результату ranker. - Хранить
ToolRankDecisionвUserRequestPipelineState.toolRankDecisions. - Сохранять
ToolRankDecisionвrequest_audit.details. - Убрать дублирующий ручной
tool-rank-audit.ts, если stage полностью заменит его. - Сохранить status UX:
🧩 Выбираю подходящие инструменты.... - Гарантировать
clearStatus()после ranker success/failure. - Добавить fallback через
PipelineFallbackExecutor: main model, all tools, no tools. - Добавить tests на fallback ranker policy.
6. Сделать model_call и tool_loop физически отдельными stages
- Stage
model_callдолжен делать только один model request. - Stage
model_callдолжен возвращать normalized model output. - Stage
tool_loopдолжен решать, есть ли tool calls. - Stage
tool_loopдолжен выполнять tools через общийexecuteToolBatch. - Stage
tool_loopдолжен добавлять tool results в provider adapter. - Stage
tool_loopдолжен управлять max rounds. - Stage
tool_loopдолжен сохранять tool result artifacts. - Stage
tool_loopдолжен уметь завершаться без tools какskipped. - Убрать tool loop из
runOpenAi. - Убрать tool loop из
runMistral. - Убрать tool loop из
runOllama. - Добавить tests на multi-round fake adapter.
7. Довести fallback notifications до централизованного UX
- Добавить
PipelineFallbackNotifier. - Для
notify_userотправлять пользователю понятное сообщение. - Для
continue_without_stageписать короткий debug/audit без user notification. - Для
use_alternate_targetлогировать исходный и alternate target. - Для
fail_requestзавершать request через единый error path. - Добавить локализацию fallback messages.
- Добавить отдельные тексты для RAG failure, STT failure, TTS failure, tool failure.
- Не спамить пользователя несколькими fallback notifications за один request.
- Сохранять fallback notification в
request_audit.details.
8. Улучшить поведение reply-chain с документами
- Явно описать стратегию merge: current user attachments + reply-chain user attachments.
- Исключать
scope: internal_artifactвсегда. - Исключать
scope: bot_output, если это не user-provided file. - Если пользователь отвечает новым документом на ответ бота с предыдущим документом, использовать оба документа.
- Если пользователь отвечает текстом на ответ бота, использовать документы из reply-chain.
- Если пользователь явно говорит "этот файл", приоритет отдавать новому вложению.
- Если несколько документов, добавлять их имена в prompt/RAG context.
- Добавить tests на follow-up с новым документом.
- Добавить tests на follow-up без нового документа.
- Добавить tests на то, что RAG internal JSON не становится пользовательским документом.
9. Интеграционные tests без реальных Telegram/AI API
- Создать fake
TelegramStreamMessage. - Создать fake provider adapter.
- Создать fake message store или in-memory DB fixture.
- Test: oversized input attachment rejected before download.
- Test: document input creates RAG artifact.
- Test: voice input creates transcript artifact.
- Test: final answer creates final_text artifact.
- Test: thrown error creates error artifact.
- Test: tool call creates tool_result artifact.
- Test: generated file creates generated_file artifact.
- Test: TTS requested creates tts_audio artifact.
- Test: fallback
continue_without_stagecontinues request. - Test: fallback
fail_requeststops request.
10. Operational cleanup and observability
- Add retention policy for
data/cache/internal-artifacts. - Add retention policy for stale RAG vector/library provider state.
- Add command or admin view for recent
ai_requests. - Add command or admin view for request audit by message id.
- Add command to inspect artifacts for a message.
- Add log correlation by
requestIdacross AI logs, tool logs and DB audit. - Add metrics counters: requests, failures, fallbacks, tool calls, RAG runs, TTS runs.
- Add startup migration logs for
ai_requests,attachments,artifacts,request_audit.
Suggested order
- 1. Normalize DB tables:
attachments,artifacts,request_audit. - 2. Build
ArtifactStoreand migrate current artifact helpers to it. - 3. Add fake integration tests for reply-chain documents and artifacts.
- 4. Introduce provider adapter interface.
- 5. Move
tool_rankinto pipeline stage. - 6. Split
model_callandtool_loopphysically. - 7. Add centralized fallback user notifications.