c96fafc4ad
Раньше каждый onStepFinish переписывал ВСЮ строку ассистента (растущий metadata.parts jsonb со всеми выводами инструментов) → O(n²) объёма записи на прогон: под MVCC/TOAST апдейт jsonb переписывает всю версию строки, так что шаг k пишет ~k×вывод. Прогон из 50 шагов по ~100 КБ = сотни МБ WAL и мёртвых кортежей за ход, что молотит autovacuum. (#490 убрал только ВТОРУЮ копию в tool_calls; сам metadata.parts всё ещё рос и переписывался.) Теперь каждый завершённый шаг ДОПИСЫВАЕТСЯ отдельной строкой в лёгкую таблицу ai_chat_run_steps (только парты этого шага), а строка сообщения получает дешёвый маркер (stepsPersisted + toolTraceVersion, без растущего блоба parts). Полный metadata.parts собирается ОДИН раз на финализации. НЕ jsonb-append (||): апдейт всё равно переписывает всю TOAST-версию — экономится только сетевой payload, а WAL/мёртвые кортежи остаются; поэтому именно ОТДЕЛЬНАЯ таблица + INSERT. Три обязательные интеграции: - reconstructRunParts(row, stepRows) → { parts, stepsPersisted }: единый шов переключения бэкенда. Читает парты из СТРОКИ, если она уже несёт inline-parts (старые записи + ЛЮБАЯ финализированная), иначе из ТАБЛИЦЫ ШАГОВ (mid-run запись #492). Дискриминатор — наличие непустого metadata.parts (флаг схемы не нужен). Потребители (attach-seed, delta-poll, export, reconnect) прогоняют строки через hydrateAssistantParts на границе чтения — их контракт/вывод не меняется, старые и новые записи восстанавливаются идентично. - сигнал ротации кольца реестра #491 (confirmPersistedStep) теперь стреляет на подтверждённый INSERT шага, под тем же контрактом (updateStreaming возвращает stepsPersisted / null). - era-marker toolTraceVersion (#490) больше не ставится полной переписью — ставится в маркере шага и на финализации (flushAssistant), остаётся консистентным. Полная обратная совместимость: прогон, записанный по-старому (полная строка, без строк шагов), восстанавливается/attach/export идентично. При отсутствии репозитория шагов (позиционные тест-конструкции) — фолбэк на прежний полнострочный flush (без регрессии, только без выигрыша WAL). Тесты (реальный pg, int-lane): - WAL-дельта (pg_current_wal_lsn) на прогоне 40×100КБ: new=4.3МБ vs old=90.3МБ (20.8x) — O(Σ шагов) против O(n²); старый путь в тесте И есть ревертнутое поведение (мутация-проверка). - reconstruct-контракт: new-style (таблица шагов) и old-style (inline) прогоны восстанавливаются в идентичные parts; hydrate заполняет строку. - миграция up/down roundtrip. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A progressive Node.js framework for building efficient and scalable server-side applications.
Description
Nest framework TypeScript starter repository.
Installation
$ npm install
Running the app
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
Migrations
# This creates a new empty migration file named 'init'
$ npm run migration:create --name=init
# Generates 'init' migration file from existing entities to update the database schema
$ npm run migration:generate --name=init
# Runs all pending migrations to update the database schema
$ npm run migration:run
# Reverts the last executed migration
$ npm run migration:revert
# Reverts all migrations
$ npm run migration:revert
# Shows the list of executed and pending migrations
$ npm run migration:show
## Test
```bash
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.
Stay in touch
- Author - Kamil Myśliwiec
- Website - https://nestjs.com
- Twitter - @nestframework
License
Nest is MIT licensed.